feat: cache the last 2 PayloadEnvelopeInputs#9260
Conversation
Move slot from ExecutionPayloadEnvelope to ExecutionPayload as slotNumber (uint64) and add slotNumber to PayloadAttributes per consensus-specs#4840. Updates all verification, gossip validation, signing, serialization, and SSZ byte extraction accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…eturn New function implements deferred parent execution payload processing (consensus-specs#5094). Moves execution requests, builder payment, and availability updates from envelope processing to block processing. Removes the isParentBlockFull early return in processWithdrawals since processParentExecutionPayload now runs before withdrawals. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lock New ordering for Gloas blocks: 1. processParentExecutionPayload (NEW - before header) 2. processBlockHeader 3. processWithdrawals (no longer has empty-parent early return) 4. processExecutionPayloadBid 5. ... rest unchanged Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Envelope verification no longer mutates state. All state effects (execution requests, builder payment, availability, latestBlockHash) have moved to processParentExecutionPayload in the next block. Changes: - Remove state cloning, execution request processing, builder payment, availability/latestBlockHash updates, and state root verification - Add executionRequestsRoot check against bid commitment - Return void instead of post-state - Remove verifyStateRoot and dontTransferCache options - Rename stateView method to verifyExecutionPayloadEnvelope Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…onPayload With deferred payload processing, the envelope no longer produces a separate post-state. The FULL variant node shares the same stateRoot as the PENDING node. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- importExecutionPayload now does pure verification only — no state cloning, no post-payload state computation, no state root check, no regen.processState(), no checkpoint caching - Remove stateRoot from executionPayload and executionPayloadGossip events - Remove stateRoot from envelope construction in validator API - Remove stateRoot from fork choice onExecutionPayload call - Envelope verification runs via verifyExecutionPayloadEnvelope (void) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rocessing Block production: - Add executionRequestsRoot to ExecutionPayloadBid construction - Add parentExecutionRequests to BeaconBlockBody via getParentExecutionRequests() - Add getParentExecutionRequests() to BeaconChain (returns parent's execution requests from cached envelope, or empty if EMPTY parent) Gossip validation: - Add executionRequestsRoot check in envelope validation - Add EXECUTION_REQUESTS_ROOT_MISMATCH error code Cleanup: - Remove stateRoot from validator envelope logging - Fix spec test for void-returning processExecutionPayloadEnvelope - Update stale TODO comment in writePayloadEnvelopeInputToDb Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use electra.ExecutionRequests type instead of unknown[] - Fix parentBlockRootHex -> parentBlock.blockRoot variable name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…processing # Conflicts: # packages/beacon-node/src/chain/blocks/importExecutionPayload.ts # packages/beacon-node/test/spec/presets/fork_choice.test.ts # packages/beacon-node/test/spec/utils/specTestIterator.ts # packages/state-transition/src/block/processExecutionPayloadEnvelope.ts
92e3b42 to
89a60b7
Compare
| * transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips | ||
| * ticks; subsequent ticks settle it back. | ||
| * | ||
| * Consumers that miss the cache fall back to DB (`chain.getParentExecutionRequests` / |
There was a problem hiding this comment.
getParentExecutionRequests doesnt exist?
There was a problem hiding this comment.
not yet, will be in the next range sync PR
| const updatedHead = this.chain.forkChoice.getBlockHexDefaultStatus(updatedHeadRoot); | ||
| const updatedHeadParent = |
There was a problem hiding this comment.
do we need to call fork choice here again?
There was a problem hiding this comment.
no need, we don't change anything here
| * Spec: https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.5/specs/gloas/validator.md#executionpayload | ||
| */ | ||
| getExpectedWithdrawalsForFullParent(envelope: gloas.SignedExecutionPayloadEnvelope): capella.Withdrawal[] { | ||
| getExpectedWithdrawalsForFullParent(executionRequests: electra.ExecutionRequests): capella.Withdrawal[] { |
There was a problem hiding this comment.
is function signature change here needed? I guess it's fine to keep in minimal but not clear why this PR changes it
There was a problem hiding this comment.
it's for range sync in produceBlockBody https://github.com/ChainSafe/lodestar/pull/9242/changes#diff-c331f7b8e7121839c55f5f20f21d1efe1375b69c6fbbe5db12a4baf1ed4acf5dR656
it's technically not from this PR, will revert it and readd in range sync PR
Performance Report🚀🚀 Significant benchmark improvement detected
Full benchmark results
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #9260 +/- ##
=========================================
Coverage 52.53% 52.53%
=========================================
Files 848 848
Lines 61311 61309 -2
Branches 4510 4510
=========================================
- Hits 32207 32206 -1
+ Misses 29039 29038 -1
Partials 65 65 🚀 New features to boost your workflow:
|
Motivation
PayloadEnvelopeInputfromseenPayloadEnvelopeInputCacheright after we persist to DB, because block production needs it (next-slotgetParentExecutionRequestsandprepareExecutionPayloadread the cached envelope synchronously).Description
PayloadEnvelopes in memory (head + head.parent)AI Assistance Disclosure
Used Claude Code to assist with implementation and review.