Skip to content

perf: reserve deposit balance capacity - #817

Closed
GrapeBaBa wants to merge 1 commit into
mainfrom
gr/reserve-deposit-balances
Closed

GrapeBaBa wants to merge 1 commit into
mainfrom
gr/reserve-deposit-balances

Conversation

@GrapeBaBa

@GrapeBaBa GrapeBaBa commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

processRewardsAndPenalties builds cache.balances with fromOwnedSlice over an exact-length slice, so the list has no spare capacity. The first balance processPendingDeposits appends for a new validator then reallocates and copies the whole list, about 18.5 MB on mainnet (2.3M validators). Instrumenting a 128-block mainnet replay (2 new validators):

process_pending_deposits     16.31 ms
  cache.balances.append      10.26 ms

Description

Reserve room in cache.balances for the deposits applied in the same epoch.

  • processRewardsAndPenalties: allocate with initCapacity(validator_count + MAX_PENDING_DEPOSITS_PER_EPOCH) and fill with getAllInto. Same single allocation and fill as before.
  • applyPendingDeposit: appendAssumeCapacity. The deposit loop applies at most MAX_PENDING_DEPOSITS_PER_EPOCH deposits per epoch and each adds at most one balance.
  • New test checks the spare capacity.

Replay A/B (EPYC 9634, ReleaseSafe, 5 alternating rounds), ms per epoch boundary:

main this PR
process_pending_deposits 4.46 1.72
process_rewards_and_penalties, median 37.23 37.13

AI Assistance Disclosure

Primarily AI-authored with Claude Code.

processRewardsAndPenalties built cache.balances from an exact-length
slice, so the first balance processPendingDeposits appended for a new
validator reallocated and copied the whole list (about 18.5 MB at 2.3M
validators).

Allocate the list with MAX_PENDING_DEPOSITS_PER_EPOCH spare capacity.
The deposit loop applies at most that many deposits per epoch and each
adds at most one balance, so applyPendingDeposit uses
appendAssumeCapacity.

Measured on a 128-block mainnet replay of silver's perf fixture
(EPYC 9634, ReleaseSafe, 5 alternating rounds against main ff956b2):
process_pending_deposits 4.46 -> 1.72 ms per epoch boundary,
process_rewards_and_penalties unchanged (median 37.23 vs 37.13 ms).
@GrapeBaBa

Copy link
Copy Markdown
Contributor Author

Moved to ChainSafe/lodestar#10523 (combined with #819) now that lodestar-z is merged into Lodestar (ChainSafe/lodestar#10513).

@GrapeBaBa GrapeBaBa closed this Oct 30, 2026
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Lodestar Team Coordination Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant