(wip) feat: gloas light client support - #9683
Conversation
Brings the EIP-7688 (progressive SSZ) branch up to the v1.7.0-alpha.11 spec baseline. Conflict resolutions of note: - @chainsafe/ssz bumped to ^1.6.0 (progressive types) across workspace; dropped unused deps (utils ssz, cli pubkey-index-map, st persistent-ts) to match unstable's #9462 cleanup. - gloas sszTypes: kept branch's progressive types, re-applied unstable's alpha.9-11 changes it predated: EIP-8282 builder deposits/exits (as ProgressiveList), BuilderPendingPayment.proposerIndex, and ExecutionPayloadBid.gasLimit UintBn64 -> UintNum64. - processParentExecutionPayload: kept #4630 length asserts, extended to builder deposits/exits, used unstable's 5-field empty-requests check. - processOperations: kept assertGloasOperationLimits + unstable's fulu zero-deposit rule. - specTestIterator: kept branch's narrower gloas light-client skips. Build, check-types, lint, and types/state-transition unit tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
https://discord.com/channels/595666850260713488/1295427781722898505/1520371177036709949 we need couple more progressive containers in gloas. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
**Motivation** - improve upgradeStateToGloas() by reusing nodes of pre-gloas BeaconState - bump `@chainsafe/ssz` version to v1.6.1 **Description** with mainnet state 14707840 - before ``` [bench] upgradeStateToGloas: 3205.5ms [bench] gloas hashTreeRoot: 32196.4ms ``` - this PR ``` [bench] upgradeStateToGloas: 1178.3ms [bench] gloas hashTreeRoot: 4899.3ms ``` **AI Assistance Disclosure** - created with the help of Claude --------- Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com> Co-authored-by: NC <17676176+ensi321@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nsensus-specs #4630) apply_parent_execution_payload performs no length checks in the spec. With EIP-7688 the ExecutionRequests lists are progressive (no SSZ max length), so the Electra-cap assertion (assertExecutionRequestsWithinLimits) is invalid -- requests exceeding the Electra caps are valid. Removes the assertion and its now-unused imports. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverts 0395641. consensus-specs master still asserts the 5 execution request length limits in apply_parent_execution_payload (beacon-chain.md L1284-1290, tip a62bc326c) through the #4630 merge and all followups; the "drop the cap" idea was never adopted (#5420 instead tightened MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD 256->64). Keep parity with spec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The value shipped in the merged #4630 (and master, tip a62bc326c) is lower than the pre-merge PR snapshot this branch used: - mainnet 4082504 -> 4027336 - minimal 1993180 -> 1938012 (MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD 256->64 and PAYLOAD_DUE_BPS 7500->5000 are handled on nc/alpha.12-constants, not here.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… gossip consensus-specs #4630 (gloas p2p-interface) requires beacon_block gossip to REJECT when parent_execution_requests counts or block body operation counts exceed their per-block limits. EIP-7688 made these lists progressive (no SSZ type-level cap), so the bounds are enforced here at the gossip layer (they are also asserted in the state transition). deposits must be empty (limit 0) post-Fulu. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring EIP-7688 progressive-containers branch current (36 commits behind). Conflicts resolved: - beacon-node/package.json: keep quic ^2.1.1 (unstable), ssz ^1.6.1 + persistent-merkle-tree ^1.3.0 (eip-7688, needed for progressive containers) - topic.test.ts: union of both test suites (gossip SSZ size limits + getAllowedTopics) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Do the alpha.12 bump in eip-7688 branch. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root package.json was left at ^1.6.1 when packages/* were bumped to 1.6.2, leaving the lockfile pointing at a dropped 1.6.1 block and breaking frozen install in CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
**Description** - more progressive ssz utils to reuse nodes, this improves: - gloas fork transition to migrate basic list - progressParticipationFlagUpdates, which happens at epoch transition - also do not check deposit length as found in #9390 (comment) **AI Assistance Disclosure** - created with the help of Claude --------- Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for the Gloas fork, implementing EIP-7688 progressive containers and lists, EIP-7732, and EIP-8282. It updates SSZ types, gossip validation, state transition logic (including an optimized Fulu-to-Gloas state upgrade), and light client proof generation. The review feedback highlights three critical issues: hardcoding Gloas withdrawals breaks pre-Gloas envelope verification, accessing builder deposits/exits directly on Electra execution requests causes a TypeError, and a missing defensive check in computeBranchRoot can lead to a crash if the branch length is less than the expected depth.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
I am having trouble creating individual review comments. Click here to see my feedback.
packages/beacon-node/src/chain/blocks/verifyExecutionPayloadEnvelope.ts (103-104)
Hardcoding ssz.gloas.Withdrawals will break verification for pre-Gloas (e.g., Electra) execution payload envelopes because they use the Capella withdrawals SSZ type (ssz.capella.Withdrawals). We should dynamically select the withdrawals SSZ type based on the active fork of the state.
const withdrawalsSsz = state.config.getForkName(state.slot) === "gloas" ? ssz.gloas.Withdrawals : ssz.capella.Withdrawals;
const payloadWithdrawalsRoot = withdrawalsSsz.hashTreeRoot(payload.withdrawals);
const expectedWithdrawalsRoot = withdrawalsSsz.hashTreeRoot(state.payloadExpectedWithdrawals);packages/beacon-node/src/chain/validation/executionPayloadEnvelope.ts (130-146)
In Electra, ExecutionRequests does not contain builderDeposits or builderExits (which are introduced in Gloas under EIP-8282). Accessing .length directly on these undefined fields will throw a TypeError and crash the beacon node when validating Electra envelopes. We should use optional chaining to safely handle these fields.
const requestCountLimits: [string, number | undefined, number][] = [
["deposits", executionRequests.deposits?.length, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD],
["withdrawals", executionRequests.withdrawals?.length, MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD],
["consolidations", executionRequests.consolidations?.length, MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD],
["builderDeposits", executionRequests.builderDeposits?.length, MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD],
["builderExits", executionRequests.builderExits?.length, MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD],
];
for (const [name, count, limit] of requestCountLimits) {
if (count !== undefined && count > limit) {
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
code: ExecutionPayloadEnvelopeErrorCode.EXECUTION_REQUESTS_COUNT_EXCEEDED,
name,
count,
limit,
});
}
}
packages/state-transition/src/lightClient/spec/utils.ts (477-488)
If branch has fewer elements than depth, proof[i] will be undefined, which will cause the hash function to crash with a TypeError. We should add a defensive check to ensure the branch has sufficient depth before reconstructing the root.
function computeBranchRoot(leaf: Uint8Array, branch: Uint8Array[], gindex: bigint): Uint8Array {
const depth = getGindexDepth(Number(gindex));
if (branch.length < depth) {
return ZERO_HASH;
}
const proof = branch.slice(-depth);
const index = getGindexIndex(Number(gindex));
let root = leaf;
for (let i = 0; i < depth; i++) {
root = Math.floor(index / 2 ** i) % 2 === 1 ? hash(proof[i], root) : hash(root, proof[i]);
}
return root;
}
|
| Benchmark suite | Current: 05adaff | Previous: 17a4805 | Ratio |
|---|---|---|---|
| send data - 1000 2048B messages | 60.604 ms/op | 18.358 ms/op | 3.30 |
| getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 | 14.373 us/op | 3.1030 us/op | 4.63 |
Full benchmark results
| Benchmark suite | Current: 05adaff | Previous: 17a4805 | Ratio |
|---|---|---|---|
| getPubkeys - index2pubkey - req 1000 vs - 250000 vc | 951.28 us/op | 942.18 us/op | 1.01 |
| getPubkeys - validatorsArr - req 1000 vs - 250000 vc | 41.370 us/op | 37.078 us/op | 1.12 |
| BLS verify - blst | 739.15 us/op | 708.48 us/op | 1.04 |
| BLS verifyMultipleSignatures 3 - blst | 1.3978 ms/op | 1.2569 ms/op | 1.11 |
| BLS verifyMultipleSignatures 8 - blst | 2.2083 ms/op | 2.0040 ms/op | 1.10 |
| BLS verifyMultipleSignatures 32 - blst | 7.0232 ms/op | 6.2567 ms/op | 1.12 |
| BLS verifyMultipleSignatures 64 - blst | 14.382 ms/op | 12.316 ms/op | 1.17 |
| BLS verifyMultipleSignatures 128 - blst | 26.355 ms/op | 23.811 ms/op | 1.11 |
| BLS deserializing 10000 signatures | 654.36 ms/op | 605.74 ms/op | 1.08 |
| BLS deserializing 100000 signatures | 6.6084 s/op | 6.1010 s/op | 1.08 |
| BLS verifyMultipleSignatures - same message - 3 - blst | 770.07 us/op | 771.88 us/op | 1.00 |
| BLS verifyMultipleSignatures - same message - 8 - blst | 927.75 us/op | 803.01 us/op | 1.16 |
| BLS verifyMultipleSignatures - same message - 32 - blst | 1.6103 ms/op | 1.4995 ms/op | 1.07 |
| BLS verifyMultipleSignatures - same message - 64 - blst | 2.4785 ms/op | 2.2035 ms/op | 1.12 |
| BLS verifyMultipleSignatures - same message - 128 - blst | 4.2090 ms/op | 3.9092 ms/op | 1.08 |
| BLS aggregatePubkeys 32 - blst | 18.430 us/op | 16.879 us/op | 1.09 |
| BLS aggregatePubkeys 128 - blst | 65.908 us/op | 60.667 us/op | 1.09 |
| getSlashingsAndExits - default max | 70.656 us/op | 44.572 us/op | 1.59 |
| getSlashingsAndExits - 2k | 427.85 us/op | 323.74 us/op | 1.32 |
| proposeBlockBody type=full, size=empty | 679.22 us/op | 556.87 us/op | 1.22 |
| isKnown best case - 1 super set check | 181.00 ns/op | 158.00 ns/op | 1.15 |
| isKnown normal case - 2 super set checks | 178.00 ns/op | 158.00 ns/op | 1.13 |
| isKnown worse case - 16 super set checks | 175.00 ns/op | 156.00 ns/op | 1.12 |
| validate api signedAggregateAndProof - struct | 1.5719 ms/op | 1.4083 ms/op | 1.12 |
| validate gossip signedAggregateAndProof - struct | 1.6701 ms/op | 1.4169 ms/op | 1.18 |
| batch validate gossip attestation - vc 640000 - chunk 32 | 113.29 us/op | 101.26 us/op | 1.12 |
| batch validate gossip attestation - vc 640000 - chunk 64 | 100.86 us/op | 88.194 us/op | 1.14 |
| batch validate gossip attestation - vc 640000 - chunk 128 | 90.172 us/op | 82.042 us/op | 1.10 |
| batch validate gossip attestation - vc 640000 - chunk 256 | 89.457 us/op | 78.766 us/op | 1.14 |
| bytes32 toHexString | 296.00 ns/op | 262.00 ns/op | 1.13 |
| bytes32 Buffer.toString(hex) | 175.00 ns/op | 173.00 ns/op | 1.01 |
| bytes32 Buffer.toString(hex) from Uint8Array | 247.00 ns/op | 241.00 ns/op | 1.02 |
| bytes32 Buffer.toString(hex) + 0x | 172.00 ns/op | 175.00 ns/op | 0.98 |
| Return object 10000 times | 0.21720 ns/op | 0.19940 ns/op | 1.09 |
| Throw Error 10000 times | 3.4141 us/op | 3.1418 us/op | 1.09 |
| toHex | 108.96 ns/op | 87.840 ns/op | 1.24 |
| Buffer.from | 87.310 ns/op | 79.857 ns/op | 1.09 |
| shared Buffer | 56.731 ns/op | 54.433 ns/op | 1.04 |
| fastMsgIdFn sha256 / 200 bytes | 1.4670 us/op | 1.3840 us/op | 1.06 |
| fastMsgIdFn h32 xxhash / 200 bytes | 160.00 ns/op | 152.00 ns/op | 1.05 |
| fastMsgIdFn h64 xxhash / 200 bytes | 205.00 ns/op | 202.00 ns/op | 1.01 |
| fastMsgIdFn sha256 / 1000 bytes | 4.6850 us/op | 4.4490 us/op | 1.05 |
| fastMsgIdFn h32 xxhash / 1000 bytes | 258.00 ns/op | 233.00 ns/op | 1.11 |
| fastMsgIdFn h64 xxhash / 1000 bytes | 264.00 ns/op | 245.00 ns/op | 1.08 |
| fastMsgIdFn sha256 / 10000 bytes | 42.387 us/op | 39.478 us/op | 1.07 |
| fastMsgIdFn h32 xxhash / 10000 bytes | 1.2930 us/op | 1.2040 us/op | 1.07 |
| fastMsgIdFn h64 xxhash / 10000 bytes | 825.00 ns/op | 791.00 ns/op | 1.04 |
| send data - 1000 256B messages | 5.3927 ms/op | 4.0394 ms/op | 1.34 |
| send data - 1000 512B messages | 6.0667 ms/op | 5.3268 ms/op | 1.14 |
| send data - 1000 1024B messages | 7.9950 ms/op | 5.6754 ms/op | 1.41 |
| send data - 1000 1200B messages | 7.4746 ms/op | 5.9514 ms/op | 1.26 |
| send data - 1000 2048B messages | 60.604 ms/op | 18.358 ms/op | 3.30 |
| send data - 1000 4096B messages | 112.39 ms/op | 46.963 ms/op | 2.39 |
| send data - 1000 16384B messages | 488.06 ms/op | 207.13 ms/op | 2.36 |
| send data - 1000 65536B messages | 1.9311 s/op | 999.63 ms/op | 1.93 |
| enrSubnets - fastDeserialize 64 bits | 768.00 ns/op | 2.4030 us/op | 0.32 |
| enrSubnets - ssz BitVector 64 bits | 290.00 ns/op | 252.00 ns/op | 1.15 |
| enrSubnets - fastDeserialize 4 bits | 107.00 ns/op | 105.00 ns/op | 1.02 |
| enrSubnets - ssz BitVector 4 bits | 285.00 ns/op | 255.00 ns/op | 1.12 |
| prioritizePeers score -10:0 att 32-0.1 sync 2-0 | 209.07 us/op | 193.89 us/op | 1.08 |
| prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 | 236.99 us/op | 220.75 us/op | 1.07 |
| prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 | 348.90 us/op | 315.34 us/op | 1.11 |
| prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 | 618.58 us/op | 563.86 us/op | 1.10 |
| prioritizePeers score 0:0 att 64-1 sync 4-1 | 737.01 us/op | 652.56 us/op | 1.13 |
| array of 16000 items push then shift | 1.2940 us/op | 1.1935 us/op | 1.08 |
| LinkedList of 16000 items push then shift | 9.3310 ns/op | 7.1270 ns/op | 1.31 |
| array of 16000 items push then pop | 91.756 ns/op | 67.096 ns/op | 1.37 |
| LinkedList of 16000 items push then pop | 6.9040 ns/op | 5.7160 ns/op | 1.21 |
| array of 24000 items push then shift | 1.9271 us/op | 1.7586 us/op | 1.10 |
| LinkedList of 24000 items push then shift | 8.5570 ns/op | 6.6750 ns/op | 1.28 |
| array of 24000 items push then pop | 128.25 ns/op | 93.368 ns/op | 1.37 |
| LinkedList of 24000 items push then pop | 7.2380 ns/op | 5.6670 ns/op | 1.28 |
| intersect bitArray bitLen 8 | 4.8310 ns/op | 4.5230 ns/op | 1.07 |
| intersect array and set length 8 | 30.776 ns/op | 27.477 ns/op | 1.12 |
| intersect bitArray bitLen 128 | 24.952 ns/op | 22.782 ns/op | 1.10 |
| intersect array and set length 128 | 533.97 ns/op | 465.67 ns/op | 1.15 |
| bitArray.getTrueBitIndexes() bitLen 128 | 1.0320 us/op | 872.00 ns/op | 1.18 |
| bitArray.getTrueBitIndexes() bitLen 248 | 1.8340 us/op | 1.5750 us/op | 1.16 |
| bitArray.getTrueBitIndexes() bitLen 512 | 3.8400 us/op | 3.2950 us/op | 1.17 |
| Full columns - reconstruct all 6 blobs | 191.33 us/op | 155.94 us/op | 1.23 |
| Full columns - reconstruct half of the blobs out of 6 | 87.811 us/op | 106.98 us/op | 0.82 |
| Full columns - reconstruct single blob out of 6 | 37.240 us/op | 31.286 us/op | 1.19 |
| Half columns - reconstruct all 6 blobs | 418.54 ms/op | 356.22 ms/op | 1.17 |
| Half columns - reconstruct half of the blobs out of 6 | 212.45 ms/op | 179.50 ms/op | 1.18 |
| Half columns - reconstruct single blob out of 6 | 77.451 ms/op | 63.565 ms/op | 1.22 |
| Set add up to 64 items then delete first | 2.2171 us/op | 1.5007 us/op | 1.48 |
| OrderedSet add up to 64 items then delete first | 3.6033 us/op | 2.3260 us/op | 1.55 |
| Set add up to 64 items then delete last | 2.5749 us/op | 1.7406 us/op | 1.48 |
| OrderedSet add up to 64 items then delete last | 4.2924 us/op | 2.5700 us/op | 1.67 |
| Set add up to 64 items then delete middle | 2.3499 us/op | 1.7337 us/op | 1.36 |
| OrderedSet add up to 64 items then delete middle | 8.1791 us/op | 3.9867 us/op | 2.05 |
| Set add up to 128 items then delete first | 5.1693 us/op | 3.4490 us/op | 1.50 |
| OrderedSet add up to 128 items then delete first | 11.229 us/op | 5.3697 us/op | 2.09 |
| Set add up to 128 items then delete last | 7.5537 us/op | 3.3543 us/op | 2.25 |
| OrderedSet add up to 128 items then delete last | 8.5197 us/op | 5.1277 us/op | 1.66 |
| Set add up to 128 items then delete middle | 5.0392 us/op | 3.3531 us/op | 1.50 |
| OrderedSet add up to 128 items then delete middle | 14.847 us/op | 10.655 us/op | 1.39 |
| Set add up to 256 items then delete first | 9.4863 us/op | 7.0402 us/op | 1.35 |
| OrderedSet add up to 256 items then delete first | 15.457 us/op | 11.116 us/op | 1.39 |
| Set add up to 256 items then delete last | 10.686 us/op | 6.7746 us/op | 1.58 |
| OrderedSet add up to 256 items then delete last | 17.112 us/op | 10.505 us/op | 1.63 |
| Set add up to 256 items then delete middle | 10.095 us/op | 6.7151 us/op | 1.50 |
| OrderedSet add up to 256 items then delete middle | 42.742 us/op | 32.989 us/op | 1.30 |
| runFastConfirmationRules vc:100000 bc:96 eq:0 | 4.9412 ms/op | 4.2483 ms/op | 1.16 |
| runFastConfirmationRules vc:600000 bc:96 eq:0 | 37.867 ms/op | 32.605 ms/op | 1.16 |
| runFastConfirmationRules vc:1000000 bc:96 eq:0 | 72.963 ms/op | 54.530 ms/op | 1.34 |
| runFastConfirmationRules vc:600000 bc:320 eq:0 | 37.506 ms/op | 32.570 ms/op | 1.15 |
| runFastConfirmationRules vc:100000 bc:96 eq:1000 | 1.1865 s/op | 1.0323 s/op | 1.15 |
| pass gossip attestations to forkchoice per slot | 2.7749 ms/op | 2.4300 ms/op | 1.14 |
| forkChoice updateHead vc 100000 bc 64 eq 0 | 426.77 us/op | 382.01 us/op | 1.12 |
| forkChoice updateHead vc 600000 bc 64 eq 0 | 2.5517 ms/op | 2.2998 ms/op | 1.11 |
| forkChoice updateHead vc 1000000 bc 64 eq 0 | 4.3154 ms/op | 3.7653 ms/op | 1.15 |
| forkChoice updateHead vc 600000 bc 320 eq 0 | 2.6291 ms/op | 2.2794 ms/op | 1.15 |
| forkChoice updateHead vc 600000 bc 1200 eq 0 | 2.6967 ms/op | 2.3203 ms/op | 1.16 |
| forkChoice updateHead vc 600000 bc 7200 eq 0 | 3.8471 ms/op | 2.7312 ms/op | 1.41 |
| forkChoice updateHead vc 600000 bc 64 eq 1000 | 2.5181 ms/op | 2.2805 ms/op | 1.10 |
| forkChoice updateHead vc 600000 bc 64 eq 10000 | 2.5996 ms/op | 2.3460 ms/op | 1.11 |
| forkChoice updateHead vc 600000 bc 64 eq 300000 | 6.8687 ms/op | 5.9797 ms/op | 1.15 |
| computeDeltas 1400000 validators 0% inactive | 12.324 ms/op | 11.305 ms/op | 1.09 |
| computeDeltas 1400000 validators 10% inactive | 11.716 ms/op | 10.720 ms/op | 1.09 |
| computeDeltas 1400000 validators 20% inactive | 11.083 ms/op | 10.208 ms/op | 1.09 |
| computeDeltas 1400000 validators 50% inactive | 9.0699 ms/op | 8.3424 ms/op | 1.09 |
| computeDeltas 2100000 validators 0% inactive | 18.553 ms/op | 17.445 ms/op | 1.06 |
| computeDeltas 2100000 validators 10% inactive | 17.659 ms/op | 16.406 ms/op | 1.08 |
| computeDeltas 2100000 validators 20% inactive | 16.398 ms/op | 15.437 ms/op | 1.06 |
| computeDeltas 2100000 validators 50% inactive | 10.828 ms/op | 10.301 ms/op | 1.05 |
| altair processAttestation - 250000 vs - 7PWei normalcase | 2.9153 ms/op | 2.4927 ms/op | 1.17 |
| altair processAttestation - 250000 vs - 7PWei worstcase | 3.5893 ms/op | 3.3092 ms/op | 1.08 |
| altair processAttestation - setStatus - 1/6 committees join | 113.08 us/op | 100.44 us/op | 1.13 |
| altair processAttestation - setStatus - 1/3 committees join | 218.52 us/op | 184.64 us/op | 1.18 |
| altair processAttestation - setStatus - 1/2 committees join | 306.25 us/op | 265.52 us/op | 1.15 |
| altair processAttestation - setStatus - 2/3 committees join | 386.12 us/op | 354.54 us/op | 1.09 |
| altair processAttestation - setStatus - 4/5 committees join | 532.92 us/op | 489.02 us/op | 1.09 |
| altair processAttestation - setStatus - 100% committees join | 631.71 us/op | 574.50 us/op | 1.10 |
| altair processBlock - 250000 vs - 7PWei normalcase | 3.9885 ms/op | 4.5303 ms/op | 0.88 |
| altair processBlock - 250000 vs - 7PWei normalcase hashState | 16.768 ms/op | 16.339 ms/op | 1.03 |
| altair processBlock - 250000 vs - 7PWei worstcase | 21.433 ms/op | 20.812 ms/op | 1.03 |
| altair processBlock - 250000 vs - 7PWei worstcase hashState | 42.020 ms/op | 37.257 ms/op | 1.13 |
| phase0 processBlock - 250000 vs - 7PWei normalcase | 1.8455 ms/op | 1.4210 ms/op | 1.30 |
| phase0 processBlock - 250000 vs - 7PWei worstcase | 18.213 ms/op | 17.760 ms/op | 1.03 |
| altair processEth1Data - 250000 vs - 7PWei normalcase | 333.02 us/op | 266.43 us/op | 1.25 |
| getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 | 14.373 us/op | 3.1030 us/op | 4.63 |
| getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 | 20.921 us/op | 19.752 us/op | 1.06 |
| getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 | 6.6990 us/op | 5.2670 us/op | 1.27 |
| getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 | 3.8210 us/op | 4.1240 us/op | 0.93 |
| getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 | 94.277 us/op | 85.352 us/op | 1.10 |
| getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 | 1.5795 ms/op | 1.2693 ms/op | 1.24 |
| getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 | 1.9298 ms/op | 1.6577 ms/op | 1.16 |
| getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 | 1.9112 ms/op | 1.6578 ms/op | 1.15 |
| getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 | 3.5922 ms/op | 3.3169 ms/op | 1.08 |
| getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 | 2.2125 ms/op | 1.9006 ms/op | 1.16 |
| getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 | 3.9321 ms/op | 3.7226 ms/op | 1.06 |
| Tree 40 250000 create | 376.40 ms/op | 300.28 ms/op | 1.25 |
| Tree 40 250000 get(125000) | 96.581 ns/op | 86.686 ns/op | 1.11 |
| Tree 40 250000 set(125000) | 968.72 ns/op | 927.35 ns/op | 1.04 |
| Tree 40 250000 toArray() | 15.831 ms/op | 11.951 ms/op | 1.32 |
| Tree 40 250000 iterate all - toArray() + loop | 16.031 ms/op | 11.022 ms/op | 1.45 |
| Tree 40 250000 iterate all - get(i) | 38.082 ms/op | 32.338 ms/op | 1.18 |
| Array 250000 create | 2.4364 ms/op | 2.0486 ms/op | 1.19 |
| Array 250000 clone - spread | 745.81 us/op | 640.81 us/op | 1.16 |
| Array 250000 get(125000) | 0.28500 ns/op | 0.27600 ns/op | 1.03 |
| Array 250000 set(125000) | 0.28700 ns/op | 0.27700 ns/op | 1.04 |
| Array 250000 iterate all - loop | 55.148 us/op | 53.986 us/op | 1.02 |
| phase0 afterProcessEpoch - 250000 vs - 7PWei | 53.163 ms/op | 37.641 ms/op | 1.41 |
| Array.fill - length 1000000 | 2.6330 ms/op | 2.0124 ms/op | 1.31 |
| Array push - length 1000000 | 9.7912 ms/op | 8.2604 ms/op | 1.19 |
| Array.get | 0.20353 ns/op | 0.19253 ns/op | 1.06 |
| Uint8Array.get | 0.23348 ns/op | 0.22586 ns/op | 1.03 |
| phase0 beforeProcessEpoch - 250000 vs - 7PWei | 15.903 ms/op | 13.599 ms/op | 1.17 |
| altair processEpoch - mainnet_e81889 | 321.92 ms/op | 275.07 ms/op | 1.17 |
| mainnet_e81889 - altair beforeProcessEpoch | 22.466 ms/op | 15.758 ms/op | 1.43 |
| mainnet_e81889 - altair processJustificationAndFinalization | 8.0280 us/op | 6.4910 us/op | 1.24 |
| mainnet_e81889 - altair processInactivityUpdates | 4.6482 ms/op | 3.7004 ms/op | 1.26 |
| mainnet_e81889 - altair processRewardsAndPenalties | 18.211 ms/op | 19.429 ms/op | 0.94 |
| mainnet_e81889 - altair processRegistryUpdates | 562.00 ns/op | 528.00 ns/op | 1.06 |
| mainnet_e81889 - altair processSlashings | 133.00 ns/op | 133.00 ns/op | 1.00 |
| mainnet_e81889 - altair processEth1DataReset | 127.00 ns/op | 131.00 ns/op | 0.97 |
| mainnet_e81889 - altair processEffectiveBalanceUpdates | 3.7771 ms/op | 2.7860 ms/op | 1.36 |
| mainnet_e81889 - altair processSlashingsReset | 677.00 ns/op | 688.00 ns/op | 0.98 |
| mainnet_e81889 - altair processRandaoMixesReset | 1.3440 us/op | 1.1290 us/op | 1.19 |
| mainnet_e81889 - altair processHistoricalRootsUpdate | 134.00 ns/op | 127.00 ns/op | 1.06 |
| mainnet_e81889 - altair processParticipationFlagUpdates | 435.00 ns/op | 413.00 ns/op | 1.05 |
| mainnet_e81889 - altair processSyncCommitteeUpdates | 106.00 ns/op | 111.00 ns/op | 0.95 |
| mainnet_e81889 - altair afterProcessEpoch | 39.714 ms/op | 39.589 ms/op | 1.00 |
| capella processEpoch - mainnet_e217614 | 976.13 ms/op | 770.25 ms/op | 1.27 |
| mainnet_e217614 - capella beforeProcessEpoch | 64.191 ms/op | 54.020 ms/op | 1.19 |
| mainnet_e217614 - capella processJustificationAndFinalization | 7.8940 us/op | 5.7900 us/op | 1.36 |
| mainnet_e217614 - capella processInactivityUpdates | 15.102 ms/op | 13.821 ms/op | 1.09 |
| mainnet_e217614 - capella processRewardsAndPenalties | 98.239 ms/op | 84.358 ms/op | 1.16 |
| mainnet_e217614 - capella processRegistryUpdates | 4.7460 us/op | 4.2820 us/op | 1.11 |
| mainnet_e217614 - capella processSlashings | 132.00 ns/op | 127.00 ns/op | 1.04 |
| mainnet_e217614 - capella processEth1DataReset | 126.00 ns/op | 120.00 ns/op | 1.05 |
| mainnet_e217614 - capella processEffectiveBalanceUpdates | 6.2416 ms/op | 12.144 ms/op | 0.51 |
| mainnet_e217614 - capella processSlashingsReset | 694.00 ns/op | 655.00 ns/op | 1.06 |
| mainnet_e217614 - capella processRandaoMixesReset | 1.3300 us/op | 1.0880 us/op | 1.22 |
| mainnet_e217614 - capella processHistoricalRootsUpdate | 131.00 ns/op | 128.00 ns/op | 1.02 |
| mainnet_e217614 - capella processParticipationFlagUpdates | 437.00 ns/op | 410.00 ns/op | 1.07 |
| mainnet_e217614 - capella afterProcessEpoch | 110.07 ms/op | 101.83 ms/op | 1.08 |
| phase0 processEpoch - mainnet_e58758 | 410.75 ms/op | 289.79 ms/op | 1.42 |
| mainnet_e58758 - phase0 beforeProcessEpoch | 86.714 ms/op | 60.424 ms/op | 1.44 |
| mainnet_e58758 - phase0 processJustificationAndFinalization | 8.7730 us/op | 5.9900 us/op | 1.46 |
| mainnet_e58758 - phase0 processRewardsAndPenalties | 17.489 ms/op | 15.466 ms/op | 1.13 |
| mainnet_e58758 - phase0 processRegistryUpdates | 2.3070 us/op | 2.1340 us/op | 1.08 |
| mainnet_e58758 - phase0 processSlashings | 143.00 ns/op | 204.00 ns/op | 0.70 |
| mainnet_e58758 - phase0 processEth1DataReset | 126.00 ns/op | 127.00 ns/op | 0.99 |
| mainnet_e58758 - phase0 processEffectiveBalanceUpdates | 834.38 us/op | 971.26 us/op | 0.86 |
| mainnet_e58758 - phase0 processSlashingsReset | 972.00 ns/op | 842.00 ns/op | 1.15 |
| mainnet_e58758 - phase0 processRandaoMixesReset | 1.5480 us/op | 1.1940 us/op | 1.30 |
| mainnet_e58758 - phase0 processHistoricalRootsUpdate | 132.00 ns/op | 135.00 ns/op | 0.98 |
| mainnet_e58758 - phase0 processParticipationRecordUpdates | 1.3690 us/op | 1.0700 us/op | 1.28 |
| mainnet_e58758 - phase0 afterProcessEpoch | 34.689 ms/op | 31.745 ms/op | 1.09 |
| phase0 processEffectiveBalanceUpdates - 250000 normalcase | 1.4443 ms/op | 937.20 us/op | 1.54 |
| phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 | 1.6913 ms/op | 1.5004 ms/op | 1.13 |
| altair processInactivityUpdates - 250000 normalcase | 12.148 ms/op | 9.8960 ms/op | 1.23 |
| altair processInactivityUpdates - 250000 worstcase | 13.379 ms/op | 9.9768 ms/op | 1.34 |
| phase0 processRegistryUpdates - 250000 normalcase | 4.4200 us/op | 3.3400 us/op | 1.32 |
| phase0 processRegistryUpdates - 250000 badcase_full_deposits | 156.75 us/op | 132.48 us/op | 1.18 |
| phase0 processRegistryUpdates - 250000 worstcase 0.5 | 69.283 ms/op | 56.755 ms/op | 1.22 |
| altair processRewardsAndPenalties - 250000 normalcase | 15.923 ms/op | 15.593 ms/op | 1.02 |
| altair processRewardsAndPenalties - 250000 worstcase | 16.528 ms/op | 15.034 ms/op | 1.10 |
| phase0 getAttestationDeltas - 250000 normalcase | 5.7820 ms/op | 5.1632 ms/op | 1.12 |
| phase0 getAttestationDeltas - 250000 worstcase | 9.5713 ms/op | 5.1901 ms/op | 1.84 |
| phase0 processSlashings - 250000 worstcase | 70.056 us/op | 57.130 us/op | 1.23 |
| altair processSyncCommitteeUpdates - 250000 | 11.331 ms/op | 9.8189 ms/op | 1.15 |
| BeaconState.hashTreeRoot - No change | 176.00 ns/op | 166.00 ns/op | 1.06 |
| BeaconState.hashTreeRoot - 1 full validator | 105.66 us/op | 73.275 us/op | 1.44 |
| BeaconState.hashTreeRoot - 32 full validator | 1.1314 ms/op | 838.88 us/op | 1.35 |
| BeaconState.hashTreeRoot - 512 full validator | 12.168 ms/op | 7.9905 ms/op | 1.52 |
| BeaconState.hashTreeRoot - 1 validator.effectiveBalance | 186.76 us/op | 95.453 us/op | 1.96 |
| BeaconState.hashTreeRoot - 32 validator.effectiveBalance | 2.5525 ms/op | 1.3661 ms/op | 1.87 |
| BeaconState.hashTreeRoot - 512 validator.effectiveBalance | 31.015 ms/op | 16.504 ms/op | 1.88 |
| BeaconState.hashTreeRoot - 1 balances | 91.343 us/op | 68.164 us/op | 1.34 |
| BeaconState.hashTreeRoot - 32 balances | 803.00 us/op | 709.34 us/op | 1.13 |
| BeaconState.hashTreeRoot - 512 balances | 6.7248 ms/op | 5.8114 ms/op | 1.16 |
| BeaconState.hashTreeRoot - 250000 balances | 238.62 ms/op | 137.03 ms/op | 1.74 |
| aggregationBits - 2048 els - zipIndexesInBitList | 22.168 us/op | 18.583 us/op | 1.19 |
| regular array get 100000 times | 23.343 us/op | 21.819 us/op | 1.07 |
| wrappedArray get 100000 times | 23.356 us/op | 21.750 us/op | 1.07 |
| arrayWithProxy get 100000 times | 10.082 ms/op | 10.424 ms/op | 0.97 |
| ssz.Root.equals | 21.611 ns/op | 20.356 ns/op | 1.06 |
| byteArrayEquals | 21.364 ns/op | 20.481 ns/op | 1.04 |
| Buffer.compare | 8.8910 ns/op | 8.3320 ns/op | 1.07 |
| processSlot - 1 slots | 10.395 us/op | 9.5810 us/op | 1.08 |
| processSlot - 32 slots | 3.3326 ms/op | 2.0460 ms/op | 1.63 |
| getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei | 7.1867 ms/op | 3.4416 ms/op | 2.09 |
| getCommitteeAssignments - req 1 vs - 250000 vc | 1.7409 ms/op | 1.6064 ms/op | 1.08 |
| getCommitteeAssignments - req 100 vs - 250000 vc | 3.5453 ms/op | 3.2923 ms/op | 1.08 |
| getCommitteeAssignments - req 1000 vs - 250000 vc | 3.8440 ms/op | 3.5133 ms/op | 1.09 |
| findModifiedValidators - 10000 modified validators | 880.87 ms/op | 728.90 ms/op | 1.21 |
| findModifiedValidators - 1000 modified validators | 570.87 ms/op | 536.49 ms/op | 1.06 |
| findModifiedValidators - 100 modified validators | 438.79 ms/op | 289.60 ms/op | 1.52 |
| findModifiedValidators - 10 modified validators | 313.49 ms/op | 158.47 ms/op | 1.98 |
| findModifiedValidators - 1 modified validators | 276.91 ms/op | 184.58 ms/op | 1.50 |
| findModifiedValidators - no difference | 168.93 ms/op | 156.69 ms/op | 1.08 |
| migrate state 1500000 validators, 3400 modified, 2000 new | 3.8418 s/op | 2.7869 s/op | 1.38 |
| RootCache.getBlockRootAtSlot - 250000 vs - 7PWei | 3.8700 ns/op | 3.4800 ns/op | 1.11 |
| state getBlockRootAtSlot - 250000 vs - 7PWei | 522.96 ns/op | 314.15 ns/op | 1.66 |
| computeProposerIndex 100000 validators | 1.5182 ms/op | 1.2777 ms/op | 1.19 |
| getNextSyncCommitteeIndices 1000 validators | 3.0249 ms/op | 2.7292 ms/op | 1.11 |
| getNextSyncCommitteeIndices 10000 validators | 26.386 ms/op | 23.883 ms/op | 1.10 |
| getNextSyncCommitteeIndices 100000 validators | 99.101 ms/op | 84.161 ms/op | 1.18 |
| computeProposers - vc 250000 | 586.79 us/op | 530.53 us/op | 1.11 |
| computeEpochShuffling - vc 250000 | 41.141 ms/op | 38.926 ms/op | 1.06 |
| getNextSyncCommittee - vc 250000 | 11.051 ms/op | 9.0377 ms/op | 1.22 |
| nodejs block root to RootHex using toHex | 106.49 ns/op | 89.074 ns/op | 1.20 |
| nodejs block root to RootHex using toRootHex | 63.906 ns/op | 58.464 ns/op | 1.09 |
| nodejs fromHex(blob) | 1.0173 ms/op | 714.55 us/op | 1.42 |
| nodejs fromHexInto(blob) | 639.79 us/op | 611.94 us/op | 1.05 |
| nodejs block root to RootHex using the deprecated toHexString | 375.55 ns/op | 349.79 ns/op | 1.07 |
| nodejs byteArrayEquals 32 bytes (block root) | 25.763 ns/op | 25.376 ns/op | 1.02 |
| nodejs byteArrayEquals 48 bytes (pubkey) | 37.223 ns/op | 36.569 ns/op | 1.02 |
| nodejs byteArrayEquals 96 bytes (signature) | 33.264 ns/op | 33.211 ns/op | 1.00 |
| nodejs byteArrayEquals 1024 bytes | 40.592 ns/op | 39.770 ns/op | 1.02 |
| nodejs byteArrayEquals 131072 bytes (blob) | 1.7307 us/op | 1.7087 us/op | 1.01 |
| browser block root to RootHex using toHex | 141.78 ns/op | 137.91 ns/op | 1.03 |
| browser block root to RootHex using toRootHex | 128.33 ns/op | 125.00 ns/op | 1.03 |
| browser fromHex(blob) | 1.9029 ms/op | 1.5074 ms/op | 1.26 |
| browser fromHexInto(blob) | 664.98 us/op | 606.18 us/op | 1.10 |
| browser block root to RootHex using the deprecated toHexString | 519.71 ns/op | 451.56 ns/op | 1.15 |
| browser byteArrayEquals 32 bytes (block root) | 28.860 ns/op | 27.012 ns/op | 1.07 |
| browser byteArrayEquals 48 bytes (pubkey) | 40.338 ns/op | 38.410 ns/op | 1.05 |
| browser byteArrayEquals 96 bytes (signature) | 77.369 ns/op | 71.484 ns/op | 1.08 |
| browser byteArrayEquals 1024 bytes | 783.09 ns/op | 731.05 ns/op | 1.07 |
| browser byteArrayEquals 131072 bytes (blob) | 97.111 us/op | 92.472 us/op | 1.05 |
by benchmarkbot/action
|
closed in favour of #9687 |
Depends on #9390.
Motivation
Implements the gloas light client spec
Supports:
Description
signedExecutionPayloadBid.message.parentBlockHash.getBlockBodyExecutionBlockHashProof)getLcExecutionRootfor comparing execution data across pre-Gloas and Gloas header representations. Note that we used to do this in-line before but here we introducegetLcExecutionRootso that we can reuse in sync tests too + there's some added complexity to it.For tests,
AI Assistance Disclosure
Planning, implementation and testing done with gpt-sol-5.6 medium