fix: gate loadOtherState validators/balances preload behind opt-in#9245
fix: gate loadOtherState validators/balances preload behind opt-in#9245
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces an optional preloadValidatorsAndBalances flag to the loadOtherState method, enabling eager materialization of validator and balance arrays only when necessary, such as during block replay. This change helps avoid significant memory overhead in API paths that only require specific fields. The update includes modifications to the BeaconStateView implementation, its interface, and the persistent checkpoint cache, along with a new unit test. A review comment suggests refactoring the inline options type into a named interface to improve code maintainability.
914f164 to
74b3a11
Compare
74b3a11 to
af04829
Compare
Performance Report✔️ no performance regression detected Full benchmark results
|
|
Cross-linking from #9246: this PR addresses the API-path memory spike, but there is a separate correctness bug in the same The cache-aliasing bug in The default Why the preload gating in this PR does not fix it The poisoning happens inside
So this PR correctly fixes the memory spike but leaves the correctness bug untouched. Also relevant: Fix #9246 (two-line |
lodekeeper
left a comment
There was a problem hiding this comment.
LGTM. Surgical fix: gates the eager getAllReadonlyValues() / getAll() preload behind an opt-in flag and only persistentCheckpointsCache (which always consumes the state immediately via block replay) sets it.
Correctness: Interface + impl + single call-site change are consistent. All six other loadOtherState() callers (api/impl/beacon/state, api/impl/validator, api/impl/proof, api/impl/lodestar × 2, plus the unit test) now revert to lazy materialization — restores pre-#8857 semantics on API paths. Optional arg keeps the signature backwards-compatible.
Risk: Low. This just narrows an existing optimization to where it's actually needed.
Independence from #9246: Confirmed — this PR doesn't touch loadState() where the cache-aliasing bug lives, so the two fixes address distinct v1.42.0 regressions (memory spike vs. withdrawal mismatch). Both are needed for the public-node redeploy.
Nice minimal fix 👍
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #9245 +/- ##
=========================================
Coverage 52.53% 52.53%
=========================================
Files 848 848
Lines 61405 61405
Branches 4525 4525
=========================================
Hits 32259 32259
Misses 29081 29081
Partials 65 65 🚀 New features to boost your workflow:
|
Motivation
Main-thread memory spike on
serveHistoricalState: truenodes after #8857#8857 rerouted the API path through
getState()inpackages/beacon-node/src/api/impl/beacon/state/index.tsfrom the lightweightloadState(...)toBeaconStateView.loadOtherState(), which eagerly materializesall validators and balances. That is only needed for
persistentCheckpointsCache.Description
loadOtherState()opt-in via{preloadValidatorsAndBalances: true}. Default is lazy, matching pre-chore: consume BeaconStateView #8857 semantics.persistentCheckpointsCachepasses in this flag as truelodestar/packages/beacon-node/src/api/impl/beacon/state/index.ts
Line 34 in 9fa9f08
AI Assistance Disclosure
This PR was developed with AI assistance (Claude Code).