Skip to content

(wip) feat: gloas light client support - #9683

Closed
spiral-ladder wants to merge 19 commits into
unstablefrom
bing/gloas-light-client-header
Closed

(wip) feat: gloas light client support#9683
spiral-ladder wants to merge 19 commits into
unstablefrom
bing/gloas-light-client-header

Conversation

@spiral-ladder

Copy link
Copy Markdown
Member

Depends on #9390.

Motivation

Implements the gloas light client spec

Supports:

  • new light client header format
  • cross-fork sync

Description

  • Support new light client header format - Construct Gloas light client headers from signedExecutionPayloadBid.message.parentBlockHash.
  • Generate the execution block hash proof using the current Gloas generalized index (see getBlockBodyExecutionBlockHashProof)
  • Add getLcExecutionRoot for comparing execution data across pre-Gloas and Gloas header representations. Note that we used to do this in-line before but here we introduce getLcExecutionRoot so that we can reuse in sync tests too + there's some added complexity to it.
  • Support upgrading light client bootstraps, updates, and stores across fork boundaries

For tests,

  • Unskip and update light client related tests
  • Validate the execution root in addition to beacon header roots and slots

AI Assistance Disclosure

Planning, implementation and testing done with gpt-sol-5.6 medium

wemeetagain and others added 18 commits May 20, 2026 12:21
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>
@spiral-ladder
spiral-ladder changed the base branch from unstable to eip-7688 July 20, 2026 18:40

@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 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)

high

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)

high

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)

medium

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;
}

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

⚠️ 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: 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

Base automatically changed from eip-7688 to unstable July 21, 2026 05:08
@spiral-ladder

Copy link
Copy Markdown
Member Author

closed in favour of #9687

@spiral-ladder
spiral-ladder deleted the bing/gloas-light-client-header branch July 21, 2026 13:33
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.

4 participants