Skip to content

feat: add payload envelope reqresp#9050

Open
ensi321 wants to merge 15 commits intounstablefrom
nc/epbs-reqresp
Open

feat: add payload envelope reqresp#9050
ensi321 wants to merge 15 commits intounstablefrom
nc/epbs-reqresp

Conversation

@ensi321
Copy link
Contributor

@ensi321 ensi321 commented Mar 17, 2026

No description provided.

@ensi321 ensi321 requested a review from a team as a code owner March 17, 2026 00:20
@gemini-code-assist
Copy link
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 new peer-to-peer (P2P) protocols to enable the retrieval of execution payload envelopes within the beacon node network. These additions are critical for supporting upcoming network requirements, likely associated with a new Ethereum fork, by allowing nodes to efficiently request and serve execution payload data either by block root or by a specified slot range.

Highlights

  • New P2P Protocols: Introduced two new P2P request/response protocols: ExecutionPayloadEnvelopesByRoot and ExecutionPayloadEnvelopesByRange to facilitate the retrieval of execution payload envelopes.
  • Handler Implementation: Implemented dedicated handlers for these new protocols, enabling the beacon node to fetch execution payload envelopes from its database based on either block root or a specified slot range, covering both finalized and unfinalized data.
  • Fork Integration: Integrated the new protocols into the ReqRespBeaconNode, activating them conditionally when the gloas fork is active.
  • Network Health Management: Established rate limiting configurations and updated peer scoring mechanisms for the newly introduced protocols to ensure network stability and prevent abuse.
  • Type Definitions: Defined necessary SSZ (Simple Serialize) types and updated request/response structures across various modules to support the new payload envelope data and protocols.

🧠 New Feature in Public Preview: You can now enable Memory 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.

Changelog
  • packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts
    • Enabled ExecutionPayloadEnvelopesByRoot and ExecutionPayloadEnvelopesByRange protocols for the gloas fork.
  • packages/beacon-node/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts
    • Added a new handler for ExecutionPayloadEnvelopesByRange requests, fetching payload envelopes by slot range from both finalized and unfinalized databases.
  • packages/beacon-node/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts
    • Added a new handler for ExecutionPayloadEnvelopesByRoot requests, fetching payload envelopes by block root.
  • packages/beacon-node/src/network/reqresp/handlers/index.ts
    • Imported and registered the new ExecutionPayloadEnvelopesByRoot and ExecutionPayloadEnvelopesByRange handlers.
  • packages/beacon-node/src/network/reqresp/protocols.ts
    • Defined ExecutionPayloadEnvelopesByRoot and ExecutionPayloadEnvelopesByRange protocols.
  • packages/beacon-node/src/network/reqresp/rateLimit.ts
    • Configured rate limits for the new ExecutionPayloadEnvelopesByRoot and ExecutionPayloadEnvelopesByRange methods.
  • packages/beacon-node/src/network/reqresp/score.ts
    • Updated peer scoring logic to include ExecutionPayloadEnvelopesByRange in mid-tolerance error handling.
  • packages/beacon-node/src/network/reqresp/types.ts
    • Expanded ReqRespMethod enum, request/response body types, and SSZ type mappings to include the new payload envelope protocols.
    • Imported gloas types.
  • packages/beacon-node/src/util/types.ts
    • Defined ExecutionPayloadEnvelopesByRootRequestType and its corresponding TypeScript type.
  • packages/types/src/gloas/sszTypes.ts
    • Added SSZ type definition for ExecutionPayloadEnvelopesByRangeRequest.
  • packages/types/src/gloas/types.ts
    • Added TypeScript type definition for ExecutionPayloadEnvelopesByRangeRequest.
Activity
  • No specific activity (comments, reviews, progress) was provided in the context for this pull request.
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.

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 support for ExecutionPayloadEnvelopes request-response protocols, which is a key feature for the upcoming gloas fork. The changes are well-structured and follow the existing patterns for adding new network protocols. I've identified one minor omission related to peer scoring on request timeouts that should be addressed for consistency.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e20f2b08a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

// TODO GLOAS: Use chain.getSerializedExecutionPayloadEnvelope() to check in-memory caches before hitting the db when the method is available
const envelopeBytes = await db.executionPayloadEnvelope.getBinary(root);

Choose a reason for hiding this comment

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

P1 Badge Read finalized envelopes when serving by-root requests

This handler accepts roots from the MIN_EPOCHS_FOR_BLOCK_REQUESTS window but only reads from db.executionPayloadEnvelope (hot/unfinalized storage), so valid finalized roots in that window are silently skipped once data is archived/pruned from hot DB. In practice, peers requesting older-but-still-allowed roots will get empty responses even when the node has the envelope in archive, so this needs a finalized fallback path before continuing.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We probably can. But onBeaconBlocksByRoot currently doesn't serve blocks from cold db. A TODO was added in #8784. We probably want to wait until that is resolved before we serve finalized payloads

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

⚠️ Performance Alert ⚠️

Possible performance regression was detected for some benchmarks.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold.

Benchmark suite Current: 7b83a39 Previous: 7e96447 Ratio
phase0 getAttestationDeltas - 250000 worstcase 17.000 ms/op 4.7573 ms/op 3.57
Full benchmark results
Benchmark suite Current: 7b83a39 Previous: 7e96447 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1699 ms/op 874.68 us/op 1.34
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.181 us/op 38.895 us/op 1.03
BLS verify - blst 751.46 us/op 889.54 us/op 0.84
BLS verifyMultipleSignatures 3 - blst 1.1672 ms/op 1.3727 ms/op 0.85
BLS verifyMultipleSignatures 8 - blst 1.6387 ms/op 2.3773 ms/op 0.69
BLS verifyMultipleSignatures 32 - blst 4.8197 ms/op 4.6486 ms/op 1.04
BLS verifyMultipleSignatures 64 - blst 8.9009 ms/op 8.8483 ms/op 1.01
BLS verifyMultipleSignatures 128 - blst 16.999 ms/op 16.222 ms/op 1.05
BLS deserializing 10000 signatures 672.84 ms/op 617.12 ms/op 1.09
BLS deserializing 100000 signatures 6.7984 s/op 6.1424 s/op 1.11
BLS verifyMultipleSignatures - same message - 3 - blst 874.34 us/op 928.60 us/op 0.94
BLS verifyMultipleSignatures - same message - 8 - blst 1.0191 ms/op 1.0635 ms/op 0.96
BLS verifyMultipleSignatures - same message - 32 - blst 1.6715 ms/op 1.7209 ms/op 0.97
BLS verifyMultipleSignatures - same message - 64 - blst 2.5440 ms/op 2.5940 ms/op 0.98
BLS verifyMultipleSignatures - same message - 128 - blst 4.2916 ms/op 4.2530 ms/op 1.01
BLS aggregatePubkeys 32 - blst 19.396 us/op 17.972 us/op 1.08
BLS aggregatePubkeys 128 - blst 69.018 us/op 63.310 us/op 1.09
getSlashingsAndExits - default max 61.273 us/op 39.104 us/op 1.57
getSlashingsAndExits - 2k 300.46 us/op 317.96 us/op 0.94
isKnown best case - 1 super set check 209.00 ns/op 421.00 ns/op 0.50
isKnown normal case - 2 super set checks 209.00 ns/op 409.00 ns/op 0.51
isKnown worse case - 16 super set checks 213.00 ns/op 409.00 ns/op 0.52
validate api signedAggregateAndProof - struct 1.3534 ms/op 1.4710 ms/op 0.92
validate gossip signedAggregateAndProof - struct 1.3599 ms/op 1.9329 ms/op 0.70
batch validate gossip attestation - vc 640000 - chunk 32 117.86 us/op 109.84 us/op 1.07
batch validate gossip attestation - vc 640000 - chunk 64 103.46 us/op 95.385 us/op 1.08
batch validate gossip attestation - vc 640000 - chunk 128 97.073 us/op 87.544 us/op 1.11
batch validate gossip attestation - vc 640000 - chunk 256 92.327 us/op 83.055 us/op 1.11
bytes32 toHexString 360.00 ns/op 547.00 ns/op 0.66
bytes32 Buffer.toString(hex) 257.00 ns/op 409.00 ns/op 0.63
bytes32 Buffer.toString(hex) from Uint8Array 336.00 ns/op 491.00 ns/op 0.68
bytes32 Buffer.toString(hex) + 0x 256.00 ns/op 396.00 ns/op 0.65
Return object 10000 times 0.22600 ns/op 0.23530 ns/op 0.96
Throw Error 10000 times 3.9110 us/op 3.3900 us/op 1.15
toHex 143.43 ns/op 101.77 ns/op 1.41
Buffer.from 134.99 ns/op 94.790 ns/op 1.42
shared Buffer 81.693 ns/op 67.366 ns/op 1.21
fastMsgIdFn sha256 / 200 bytes 1.7790 us/op 1.7430 us/op 1.02
fastMsgIdFn h32 xxhash / 200 bytes 193.00 ns/op 384.00 ns/op 0.50
fastMsgIdFn h64 xxhash / 200 bytes 259.00 ns/op 429.00 ns/op 0.60
fastMsgIdFn sha256 / 1000 bytes 5.7120 us/op 5.3100 us/op 1.08
fastMsgIdFn h32 xxhash / 1000 bytes 289.00 ns/op 485.00 ns/op 0.60
fastMsgIdFn h64 xxhash / 1000 bytes 316.00 ns/op 488.00 ns/op 0.65
fastMsgIdFn sha256 / 10000 bytes 51.772 us/op 42.454 us/op 1.22
fastMsgIdFn h32 xxhash / 10000 bytes 1.3790 us/op 1.5240 us/op 0.90
fastMsgIdFn h64 xxhash / 10000 bytes 900.00 ns/op 1.0800 us/op 0.83
send data - 1000 256B messages 4.9273 ms/op 4.1919 ms/op 1.18
send data - 1000 512B messages 4.5907 ms/op 4.2167 ms/op 1.09
send data - 1000 1024B messages 4.8807 ms/op 4.3049 ms/op 1.13
send data - 1000 1200B messages 5.0844 ms/op 4.8521 ms/op 1.05
send data - 1000 2048B messages 5.2807 ms/op 5.1791 ms/op 1.02
send data - 1000 4096B messages 6.5556 ms/op 5.5341 ms/op 1.18
send data - 1000 16384B messages 41.448 ms/op 47.954 ms/op 0.86
send data - 1000 65536B messages 127.42 ms/op 117.15 ms/op 1.09
enrSubnets - fastDeserialize 64 bits 893.00 ns/op 1.1780 us/op 0.76
enrSubnets - ssz BitVector 64 bits 376.00 ns/op 498.00 ns/op 0.76
enrSubnets - fastDeserialize 4 bits 140.00 ns/op 328.00 ns/op 0.43
enrSubnets - ssz BitVector 4 bits 383.00 ns/op 508.00 ns/op 0.75
prioritizePeers score -10:0 att 32-0.1 sync 2-0 234.54 us/op 261.17 us/op 0.90
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 308.21 us/op 235.83 us/op 1.31
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 393.03 us/op 342.71 us/op 1.15
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 707.23 us/op 595.22 us/op 1.19
prioritizePeers score 0:0 att 64-1 sync 4-1 885.46 us/op 730.11 us/op 1.21
array of 16000 items push then shift 1.6104 us/op 1.2452 us/op 1.29
LinkedList of 16000 items push then shift 7.3960 ns/op 8.6320 ns/op 0.86
array of 16000 items push then pop 74.419 ns/op 69.058 ns/op 1.08
LinkedList of 16000 items push then pop 7.2050 ns/op 6.4720 ns/op 1.11
array of 24000 items push then shift 2.3686 us/op 2.0370 us/op 1.16
LinkedList of 24000 items push then shift 7.4420 ns/op 7.6210 ns/op 0.98
array of 24000 items push then pop 106.18 ns/op 96.044 ns/op 1.11
LinkedList of 24000 items push then pop 7.1900 ns/op 6.4700 ns/op 1.11
intersect bitArray bitLen 8 5.7300 ns/op 4.9250 ns/op 1.16
intersect array and set length 8 33.822 ns/op 31.470 ns/op 1.07
intersect bitArray bitLen 128 28.629 ns/op 26.440 ns/op 1.08
intersect array and set length 128 550.08 ns/op 502.57 ns/op 1.09
bitArray.getTrueBitIndexes() bitLen 128 1.1370 us/op 1.2050 us/op 0.94
bitArray.getTrueBitIndexes() bitLen 248 1.8330 us/op 1.9580 us/op 0.94
bitArray.getTrueBitIndexes() bitLen 512 3.6700 us/op 3.8770 us/op 0.95
Full columns - reconstruct all 6 blobs 286.42 us/op 202.20 us/op 1.42
Full columns - reconstruct half of the blobs out of 6 118.22 us/op 107.15 us/op 1.10
Full columns - reconstruct single blob out of 6 32.725 us/op 33.227 us/op 0.98
Half columns - reconstruct all 6 blobs 265.07 ms/op 253.31 ms/op 1.05
Half columns - reconstruct half of the blobs out of 6 136.34 ms/op 130.09 ms/op 1.05
Half columns - reconstruct single blob out of 6 48.457 ms/op 47.855 ms/op 1.01
Full columns - reconstruct all 10 blobs 302.36 us/op 416.88 us/op 0.73
Full columns - reconstruct half of the blobs out of 10 183.27 us/op 180.65 us/op 1.01
Full columns - reconstruct single blob out of 10 32.327 us/op 26.931 us/op 1.20
Half columns - reconstruct all 10 blobs 440.42 ms/op 419.11 ms/op 1.05
Half columns - reconstruct half of the blobs out of 10 224.95 ms/op 222.16 ms/op 1.01
Half columns - reconstruct single blob out of 10 48.895 ms/op 48.732 ms/op 1.00
Full columns - reconstruct all 20 blobs 827.13 us/op 815.93 us/op 1.01
Full columns - reconstruct half of the blobs out of 20 348.83 us/op 351.12 us/op 0.99
Full columns - reconstruct single blob out of 20 40.841 us/op 26.858 us/op 1.52
Half columns - reconstruct all 20 blobs 879.98 ms/op 836.41 ms/op 1.05
Half columns - reconstruct half of the blobs out of 20 445.93 ms/op 419.56 ms/op 1.06
Half columns - reconstruct single blob out of 20 48.765 ms/op 47.086 ms/op 1.04
Set add up to 64 items then delete first 2.0343 us/op 1.6618 us/op 1.22
OrderedSet add up to 64 items then delete first 2.9908 us/op 2.5536 us/op 1.17
Set add up to 64 items then delete last 2.2776 us/op 1.9034 us/op 1.20
OrderedSet add up to 64 items then delete last 3.4440 us/op 2.8280 us/op 1.22
Set add up to 64 items then delete middle 2.4292 us/op 1.9713 us/op 1.23
OrderedSet add up to 64 items then delete middle 5.0199 us/op 4.2977 us/op 1.17
Set add up to 128 items then delete first 5.0302 us/op 3.7431 us/op 1.34
OrderedSet add up to 128 items then delete first 7.3922 us/op 5.7682 us/op 1.28
Set add up to 128 items then delete last 4.7860 us/op 3.6152 us/op 1.32
OrderedSet add up to 128 items then delete last 6.9957 us/op 5.4104 us/op 1.29
Set add up to 128 items then delete middle 4.7638 us/op 3.6226 us/op 1.31
OrderedSet add up to 128 items then delete middle 13.431 us/op 11.345 us/op 1.18
Set add up to 256 items then delete first 10.483 us/op 7.4081 us/op 1.42
OrderedSet add up to 256 items then delete first 15.646 us/op 12.508 us/op 1.25
Set add up to 256 items then delete last 9.8413 us/op 7.3776 us/op 1.33
OrderedSet add up to 256 items then delete last 14.348 us/op 11.521 us/op 1.25
Set add up to 256 items then delete middle 9.6594 us/op 6.9093 us/op 1.40
OrderedSet add up to 256 items then delete middle 41.602 us/op 37.020 us/op 1.12
pass gossip attestations to forkchoice per slot 506.15 us/op 395.32 us/op 1.28
computeDeltas 1400000 validators 0% inactive 14.459 ms/op 12.332 ms/op 1.17
computeDeltas 1400000 validators 10% inactive 13.688 ms/op 11.105 ms/op 1.23
computeDeltas 1400000 validators 20% inactive 12.614 ms/op 10.396 ms/op 1.21
computeDeltas 1400000 validators 50% inactive 9.8010 ms/op 7.9768 ms/op 1.23
computeDeltas 2100000 validators 0% inactive 21.762 ms/op 17.862 ms/op 1.22
computeDeltas 2100000 validators 10% inactive 20.317 ms/op 16.734 ms/op 1.21
computeDeltas 2100000 validators 20% inactive 18.928 ms/op 15.565 ms/op 1.22
computeDeltas 2100000 validators 50% inactive 14.747 ms/op 8.9982 ms/op 1.64
altair processAttestation - setStatus - 1/6 committees join 576.00 ns/op 1.3560 us/op 0.42
altair processAttestation - setStatus - 1/3 committees join 884.00 ns/op 1.0590 us/op 0.83
altair processAttestation - setStatus - 1/2 committees join 1.2280 us/op 1.2940 us/op 0.95
altair processAttestation - setStatus - 2/3 committees join 1.4320 us/op 1.4260 us/op 1.00
altair processAttestation - setStatus - 4/5 committees join 1.6200 us/op 1.5780 us/op 1.03
altair processAttestation - setStatus - 100% committees join 1.9200 us/op 1.8360 us/op 1.05
phase0 processBlock - 250000 vs - 7PWei normalcase 1.6637 ms/op 1.6090 ms/op 1.03
phase0 processBlock - 250000 vs - 7PWei worstcase 19.600 ms/op 20.637 ms/op 0.95
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 5.7810 us/op 3.2060 us/op 1.80
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 32.412 us/op 34.455 us/op 0.94
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 9.8490 us/op 8.5530 us/op 1.15
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 6.7130 us/op 3.6950 us/op 1.82
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 125.50 us/op 89.915 us/op 1.40
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.6530 ms/op 1.3850 ms/op 1.19
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.0383 ms/op 1.8494 ms/op 1.10
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.1068 ms/op 1.7200 ms/op 1.22
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.9679 ms/op 3.7825 ms/op 1.05
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.5091 ms/op 2.0362 ms/op 1.23
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.3373 ms/op 4.2199 ms/op 1.03
Tree 40 250000 create 352.68 ms/op 317.49 ms/op 1.11
Tree 40 250000 get(125000) 123.89 ns/op 96.236 ns/op 1.29
Tree 40 250000 set(125000) 1.1980 us/op 1.0273 us/op 1.17
Tree 40 250000 toArray() 12.515 ms/op 9.0991 ms/op 1.38
Tree 40 250000 iterate all - toArray() + loop 12.579 ms/op 17.120 ms/op 0.73
Tree 40 250000 iterate all - get(i) 40.922 ms/op 38.259 ms/op 1.07
Array 250000 create 2.3870 ms/op 2.0894 ms/op 1.14
Array 250000 clone - spread 783.30 us/op 641.80 us/op 1.22
Array 250000 get(125000) 0.36000 ns/op 0.52500 ns/op 0.69
Array 250000 set(125000) 0.37500 ns/op 0.52800 ns/op 0.71
Array 250000 iterate all - loop 61.171 us/op 57.946 us/op 1.06
phase0 afterProcessEpoch - 250000 vs - 7PWei 42.636 ms/op 38.753 ms/op 1.10
Array.fill - length 1000000 2.9831 ms/op 1.9843 ms/op 1.50
Array push - length 1000000 10.246 ms/op 7.1091 ms/op 1.44
Array.get 0.21776 ns/op 0.20661 ns/op 1.05
Uint8Array.get 0.22006 ns/op 0.20315 ns/op 1.08
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.051 ms/op 11.960 ms/op 1.26
altair processEpoch - mainnet_e81889 332.93 ms/op 241.55 ms/op 1.38
mainnet_e81889 - altair beforeProcessEpoch 32.455 ms/op 17.178 ms/op 1.89
mainnet_e81889 - altair processJustificationAndFinalization 7.2690 us/op 5.4800 us/op 1.33
mainnet_e81889 - altair processInactivityUpdates 3.9338 ms/op 4.3605 ms/op 0.90
mainnet_e81889 - altair processRewardsAndPenalties 18.554 ms/op 19.190 ms/op 0.97
mainnet_e81889 - altair processRegistryUpdates 658.00 ns/op 820.00 ns/op 0.80
mainnet_e81889 - altair processSlashings 173.00 ns/op 379.00 ns/op 0.46
mainnet_e81889 - altair processEth1DataReset 167.00 ns/op 370.00 ns/op 0.45
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.6150 ms/op 2.3362 ms/op 0.69
mainnet_e81889 - altair processSlashingsReset 826.00 ns/op 995.00 ns/op 0.83
mainnet_e81889 - altair processRandaoMixesReset 1.3880 us/op 1.6550 us/op 0.84
mainnet_e81889 - altair processHistoricalRootsUpdate 178.00 ns/op 398.00 ns/op 0.45
mainnet_e81889 - altair processParticipationFlagUpdates 516.00 ns/op 713.00 ns/op 0.72
mainnet_e81889 - altair processSyncCommitteeUpdates 146.00 ns/op 348.00 ns/op 0.42
mainnet_e81889 - altair afterProcessEpoch 52.341 ms/op 39.649 ms/op 1.32
capella processEpoch - mainnet_e217614 852.74 ms/op 749.91 ms/op 1.14
mainnet_e217614 - capella beforeProcessEpoch 82.915 ms/op 60.893 ms/op 1.36
mainnet_e217614 - capella processJustificationAndFinalization 5.7160 us/op 4.8670 us/op 1.17
mainnet_e217614 - capella processInactivityUpdates 18.210 ms/op 10.948 ms/op 1.66
mainnet_e217614 - capella processRewardsAndPenalties 108.42 ms/op 96.279 ms/op 1.13
mainnet_e217614 - capella processRegistryUpdates 5.8670 us/op 4.8160 us/op 1.22
mainnet_e217614 - capella processSlashings 178.00 ns/op 380.00 ns/op 0.47
mainnet_e217614 - capella processEth1DataReset 175.00 ns/op 376.00 ns/op 0.47
mainnet_e217614 - capella processEffectiveBalanceUpdates 11.381 ms/op 15.273 ms/op 0.75
mainnet_e217614 - capella processSlashingsReset 834.00 ns/op 962.00 ns/op 0.87
mainnet_e217614 - capella processRandaoMixesReset 1.1930 us/op 1.1860 us/op 1.01
mainnet_e217614 - capella processHistoricalRootsUpdate 174.00 ns/op 390.00 ns/op 0.45
mainnet_e217614 - capella processParticipationFlagUpdates 491.00 ns/op 738.00 ns/op 0.67
mainnet_e217614 - capella afterProcessEpoch 111.51 ms/op 111.82 ms/op 1.00
phase0 processEpoch - mainnet_e58758 257.57 ms/op 202.56 ms/op 1.27
mainnet_e58758 - phase0 beforeProcessEpoch 55.549 ms/op 53.264 ms/op 1.04
mainnet_e58758 - phase0 processJustificationAndFinalization 5.7430 us/op 4.8380 us/op 1.19
mainnet_e58758 - phase0 processRewardsAndPenalties 18.573 ms/op 16.505 ms/op 1.13
mainnet_e58758 - phase0 processRegistryUpdates 2.7090 us/op 3.2040 us/op 0.85
mainnet_e58758 - phase0 processSlashings 181.00 ns/op 398.00 ns/op 0.45
mainnet_e58758 - phase0 processEth1DataReset 177.00 ns/op 390.00 ns/op 0.45
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.0965 ms/op 962.30 us/op 1.14
mainnet_e58758 - phase0 processSlashingsReset 835.00 ns/op 1.0240 us/op 0.82
mainnet_e58758 - phase0 processRandaoMixesReset 1.1540 us/op 1.2450 us/op 0.93
mainnet_e58758 - phase0 processHistoricalRootsUpdate 182.00 ns/op 383.00 ns/op 0.48
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.0650 us/op 1.1950 us/op 0.89
mainnet_e58758 - phase0 afterProcessEpoch 34.171 ms/op 34.321 ms/op 1.00
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.7276 ms/op 957.27 us/op 1.80
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5872 ms/op 1.5227 ms/op 1.04
altair processInactivityUpdates - 250000 normalcase 54.807 us/op 55.672 us/op 0.98
altair processInactivityUpdates - 250000 worstcase 51.795 us/op 54.302 us/op 0.95
phase0 processRegistryUpdates - 250000 normalcase 6.8510 us/op 5.9850 us/op 1.14
phase0 processRegistryUpdates - 250000 badcase_full_deposits 188.78 us/op 243.95 us/op 0.77
phase0 processRegistryUpdates - 250000 worstcase 0.5 64.542 ms/op 62.513 ms/op 1.03
altair processRewardsAndPenalties - 250000 normalcase 79.495 us/op 83.797 us/op 0.95
altair processRewardsAndPenalties - 250000 worstcase 76.771 us/op 81.993 us/op 0.94
phase0 getAttestationDeltas - 250000 normalcase 6.6790 ms/op 4.6965 ms/op 1.42
phase0 getAttestationDeltas - 250000 worstcase 17.000 ms/op 4.7573 ms/op 3.57
phase0 processSlashings - 250000 worstcase 76.739 us/op 89.218 us/op 0.86
altair processSyncCommitteeUpdates - 250000 8.3185 ms/op 7.8630 ms/op 1.06
BeaconState.hashTreeRoot - No change 202.00 ns/op 431.00 ns/op 0.47
BeaconState.hashTreeRoot - 1 full validator 82.194 us/op 74.691 us/op 1.10
BeaconState.hashTreeRoot - 32 full validator 941.17 us/op 1.0124 ms/op 0.93
BeaconState.hashTreeRoot - 512 full validator 7.7372 ms/op 7.6708 ms/op 1.01
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 110.21 us/op 120.89 us/op 0.91
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.5106 ms/op 2.5256 ms/op 0.60
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 16.788 ms/op 15.951 ms/op 1.05
BeaconState.hashTreeRoot - 1 balances 77.578 us/op 92.369 us/op 0.84
BeaconState.hashTreeRoot - 32 balances 796.83 us/op 799.39 us/op 1.00
BeaconState.hashTreeRoot - 512 balances 5.7188 ms/op 6.1408 ms/op 0.93
BeaconState.hashTreeRoot - 250000 balances 147.86 ms/op 133.65 ms/op 1.11
aggregationBits - 2048 els - zipIndexesInBitList 20.859 us/op 19.078 us/op 1.09
regular array get 100000 times 24.482 us/op 23.474 us/op 1.04
wrappedArray get 100000 times 24.421 us/op 23.708 us/op 1.03
arrayWithProxy get 100000 times 13.859 ms/op 10.578 ms/op 1.31
ssz.Root.equals 23.544 ns/op 21.889 ns/op 1.08
byteArrayEquals 23.108 ns/op 23.878 ns/op 0.97
Buffer.compare 9.8940 ns/op 9.1340 ns/op 1.08
processSlot - 1 slots 9.5330 us/op 12.212 us/op 0.78
processSlot - 32 slots 2.1580 ms/op 2.6943 ms/op 0.80
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 3.3196 ms/op 1.0258 ms/op 3.24
getCommitteeAssignments - req 1 vs - 250000 vc 1.9051 ms/op 1.6817 ms/op 1.13
getCommitteeAssignments - req 100 vs - 250000 vc 3.7126 ms/op 3.4202 ms/op 1.09
getCommitteeAssignments - req 1000 vs - 250000 vc 3.8399 ms/op 3.7213 ms/op 1.03
findModifiedValidators - 10000 modified validators 526.28 ms/op 463.82 ms/op 1.13
findModifiedValidators - 1000 modified validators 308.80 ms/op 440.26 ms/op 0.70
findModifiedValidators - 100 modified validators 245.88 ms/op 236.15 ms/op 1.04
findModifiedValidators - 10 modified validators 145.82 ms/op 155.67 ms/op 0.94
findModifiedValidators - 1 modified validators 113.89 ms/op 138.60 ms/op 0.82
findModifiedValidators - no difference 147.41 ms/op 141.78 ms/op 1.04
migrate state 1500000 validators, 3400 modified, 2000 new 341.15 ms/op 337.73 ms/op 1.01
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.2500 ns/op 5.9300 ns/op 0.72
state getBlockRootAtSlot - 250000 vs - 7PWei 517.78 ns/op 395.71 ns/op 1.31
computeProposerIndex 100000 validators 1.5177 ms/op 1.3780 ms/op 1.10
getNextSyncCommitteeIndices 1000 validators 3.3035 ms/op 2.8917 ms/op 1.14
getNextSyncCommitteeIndices 10000 validators 3.3094 ms/op 2.9065 ms/op 1.14
getNextSyncCommitteeIndices 100000 validators 3.3170 ms/op 2.8994 ms/op 1.14
computeProposers - vc 250000 606.35 us/op 558.95 us/op 1.08
computeEpochShuffling - vc 250000 41.138 ms/op 38.789 ms/op 1.06
getNextSyncCommittee - vc 250000 10.147 ms/op 9.6412 ms/op 1.05
nodejs block root to RootHex using toHex 141.84 ns/op 110.21 ns/op 1.29
nodejs block root to RootHex using toRootHex 87.169 ns/op 71.782 ns/op 1.21
nodejs fromHex(blob) 285.36 us/op 417.62 us/op 0.68
nodejs fromHexInto(blob) 687.44 us/op 641.81 us/op 1.07
nodejs block root to RootHex using the deprecated toHexString 563.03 ns/op 549.51 ns/op 1.02
nodejs byteArrayEquals 32 bytes (block root) 27.939 ns/op 27.215 ns/op 1.03
nodejs byteArrayEquals 48 bytes (pubkey) 39.934 ns/op 42.134 ns/op 0.95
nodejs byteArrayEquals 96 bytes (signature) 38.716 ns/op 34.912 ns/op 1.11
nodejs byteArrayEquals 1024 bytes 44.918 ns/op 41.161 ns/op 1.09
nodejs byteArrayEquals 131072 bytes (blob) 1.8359 us/op 1.7716 us/op 1.04
browser block root to RootHex using toHex 159.39 ns/op 149.42 ns/op 1.07
browser block root to RootHex using toRootHex 152.04 ns/op 135.13 ns/op 1.13
browser fromHex(blob) 1.1253 ms/op 917.21 us/op 1.23
browser fromHexInto(blob) 710.24 us/op 598.22 us/op 1.19
browser block root to RootHex using the deprecated toHexString 407.74 ns/op 348.14 ns/op 1.17
browser byteArrayEquals 32 bytes (block root) 30.449 ns/op 29.086 ns/op 1.05
browser byteArrayEquals 48 bytes (pubkey) 42.358 ns/op 38.043 ns/op 1.11
browser byteArrayEquals 96 bytes (signature) 82.841 ns/op 74.126 ns/op 1.12
browser byteArrayEquals 1024 bytes 782.57 ns/op 723.31 ns/op 1.08
browser byteArrayEquals 131072 bytes (blob) 98.528 us/op 91.199 us/op 1.08

by benchmarkbot/action

Copy link
Member

@nflaig nflaig left a comment

Choose a reason for hiding this comment

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

this PR needs to be reworked once payload input PR is merged, let's hold off on it for now

return collectMaxResponseTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.ExecutionPayloadEnvelopesByRange, [Version.V1], request),
request.count,
responseSszTypeByMethod[ReqRespMethod.ExecutionPayloadEnvelopesByRange]
Copy link
Member

Choose a reason for hiding this comment

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

no serialized chache passed in?

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 am not sure. Other by range methods don't have serialized cached passed in, but by root methods do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Intuitively we should, because ultimately these envelopes we receive via range sync will be written to hot db which serialization will be performed if we don't have the serialized bytes

const envelopePromise = envelopeBytes
? this.db.executionPayloadEnvelope.putBinary(this.db.executionPayloadEnvelope.getId(envelope), envelopeBytes)
: this.db.executionPayloadEnvelope.add(envelope);

So I think we should update sendDataColumnSidecarsByRange too.

async sendDataColumnSidecarsByRange(
peerId: PeerIdStr,
request: fulu.DataColumnSidecarsByRangeRequest
): Promise<fulu.DataColumnSidecar[]> {
return collectMaxResponseTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.DataColumnSidecarsByRange, [Version.V1], request),
request.count * request.columns.length,
responseSszTypeByMethod[ReqRespMethod.DataColumnSidecarsByRange]
);
}

Any thought @twoeths ?

): AsyncIterable<ResponseOutgoing> {
const {startSlot, count} = validateExecutionPayloadEnvelopesByRangeRequest(chain.config, request);
const endSlot = startSlot + count;

Copy link
Member

Choose a reason for hiding this comment

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

we are missing [max(GLOAS_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch] check from spec

Copy link
Contributor Author

@ensi321 ensi321 Mar 25, 2026

Choose a reason for hiding this comment

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

we are missing [max(GLOAS_FORK_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch] check from spec

I think other by range methods are also skipping this check:

// TODO: validate against MIN_EPOCHS_FOR_BLOCK_REQUESTS

// TODO: validate against MIN_EPOCHS_FOR_BLOCK_REQUESTS

// TODO: validate against MIN_EPOCHS_FOR_BLOCK_REQUESTS

I think I am going to stay aligned with these methods in this PR

@nflaig
Copy link
Member

nflaig commented Mar 24, 2026

to quickly summarize how I think we should deal with orphaned payloads

by range

  • never serve orphaned payloads
  • for unfinalized data, serve only envelopes that match our current fork choice view
  • for finalized data, do not serve them either, already handled since we prune orphaned payloads before archiving

by root

  • for unfinalized data, serve payloads irrespective of fork choice view since it's a single item lookup
  • for finalized data, do not serve them, already handled by archiving (same as by range)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
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