Skip to content

feat: add gloas execution payload envelope import pipeline - #8962

Merged
nflaig merged 47 commits into
unstablefrom
nc/epbs-payload-import
Mar 20, 2026
Merged

feat: add gloas execution payload envelope import pipeline#8962
nflaig merged 47 commits into
unstablefrom
nc/epbs-payload-import

Conversation

@ensi321

@ensi321 ensi321 commented Feb 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Implement the execution payload import pipeline for Gloas (ePBS)
  • Add PayloadEnvelopeInput class to track payload envelope + data columns
  • Add importExecutionPayload function for EL verification and execution payload state transition
  • Add SeenPayloadEnvelopeInput cache for managing payload inputs
  • Remove SeenExecutionPayloadEnvelopes in favour of SeenPayloadEnvelopeInput
  • Integrate with gossip handlers and API for payload publishing

Background

In Gloas (ePBS), beacon blocks and execution payloads have separate validity requirements:

  • Beacon blocks are valid immediately (builder may not reveal payload)
  • Execution payloads require data availability (payload envelope + sampled columns)

Key Changes

New Files

  • payloadEnvelopeInput/payloadEnvelopeInput.ts - Tracks bid + envelope + columns with 4-state machine
  • importExecutionPayload.ts - EL verification, signature check, execution payload state transition
  • writePayloadEnvelopeInputToDb.ts - Persists envelope + columns to DB
  • seenPayloadEnvelopeInput.ts - Cache with finalization pruning

Modified Files

  • importBlock.ts - Creates PayloadEnvelopeInput during Gloas block import
  • gossipHandlers.ts - Handles execution_payload topic, triggers import on completion
  • extractSlotRootFns.ts - SSZ helpers for payload envelope queueing
  • executionPayloadEnvelope.ts - Validation using block post-state (not head state)
  • fork-choice - Removed builderIndex/blockHashHex from ProtoBlock (now in PayloadEnvelopeInput)

TODO

  • Gloas data_column_sidecar gossip handler integration (commented, needs Gloas-specific validation)

🤖 Generated with Claude Code

@ensi321 ensi321 changed the title feat: add gloas execution payload envelope import pipeline feat: add gloas execution payload envelope import pipeline p[wip] Feb 26, 2026
@ensi321 ensi321 changed the title feat: add gloas execution payload envelope import pipeline p[wip] feat: add gloas execution payload envelope import pipeline [wip] Feb 26, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ensi321, 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 the foundational infrastructure for handling Gloas execution payload envelopes within the beacon node. It establishes a new data flow that tracks the availability of execution payloads and their associated data columns, ensuring that blocks are only processed once all necessary components are received. This enhancement is crucial for supporting future Gloas-specific functionalities and maintaining data integrity throughout the block processing pipeline.

Highlights

  • New Execution Payload Envelope Import Pipeline: Introduced a comprehensive pipeline for importing Gloas execution payload envelopes, managing their lifecycle from initial block import to final persistence and event emission.
  • PayloadEnvelopeInput Class: Implemented a new PayloadEnvelopeInput class to track and manage the state of execution payload envelopes and their associated data columns for Gloas blocks, including methods for adding data and checking completion.
  • API and Gossip Integration: Integrated the new payload envelope processing into the beacon node's API for block submission and the gossip network handler for execution_payload messages, ensuring proper validation and event emission.
  • Database Persistence and Caching: Added functionality to persist complete PayloadEnvelopeInput data (envelope and data column sidecars) to the database and introduced a SeenPayloadEnvelopeInput cache to manage these instances, with pruning on finalization.
  • New Event and Metrics: Added a new EventType.executionPayloadAvailable to the API and introduced new Prometheus metrics to monitor the import activity and cache usage of execution payload envelopes.

🧠 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/api/src/beacon/routes/events.ts
    • Extended EventType enum and EventData type to include executionPayloadAvailable and defined its SSZ serialization.
  • packages/api/test/unit/beacon/testData/events.ts
    • Added test data for the new executionPayloadAvailable event.
  • packages/beacon-node/src/api/impl/beacon/blocks/index.ts
    • Updated block API to process signedExecutionPayloadEnvelope using PayloadEnvelopeInput and emit executionPayloadAvailable event.
  • packages/beacon-node/src/chain/blocks/importBlock.ts
    • Modified block import to create a PayloadEnvelopeInput for Gloas blocks.
  • packages/beacon-node/src/chain/blocks/importExecutionPayload.ts
    • Added importExecutionPayload function to handle the full import pipeline for execution payload envelopes, including EL verification and state transition.
  • packages/beacon-node/src/chain/blocks/payloadEnvelopeInput/index.ts
    • Created an index file to export payloadEnvelopeInput and types modules.
  • packages/beacon-node/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts
    • Implemented PayloadEnvelopeInput class to track and manage the state of execution payload envelopes and data columns for Gloas blocks.
  • packages/beacon-node/src/chain/blocks/payloadEnvelopeInput/types.ts
    • Defined various types and enums for PayloadEnvelopeInput and its related data sources.
  • packages/beacon-node/src/chain/blocks/writePayloadEnvelopeInputToDb.ts
    • Added functions to persist PayloadEnvelopeInput data, including the envelope and data column sidecars, to the database and prune from cache.
  • packages/beacon-node/src/chain/chain.ts
    • Refactored BeaconChain to utilize the new SeenPayloadEnvelopeInput cache and integrate the importExecutionPayload and persistPayloadEnvelopeInput functions.
  • packages/beacon-node/src/chain/interface.ts
    • Updated IBeaconChain interface to include PayloadEnvelopeInput related types and methods.
  • packages/beacon-node/src/chain/seenCache/index.ts
    • Updated the seen cache index to export the new PayloadEnvelopeInput and SeenPayloadEnvelopeInput modules.
  • packages/beacon-node/src/chain/seenCache/seenExecutionPayloadEnvelope.ts
    • Removed the SeenExecutionPayloadEnvelopes module.
  • packages/beacon-node/src/chain/seenCache/seenPayloadEnvelopeInput.ts
    • Added SeenPayloadEnvelopeInput class to cache and manage PayloadEnvelopeInput instances, with pruning on finalization.
  • packages/beacon-node/src/chain/validation/executionPayloadEnvelope.ts
    • Refactored execution payload envelope validation to leverage the new SeenPayloadEnvelopeInput cache and its methods.
  • packages/beacon-node/src/chain/validatorMonitor.ts
    • Updated ValidatorMonitor to register and monitor executionPayloadEnvelope events.
  • packages/beacon-node/src/metrics/metrics/lodestar.ts
    • Introduced new Prometheus metrics for tracking execution payload envelope import activity and PayloadEnvelopeInput cache size.
  • packages/beacon-node/src/network/processor/extractSlotRootFns.ts
    • Updated SSZ byte extraction utilities to correctly parse slot and root from Gloas data column sidecars and execution payload envelopes.
  • packages/beacon-node/src/network/processor/gossipHandlers.ts
    • Implemented the gossip handler for execution_payload to process incoming envelopes, update PayloadEnvelopeInput, and trigger import.
  • packages/fork-choice/src/forkChoice/forkChoice.ts
    • Removed Gloas-specific builderIndex and blockHashHex fields from ProtoBlock creation in ForkChoice.
  • packages/fork-choice/src/protoArray/interface.ts
    • Removed builderIndex and blockHashHex properties from the ProtoBlock interface.
Activity
  • The author ensi321 has implemented a new feature to handle Gloas execution payload envelope import. No specific review comments or further progress are available in the provided context.
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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

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 the import pipeline for Gloas execution payload envelopes, a significant feature for the upcoming Gloas fork. The changes are extensive, touching the API, core chain logic, validation, caching, and fork-choice mechanisms. The introduction of PayloadEnvelopeInput and SeenPayloadEnvelopeInput provides a robust mechanism for handling the asynchronous arrival of different components of a Gloas block. The refactoring to remove Gloas-specific details from ProtoBlock is a good architectural improvement, enhancing separation of concerns. The code is well-structured, and the changes are consistent across the codebase. I've identified one minor latent issue in some commented-out code and provided a suggestion to fix it.

Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts Outdated
@github-actions

github-actions Bot commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: ce78d5d Previous: 4411584 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1560 ms/op 1.0738 ms/op 1.08
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 38.018 us/op 35.732 us/op 1.06
BLS verify - blst 864.21 us/op 898.16 us/op 0.96
BLS verifyMultipleSignatures 3 - blst 1.2558 ms/op 1.5618 ms/op 0.80
BLS verifyMultipleSignatures 8 - blst 1.6898 ms/op 2.4661 ms/op 0.69
BLS verifyMultipleSignatures 32 - blst 5.0209 ms/op 7.2611 ms/op 0.69
BLS verifyMultipleSignatures 64 - blst 9.6835 ms/op 10.894 ms/op 0.89
BLS verifyMultipleSignatures 128 - blst 17.773 ms/op 17.033 ms/op 1.04
BLS deserializing 10000 signatures 709.03 ms/op 649.95 ms/op 1.09
BLS deserializing 100000 signatures 7.0224 s/op 6.7645 s/op 1.04
BLS verifyMultipleSignatures - same message - 3 - blst 920.54 us/op 1.5744 ms/op 0.58
BLS verifyMultipleSignatures - same message - 8 - blst 1.0243 ms/op 1.1199 ms/op 0.91
BLS verifyMultipleSignatures - same message - 32 - blst 1.7199 ms/op 1.8415 ms/op 0.93
BLS verifyMultipleSignatures - same message - 64 - blst 2.6191 ms/op 2.6554 ms/op 0.99
BLS verifyMultipleSignatures - same message - 128 - blst 4.4836 ms/op 4.7013 ms/op 0.95
BLS aggregatePubkeys 32 - blst 19.910 us/op 19.419 us/op 1.03
BLS aggregatePubkeys 128 - blst 70.930 us/op 69.617 us/op 1.02
getSlashingsAndExits - default max 70.498 us/op 68.046 us/op 1.04
getSlashingsAndExits - 2k 313.00 us/op 305.69 us/op 1.02
isKnown best case - 1 super set check 223.00 ns/op 197.00 ns/op 1.13
isKnown normal case - 2 super set checks 230.00 ns/op 196.00 ns/op 1.17
isKnown worse case - 16 super set checks 228.00 ns/op 196.00 ns/op 1.16
validate api signedAggregateAndProof - struct 1.4386 ms/op 2.0293 ms/op 0.71
validate gossip signedAggregateAndProof - struct 1.4300 ms/op 2.5863 ms/op 0.55
batch validate gossip attestation - vc 640000 - chunk 32 120.08 us/op 167.26 us/op 0.72
batch validate gossip attestation - vc 640000 - chunk 64 107.16 us/op 117.77 us/op 0.91
batch validate gossip attestation - vc 640000 - chunk 128 98.494 us/op 98.828 us/op 1.00
batch validate gossip attestation - vc 640000 - chunk 256 106.47 us/op 92.787 us/op 1.15
bytes32 toHexString 378.00 ns/op 360.00 ns/op 1.05
bytes32 Buffer.toString(hex) 266.00 ns/op 228.00 ns/op 1.17
bytes32 Buffer.toString(hex) from Uint8Array 354.00 ns/op 384.00 ns/op 0.92
bytes32 Buffer.toString(hex) + 0x 264.00 ns/op 226.00 ns/op 1.17
Return object 10000 times 0.23410 ns/op 0.22760 ns/op 1.03
Throw Error 10000 times 4.1895 us/op 4.1520 us/op 1.01
toHex 133.66 ns/op 141.62 ns/op 0.94
Buffer.from 130.05 ns/op 129.50 ns/op 1.00
shared Buffer 78.839 ns/op 75.784 ns/op 1.04
fastMsgIdFn sha256 / 200 bytes 1.8890 us/op 1.9070 us/op 0.99
fastMsgIdFn h32 xxhash / 200 bytes 205.00 ns/op 197.00 ns/op 1.04
fastMsgIdFn h64 xxhash / 200 bytes 288.00 ns/op 359.00 ns/op 0.80
fastMsgIdFn sha256 / 1000 bytes 5.9490 us/op 6.0200 us/op 0.99
fastMsgIdFn h32 xxhash / 1000 bytes 314.00 ns/op 291.00 ns/op 1.08
fastMsgIdFn h64 xxhash / 1000 bytes 329.00 ns/op 433.00 ns/op 0.76
fastMsgIdFn sha256 / 10000 bytes 70.401 us/op 51.330 us/op 1.37
fastMsgIdFn h32 xxhash / 10000 bytes 1.4590 us/op 1.4040 us/op 1.04
fastMsgIdFn h64 xxhash / 10000 bytes 934.00 ns/op 1.1330 us/op 0.82
send data - 1000 256B messages 4.7047 ms/op 5.1387 ms/op 0.92
send data - 1000 512B messages 4.1991 ms/op 4.8959 ms/op 0.86
send data - 1000 1024B messages 4.6753 ms/op 5.8432 ms/op 0.80
send data - 1000 1200B messages 5.1042 ms/op 5.3484 ms/op 0.95
send data - 1000 2048B messages 5.4423 ms/op 6.0405 ms/op 0.90
send data - 1000 4096B messages 6.0309 ms/op 8.3356 ms/op 0.72
send data - 1000 16384B messages 34.420 ms/op 33.776 ms/op 1.02
send data - 1000 65536B messages 97.650 ms/op 99.696 ms/op 0.98
enrSubnets - fastDeserialize 64 bits 900.00 ns/op 870.00 ns/op 1.03
enrSubnets - ssz BitVector 64 bits 360.00 ns/op 324.00 ns/op 1.11
enrSubnets - fastDeserialize 4 bits 140.00 ns/op 178.00 ns/op 0.79
enrSubnets - ssz BitVector 4 bits 355.00 ns/op 328.00 ns/op 1.08
prioritizePeers score -10:0 att 32-0.1 sync 2-0 230.35 us/op 230.59 us/op 1.00
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 254.28 us/op 345.45 us/op 0.74
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 366.66 us/op 480.92 us/op 0.76
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 683.22 us/op 704.46 us/op 0.97
prioritizePeers score 0:0 att 64-1 sync 4-1 849.25 us/op 847.91 us/op 1.00
array of 16000 items push then shift 1.6010 us/op 1.5623 us/op 1.02
LinkedList of 16000 items push then shift 8.1140 ns/op 7.1200 ns/op 1.14
array of 16000 items push then pop 79.367 ns/op 73.867 ns/op 1.07
LinkedList of 16000 items push then pop 7.2320 ns/op 6.8520 ns/op 1.06
array of 24000 items push then shift 2.4042 us/op 2.3206 us/op 1.04
LinkedList of 24000 items push then shift 7.4690 ns/op 7.3010 ns/op 1.02
array of 24000 items push then pop 104.66 ns/op 103.44 ns/op 1.01
LinkedList of 24000 items push then pop 7.1050 ns/op 6.8580 ns/op 1.04
intersect bitArray bitLen 8 5.6910 ns/op 5.5570 ns/op 1.02
intersect array and set length 8 33.093 ns/op 32.718 ns/op 1.01
intersect bitArray bitLen 128 28.438 ns/op 27.840 ns/op 1.02
intersect array and set length 128 539.14 ns/op 536.96 ns/op 1.00
bitArray.getTrueBitIndexes() bitLen 128 992.00 ns/op 1.0270 us/op 0.97
bitArray.getTrueBitIndexes() bitLen 248 1.7290 us/op 1.8080 us/op 0.96
bitArray.getTrueBitIndexes() bitLen 512 3.5090 us/op 3.7800 us/op 0.93
Full columns - reconstruct all 6 blobs 271.19 us/op 239.41 us/op 1.13
Full columns - reconstruct half of the blobs out of 6 105.16 us/op 102.78 us/op 1.02
Full columns - reconstruct single blob out of 6 31.046 us/op 30.777 us/op 1.01
Half columns - reconstruct all 6 blobs 262.86 ms/op 260.12 ms/op 1.01
Half columns - reconstruct half of the blobs out of 6 133.96 ms/op 130.80 ms/op 1.02
Half columns - reconstruct single blob out of 6 47.969 ms/op 48.385 ms/op 0.99
Full columns - reconstruct all 10 blobs 284.45 us/op 365.66 us/op 0.78
Full columns - reconstruct half of the blobs out of 10 196.36 us/op 190.51 us/op 1.03
Full columns - reconstruct single blob out of 10 30.759 us/op 41.228 us/op 0.75
Half columns - reconstruct all 10 blobs 427.79 ms/op 428.13 ms/op 1.00
Half columns - reconstruct half of the blobs out of 10 217.75 ms/op 220.50 ms/op 0.99
Half columns - reconstruct single blob out of 10 48.184 ms/op 48.393 ms/op 1.00
Full columns - reconstruct all 20 blobs 747.55 us/op 865.51 us/op 0.86
Full columns - reconstruct half of the blobs out of 20 301.54 us/op 294.00 us/op 1.03
Full columns - reconstruct single blob out of 20 41.535 us/op 30.446 us/op 1.36
Half columns - reconstruct all 20 blobs 853.62 ms/op 857.83 ms/op 1.00
Half columns - reconstruct half of the blobs out of 20 428.57 ms/op 432.65 ms/op 0.99
Half columns - reconstruct single blob out of 20 47.783 ms/op 47.883 ms/op 1.00
Set add up to 64 items then delete first 2.0257 us/op 2.0032 us/op 1.01
OrderedSet add up to 64 items then delete first 2.9674 us/op 2.9809 us/op 1.00
Set add up to 64 items then delete last 2.4326 us/op 2.2801 us/op 1.07
OrderedSet add up to 64 items then delete last 3.7291 us/op 3.2456 us/op 1.15
Set add up to 64 items then delete middle 2.3064 us/op 2.2656 us/op 1.02
OrderedSet add up to 64 items then delete middle 5.0066 us/op 4.7935 us/op 1.04
Set add up to 128 items then delete first 4.7655 us/op 4.6983 us/op 1.01
OrderedSet add up to 128 items then delete first 7.0810 us/op 6.9724 us/op 1.02
Set add up to 128 items then delete last 4.8277 us/op 4.5347 us/op 1.06
OrderedSet add up to 128 items then delete last 6.9994 us/op 6.5834 us/op 1.06
Set add up to 128 items then delete middle 5.0431 us/op 4.4668 us/op 1.13
OrderedSet add up to 128 items then delete middle 13.719 us/op 12.846 us/op 1.07
Set add up to 256 items then delete first 9.9046 us/op 9.5715 us/op 1.03
OrderedSet add up to 256 items then delete first 15.164 us/op 14.595 us/op 1.04
Set add up to 256 items then delete last 9.9440 us/op 9.1681 us/op 1.08
OrderedSet add up to 256 items then delete last 14.426 us/op 13.510 us/op 1.07
Set add up to 256 items then delete middle 9.4655 us/op 9.0628 us/op 1.04
OrderedSet add up to 256 items then delete middle 40.869 us/op 39.612 us/op 1.03
pass gossip attestations to forkchoice per slot 485.23 us/op 491.42 us/op 0.99
computeDeltas 1400000 validators 0% inactive 13.893 ms/op 14.055 ms/op 0.99
computeDeltas 1400000 validators 10% inactive 13.041 ms/op 13.123 ms/op 0.99
computeDeltas 1400000 validators 20% inactive 12.117 ms/op 12.200 ms/op 0.99
computeDeltas 1400000 validators 50% inactive 9.4211 ms/op 9.4721 ms/op 0.99
computeDeltas 2100000 validators 0% inactive 20.965 ms/op 21.038 ms/op 1.00
computeDeltas 2100000 validators 10% inactive 19.595 ms/op 19.671 ms/op 1.00
computeDeltas 2100000 validators 20% inactive 18.295 ms/op 18.285 ms/op 1.00
computeDeltas 2100000 validators 50% inactive 14.159 ms/op 14.248 ms/op 0.99
altair processAttestation - setStatus - 1/6 committees join 563.00 ns/op 571.00 ns/op 0.99
altair processAttestation - setStatus - 1/3 committees join 882.00 ns/op 885.00 ns/op 1.00
altair processAttestation - setStatus - 1/2 committees join 1.1800 us/op 1.2390 us/op 0.95
altair processAttestation - setStatus - 2/3 committees join 1.3930 us/op 1.4320 us/op 0.97
altair processAttestation - setStatus - 4/5 committees join 1.5950 us/op 1.6410 us/op 0.97
altair processAttestation - setStatus - 100% committees join 1.8880 us/op 1.9440 us/op 0.97
phase0 processBlock - 250000 vs - 7PWei normalcase 1.5917 ms/op 2.4979 ms/op 0.64
phase0 processBlock - 250000 vs - 7PWei worstcase 18.561 ms/op 24.963 ms/op 0.74
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 5.8530 us/op 8.9470 us/op 0.65
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 32.249 us/op 50.363 us/op 0.64
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 10.102 us/op 16.257 us/op 0.62
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 6.8180 us/op 10.792 us/op 0.63
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 132.97 us/op 227.33 us/op 0.58
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.6157 ms/op 1.6115 ms/op 1.00
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.0489 ms/op 2.0264 ms/op 1.01
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.2790 ms/op 2.0629 ms/op 1.10
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.7522 ms/op 4.3097 ms/op 1.10
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.8775 ms/op 2.5053 ms/op 1.15
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 5.0176 ms/op 4.4573 ms/op 1.13
Tree 40 250000 create 373.48 ms/op 392.04 ms/op 0.95
Tree 40 250000 get(125000) 128.81 ns/op 120.36 ns/op 1.07
Tree 40 250000 set(125000) 1.1867 us/op 1.2773 us/op 0.93
Tree 40 250000 toArray() 12.094 ms/op 12.101 ms/op 1.00
Tree 40 250000 iterate all - toArray() + loop 12.991 ms/op 12.656 ms/op 1.03
Tree 40 250000 iterate all - get(i) 42.916 ms/op 41.055 ms/op 1.05
Array 250000 create 2.4056 ms/op 2.3517 ms/op 1.02
Array 250000 clone - spread 788.05 us/op 785.31 us/op 1.00
Array 250000 get(125000) 0.35000 ns/op 0.34500 ns/op 1.01
Array 250000 set(125000) 0.35300 ns/op 0.38400 ns/op 0.92
Array 250000 iterate all - loop 59.438 us/op 61.330 us/op 0.97
phase0 afterProcessEpoch - 250000 vs - 7PWei 40.702 ms/op 42.553 ms/op 0.96
Array.fill - length 1000000 2.8875 ms/op 3.1217 ms/op 0.92
Array push - length 1000000 10.648 ms/op 10.598 ms/op 1.00
Array.get 0.21585 ns/op 0.21391 ns/op 1.01
Uint8Array.get 0.22086 ns/op 0.22111 ns/op 1.00
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.108 ms/op 14.606 ms/op 1.03
altair processEpoch - mainnet_e81889 267.06 ms/op 319.27 ms/op 0.84
mainnet_e81889 - altair beforeProcessEpoch 22.702 ms/op 27.947 ms/op 0.81
mainnet_e81889 - altair processJustificationAndFinalization 5.5340 us/op 6.8640 us/op 0.81
mainnet_e81889 - altair processInactivityUpdates 3.9512 ms/op 3.8593 ms/op 1.02
mainnet_e81889 - altair processRewardsAndPenalties 22.245 ms/op 18.451 ms/op 1.21
mainnet_e81889 - altair processRegistryUpdates 643.00 ns/op 588.00 ns/op 1.09
mainnet_e81889 - altair processSlashings 190.00 ns/op 230.00 ns/op 0.83
mainnet_e81889 - altair processEth1DataReset 194.00 ns/op 212.00 ns/op 0.92
mainnet_e81889 - altair processEffectiveBalanceUpdates 2.1392 ms/op 1.4102 ms/op 1.52
mainnet_e81889 - altair processSlashingsReset 862.00 ns/op 852.00 ns/op 1.01
mainnet_e81889 - altair processRandaoMixesReset 1.0840 us/op 1.7910 us/op 0.61
mainnet_e81889 - altair processHistoricalRootsUpdate 193.00 ns/op 166.00 ns/op 1.16
mainnet_e81889 - altair processParticipationFlagUpdates 523.00 ns/op 606.00 ns/op 0.86
mainnet_e81889 - altair processSyncCommitteeUpdates 162.00 ns/op 130.00 ns/op 1.25
mainnet_e81889 - altair afterProcessEpoch 43.861 ms/op 43.401 ms/op 1.01
capella processEpoch - mainnet_e217614 747.75 ms/op 874.45 ms/op 0.86
mainnet_e217614 - capella beforeProcessEpoch 59.403 ms/op 61.318 ms/op 0.97
mainnet_e217614 - capella processJustificationAndFinalization 5.9940 us/op 6.0990 us/op 0.98
mainnet_e217614 - capella processInactivityUpdates 17.116 ms/op 16.974 ms/op 1.01
mainnet_e217614 - capella processRewardsAndPenalties 101.50 ms/op 108.94 ms/op 0.93
mainnet_e217614 - capella processRegistryUpdates 5.7410 us/op 5.7570 us/op 1.00
mainnet_e217614 - capella processSlashings 198.00 ns/op 207.00 ns/op 0.96
mainnet_e217614 - capella processEth1DataReset 188.00 ns/op 160.00 ns/op 1.18
mainnet_e217614 - capella processEffectiveBalanceUpdates 16.120 ms/op 11.641 ms/op 1.38
mainnet_e217614 - capella processSlashingsReset 883.00 ns/op 1.1320 us/op 0.78
mainnet_e217614 - capella processRandaoMixesReset 1.1550 us/op 1.0790 us/op 1.07
mainnet_e217614 - capella processHistoricalRootsUpdate 203.00 ns/op 168.00 ns/op 1.21
mainnet_e217614 - capella processParticipationFlagUpdates 541.00 ns/op 931.00 ns/op 0.58
mainnet_e217614 - capella afterProcessEpoch 115.30 ms/op 112.90 ms/op 1.02
phase0 processEpoch - mainnet_e58758 273.28 ms/op 261.55 ms/op 1.04
mainnet_e58758 - phase0 beforeProcessEpoch 58.705 ms/op 57.437 ms/op 1.02
mainnet_e58758 - phase0 processJustificationAndFinalization 6.7320 us/op 6.7120 us/op 1.00
mainnet_e58758 - phase0 processRewardsAndPenalties 20.564 ms/op 21.112 ms/op 0.97
mainnet_e58758 - phase0 processRegistryUpdates 2.8500 us/op 2.7780 us/op 1.03
mainnet_e58758 - phase0 processSlashings 198.00 ns/op 166.00 ns/op 1.19
mainnet_e58758 - phase0 processEth1DataReset 203.00 ns/op 194.00 ns/op 1.05
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.4550 ms/op 1.0602 ms/op 1.37
mainnet_e58758 - phase0 processSlashingsReset 1.0050 us/op 823.00 ns/op 1.22
mainnet_e58758 - phase0 processRandaoMixesReset 1.1640 us/op 1.1230 us/op 1.04
mainnet_e58758 - phase0 processHistoricalRootsUpdate 228.00 ns/op 163.00 ns/op 1.40
mainnet_e58758 - phase0 processParticipationRecordUpdates 2.9400 us/op 841.00 ns/op 3.50
mainnet_e58758 - phase0 afterProcessEpoch 37.098 ms/op 35.275 ms/op 1.05
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.9038 ms/op 1.9559 ms/op 0.97
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.7321 ms/op 3.8115 ms/op 0.45
altair processInactivityUpdates - 250000 normalcase 101.38 us/op 52.954 us/op 1.91
altair processInactivityUpdates - 250000 worstcase 100.78 us/op 78.973 us/op 1.28
phase0 processRegistryUpdates - 250000 normalcase 5.5770 us/op 6.9930 us/op 0.80
phase0 processRegistryUpdates - 250000 badcase_full_deposits 278.95 us/op 339.35 us/op 0.82
phase0 processRegistryUpdates - 250000 worstcase 0.5 87.223 ms/op 65.997 ms/op 1.32
altair processRewardsAndPenalties - 250000 normalcase 110.69 us/op 125.48 us/op 0.88
altair processRewardsAndPenalties - 250000 worstcase 108.43 us/op 121.00 us/op 0.90
phase0 getAttestationDeltas - 250000 normalcase 7.0503 ms/op 6.5389 ms/op 1.08
phase0 getAttestationDeltas - 250000 worstcase 7.1860 ms/op 6.6645 ms/op 1.08
phase0 processSlashings - 250000 worstcase 123.12 us/op 119.72 us/op 1.03
altair processSyncCommitteeUpdates - 250000 9.4703 ms/op 8.3093 ms/op 1.14
BeaconState.hashTreeRoot - No change 235.00 ns/op 185.00 ns/op 1.27
BeaconState.hashTreeRoot - 1 full validator 100.11 us/op 80.342 us/op 1.25
BeaconState.hashTreeRoot - 32 full validator 1.1161 ms/op 952.00 us/op 1.17
BeaconState.hashTreeRoot - 512 full validator 9.6162 ms/op 8.4560 ms/op 1.14
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 135.20 us/op 109.04 us/op 1.24
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.8860 ms/op 1.7491 ms/op 1.08
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 24.595 ms/op 23.679 ms/op 1.04
BeaconState.hashTreeRoot - 1 balances 103.86 us/op 82.499 us/op 1.26
BeaconState.hashTreeRoot - 32 balances 942.36 us/op 679.00 us/op 1.39
BeaconState.hashTreeRoot - 512 balances 7.2330 ms/op 6.3973 ms/op 1.13
BeaconState.hashTreeRoot - 250000 balances 158.74 ms/op 181.20 ms/op 0.88
aggregationBits - 2048 els - zipIndexesInBitList 23.754 us/op 20.923 us/op 1.14
regular array get 100000 times 25.795 us/op 24.745 us/op 1.04
wrappedArray get 100000 times 25.758 us/op 24.742 us/op 1.04
arrayWithProxy get 100000 times 15.756 ms/op 14.948 ms/op 1.05
ssz.Root.equals 24.930 ns/op 24.068 ns/op 1.04
byteArrayEquals 24.463 ns/op 23.644 ns/op 1.03
Buffer.compare 10.532 ns/op 10.063 ns/op 1.05
processSlot - 1 slots 12.615 us/op 15.853 us/op 0.80
processSlot - 32 slots 2.6465 ms/op 2.3990 ms/op 1.10
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.3996 ms/op 3.3178 ms/op 1.33
getCommitteeAssignments - req 1 vs - 250000 vc 1.9324 ms/op 1.8567 ms/op 1.04
getCommitteeAssignments - req 100 vs - 250000 vc 3.7752 ms/op 3.6812 ms/op 1.03
getCommitteeAssignments - req 1000 vs - 250000 vc 3.9872 ms/op 3.9307 ms/op 1.01
findModifiedValidators - 10000 modified validators 442.72 ms/op 531.41 ms/op 0.83
findModifiedValidators - 1000 modified validators 299.54 ms/op 394.66 ms/op 0.76
findModifiedValidators - 100 modified validators 276.88 ms/op 282.44 ms/op 0.98
findModifiedValidators - 10 modified validators 138.87 ms/op 138.54 ms/op 1.00
findModifiedValidators - 1 modified validators 132.87 ms/op 147.96 ms/op 0.90
findModifiedValidators - no difference 153.30 ms/op 149.33 ms/op 1.03
migrate state 1500000 validators, 3400 modified, 2000 new 338.56 ms/op 373.79 ms/op 0.91
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.3000 ns/op 4.0900 ns/op 1.05
state getBlockRootAtSlot - 250000 vs - 7PWei 448.10 ns/op 869.31 ns/op 0.52
computeProposerIndex 100000 validators 1.4771 ms/op 1.5430 ms/op 0.96
getNextSyncCommitteeIndices 1000 validators 3.2845 ms/op 3.3283 ms/op 0.99
getNextSyncCommitteeIndices 10000 validators 3.2783 ms/op 3.3165 ms/op 0.99
getNextSyncCommitteeIndices 100000 validators 3.2902 ms/op 3.3514 ms/op 0.98
computeProposers - vc 250000 618.13 us/op 636.20 us/op 0.97
computeEpochShuffling - vc 250000 41.290 ms/op 42.501 ms/op 0.97
getNextSyncCommittee - vc 250000 10.398 ms/op 10.670 ms/op 0.97
nodejs block root to RootHex using toHex 135.17 ns/op 147.82 ns/op 0.91
nodejs block root to RootHex using toRootHex 83.069 ns/op 88.123 ns/op 0.94
nodejs fromHex(blob) 245.61 us/op 213.68 us/op 1.15
nodejs fromHexInto(blob) 701.77 us/op 718.61 us/op 0.98
nodejs block root to RootHex using the deprecated toHexString 563.57 ns/op 576.60 ns/op 0.98
nodejs byteArrayEquals 32 bytes (block root) 28.105 ns/op 28.443 ns/op 0.99
nodejs byteArrayEquals 48 bytes (pubkey) 40.225 ns/op 45.971 ns/op 0.88
nodejs byteArrayEquals 96 bytes (signature) 39.546 ns/op 40.942 ns/op 0.97
nodejs byteArrayEquals 1024 bytes 45.469 ns/op 46.869 ns/op 0.97
nodejs byteArrayEquals 131072 bytes (blob) 1.8491 us/op 1.9132 us/op 0.97
browser block root to RootHex using toHex 160.76 ns/op 290.79 ns/op 0.55
browser block root to RootHex using toRootHex 151.39 ns/op 156.88 ns/op 0.97
browser fromHex(blob) 1.0174 ms/op 1.2050 ms/op 0.84
browser fromHexInto(blob) 693.81 us/op 716.64 us/op 0.97
browser block root to RootHex using the deprecated toHexString 407.84 ns/op 594.47 ns/op 0.69
browser byteArrayEquals 32 bytes (block root) 30.865 ns/op 31.707 ns/op 0.97
browser byteArrayEquals 48 bytes (pubkey) 42.976 ns/op 44.237 ns/op 0.97
browser byteArrayEquals 96 bytes (signature) 84.085 ns/op 87.166 ns/op 0.96
browser byteArrayEquals 1024 bytes 790.50 ns/op 814.59 ns/op 0.97
browser byteArrayEquals 131072 bytes (blob) 100.32 us/op 103.09 us/op 0.97

by benchmarkbot/action

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/beacon-node/src/chain/blocks/importBlock.ts
Comment thread packages/beacon-node/src/chain/validation/executionPayloadEnvelope.ts Outdated
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts
Comment thread packages/beacon-node/src/chain/blocks/writePayloadEnvelopeInputToDb.ts Outdated
ensi321 and others added 3 commits March 2, 2026 16:24
Use getBlockSlotState instead of getHeadState for builder pubkey lookup
during execution payload envelope validation. This ensures signature
verification uses the correct builder registry state at the block's slot,
rather than potentially stale head state that could differ due to reorgs
or head changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@ensi321 ensi321 changed the title feat: add gloas execution payload envelope import pipeline [wip] feat: add gloas execution payload envelope import pipeline Mar 3, 2026
ensi321 and others added 2 commits March 2, 2026 17:42
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@ensi321
ensi321 marked this pull request as ready for review March 3, 2026 01:44
@ensi321
ensi321 requested a review from a team as a code owner March 3, 2026 01:44
@ensi321

ensi321 commented Mar 3, 2026

Copy link
Copy Markdown
Member Author

@lodekeeper can you do a review on this?

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

Copy link
Copy Markdown

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: 7c998d3b70

ℹ️ 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".

Comment thread packages/beacon-node/src/chain/produceBlock/computeNewStateRoot.ts Outdated

@lodekeeper lodekeeper left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Superseded by corrected review: #8962 (review)

@lodekeeper lodekeeper left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Did a pass on the latest diff. I agree with the newly raised P1s and think they should be addressed before merge:

  1. computeEnvelopeStateRoot currently calls processExecutionPayloadEnvelope with verifyStateRoot=true while deriving the state root from an envelope that still has a placeholder stateRoot. That can self-fail block production in this path. This derivation step should skip state-root verification and only verify after the computed root is populated.

  2. PayloadEnvelopeInput.shouldImport sets importClaimed=true before import success and never resets on import failure. If EL import fails transiently (ELERROR / UNAVAILABLE), later envelope/column arrivals cannot retry import and we can stay stuck until pruning/finalization.

Also +1 on the cache-eviction TODO thread (clearByRootAndSlot) — clearing too aggressively can wipe useful pending data paths and likely needs narrower eviction semantics.

@lodekeeper

Copy link
Copy Markdown
Contributor

@ensi321 done — I left a review pass on the latest diff (including the two new P1s and cache-eviction concern): #8962 (review)

Comment thread packages/beacon-node/src/chain/validation/executionPayloadEnvelope.ts Outdated
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts Outdated

@twoeths twoeths left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

did not fully review the PR
the PayloadEnvelopeInput should support having available data if it sees >= 64 columns similar to what we have pre-gloas
I have #8974 to make it easier to transition there and deduplicate persisting DataColumnSidecar to db

Comment thread packages/beacon-node/src/chain/blocks/importBlock.ts Outdated
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts Outdated
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts Outdated
Comment thread packages/beacon-node/src/chain/blocks/writePayloadEnvelopeInputToDb.ts Outdated
Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts Outdated
Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts Outdated
Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts
Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts
Comment thread packages/beacon-node/src/chain/validatorMonitor.ts
Comment thread packages/state-transition/src/signatureSets/executionPayloadEnvelope.ts Outdated

@twoeths twoeths left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to make it ready for BeaconStateView too, dropped some more minor comments

ensi321 and others added 4 commits March 18, 2026 23:04
Co-authored-by: Nico Flaig <nflaig@protonmail.com>
Co-authored-by: Nico Flaig <nflaig@protonmail.com>
twoeths added a commit that referenced this pull request Mar 19, 2026
twoeths added a commit that referenced this pull request Mar 19, 2026
Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>

@lodekeeper lodekeeper left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thorough review of the full payload envelope import pipeline. Architecture is sound — the PayloadEnvelopeInput state machine, PayloadEnvelopeProcessor queue, and SeenPayloadEnvelopeInput cache mirror the block import pipeline cleanly. Removal of builderIndex/blockHashFromBid from ProtoBlock is a good separation of concerns.

Main concerns are around persistence ordering, error handling edge cases, and two .ts import extensions that will break at runtime. Details inline.

Comment thread packages/beacon-node/src/network/processor/gossipHandlers.ts Outdated
Comment thread packages/state-transition/src/stateView/beaconStateView.ts Outdated
Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts Outdated
Comment thread packages/beacon-node/src/chain/blocks/importExecutionPayload.ts
ensi321 and others added 2 commits March 19, 2026 16:59
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

// 2. Apply backpressure from the write queue early, before doing verification work.
// The actual DB write is deferred until after verification succeeds.
await this.unfinalizedPayloadEnvelopeWrites.waitForSpace();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ensi321 agree that the actual DB write should be deferred until after verification but I don't see why we should delay verification just because the db write queue is full, these seem kinda independent to me, curious about your thoughts why you kept the check here (at the start of the import)

// TODO GLOAS: Enable when PR #8868 merged (adds processPayloadState)
// this.regen.processPayloadState(postPayloadState);
// if epoch boundary also call
// this.regen.addCheckpointState(cp, checkpointState, true);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we could address this now, but fine to do in a follow up

nflaig added 3 commits March 20, 2026 15:34
This reverts commit 1cdc693.

ah I think this was correct cc @twoeths, it doesn't change much it will
be either way treated as `IGNORE` but if we pruned `payloadInput` then
we would use code `PAYLOAD_ENVELOPE_INPUT_MISSING` even though it should be
`ENVELOPE_ALREADY_KNOWN`, I guess that was the initial concern I raised.
So I am reverting this commit.

@nflaig nflaig left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@nflaig
nflaig merged commit 70938e1 into unstable Mar 20, 2026
25 of 26 checks passed
@nflaig
nflaig deleted the nc/epbs-payload-import branch March 20, 2026 16:19
@codecov

codecov Bot commented Mar 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.28%. Comparing base (4411584) to head (81b5cd2).
⚠️ Report is 1 commits behind head on unstable.

Additional details and impacted files
@@            Coverage Diff            @@
##           unstable    #8962   +/-   ##
=========================================
  Coverage     52.28%   52.28%           
=========================================
  Files           848      848           
  Lines         62165    62155   -10     
  Branches       4544     4544           
=========================================
- Hits          32503    32498    -5     
+ Misses        29597    29592    -5     
  Partials         65       65           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wemeetagain

Copy link
Copy Markdown
Member

🎉 This PR is included in v1.42.0 🎉

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.

5 participants