Skip to content

fix: sync through empty epochs in range sync#9417

Open
wemeetagain wants to merge 3 commits into
unstablefrom
cayman/fix-empty-epoch-sync
Open

fix: sync through empty epochs in range sync#9417
wemeetagain wants to merge 3 commits into
unstablefrom
cayman/fix-empty-epoch-sync

Conversation

@wemeetagain
Copy link
Copy Markdown
Member

@wemeetagain wemeetagain commented May 28, 2026

Motivation

A peer's correct response for an epoch in which every slot was skipped is zero
blocks. Range sync rejected that response, so the node could not sync past an
empty epoch during periods of poor chain liveness.

Two interacting defects, both introduced during the fulu/PeerDAS sync work:

  1. validateBlockByRangeResponse threw MISSING_BLOCKS_RESPONSE on a 0-block
    response. In sendBatch this became a downloadingError; since every peer
    returns empty for a genuinely empty epoch, all retries failed and after
    MAX_BATCH_DOWNLOAD_ATTEMPTS the batch threw MAX_DOWNLOAD_ATTEMPTS and the
    whole SyncChain errored out. A second copy of the throw in validateResponses
    fired for post-Deneb epochs that also carry a blobs/columns request.

  2. The MAX_LOOK_AHEAD_EPOCHS guard in includeNextBatch counted batches in the
    AwaitingValidation state. Empty batches reach AwaitingValidation but never
    call advanceChain (only non-empty batches do), so lastEpochWithProcessBlocks
    never advances. A run of empty epochs longer than MAX_LOOK_AHEAD_EPOCHS (2)
    filled the look-ahead window, includeNextBatch returned null, and the chain
    stalled with nothing left to download or process. This deadlock is why the
    naive "return [] instead of throw" fix had previously been reverted.

Description

  • validateBlockByRangeResponse returns an empty result with a
    MISSING_BLOCKS_RESPONSE warning instead of throwing. Whether an epoch is
    genuinely empty is enforced at the chain level: the empty batch is held in
    AwaitingValidation and only confirmed once a later batch imports a block, so
    a peer cannot stall sync by falsely claiming an epoch is empty.
  • validateResponses skips data-sidecar validation when there are no blocks in
    the data request's slot range (parent-by-root columns and envelopes still
    run).
  • includeNextBatch's look-ahead guard ignores AwaitingValidation batches,
    mirroring the BATCH_BUFFER_SIZE carve-out.

Archeology

  • downloadByRange.ts was introduced in feat: refactor block input #8200 (feat: refactor block input,
    2025-09-18) -- the fulu block-input/PeerDAS sync rewrite that deleted the old
    Deneb-era beaconBlocksMaybeBlobsByRange.ts downloader, which had tolerated
    empty epochs. The empty-blocks throw was then cemented in fix: refactor validateColumnsByRangeResponse #8482 (fix:
    refactor validateColumnsByRangeResponse, 2025-10-27, b992c32).
  • The MAX_LOOK_AHEAD_EPOCHS guard was added 2025-08-11 (38889e2) during
    PeerDAS sync work. The original 2021 BATCH_BUFFER_SIZE check directly above it
    (f46b63f, dapplion) deliberately excluded AwaitingValidation batches "to
    prevent stalling sync if the current processing window is contained in a long
    range of skip slots." The new guard did not replicate that carve-out,
    re-creating the exact stall the 2021 code was written to avoid.

AI Assistance Disclosure

  • claude assistance

A peer's correct response for an epoch in which every slot was skipped is zero
blocks. Range sync rejected that response, so the node could not sync past an
empty epoch during periods of poor chain liveness.

Two interacting defects, both introduced during the fulu/PeerDAS sync work:

1. validateBlockByRangeResponse threw MISSING_BLOCKS_RESPONSE on a 0-block
   response. In sendBatch this became a downloadingError; since every peer
   returns empty for a genuinely empty epoch, all retries failed and after
   MAX_BATCH_DOWNLOAD_ATTEMPTS the batch threw MAX_DOWNLOAD_ATTEMPTS and the
   whole SyncChain errored out. A second copy of the throw in validateResponses
   fired for post-Deneb epochs that also carry a blobs/columns request.

2. The MAX_LOOK_AHEAD_EPOCHS guard in includeNextBatch counted batches in the
   AwaitingValidation state. Empty batches reach AwaitingValidation but never
   call advanceChain (only non-empty batches do), so lastEpochWithProcessBlocks
   never advances. A run of empty epochs longer than MAX_LOOK_AHEAD_EPOCHS (2)
   filled the look-ahead window, includeNextBatch returned null, and the chain
   stalled with nothing left to download or process. This deadlock is why the
   naive "return [] instead of throw" fix had previously been reverted.

Archeology:
- downloadByRange.ts was introduced in #8200 (feat: refactor block input,
  2025-09-18) -- the fulu block-input/PeerDAS sync rewrite that deleted the old
  Deneb-era beaconBlocksMaybeBlobsByRange.ts downloader, which had tolerated
  empty epochs. The empty-blocks throw was then cemented in #8482 (fix:
  refactor validateColumnsByRangeResponse, 2025-10-27, b992c32).
- The MAX_LOOK_AHEAD_EPOCHS guard was added 2025-08-11 (38889e2) during
  PeerDAS sync work. The original 2021 BATCH_BUFFER_SIZE check directly above it
  (f46b63f, dapplion) deliberately excluded AwaitingValidation batches "to
  prevent stalling sync if the current processing window is contained in a long
  range of skip slots." The new guard did not replicate that carve-out,
  re-creating the exact stall the 2021 code was written to avoid.

Fix:
- validateBlockByRangeResponse returns an empty result with a
  MISSING_BLOCKS_RESPONSE warning instead of throwing. Whether an epoch is
  genuinely empty is enforced at the chain level: the empty batch is held in
  AwaitingValidation and only confirmed once a later batch imports a block, so
  a peer cannot stall sync by falsely claiming an epoch is empty.
- validateResponses skips data-sidecar validation when there are no blocks in
  the data request's slot range (parent-by-root columns and envelopes still
  run).
- includeNextBatch's look-ahead guard ignores AwaitingValidation batches,
  mirroring the BATCH_BUFFER_SIZE carve-out.

Tests:
- validateBlockByRangeResponse accepts an empty response during chain liveness
  issues.
- validateResponses accepts an empty epoch that carries a data request.
- chain.test.ts gains a "3 epochs of skipped slots" case -- a run longer than
  MAX_LOOK_AHEAD_EPOCHS -- which previously deadlocked.

Refs: #8147
validateResponses had three separate "nothing to validate here, fall through to
parent-by-root columns + envelope validation" paths, with that parent + envelope
tail duplicated between the no-data-request branch and the main path. The
empty-epoch fix made the duplication more pronounced by adding a third skip path.

Collapse them: gate getBlocksForDataValidation on `dataRequest` (defaulting to an
empty list when absent) and let the single shared tail handle parent-by-root
columns and envelopes for every case. This deletes the no-data-request early
return entirely, and flattens data-sidecar validation from an outer
`if (blocksForDataValidation.length > 0)` wrapper into per-request guards.

Behavior-preserving: an envelopes-only / parent-payload-only request and an empty
epoch now flow through the same path that already validated them, minus the
duplicated branch. Net -20 lines.

Adds a characterization test pinning the no-data-request (envelopes-only) path,
which previously had no direct unit coverage.
@wemeetagain wemeetagain requested a review from a team as a code owner May 28, 2026 20:15
Copy link
Copy Markdown
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 addresses sync deadlocks during periods of poor chain liveness by allowing the sync chain to process empty epochs (epochs with zero blocks) without stalling or throwing errors. It updates the look-ahead window check to only count pending batches, preventing empty batches in AwaitingValidation from filling the window. Additionally, it refactors the response validation to return warnings instead of throwing errors when zero blocks are returned for an epoch, and adds corresponding regression tests. A review comment suggests simplifying a redundant ternary operator in validateResponses when passing validated blocks to getBlocksForDataValidation.

Comment thread packages/beacon-node/src/sync/utils/downloadByRange.ts Outdated
Copy link
Copy Markdown

@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: fe749a76a7

ℹ️ 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 thread packages/beacon-node/src/sync/utils/downloadByRange.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 0b6fc84 Previous: edb7c53 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 988.41 us/op 894.42 us/op 1.11
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.539 us/op 42.097 us/op 0.96
BLS verify - blst 737.77 us/op 732.37 us/op 1.01
BLS verifyMultipleSignatures 3 - blst 1.3755 ms/op 1.3405 ms/op 1.03
BLS verifyMultipleSignatures 8 - blst 2.2091 ms/op 2.1105 ms/op 1.05
BLS verifyMultipleSignatures 32 - blst 6.9042 ms/op 6.4824 ms/op 1.07
BLS verifyMultipleSignatures 64 - blst 13.060 ms/op 12.690 ms/op 1.03
BLS verifyMultipleSignatures 128 - blst 26.194 ms/op 24.879 ms/op 1.05
BLS deserializing 10000 signatures 619.24 ms/op 619.28 ms/op 1.00
BLS deserializing 100000 signatures 6.1894 s/op 6.2975 s/op 0.98
BLS verifyMultipleSignatures - same message - 3 - blst 747.01 us/op 761.59 us/op 0.98
BLS verifyMultipleSignatures - same message - 8 - blst 832.77 us/op 888.08 us/op 0.94
BLS verifyMultipleSignatures - same message - 32 - blst 1.5060 ms/op 1.4773 ms/op 1.02
BLS verifyMultipleSignatures - same message - 64 - blst 2.2560 ms/op 2.4246 ms/op 0.93
BLS verifyMultipleSignatures - same message - 128 - blst 3.9095 ms/op 4.0663 ms/op 0.96
BLS aggregatePubkeys 32 - blst 16.870 us/op 17.597 us/op 0.96
BLS aggregatePubkeys 128 - blst 59.873 us/op 63.931 us/op 0.94
getSlashingsAndExits - default max 48.186 us/op 47.540 us/op 1.01
getSlashingsAndExits - 2k 345.77 us/op 354.47 us/op 0.98
proposeBlockBody type=full, size=empty 1.6243 ms/op 842.19 us/op 1.93
isKnown best case - 1 super set check 175.00 ns/op 174.00 ns/op 1.01
isKnown normal case - 2 super set checks 355.00 ns/op 166.00 ns/op 2.14
isKnown worse case - 16 super set checks 170.00 ns/op 167.00 ns/op 1.02
validate api signedAggregateAndProof - struct 1.5405 ms/op 1.4982 ms/op 1.03
validate gossip signedAggregateAndProof - struct 1.5268 ms/op 1.5075 ms/op 1.01
batch validate gossip attestation - vc 640000 - chunk 32 105.62 us/op 107.29 us/op 0.98
batch validate gossip attestation - vc 640000 - chunk 64 91.620 us/op 96.029 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 128 85.544 us/op 89.847 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 256 81.189 us/op 87.323 us/op 0.93
bytes32 toHexString 299.00 ns/op 293.00 ns/op 1.02
bytes32 Buffer.toString(hex) 169.00 ns/op 166.00 ns/op 1.02
bytes32 Buffer.toString(hex) from Uint8Array 227.00 ns/op 223.00 ns/op 1.02
bytes32 Buffer.toString(hex) + 0x 167.00 ns/op 169.00 ns/op 0.99
Return object 10000 times 0.21020 ns/op 0.21490 ns/op 0.98
Throw Error 10000 times 3.2512 us/op 3.2943 us/op 0.99
toHex 92.677 ns/op 96.687 ns/op 0.96
Buffer.from 83.394 ns/op 79.377 ns/op 1.05
shared Buffer 55.397 ns/op 51.895 ns/op 1.07
fastMsgIdFn sha256 / 200 bytes 1.4860 us/op 1.4400 us/op 1.03
fastMsgIdFn h32 xxhash / 200 bytes 152.00 ns/op 162.00 ns/op 0.94
fastMsgIdFn h64 xxhash / 200 bytes 201.00 ns/op 207.00 ns/op 0.97
fastMsgIdFn sha256 / 1000 bytes 4.9020 us/op 4.7150 us/op 1.04
fastMsgIdFn h32 xxhash / 1000 bytes 244.00 ns/op 243.00 ns/op 1.00
fastMsgIdFn h64 xxhash / 1000 bytes 253.00 ns/op 249.00 ns/op 1.02
fastMsgIdFn sha256 / 10000 bytes 43.877 us/op 41.076 us/op 1.07
fastMsgIdFn h32 xxhash / 10000 bytes 1.2410 us/op 1.2680 us/op 0.98
fastMsgIdFn h64 xxhash / 10000 bytes 802.00 ns/op 813.00 ns/op 0.99
send data - 1000 256B messages 3.9748 ms/op 4.4352 ms/op 0.90
send data - 1000 512B messages 3.8476 ms/op 4.4465 ms/op 0.87
send data - 1000 1024B messages 3.9902 ms/op 4.8800 ms/op 0.82
send data - 1000 1200B messages 4.6147 ms/op 5.1464 ms/op 0.90
send data - 1000 2048B messages 4.3401 ms/op 5.0768 ms/op 0.85
send data - 1000 4096B messages 5.6705 ms/op 5.9326 ms/op 0.96
send data - 1000 16384B messages 19.928 ms/op 15.717 ms/op 1.27
send data - 1000 65536B messages 203.47 ms/op 155.98 ms/op 1.30
enrSubnets - fastDeserialize 64 bits 709.00 ns/op 717.00 ns/op 0.99
enrSubnets - ssz BitVector 64 bits 250.00 ns/op 272.00 ns/op 0.92
enrSubnets - fastDeserialize 4 bits 96.000 ns/op 103.00 ns/op 0.93
enrSubnets - ssz BitVector 4 bits 256.00 ns/op 272.00 ns/op 0.94
prioritizePeers score -10:0 att 32-0.1 sync 2-0 218.91 us/op 199.81 us/op 1.10
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 253.43 us/op 234.17 us/op 1.08
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 382.61 us/op 342.89 us/op 1.12
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 622.04 us/op 607.35 us/op 1.02
prioritizePeers score 0:0 att 64-1 sync 4-1 727.45 us/op 700.36 us/op 1.04
array of 16000 items push then shift 1.2745 us/op 1.2488 us/op 1.02
LinkedList of 16000 items push then shift 6.6010 ns/op 7.6340 ns/op 0.86
array of 16000 items push then pop 67.000 ns/op 67.742 ns/op 0.99
LinkedList of 16000 items push then pop 5.9380 ns/op 5.9710 ns/op 0.99
array of 24000 items push then shift 1.8887 us/op 1.8704 us/op 1.01
LinkedList of 24000 items push then shift 6.3250 ns/op 7.5130 ns/op 0.84
array of 24000 items push then pop 92.237 ns/op 96.469 ns/op 0.96
LinkedList of 24000 items push then pop 5.9570 ns/op 6.0450 ns/op 0.99
intersect bitArray bitLen 8 4.6380 ns/op 4.6920 ns/op 0.99
intersect array and set length 8 32.199 ns/op 29.246 ns/op 1.10
intersect bitArray bitLen 128 24.911 ns/op 23.763 ns/op 1.05
intersect array and set length 128 466.09 ns/op 489.17 ns/op 0.95
bitArray.getTrueBitIndexes() bitLen 128 990.00 ns/op 1.0130 us/op 0.98
bitArray.getTrueBitIndexes() bitLen 248 1.7110 us/op 1.7190 us/op 1.00
bitArray.getTrueBitIndexes() bitLen 512 3.5550 us/op 3.5520 us/op 1.00
Full columns - reconstruct all 6 blobs 122.71 us/op 165.50 us/op 0.74
Full columns - reconstruct half of the blobs out of 6 66.085 us/op 99.107 us/op 0.67
Full columns - reconstruct single blob out of 6 31.748 us/op 34.561 us/op 0.92
Half columns - reconstruct all 6 blobs 383.50 ms/op 392.55 ms/op 0.98
Half columns - reconstruct half of the blobs out of 6 192.40 ms/op 199.38 ms/op 0.97
Half columns - reconstruct single blob out of 6 70.254 ms/op 71.126 ms/op 0.99
Full columns - reconstruct all 10 blobs 237.09 us/op 385.66 us/op 0.61
Full columns - reconstruct half of the blobs out of 10 94.723 us/op 140.68 us/op 0.67
Full columns - reconstruct single blob out of 10 35.275 us/op 32.596 us/op 1.08
Half columns - reconstruct all 10 blobs 644.78 ms/op 644.07 ms/op 1.00
Half columns - reconstruct half of the blobs out of 10 325.14 ms/op 324.28 ms/op 1.00
Half columns - reconstruct single blob out of 10 71.737 ms/op 68.655 ms/op 1.04
Full columns - reconstruct all 20 blobs 1.5683 ms/op 606.80 us/op 2.58
Full columns - reconstruct half of the blobs out of 20 216.39 us/op 178.16 us/op 1.21
Full columns - reconstruct single blob out of 20 31.052 us/op 31.842 us/op 0.98
Half columns - reconstruct all 20 blobs 1.2858 s/op 1.2656 s/op 1.02
Half columns - reconstruct half of the blobs out of 20 638.81 ms/op 646.71 ms/op 0.99
Half columns - reconstruct single blob out of 20 69.573 ms/op 69.815 ms/op 1.00
Set add up to 64 items then delete first 2.6087 us/op 2.5586 us/op 1.02
OrderedSet add up to 64 items then delete first 3.4252 us/op 3.3893 us/op 1.01
Set add up to 64 items then delete last 2.4445 us/op 2.3127 us/op 1.06
OrderedSet add up to 64 items then delete last 3.4743 us/op 3.3728 us/op 1.03
Set add up to 64 items then delete middle 2.2231 us/op 2.1438 us/op 1.04
OrderedSet add up to 64 items then delete middle 4.9970 us/op 4.8676 us/op 1.03
Set add up to 128 items then delete first 4.2654 us/op 4.1208 us/op 1.04
OrderedSet add up to 128 items then delete first 6.4357 us/op 6.1748 us/op 1.04
Set add up to 128 items then delete last 4.2972 us/op 4.0368 us/op 1.06
OrderedSet add up to 128 items then delete last 6.2280 us/op 6.1378 us/op 1.01
Set add up to 128 items then delete middle 4.0103 us/op 3.9196 us/op 1.02
OrderedSet add up to 128 items then delete middle 12.182 us/op 11.887 us/op 1.02
Set add up to 256 items then delete first 7.9766 us/op 7.6890 us/op 1.04
OrderedSet add up to 256 items then delete first 12.050 us/op 12.571 us/op 0.96
Set add up to 256 items then delete last 8.0268 us/op 7.7562 us/op 1.03
OrderedSet add up to 256 items then delete last 12.382 us/op 12.058 us/op 1.03
Set add up to 256 items then delete middle 7.9642 us/op 7.8362 us/op 1.02
OrderedSet add up to 256 items then delete middle 38.439 us/op 37.246 us/op 1.03
pass gossip attestations to forkchoice per slot 2.4718 ms/op 2.5930 ms/op 0.95
forkChoice updateHead vc 100000 bc 64 eq 0 373.85 us/op 383.90 us/op 0.97
forkChoice updateHead vc 600000 bc 64 eq 0 2.2380 ms/op 2.3367 ms/op 0.96
forkChoice updateHead vc 1000000 bc 64 eq 0 3.7562 ms/op 3.8811 ms/op 0.97
forkChoice updateHead vc 600000 bc 320 eq 0 2.2985 ms/op 2.3296 ms/op 0.99
forkChoice updateHead vc 600000 bc 1200 eq 0 2.2650 ms/op 2.5218 ms/op 0.90
forkChoice updateHead vc 600000 bc 7200 eq 0 3.1658 ms/op 2.9193 ms/op 1.08
forkChoice updateHead vc 600000 bc 64 eq 1000 2.7474 ms/op 2.9003 ms/op 0.95
forkChoice updateHead vc 600000 bc 64 eq 10000 2.8891 ms/op 3.0362 ms/op 0.95
forkChoice updateHead vc 600000 bc 64 eq 300000 7.1304 ms/op 6.8176 ms/op 1.05
computeDeltas 1400000 validators 0% inactive 12.049 ms/op 12.634 ms/op 0.95
computeDeltas 1400000 validators 10% inactive 11.358 ms/op 11.639 ms/op 0.98
computeDeltas 1400000 validators 20% inactive 10.093 ms/op 10.703 ms/op 0.94
computeDeltas 1400000 validators 50% inactive 7.8326 ms/op 8.2531 ms/op 0.95
computeDeltas 2100000 validators 0% inactive 18.161 ms/op 18.795 ms/op 0.97
computeDeltas 2100000 validators 10% inactive 17.032 ms/op 17.556 ms/op 0.97
computeDeltas 2100000 validators 20% inactive 15.231 ms/op 15.908 ms/op 0.96
computeDeltas 2100000 validators 50% inactive 11.819 ms/op 10.471 ms/op 1.13
altair processAttestation - 250000 vs - 7PWei normalcase 1.8076 ms/op 1.8715 ms/op 0.97
altair processAttestation - 250000 vs - 7PWei worstcase 2.4728 ms/op 3.3651 ms/op 0.73
altair processAttestation - setStatus - 1/6 committees join 104.71 us/op 99.779 us/op 1.05
altair processAttestation - setStatus - 1/3 committees join 208.37 us/op 193.70 us/op 1.08
altair processAttestation - setStatus - 1/2 committees join 298.34 us/op 279.29 us/op 1.07
altair processAttestation - setStatus - 2/3 committees join 376.85 us/op 362.48 us/op 1.04
altair processAttestation - setStatus - 4/5 committees join 525.57 us/op 511.44 us/op 1.03
altair processAttestation - setStatus - 100% committees join 622.07 us/op 589.04 us/op 1.06
altair processBlock - 250000 vs - 7PWei normalcase 3.0462 ms/op 3.9334 ms/op 0.77
altair processBlock - 250000 vs - 7PWei normalcase hashState 17.348 ms/op 16.403 ms/op 1.06
altair processBlock - 250000 vs - 7PWei worstcase 19.871 ms/op 23.045 ms/op 0.86
altair processBlock - 250000 vs - 7PWei worstcase hashState 38.423 ms/op 44.877 ms/op 0.86
phase0 processBlock - 250000 vs - 7PWei normalcase 1.5604 ms/op 1.4197 ms/op 1.10
phase0 processBlock - 250000 vs - 7PWei worstcase 17.466 ms/op 17.236 ms/op 1.01
altair processEth1Data - 250000 vs - 7PWei normalcase 306.52 us/op 284.42 us/op 1.08
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.5080 us/op 3.1440 us/op 1.12
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 22.280 us/op 19.702 us/op 1.13
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 6.6230 us/op 5.2930 us/op 1.25
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 4.2470 us/op 3.2490 us/op 1.31
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 105.74 us/op 86.216 us/op 1.23
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4010 ms/op 1.3519 ms/op 1.04
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8349 ms/op 1.7968 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7043 ms/op 1.7991 ms/op 0.95
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.6017 ms/op 3.2912 ms/op 1.40
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0702 ms/op 2.0286 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.7513 ms/op 3.5296 ms/op 1.35
Tree 40 250000 create 383.46 ms/op 323.69 ms/op 1.18
Tree 40 250000 get(125000) 98.825 ns/op 91.931 ns/op 1.07
Tree 40 250000 set(125000) 1.0758 us/op 990.77 ns/op 1.09
Tree 40 250000 toArray() 16.118 ms/op 13.797 ms/op 1.17
Tree 40 250000 iterate all - toArray() + loop 17.075 ms/op 12.603 ms/op 1.35
Tree 40 250000 iterate all - get(i) 40.865 ms/op 38.924 ms/op 1.05
Array 250000 create 2.0599 ms/op 2.0966 ms/op 0.98
Array 250000 clone - spread 656.57 us/op 655.25 us/op 1.00
Array 250000 get(125000) 0.29000 ns/op 0.29500 ns/op 0.98
Array 250000 set(125000) 0.29300 ns/op 0.29500 ns/op 0.99
Array 250000 iterate all - loop 55.953 us/op 56.011 us/op 1.00
phase0 afterProcessEpoch - 250000 vs - 7PWei 39.140 ms/op 52.705 ms/op 0.74
Array.fill - length 1000000 2.3083 ms/op 2.1009 ms/op 1.10
Array push - length 1000000 7.7978 ms/op 9.4443 ms/op 0.83
Array.get 0.20571 ns/op 0.21014 ns/op 0.98
Uint8Array.get 0.22569 ns/op 0.24479 ns/op 0.92
phase0 beforeProcessEpoch - 250000 vs - 7PWei 17.863 ms/op 15.930 ms/op 1.12
altair processEpoch - mainnet_e81889 311.32 ms/op 273.09 ms/op 1.14
mainnet_e81889 - altair beforeProcessEpoch 35.253 ms/op 15.130 ms/op 2.33
mainnet_e81889 - altair processJustificationAndFinalization 8.2330 us/op 6.3760 us/op 1.29
mainnet_e81889 - altair processInactivityUpdates 5.8182 ms/op 6.5698 ms/op 0.89
mainnet_e81889 - altair processRewardsAndPenalties 19.173 ms/op 20.227 ms/op 0.95
mainnet_e81889 - altair processRegistryUpdates 515.00 ns/op 533.00 ns/op 0.97
mainnet_e81889 - altair processSlashings 144.00 ns/op 135.00 ns/op 1.07
mainnet_e81889 - altair processEth1DataReset 124.00 ns/op 131.00 ns/op 0.95
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.4114 ms/op 3.5240 ms/op 0.40
mainnet_e81889 - altair processSlashingsReset 703.00 ns/op 712.00 ns/op 0.99
mainnet_e81889 - altair processRandaoMixesReset 1.2980 us/op 1.3320 us/op 0.97
mainnet_e81889 - altair processHistoricalRootsUpdate 126.00 ns/op 130.00 ns/op 0.97
mainnet_e81889 - altair processParticipationFlagUpdates 443.00 ns/op 441.00 ns/op 1.00
mainnet_e81889 - altair processSyncCommitteeUpdates 105.00 ns/op 106.00 ns/op 0.99
mainnet_e81889 - altair afterProcessEpoch 41.980 ms/op 43.869 ms/op 0.96
capella processEpoch - mainnet_e217614 957.34 ms/op 850.45 ms/op 1.13
mainnet_e217614 - capella beforeProcessEpoch 63.722 ms/op 57.411 ms/op 1.11
mainnet_e217614 - capella processJustificationAndFinalization 6.0450 us/op 6.8000 us/op 0.89
mainnet_e217614 - capella processInactivityUpdates 11.595 ms/op 15.535 ms/op 0.75
mainnet_e217614 - capella processRewardsAndPenalties 101.26 ms/op 95.929 ms/op 1.06
mainnet_e217614 - capella processRegistryUpdates 4.5390 us/op 4.6190 us/op 0.98
mainnet_e217614 - capella processSlashings 133.00 ns/op 137.00 ns/op 0.97
mainnet_e217614 - capella processEth1DataReset 123.00 ns/op 131.00 ns/op 0.94
mainnet_e217614 - capella processEffectiveBalanceUpdates 17.205 ms/op 16.378 ms/op 1.05
mainnet_e217614 - capella processSlashingsReset 654.00 ns/op 689.00 ns/op 0.95
mainnet_e217614 - capella processRandaoMixesReset 1.4360 us/op 1.3100 us/op 1.10
mainnet_e217614 - capella processHistoricalRootsUpdate 124.00 ns/op 131.00 ns/op 0.95
mainnet_e217614 - capella processParticipationFlagUpdates 408.00 ns/op 427.00 ns/op 0.96
mainnet_e217614 - capella afterProcessEpoch 106.24 ms/op 112.33 ms/op 0.95
phase0 processEpoch - mainnet_e58758 315.75 ms/op 320.64 ms/op 0.98
mainnet_e58758 - phase0 beforeProcessEpoch 81.384 ms/op 60.775 ms/op 1.34
mainnet_e58758 - phase0 processJustificationAndFinalization 7.0730 us/op 6.2660 us/op 1.13
mainnet_e58758 - phase0 processRewardsAndPenalties 15.860 ms/op 16.094 ms/op 0.99
mainnet_e58758 - phase0 processRegistryUpdates 2.2400 us/op 2.2740 us/op 0.99
mainnet_e58758 - phase0 processSlashings 125.00 ns/op 135.00 ns/op 0.93
mainnet_e58758 - phase0 processEth1DataReset 203.00 ns/op 128.00 ns/op 1.59
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 807.26 us/op 829.88 us/op 0.97
mainnet_e58758 - phase0 processSlashingsReset 878.00 ns/op 867.00 ns/op 1.01
mainnet_e58758 - phase0 processRandaoMixesReset 1.5200 us/op 1.8640 us/op 0.82
mainnet_e58758 - phase0 processHistoricalRootsUpdate 125.00 ns/op 134.00 ns/op 0.93
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2440 us/op 1.0260 us/op 1.21
mainnet_e58758 - phase0 afterProcessEpoch 32.788 ms/op 34.739 ms/op 0.94
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.0204 ms/op 1.0025 ms/op 1.02
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5971 ms/op 2.3454 ms/op 0.68
altair processInactivityUpdates - 250000 normalcase 10.435 ms/op 10.744 ms/op 0.97
altair processInactivityUpdates - 250000 worstcase 10.484 ms/op 10.854 ms/op 0.97
phase0 processRegistryUpdates - 250000 normalcase 2.3140 us/op 2.3060 us/op 1.00
phase0 processRegistryUpdates - 250000 badcase_full_deposits 150.63 us/op 142.36 us/op 1.06
phase0 processRegistryUpdates - 250000 worstcase 0.5 52.040 ms/op 58.617 ms/op 0.89
altair processRewardsAndPenalties - 250000 normalcase 14.840 ms/op 15.152 ms/op 0.98
altair processRewardsAndPenalties - 250000 worstcase 13.599 ms/op 14.602 ms/op 0.93
phase0 getAttestationDeltas - 250000 normalcase 5.2299 ms/op 5.2137 ms/op 1.00
phase0 getAttestationDeltas - 250000 worstcase 5.3241 ms/op 5.5073 ms/op 0.97
phase0 processSlashings - 250000 worstcase 60.678 us/op 57.819 us/op 1.05
altair processSyncCommitteeUpdates - 250000 12.199 ms/op 9.8940 ms/op 1.23
BeaconState.hashTreeRoot - No change 162.00 ns/op 166.00 ns/op 0.98
BeaconState.hashTreeRoot - 1 full validator 74.001 us/op 79.465 us/op 0.93
BeaconState.hashTreeRoot - 32 full validator 890.08 us/op 866.14 us/op 1.03
BeaconState.hashTreeRoot - 512 full validator 8.0047 ms/op 8.0182 ms/op 1.00
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 94.934 us/op 98.058 us/op 0.97
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.4255 ms/op 1.4901 ms/op 1.63
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 20.292 ms/op 16.363 ms/op 1.24
BeaconState.hashTreeRoot - 1 balances 109.95 us/op 75.852 us/op 1.45
BeaconState.hashTreeRoot - 32 balances 1.1319 ms/op 758.69 us/op 1.49
BeaconState.hashTreeRoot - 512 balances 5.5602 ms/op 6.2516 ms/op 0.89
BeaconState.hashTreeRoot - 250000 balances 190.87 ms/op 130.00 ms/op 1.47
aggregationBits - 2048 els - zipIndexesInBitList 21.683 us/op 18.985 us/op 1.14
regular array get 100000 times 22.524 us/op 22.445 us/op 1.00
wrappedArray get 100000 times 22.413 us/op 22.625 us/op 0.99
arrayWithProxy get 100000 times 11.964 ms/op 10.241 ms/op 1.17
ssz.Root.equals 20.902 ns/op 21.024 ns/op 0.99
byteArrayEquals 20.542 ns/op 20.815 ns/op 0.99
Buffer.compare 8.5140 ns/op 8.6490 ns/op 0.98
processSlot - 1 slots 12.504 us/op 10.899 us/op 1.15
processSlot - 32 slots 2.8019 ms/op 2.0637 ms/op 1.36
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.8829 ms/op 3.5655 ms/op 1.37
getCommitteeAssignments - req 1 vs - 250000 vc 1.5874 ms/op 1.6808 ms/op 0.94
getCommitteeAssignments - req 100 vs - 250000 vc 3.3108 ms/op 3.4125 ms/op 0.97
getCommitteeAssignments - req 1000 vs - 250000 vc 3.5915 ms/op 3.6726 ms/op 0.98
findModifiedValidators - 10000 modified validators 852.47 ms/op 689.94 ms/op 1.24
findModifiedValidators - 1000 modified validators 535.43 ms/op 426.30 ms/op 1.26
findModifiedValidators - 100 modified validators 324.83 ms/op 306.99 ms/op 1.06
findModifiedValidators - 10 modified validators 217.38 ms/op 241.70 ms/op 0.90
findModifiedValidators - 1 modified validators 195.17 ms/op 169.00 ms/op 1.15
findModifiedValidators - no difference 150.95 ms/op 155.20 ms/op 0.97
migrate state 1500000 validators, 3400 modified, 2000 new 4.4406 s/op 3.1282 s/op 1.42
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.7200 ns/op 3.6900 ns/op 1.01
state getBlockRootAtSlot - 250000 vs - 7PWei 496.84 ns/op 366.94 ns/op 1.35
computeProposerIndex 100000 validators 1.3886 ms/op 1.3538 ms/op 1.03
getNextSyncCommitteeIndices 1000 validators 2.9314 ms/op 3.2535 ms/op 0.90
getNextSyncCommitteeIndices 10000 validators 26.049 ms/op 28.569 ms/op 0.91
getNextSyncCommitteeIndices 100000 validators 89.821 ms/op 94.905 ms/op 0.95
computeProposers - vc 250000 561.72 us/op 546.57 us/op 1.03
computeEpochShuffling - vc 250000 39.537 ms/op 40.120 ms/op 0.99
getNextSyncCommittee - vc 250000 10.477 ms/op 9.4899 ms/op 1.10
nodejs block root to RootHex using toHex 85.573 ns/op 88.410 ns/op 0.97
nodejs block root to RootHex using toRootHex 51.413 ns/op 53.902 ns/op 0.95
nodejs fromHex(blob) 901.42 us/op 794.99 us/op 1.13
nodejs fromHexInto(blob) 614.61 us/op 635.13 us/op 0.97
nodejs block root to RootHex using the deprecated toHexString 461.87 ns/op 465.29 ns/op 0.99
nodejs byteArrayEquals 32 bytes (block root) 25.551 ns/op 25.950 ns/op 0.98
nodejs byteArrayEquals 48 bytes (pubkey) 36.943 ns/op 37.486 ns/op 0.99
nodejs byteArrayEquals 96 bytes (signature) 33.153 ns/op 33.625 ns/op 0.99
nodejs byteArrayEquals 1024 bytes 39.733 ns/op 40.955 ns/op 0.97
nodejs byteArrayEquals 131072 bytes (blob) 1.7221 us/op 1.7697 us/op 0.97
browser block root to RootHex using toHex 140.64 ns/op 145.85 ns/op 0.96
browser block root to RootHex using toRootHex 128.78 ns/op 132.03 ns/op 0.98
browser fromHex(blob) 1.7340 ms/op 1.6923 ms/op 1.02
browser fromHexInto(blob) 596.67 us/op 640.37 us/op 0.93
browser block root to RootHex using the deprecated toHexString 450.03 ns/op 470.99 ns/op 0.96
browser byteArrayEquals 32 bytes (block root) 26.739 ns/op 27.901 ns/op 0.96
browser byteArrayEquals 48 bytes (pubkey) 37.845 ns/op 39.620 ns/op 0.96
browser byteArrayEquals 96 bytes (signature) 70.406 ns/op 73.607 ns/op 0.96
browser byteArrayEquals 1024 bytes 721.94 ns/op 758.03 ns/op 0.95
browser byteArrayEquals 131072 bytes (blob) 91.569 us/op 93.872 us/op 0.98

by benchmarkbot/action

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