Skip to content

Conversation

@twoeths
Copy link
Contributor

@twoeths twoeths commented Dec 5, 2025

Motivation

  • snappy-wasm introduced different behaviour on different nodes: great on non-sas nodes but introduced performance regression on sas nodes, see feat: use snappy-wasm (#6483) #8647

Description

  • bring snappy-js implementation to lodestar
    • a little improvement: use Buffer.allocUnsafe() there
  • use snappy-js for beacon_attestation topic type and snappy-wasm for other topics
  • this is deployed to feat3

@twoeths twoeths requested a review from a team as a code owner December 5, 2025 03:24
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @twoeths, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a strategic change to the Snappy decompression mechanism within the beacon node to resolve a performance bottleneck identified on SAS nodes. By selectively applying snappy-js for beacon_attestation messages and retaining snappy-wasm for other data, the system aims to optimize decompression efficiency. The changes involve integrating a new library, refactoring core data transformation logic, and ensuring robust error handling and test coverage for the new hybrid approach.

Highlights

  • Performance Improvement: Addresses a performance regression on SAS nodes caused by snappy-wasm by introducing a hybrid compression strategy.
  • Hybrid Snappy Decompression: Implements a dynamic selection mechanism to use snappy-js for beacon_attestation topic types (typically smaller payloads) and snappy-wasm for all other topics.
  • New Dependency: Adds snappyjs as a new dependency to the beacon-node package.
  • Refactored Decompression Logic: The inboundTransform function in encoding.ts has been refactored to utilize a new ISnappyDecompressor interface, allowing for different Snappy implementations to be used based on the topic type. Error messages for decompression failures have also been enhanced.
  • New Snappy-JS Implementation: Introduces a complete snappy-js implementation, including SnappyCompressor, SnappyDecompressor, and associated error handling, within the project.
  • Unit Tests: Adds new unit tests to validate the correct functioning of the hybrid snappy decompression logic across various data lengths and gossip types.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@twoeths twoeths changed the title Te/cayman/snappy feat: use different snappy implementations for different topics Dec 5, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces snappyjs for decompressing beacon_attestation messages to address performance regressions on certain nodes, while snappy-wasm is retained for other message types and all compression tasks. The changes are well-structured, using a decompressor interface and a factory function for selecting the appropriate implementation. My review focuses on improving the consistency and error handling between the two snappy implementations to make the new abstraction more robust.

*/
export function getSnappyDecompressor(topicType: GossipType, data: Uint8Array): ISnappyDecompressor {
switch (topicType) {
case GossipType.beacon_attestation:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also aggregate and proof?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched to use snappy-wasm for data_column_sidecar and beacon_block
for others use snappy-js

@@ -0,0 +1,56 @@
import {SnappyCompressor} from "./compressor.js";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, this is snappyjs but converted to typescript?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should leave a comment here linking back to the upstream,
eg, // Based on snappyjs - https://github.com/zhipeng-jia/snappyjs

return -1;
}

uncompressInto(outBuffer: Uint8Array): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and we are now using this, which was previously hidden by our incomplete manually-crafted types

Copy link
Member

@wemeetagain wemeetagain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you update the snappy benchmarks with this impl of snappyjs?

@twoeths
Copy link
Contributor Author

twoeths commented Dec 5, 2025

The high MarkSweepCompact gc issue on feat3 is still high until I switched back to Buffer.alloc()

Screenshot 2025-12-05 at 14 49 24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants