Skip to content

feat: update to spec v1.7.0-alpha.2 [wip]#8881

Draft
nflaig wants to merge 1 commit intounstablefrom
nflaig/spec-alpha2
Draft

feat: update to spec v1.7.0-alpha.2 [wip]#8881
nflaig wants to merge 1 commit intounstablefrom
nflaig/spec-alpha2

Conversation

@nflaig
Copy link
Member

@nflaig nflaig commented Feb 8, 2026

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @nflaig, 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 brings the codebase up-to-date with the v1.7.0-alpha.2 version of the Ethereum consensus specifications, primarily focusing on the gloas fork. The changes streamline the handling of KZG commitments within execution payloads, enhance the accuracy and efficiency of builder deposit processing, and optimize the calculation of the Payload Timeliness Committee. Additionally, it includes critical adjustments to withdrawal sweep mechanisms and updates to key configuration parameters, ensuring the client's adherence to the latest protocol definitions.

Highlights

  • Spec Version Update: The project has been updated to align with Ethereum consensus specs v1.7.0-alpha.2.
  • Blob KZG Commitments Refactor: The handling of blobKzgCommitments has been refactored, moving them from the ExecutionPayloadEnvelope to the ExecutionPayloadBid. This changes where commitment limits are enforced and how sidecars are generated.
  • Builder Deposit Processing Enhancements: Builder deposit logic has been improved to correctly onboard pending builders during the gloas fork upgrade and to use the deposit slot for epoch calculation.
  • Payload Timeliness Committee (PTC) Optimization: The computation of the Payload Timeliness Committee (PTC) has been optimized for lazy, per-slot calculation, reducing eager computation overhead.
  • Withdrawal Sweep Logic Refinement: The logic for processing withdrawals (builder, pending partial, and validator sweeps) has been updated to use a >= comparison for withdrawal limits, ensuring correct behavior when the limit is met or exceeded.
  • Configuration Updates: The MIN_BUILDER_WITHDRAWABILITY_DELAY constant has been significantly reduced in both mainnet and minimal configurations, reflecting updated spec values.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • packages/beacon-node/test/spec/specTestVersioning.ts
    • Updated specVersion to v1.7.0-alpha.2.
  • packages/beacon-node/test/spec/utils/specTestIterator.ts
    • Modified gloas test skipping logic to only skip finality and fork_choice tests, while running sanity and transition tests.
  • packages/beacon-node/test/unit/util/kzg.test.ts
    • Added type casting for DataColumnSidecars.
    • Increased test timeout for a KZG test to 60 seconds.
  • packages/config/src/chainConfig/configs/mainnet.ts
    • Decreased MIN_BUILDER_WITHDRAWABILITY_DELAY from 4096 to 64.
  • packages/config/src/chainConfig/configs/minimal.ts
    • Decreased MIN_BUILDER_WITHDRAWABILITY_DELAY from 8 to 2.
  • packages/state-transition/src/block/processDepositRequest.ts
    • Modified applyDepositForBuilder and addBuilderToRegistry to accept and use slot for deposit epoch calculation.
    • Updated calls to applyDepositForBuilder in processDepositRequest to pass the current state slot.
  • packages/state-transition/src/block/processExecutionPayloadBid.ts
    • Added blobKzgCommitments limit verification, moved from processExecutionPayloadEnvelope.
  • packages/state-transition/src/block/processExecutionPayloadEnvelope.ts
    • Removed blobKzgCommitments related verification, as it was moved to processExecutionPayloadBid.
  • packages/state-transition/src/block/processWithdrawals.ts
    • Changed withdrawal limit check from == to >= in getValidatorsSweepWithdrawals to prevent potential overflows.
  • packages/state-transition/src/cache/epochCache.ts
    • Refactored Payload Timeliness Committee (PTC) caching to be lazy and per-slot, storing only the seed.
    • Updated getPayloadTimelinessCommittee method to compute the committee on demand if not cached.
  • packages/state-transition/src/signatureSets/indexedPayloadAttestation.ts
    • Updated getPayloadAttestationDataSigningRoot to use attestation.data.slot for domain epoch calculation, aligning with spec changes.
  • packages/state-transition/src/slot/upgradeStateToGloas.ts
    • Implemented onboardBuildersFromPendingDeposits to process pending deposits for builders during the gloas state upgrade.
  • packages/state-transition/src/util/gloas.ts
    • Updated builder index utility functions (isBuilderIndex, convertBuilderIndexToValidatorIndex, convertValidatorIndexToBuilderIndex) to use arithmetic operations instead of bitwise operations for BUILDER_INDEX_FLAG due to its size.
  • packages/state-transition/src/util/seed.ts
    • Replaced eager PTC computation with lazy computePayloadTimelinessCommitteeForSlot.
    • Optimized internal hash computation within naiveComputePayloadTimelinessCommitteeIndices by pre-allocating a buffer and recomputing the hash less frequently.
  • packages/types/src/gloas/sszTypes.ts
    • Updated SSZ types for ExecutionPayloadBid to include blobKzgCommitments directly instead of blobKzgCommitmentsRoot.
    • Removed blobKzgCommitments from ExecutionPayloadEnvelope SSZ type.
    • Removed kzgCommitments field from DataColumnSidecar SSZ type.
  • specrefs/.ethspecify.yml
    • Updated spec version from v1.7.0-alpha.1 to v1.7.0-alpha.2.
    • Removed multi_exp#deneb and get_builder_from_deposit#gloas from exceptions.
  • specrefs/configs.yml
    • Updated MIN_BUILDER_WITHDRAWABILITY_DELAY spec value from 4096 to 64 and updated its hash.
  • specrefs/containers.yml
    • Updated spec definitions and hashes for DataColumnSidecar, ExecutionPayloadBid, and ExecutionPayloadEnvelope to reflect changes in SSZ types.
  • specrefs/functions.yml
    • Updated spec definitions and hashes for various functions including add_builder_to_registry#gloas, apply_deposit_for_builder#gloas, compute_domain#phase0, get_builder_withdrawals#gloas, get_builders_sweep_withdrawals#gloas, get_pending_partial_withdrawals#electra, get_validators_sweep_withdrawals#capella, get_validators_sweep_withdrawals#electra, get_data_column_sidecars#gloas, get_data_column_sidecars_from_block#gloas, get_data_column_sidecars_from_column_sidecar#gloas, get_domain#phase0, get_ptc_assignment#gloas, is_valid_indexed_payload_attestation#gloas, prepare_execution_payload#capella, prepare_execution_payload#gloas, process_deposit_request#gloas, process_execution_payload#gloas, process_execution_payload_bid#gloas, slash_validator (all forks), upgrade_to_gloas#gloas, and verify_data_column_sidecar#gloas to reflect parameter changes, logic adjustments, and type hints.
    • Removed get_builder_from_deposit#gloas spec.
    • Added new specs for is_data_available#gloas and onboard_builders_from_pending_deposits#gloas.
    • Added new spec for verify_data_column_sidecar_kzg_proofs#gloas.
Activity
  • The pull request was created by nflaig.
  • The title indicates a feature update to spec v1.7.0-alpha.2 and is marked as [wip].
  • No explicit reviewer comments or approvals 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.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request updates the codebase to align with the v1.7.0-alpha.2 consensus spec. The changes are extensive, touching configuration, state transition logic, caching, and type definitions. The refactoring of the Payload Timeliness Committee (PTC) handling to a lazy computation model is a notable performance improvement.

I've reviewed the changes and found a couple of potential issues. One is related to an incorrect optimization in the onboardBuildersFromPendingDeposits function that could lead to incorrect state during the Gloas fork upgrade. Another is a potential integer overflow bug in an optimized hashing function in seed.ts that could affect consensus in edge cases. My detailed comments are below.

Comment on lines +87 to +91
// Pre-compute builder pubkeys set for O(1) lookup instead of O(n) per deposit
const builderPubkeys = new Set<string>();
for (let i = 0; i < state.builders.length; i++) {
builderPubkeys.add(toHex(state.builders.getReadonly(i).pubkey));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The pre-computation of builderPubkeys is an optimization that doesn't align with the spec and could lead to incorrect behavior. The spec for onboard_builders_from_pending_deposits states that the list of builder pubkeys should be recomputed in each iteration of the loop over pending deposits. This is because applyDepositForBuilder can mutate state.builders by reusing a slot for an exited builder, which would replace an old builder (and its pubkey) with a new one. Your current implementation only adds new pubkeys to the Set but doesn't handle the removal of old pubkeys when a slot is reused. This can lead to isExistingBuilder being incorrectly true for a pubkey that should no longer be considered a builder.

To fix this, you should re-create the builderPubkeys set inside the loop over state.pendingDeposits to ensure it's always in sync with state.builders.

Example:

function onboardBuildersFromPendingDeposits(state: CachedBeaconStateGloas): void {
  const trackedValidatorPubkeys = new Set<string>();

  const remainingPendingDeposits = state.pendingDeposits.sliceFrom(state.pendingDeposits.length);
  for (let i = 0; i < state.pendingDeposits.length; i++) {
    // Re-compute builder pubkeys set inside the loop
    const builderPubkeys = new Set<string>();
    for (let j = 0; j < state.builders.length; j++) {
      builderPubkeys.add(toHex(state.builders.getReadonly(j).pubkey));
    }

    const deposit = state.pendingDeposits.getReadonly(i);
    // ... rest of the logic
  }

  state.pendingDeposits = remainingPendingDeposits;
}

Comment on lines +322 to +324
hashInput.writeUInt32LE(block, seed.length);
// Zero the upper 4 bytes for correct 8-byte little-endian encoding
hashInput.writeUInt32LE(0, seed.length + 4);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This optimization to write a 64-bit little-endian integer using writeUInt32LE is unsafe and can lead to incorrect behavior. The block variable, calculated as Math.floor(i / 16), can grow larger than 2**32 - 1 if the while loop runs for many iterations (e.g., in scenarios with very low effective balances). writeUInt32LE will truncate values larger than 32 bits, leading to an incorrect hash input and a potential consensus split.

You should use a method that safely handles 64-bit integers, such as Buffer.writeBigUInt64LE() or by using a DataView.

Suggested change
hashInput.writeUInt32LE(block, seed.length);
// Zero the upper 4 bytes for correct 8-byte little-endian encoding
hashInput.writeUInt32LE(0, seed.length + 4);
hashInput.writeBigUInt64LE(BigInt(block), seed.length);

@nflaig
Copy link
Member Author

nflaig commented Feb 8, 2026

@codex review

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 0d57069 Previous: 45b0426 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1201 ms/op 888.72 us/op 1.26
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 42.763 us/op 34.559 us/op 1.24
BLS verify - blst 877.50 us/op 862.37 us/op 1.02
BLS verifyMultipleSignatures 3 - blst 1.3263 ms/op 1.2847 ms/op 1.03
BLS verifyMultipleSignatures 8 - blst 2.2240 ms/op 2.1370 ms/op 1.04
BLS verifyMultipleSignatures 32 - blst 6.8008 ms/op 4.5584 ms/op 1.49
BLS verifyMultipleSignatures 64 - blst 11.113 ms/op 8.6243 ms/op 1.29
BLS verifyMultipleSignatures 128 - blst 16.992 ms/op 16.488 ms/op 1.03
BLS deserializing 10000 signatures 668.57 ms/op 640.21 ms/op 1.04
BLS deserializing 100000 signatures 6.6679 s/op 6.1574 s/op 1.08
BLS verifyMultipleSignatures - same message - 3 - blst 1.1991 ms/op 932.23 us/op 1.29
BLS verifyMultipleSignatures - same message - 8 - blst 1.4345 ms/op 1.0582 ms/op 1.36
BLS verifyMultipleSignatures - same message - 32 - blst 1.9598 ms/op 1.6434 ms/op 1.19
BLS verifyMultipleSignatures - same message - 64 - blst 2.6392 ms/op 2.4603 ms/op 1.07
BLS verifyMultipleSignatures - same message - 128 - blst 4.3331 ms/op 4.0066 ms/op 1.08
BLS aggregatePubkeys 32 - blst 18.671 us/op 17.041 us/op 1.10
BLS aggregatePubkeys 128 - blst 68.132 us/op 60.115 us/op 1.13
getSlashingsAndExits - default max 69.436 us/op 42.188 us/op 1.65
getSlashingsAndExits - 2k 300.94 us/op 331.49 us/op 0.91
isKnown best case - 1 super set check 194.00 ns/op 399.00 ns/op 0.49
isKnown normal case - 2 super set checks 192.00 ns/op 403.00 ns/op 0.48
isKnown worse case - 16 super set checks 190.00 ns/op 406.00 ns/op 0.47
validate api signedAggregateAndProof - struct 1.7346 ms/op 1.9981 ms/op 0.87
validate gossip signedAggregateAndProof - struct 1.7430 ms/op 1.9152 ms/op 0.91
batch validate gossip attestation - vc 640000 - chunk 32 113.10 us/op 110.14 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 64 99.646 us/op 109.76 us/op 0.91
batch validate gossip attestation - vc 640000 - chunk 128 92.103 us/op 86.393 us/op 1.07
batch validate gossip attestation - vc 640000 - chunk 256 88.965 us/op 82.160 us/op 1.08
bytes32 toHexString 378.00 ns/op 513.00 ns/op 0.74
bytes32 Buffer.toString(hex) 296.00 ns/op 410.00 ns/op 0.72
bytes32 Buffer.toString(hex) from Uint8Array 386.00 ns/op 498.00 ns/op 0.78
bytes32 Buffer.toString(hex) + 0x 320.00 ns/op 413.00 ns/op 0.77
Return object 10000 times 0.23570 ns/op 0.23030 ns/op 1.02
Throw Error 10000 times 3.9944 us/op 3.3913 us/op 1.18
toHex 127.03 ns/op 91.026 ns/op 1.40
Buffer.from 117.94 ns/op 85.905 ns/op 1.37
shared Buffer 75.824 ns/op 57.925 ns/op 1.31
fastMsgIdFn sha256 / 200 bytes 1.7730 us/op 1.6250 us/op 1.09
fastMsgIdFn h32 xxhash / 200 bytes 184.00 ns/op 369.00 ns/op 0.50
fastMsgIdFn h64 xxhash / 200 bytes 242.00 ns/op 453.00 ns/op 0.53
fastMsgIdFn sha256 / 1000 bytes 5.7390 us/op 5.0480 us/op 1.14
fastMsgIdFn h32 xxhash / 1000 bytes 282.00 ns/op 463.00 ns/op 0.61
fastMsgIdFn h64 xxhash / 1000 bytes 295.00 ns/op 524.00 ns/op 0.56
fastMsgIdFn sha256 / 10000 bytes 52.001 us/op 39.975 us/op 1.30
fastMsgIdFn h32 xxhash / 10000 bytes 1.3520 us/op 1.4600 us/op 0.93
fastMsgIdFn h64 xxhash / 10000 bytes 863.00 ns/op 1.1050 us/op 0.78
send data - 1000 256B messages 14.485 ms/op 11.360 ms/op 1.28
send data - 1000 512B messages 15.922 ms/op 14.157 ms/op 1.12
send data - 1000 1024B messages 21.238 ms/op 16.975 ms/op 1.25
send data - 1000 1200B messages 22.623 ms/op 14.723 ms/op 1.54
send data - 1000 2048B messages 23.974 ms/op 16.212 ms/op 1.48
send data - 1000 4096B messages 23.625 ms/op 15.522 ms/op 1.52
send data - 1000 16384B messages 102.15 ms/op 103.41 ms/op 0.99
send data - 1000 65536B messages 250.68 ms/op 208.57 ms/op 1.20
enrSubnets - fastDeserialize 64 bits 859.00 ns/op 968.00 ns/op 0.89
enrSubnets - ssz BitVector 64 bits 311.00 ns/op 525.00 ns/op 0.59
enrSubnets - fastDeserialize 4 bits 163.00 ns/op 331.00 ns/op 0.49
enrSubnets - ssz BitVector 4 bits 323.00 ns/op 512.00 ns/op 0.63
prioritizePeers score -10:0 att 32-0.1 sync 2-0 301.19 us/op 253.27 us/op 1.19
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 253.89 us/op 288.97 us/op 0.88
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 488.44 us/op 341.18 us/op 1.43
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 819.85 us/op 604.66 us/op 1.36
prioritizePeers score 0:0 att 64-1 sync 4-1 1.1021 ms/op 1.0145 ms/op 1.09
array of 16000 items push then shift 1.5496 us/op 1.1757 us/op 1.32
LinkedList of 16000 items push then shift 7.1510 ns/op 7.3690 ns/op 0.97
array of 16000 items push then pop 71.852 ns/op 62.529 ns/op 1.15
LinkedList of 16000 items push then pop 6.8070 ns/op 6.0270 ns/op 1.13
array of 24000 items push then shift 2.2996 us/op 1.7619 us/op 1.31
LinkedList of 24000 items push then shift 7.2090 ns/op 7.0310 ns/op 1.03
array of 24000 items push then pop 101.33 ns/op 88.270 ns/op 1.15
LinkedList of 24000 items push then pop 6.8400 ns/op 6.0430 ns/op 1.13
intersect bitArray bitLen 8 5.5000 ns/op 4.6380 ns/op 1.19
intersect array and set length 8 32.315 ns/op 28.145 ns/op 1.15
intersect bitArray bitLen 128 27.542 ns/op 25.046 ns/op 1.10
intersect array and set length 128 530.33 ns/op 469.30 ns/op 1.13
bitArray.getTrueBitIndexes() bitLen 128 1000.0 ns/op 1.1470 us/op 0.87
bitArray.getTrueBitIndexes() bitLen 248 2.3940 us/op 1.9490 us/op 1.23
bitArray.getTrueBitIndexes() bitLen 512 3.9780 us/op 3.7820 us/op 1.05
Full columns - reconstruct all 6 blobs 251.38 us/op 305.72 us/op 0.82
Full columns - reconstruct half of the blobs out of 6 101.77 us/op 93.762 us/op 1.09
Full columns - reconstruct single blob out of 6 33.022 us/op 30.040 us/op 1.10
Half columns - reconstruct all 6 blobs 300.60 ms/op 235.52 ms/op 1.28
Half columns - reconstruct half of the blobs out of 6 132.18 ms/op 119.02 ms/op 1.11
Half columns - reconstruct single blob out of 6 47.826 ms/op 44.629 ms/op 1.07
Full columns - reconstruct all 10 blobs 388.27 us/op 350.53 us/op 1.11
Full columns - reconstruct half of the blobs out of 10 192.03 us/op 202.27 us/op 0.95
Full columns - reconstruct single blob out of 10 47.330 us/op 35.998 us/op 1.31
Half columns - reconstruct all 10 blobs 535.11 ms/op 390.04 ms/op 1.37
Half columns - reconstruct half of the blobs out of 10 221.41 ms/op 198.50 ms/op 1.12
Half columns - reconstruct single blob out of 10 48.671 ms/op 44.291 ms/op 1.10
Full columns - reconstruct all 20 blobs 799.01 us/op 657.74 us/op 1.21
Full columns - reconstruct half of the blobs out of 20 306.65 us/op 316.49 us/op 0.97
Full columns - reconstruct single blob out of 20 41.036 us/op 39.331 us/op 1.04
Half columns - reconstruct all 20 blobs 862.71 ms/op 779.82 ms/op 1.11
Half columns - reconstruct half of the blobs out of 20 432.58 ms/op 427.59 ms/op 1.01
Half columns - reconstruct single blob out of 20 48.072 ms/op 44.501 ms/op 1.08
Set add up to 64 items then delete first 1.9651 us/op 1.6665 us/op 1.18
OrderedSet add up to 64 items then delete first 2.9339 us/op 2.5391 us/op 1.16
Set add up to 64 items then delete last 2.2100 us/op 1.7757 us/op 1.24
OrderedSet add up to 64 items then delete last 3.1530 us/op 2.5973 us/op 1.21
Set add up to 64 items then delete middle 2.3113 us/op 1.7872 us/op 1.29
OrderedSet add up to 64 items then delete middle 4.6765 us/op 4.3565 us/op 1.07
Set add up to 128 items then delete first 4.5982 us/op 3.4357 us/op 1.34
OrderedSet add up to 128 items then delete first 6.8437 us/op 5.4183 us/op 1.26
Set add up to 128 items then delete last 4.4371 us/op 3.3265 us/op 1.33
OrderedSet add up to 128 items then delete last 6.3349 us/op 4.9802 us/op 1.27
Set add up to 128 items then delete middle 4.2833 us/op 3.3237 us/op 1.29
OrderedSet add up to 128 items then delete middle 12.477 us/op 10.675 us/op 1.17
Set add up to 256 items then delete first 9.6847 us/op 6.7248 us/op 1.44
OrderedSet add up to 256 items then delete first 14.419 us/op 10.807 us/op 1.33
Set add up to 256 items then delete last 8.7787 us/op 6.7073 us/op 1.31
OrderedSet add up to 256 items then delete last 13.535 us/op 10.289 us/op 1.32
Set add up to 256 items then delete middle 8.6943 us/op 6.6128 us/op 1.31
OrderedSet add up to 256 items then delete middle 38.008 us/op 33.268 us/op 1.14
pass gossip attestations to forkchoice per slot 2.3591 ms/op 2.0377 ms/op 1.16
forkChoice updateHead vc 100000 bc 64 eq 0 472.56 us/op 366.75 us/op 1.29
forkChoice updateHead vc 600000 bc 64 eq 0 2.8008 ms/op 2.1864 ms/op 1.28
forkChoice updateHead vc 1000000 bc 64 eq 0 4.6561 ms/op 3.6375 ms/op 1.28
forkChoice updateHead vc 600000 bc 320 eq 0 3.0107 ms/op 2.1948 ms/op 1.37
forkChoice updateHead vc 600000 bc 1200 eq 0 2.9103 ms/op 2.2232 ms/op 1.31
forkChoice updateHead vc 600000 bc 7200 eq 0 3.2264 ms/op 2.8417 ms/op 1.14
forkChoice updateHead vc 600000 bc 64 eq 1000 3.2861 ms/op 3.0663 ms/op 1.07
forkChoice updateHead vc 600000 bc 64 eq 10000 3.4058 ms/op 4.3265 ms/op 0.79
forkChoice updateHead vc 600000 bc 64 eq 300000 8.6485 ms/op 7.5716 ms/op 1.14
computeDeltas 1400000 validators 0% inactive 14.009 ms/op 13.056 ms/op 1.07
computeDeltas 1400000 validators 10% inactive 13.102 ms/op 12.305 ms/op 1.06
computeDeltas 1400000 validators 20% inactive 12.235 ms/op 11.850 ms/op 1.03
computeDeltas 1400000 validators 50% inactive 9.6036 ms/op 8.4943 ms/op 1.13
computeDeltas 2100000 validators 0% inactive 21.062 ms/op 19.244 ms/op 1.09
computeDeltas 2100000 validators 10% inactive 19.781 ms/op 18.988 ms/op 1.04
computeDeltas 2100000 validators 20% inactive 18.368 ms/op 17.995 ms/op 1.02
computeDeltas 2100000 validators 50% inactive 14.415 ms/op 12.725 ms/op 1.13
altair processAttestation - 250000 vs - 7PWei normalcase 1.8243 ms/op 1.5922 ms/op 1.15
altair processAttestation - 250000 vs - 7PWei worstcase 2.6565 ms/op 2.2843 ms/op 1.16
altair processAttestation - setStatus - 1/6 committees join 112.97 us/op 95.170 us/op 1.19
altair processAttestation - setStatus - 1/3 committees join 219.00 us/op 172.88 us/op 1.27
altair processAttestation - setStatus - 1/2 committees join 305.80 us/op 235.34 us/op 1.30
altair processAttestation - setStatus - 2/3 committees join 411.43 us/op 311.39 us/op 1.32
altair processAttestation - setStatus - 4/5 committees join 561.00 us/op 488.35 us/op 1.15
altair processAttestation - setStatus - 100% committees join 648.78 us/op 568.92 us/op 1.14
altair processBlock - 250000 vs - 7PWei normalcase 3.5928 ms/op 3.0419 ms/op 1.18
altair processBlock - 250000 vs - 7PWei normalcase hashState 21.084 ms/op 14.028 ms/op 1.50
altair processBlock - 250000 vs - 7PWei worstcase 24.072 ms/op 22.491 ms/op 1.07
altair processBlock - 250000 vs - 7PWei worstcase hashState 62.928 ms/op 53.369 ms/op 1.18
phase0 processBlock - 250000 vs - 7PWei normalcase 1.5170 ms/op 1.5764 ms/op 0.96
phase0 processBlock - 250000 vs - 7PWei worstcase 27.555 ms/op 19.693 ms/op 1.40
altair processEth1Data - 250000 vs - 7PWei normalcase 354.43 us/op 295.61 us/op 1.20
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 5.8660 us/op 5.4370 us/op 1.08
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 42.756 us/op 42.736 us/op 1.00
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 12.263 us/op 13.245 us/op 0.93
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 10.975 us/op 3.8980 us/op 2.82
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 184.01 us/op 148.38 us/op 1.24
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.6903 ms/op 1.2957 ms/op 1.30
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.1395 ms/op 1.7034 ms/op 1.26
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.2075 ms/op 1.8220 ms/op 1.21
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.2937 ms/op 3.8822 ms/op 1.11
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.5570 ms/op 2.1550 ms/op 1.19
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.6907 ms/op 4.2066 ms/op 1.12
Tree 40 250000 create 367.99 ms/op 326.49 ms/op 1.13
Tree 40 250000 get(125000) 123.94 ns/op 87.878 ns/op 1.41
Tree 40 250000 set(125000) 1.2079 us/op 939.27 ns/op 1.29
Tree 40 250000 toArray() 12.361 ms/op 10.760 ms/op 1.15
Tree 40 250000 iterate all - toArray() + loop 13.155 ms/op 10.692 ms/op 1.23
Tree 40 250000 iterate all - get(i) 44.985 ms/op 32.107 ms/op 1.40
Array 250000 create 2.4432 ms/op 1.9959 ms/op 1.22
Array 250000 clone - spread 778.32 us/op 615.17 us/op 1.27
Array 250000 get(125000) 0.40100 ns/op 0.51800 ns/op 0.77
Array 250000 set(125000) 0.34900 ns/op 0.52400 ns/op 0.67
Array 250000 iterate all - loop 58.728 us/op 56.656 us/op 1.04
phase0 afterProcessEpoch - 250000 vs - 7PWei 40.834 ms/op 38.487 ms/op 1.06
Array.fill - length 1000000 2.7716 ms/op 1.8497 ms/op 1.50
Array push - length 1000000 10.336 ms/op 6.7931 ms/op 1.52
Array.get 0.21709 ns/op 0.19625 ns/op 1.11
Uint8Array.get 0.22198 ns/op 0.19954 ns/op 1.11
phase0 beforeProcessEpoch - 250000 vs - 7PWei 13.605 ms/op 11.055 ms/op 1.23
altair processEpoch - mainnet_e81889 245.68 ms/op 233.82 ms/op 1.05
mainnet_e81889 - altair beforeProcessEpoch 16.645 ms/op 13.749 ms/op 1.21
mainnet_e81889 - altair processJustificationAndFinalization 6.0720 us/op 5.3560 us/op 1.13
mainnet_e81889 - altair processInactivityUpdates 3.6970 ms/op 3.3345 ms/op 1.11
mainnet_e81889 - altair processRewardsAndPenalties 17.791 ms/op 21.215 ms/op 0.84
mainnet_e81889 - altair processRegistryUpdates 631.00 ns/op 785.00 ns/op 0.80
mainnet_e81889 - altair processSlashings 212.00 ns/op 359.00 ns/op 0.59
mainnet_e81889 - altair processEth1DataReset 170.00 ns/op 356.00 ns/op 0.48
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.9650 ms/op 1.6296 ms/op 1.21
mainnet_e81889 - altair processSlashingsReset 918.00 ns/op 946.00 ns/op 0.97
mainnet_e81889 - altair processRandaoMixesReset 1.0660 us/op 1.3000 us/op 0.82
mainnet_e81889 - altair processHistoricalRootsUpdate 167.00 ns/op 365.00 ns/op 0.46
mainnet_e81889 - altair processParticipationFlagUpdates 532.00 ns/op 694.00 ns/op 0.77
mainnet_e81889 - altair processSyncCommitteeUpdates 155.00 ns/op 337.00 ns/op 0.46
mainnet_e81889 - altair afterProcessEpoch 43.097 ms/op 41.612 ms/op 1.04
capella processEpoch - mainnet_e217614 852.89 ms/op 742.60 ms/op 1.15
mainnet_e217614 - capella beforeProcessEpoch 62.799 ms/op 53.538 ms/op 1.17
mainnet_e217614 - capella processJustificationAndFinalization 5.7790 us/op 5.0310 us/op 1.15
mainnet_e217614 - capella processInactivityUpdates 15.336 ms/op 10.792 ms/op 1.42
mainnet_e217614 - capella processRewardsAndPenalties 108.20 ms/op 97.502 ms/op 1.11
mainnet_e217614 - capella processRegistryUpdates 5.7790 us/op 4.8390 us/op 1.19
mainnet_e217614 - capella processSlashings 165.00 ns/op 383.00 ns/op 0.43
mainnet_e217614 - capella processEth1DataReset 162.00 ns/op 392.00 ns/op 0.41
mainnet_e217614 - capella processEffectiveBalanceUpdates 11.057 ms/op 5.4102 ms/op 2.04
mainnet_e217614 - capella processSlashingsReset 807.00 ns/op 1.1990 us/op 0.67
mainnet_e217614 - capella processRandaoMixesReset 1.5900 us/op 1.3360 us/op 1.19
mainnet_e217614 - capella processHistoricalRootsUpdate 218.00 ns/op 365.00 ns/op 0.60
mainnet_e217614 - capella processParticipationFlagUpdates 615.00 ns/op 680.00 ns/op 0.90
mainnet_e217614 - capella afterProcessEpoch 112.44 ms/op 106.39 ms/op 1.06
phase0 processEpoch - mainnet_e58758 255.07 ms/op 231.79 ms/op 1.10
mainnet_e58758 - phase0 beforeProcessEpoch 54.355 ms/op 48.574 ms/op 1.12
mainnet_e58758 - phase0 processJustificationAndFinalization 6.8350 us/op 5.0540 us/op 1.35
mainnet_e58758 - phase0 processRewardsAndPenalties 30.925 ms/op 17.978 ms/op 1.72
mainnet_e58758 - phase0 processRegistryUpdates 2.7270 us/op 2.4710 us/op 1.10
mainnet_e58758 - phase0 processSlashings 220.00 ns/op 379.00 ns/op 0.58
mainnet_e58758 - phase0 processEth1DataReset 215.00 ns/op 381.00 ns/op 0.56
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.1176 ms/op 879.92 us/op 1.27
mainnet_e58758 - phase0 processSlashingsReset 911.00 ns/op 1.0980 us/op 0.83
mainnet_e58758 - phase0 processRandaoMixesReset 1.2100 us/op 1.2010 us/op 1.01
mainnet_e58758 - phase0 processHistoricalRootsUpdate 164.00 ns/op 443.00 ns/op 0.37
mainnet_e58758 - phase0 processParticipationRecordUpdates 817.00 ns/op 1.4440 us/op 0.57
mainnet_e58758 - phase0 afterProcessEpoch 35.248 ms/op 31.875 ms/op 1.11
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.2643 ms/op 1.4895 ms/op 0.85
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.5572 ms/op 1.5946 ms/op 1.60
altair processInactivityUpdates - 250000 normalcase 13.110 ms/op 10.400 ms/op 1.26
altair processInactivityUpdates - 250000 worstcase 11.995 ms/op 9.6307 ms/op 1.25
phase0 processRegistryUpdates - 250000 normalcase 7.4310 us/op 4.1790 us/op 1.78
phase0 processRegistryUpdates - 250000 badcase_full_deposits 378.05 us/op 243.01 us/op 1.56
phase0 processRegistryUpdates - 250000 worstcase 0.5 65.282 ms/op 63.454 ms/op 1.03
altair processRewardsAndPenalties - 250000 normalcase 15.787 ms/op 13.135 ms/op 1.20
altair processRewardsAndPenalties - 250000 worstcase 21.927 ms/op 18.518 ms/op 1.18
phase0 getAttestationDeltas - 250000 normalcase 6.5436 ms/op 5.5053 ms/op 1.19
phase0 getAttestationDeltas - 250000 worstcase 6.5484 ms/op 5.0546 ms/op 1.30
phase0 processSlashings - 250000 worstcase 97.037 us/op 92.116 us/op 1.05
altair processSyncCommitteeUpdates - 250000 10.697 ms/op 9.2651 ms/op 1.15
BeaconState.hashTreeRoot - No change 229.00 ns/op 415.00 ns/op 0.55
BeaconState.hashTreeRoot - 1 full validator 89.972 us/op 87.306 us/op 1.03
BeaconState.hashTreeRoot - 32 full validator 1.0395 ms/op 980.96 us/op 1.06
BeaconState.hashTreeRoot - 512 full validator 7.6181 ms/op 6.5908 ms/op 1.16
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 131.49 us/op 93.423 us/op 1.41
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.4272 ms/op 1.5169 ms/op 1.60
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 27.508 ms/op 13.433 ms/op 2.05
BeaconState.hashTreeRoot - 1 balances 75.046 us/op 73.836 us/op 1.02
BeaconState.hashTreeRoot - 32 balances 1.0154 ms/op 801.90 us/op 1.27
BeaconState.hashTreeRoot - 512 balances 8.9783 ms/op 4.8058 ms/op 1.87
BeaconState.hashTreeRoot - 250000 balances 167.62 ms/op 131.01 ms/op 1.28
aggregationBits - 2048 els - zipIndexesInBitList 20.000 us/op 19.233 us/op 1.04
regular array get 100000 times 24.216 us/op 22.771 us/op 1.06
wrappedArray get 100000 times 24.087 us/op 22.746 us/op 1.06
arrayWithProxy get 100000 times 14.960 ms/op 10.347 ms/op 1.45
ssz.Root.equals 23.162 ns/op 21.803 ns/op 1.06
byteArrayEquals 22.271 ns/op 25.063 ns/op 0.89
Buffer.compare 9.4590 ns/op 9.1360 ns/op 1.04
processSlot - 1 slots 13.210 us/op 9.8770 us/op 1.34
processSlot - 32 slots 2.0465 ms/op 2.4299 ms/op 0.84
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 3.1310 ms/op 1.9564 ms/op 1.60
getCommitteeAssignments - req 1 vs - 250000 vc 1.8047 ms/op 1.6907 ms/op 1.07
getCommitteeAssignments - req 100 vs - 250000 vc 3.5293 ms/op 3.4355 ms/op 1.03
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7776 ms/op 3.6835 ms/op 1.03
findModifiedValidators - 10000 modified validators 496.28 ms/op 407.46 ms/op 1.22
findModifiedValidators - 1000 modified validators 391.76 ms/op 328.56 ms/op 1.19
findModifiedValidators - 100 modified validators 257.79 ms/op 240.79 ms/op 1.07
findModifiedValidators - 10 modified validators 154.31 ms/op 196.03 ms/op 0.79
findModifiedValidators - 1 modified validators 141.42 ms/op 129.23 ms/op 1.09
findModifiedValidators - no difference 166.21 ms/op 103.89 ms/op 1.60
migrate state 1500000 validators, 3400 modified, 2000 new 963.82 ms/op 903.43 ms/op 1.07
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 5.6700 ns/op 5.8600 ns/op 0.97
state getBlockRootAtSlot - 250000 vs - 7PWei 617.51 ns/op 481.21 ns/op 1.28
computeProposerIndex 100000 validators 1.4974 ms/op 1.3262 ms/op 1.13
getNextSyncCommitteeIndices 1000 validators 112.69 ms/op 98.630 ms/op 1.14
getNextSyncCommitteeIndices 10000 validators 112.59 ms/op 98.913 ms/op 1.14
getNextSyncCommitteeIndices 100000 validators 112.97 ms/op 98.383 ms/op 1.15
computeProposers - vc 250000 636.15 us/op 545.56 us/op 1.17
computeEpochShuffling - vc 250000 40.400 ms/op 38.770 ms/op 1.04
getNextSyncCommittee - vc 250000 10.127 ms/op 9.2830 ms/op 1.09
nodejs block root to RootHex using toHex 128.13 ns/op 115.39 ns/op 1.11
nodejs block root to RootHex using toRootHex 80.809 ns/op 75.982 ns/op 1.06
nodejs fromHex(blob) 214.87 us/op 259.74 us/op 0.83
nodejs fromHexInto(blob) 691.23 us/op 702.04 us/op 0.98
nodejs block root to RootHex using the deprecated toHexString 522.74 ns/op 529.30 ns/op 0.99
nodejs byteArrayEquals 32 bytes (block root) 27.779 ns/op 28.045 ns/op 0.99
nodejs byteArrayEquals 48 bytes (pubkey) 39.773 ns/op 41.404 ns/op 0.96
nodejs byteArrayEquals 96 bytes (signature) 37.920 ns/op 37.858 ns/op 1.00
nodejs byteArrayEquals 1024 bytes 44.826 ns/op 42.172 ns/op 1.06
nodejs byteArrayEquals 131072 bytes (blob) 1.8347 us/op 1.7469 us/op 1.05
browser block root to RootHex using toHex 158.84 ns/op 148.43 ns/op 1.07
browser block root to RootHex using toRootHex 149.62 ns/op 135.66 ns/op 1.10
browser fromHex(blob) 1.2443 ms/op 982.52 us/op 1.27
browser fromHexInto(blob) 682.49 us/op 674.16 us/op 1.01
browser block root to RootHex using the deprecated toHexString 360.07 ns/op 367.13 ns/op 0.98
browser byteArrayEquals 32 bytes (block root) 30.343 ns/op 33.547 ns/op 0.90
browser byteArrayEquals 48 bytes (pubkey) 47.197 ns/op 39.941 ns/op 1.18
browser byteArrayEquals 96 bytes (signature) 83.246 ns/op 74.737 ns/op 1.11
browser byteArrayEquals 1024 bytes 781.44 ns/op 747.04 ns/op 1.05
browser byteArrayEquals 131072 bytes (blob) 98.922 us/op 93.351 us/op 1.06

by benchmarkbot/action

Copy link

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

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28cf5d59e3

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +118 to +119
// Track newly added builder pubkeys for subsequent deposits
builderPubkeys.add(pubkeyHex);

Choose a reason for hiding this comment

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

P2 Badge Only mark builder pubkey after successful onboarding

builderPubkeys is updated unconditionally after applyDepositForBuilder(...). If that call rejects the deposit (e.g., invalid signature), the pubkey is still treated as an existing builder in subsequent iterations. That can route later deposits for the same pubkey through the builder path even when the withdrawal credentials are not builder credentials, potentially creating a builder with validator-style credentials or dropping validator deposits that should stay pending. The spec recomputes builder pubkeys from state each iteration specifically to avoid this; you should only add to builderPubkeys when applyDepositForBuilder actually adds a builder.

Useful? React with 👍 / 👎.

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.

1 participant