Skip to content

feat: support native loadState#351

Draft
spiral-ladder wants to merge 5 commits intomainfrom
bing/load-state
Draft

feat: support native loadState#351
spiral-ladder wants to merge 5 commits intomainfrom
bing/load-state

Conversation

@spiral-ladder
Copy link
Copy Markdown
Collaborator

  • add native loadState that mirrors TS implementation
  • add bindings
  • add benchmarks to bench naive + loadState difference

part of #347

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 native loadState mechanism to the project, designed to optimize state transition performance. By leveraging tree-reuse for validator and inactivity score subtrees, the implementation minimizes redundant memory operations when loading new states from existing ones. This change is part of a broader effort to improve the efficiency of state handling within the beacon node.

Highlights

  • Native loadState Implementation: Introduced a native loadState function in Zig that mirrors the existing TypeScript implementation, enabling efficient state loading by reusing validator and inactivity score subtrees.
  • Performance Optimization: Implemented tree-reuse logic that significantly reduces memory allocation and processing time by sharing unchanged nodes between states.
  • Bindings and Benchmarks: Added NAPI bindings for loadOtherState and included new benchmarks to compare the performance of the native implementation against the existing TypeScript version.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

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 the 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 counterproductive. 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.

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.

Copy link
Copy Markdown
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 a tree-reuse optimized loadOtherState method to BeaconStateView and a corresponding utility module in src/state_transition/utils/load_state.zig to improve state loading performance by sharing unchanged validator and inactivity score subtrees. The reviewer highlighted several violations of the repository style guide, specifically the use of recursion in findModifiedValidators and findModifiedInactivityScores, insufficient assertion density across the new utility functions, and a function length exceeding the 70-line limit in loadState. Additionally, a potential memory leak was identified regarding the deinitialization of TreeView objects returned by seed_view.get(i).

I am having trouble creating individual review comments. Click here to see my feedback.

src/state_transition/utils/load_state.zig (23-41)

high

The use of recursion in findModifiedValidators violates the repository style guide (Rule 32), which prohibits recursion to ensure bounded execution. Please refactor this to an iterative implementation. A simple loop over the validator chunks would be safer and likely sufficiently performant for this use case.

References
  1. Do not use recursion to ensure that all executions that should be bounded are bounded. (link)

src/state_transition/utils/load_state.zig (45-63)

high

The use of recursion in findModifiedInactivityScores violates the repository style guide (Rule 32). This should be refactored into an iterative loop.

References
  1. Do not use recursion to ensure that all executions that should be bounded are bounded. (link)

src/state_transition/utils/load_state.zig (138)

high

The seed_validator view obtained via seed_view.get(i) is likely leaking. In this architecture, get() typically returns a heap-allocated TreeView that the caller is responsible for deinitializing. Since it is only used as a temporary reference to fetch root nodes in loadValidator, it should be deinited at the end of each iteration.

src/state_transition/utils/load_state.zig (72-77)

medium

This function lacks assertions for its arguments and invariants. According to the style guide (Rule 51, 54), every function must have a minimum of two assertions to detect programmer errors and document pre/postconditions. This is a widespread issue in this new file (e.g., loadValidators, loadInactivityScores, loadState).

References
  1. Assert all function arguments and return values, pre/postconditions and invariants. The assertion density of the code must average a minimum of two assertions per function. (link)

src/state_transition/utils/load_state.zig (268-347)

medium

The loadState function is 80 lines long, exceeding the hard limit of 70 lines per function defined in the style guide (Rule 108). Consider refactoring the fork-specific logic into helper functions to improve readability and maintainability.

References
  1. Restrict the length of function bodies to reduce the probability of poorly structured code. We enforce a hard limit of 70 lines per function. (link)

- add native `loadState` that mirrors TS implementation
- add bindings
- add benchmarks to bench naive + loadState difference


part of #347
@GrapeBaBa
Copy link
Copy Markdown
Contributor

native part has been implemented in #165

@spiral-ladder
Copy link
Copy Markdown
Collaborator Author

@GrapeBaBa missed this PR, sorry!taking a look

GrapeBaBa added a commit that referenced this pull request May 7, 2026
Adds the bench requested by spiral-ladder on PR #165, mirroring PR #351's
loadState perf test shape:

- BeaconStateView.loadOtherStateBench (NAPI): bench-only entry that runs
  st.loadState end-to-end and tears down the result, no CachedBeaconState
  wrap or EpochCache build, so native vs TS comparisons isolate the SSZ
  tree-rebuild cost.
- index.d.ts: TS surface declaration.
- bindings/perf/loadState.test.ts: 4 cases (native/TS x with/without
  prebuilt seedValidatorsBytes) using @chainsafe/benchmark on a mainnet
  era state.
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.

2 participants