Skip to content

feat: only give proposer boost to canonical proposer#9313

Open
ensi321 wants to merge 2 commits intounstablefrom
nc/proposer-boost-canonical-check
Open

feat: only give proposer boost to canonical proposer#9313
ensi321 wants to merge 2 commits intounstablefrom
nc/proposer-boost-canonical-check

Conversation

@ensi321
Copy link
Copy Markdown
Contributor

@ensi321 ensi321 commented Apr 30, 2026

closes #9231

Per consensus-specs PR #4807, `update_proposer_boost_root` now only sets
`proposer_boost_root` when the imported block's `proposer_index` matches
the head state's expected proposer for the slot, so a divergent proposer
shuffling on a non-canonical fork cannot nullify proposer boost.

`onBlock` gains an `expectedProposerIndex` argument; `importBlock`
resolves it via `headState.currentProposers` / `nextProposers` (O(1),
backed by `state.proposerLookahead` post-fulu) — same fast path used by
the proposer-preferences gossip validator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 updates the onBlock method in the fork choice implementation to include an expectedProposerIndex parameter, which is used to restrict proposer boost to blocks from the expected proposer. Changes include updating the IForkChoice interface, the importBlock logic, and relevant tests. A review comment suggests refactoring the logic for determining the expected proposer index to avoid duplication between the main code and test utilities.

Comment on lines +120 to +126
let expectedProposerIndex: number | null = null;
const headState = this.getHeadState();
if (headState.epoch === blockEpoch) {
expectedProposerIndex = headState.currentProposers[blockSlot % SLOTS_PER_EPOCH];
} else if (headState.epoch + 1 === blockEpoch) {
expectedProposerIndex = headState.nextProposers[blockSlot % SLOTS_PER_EPOCH];
}
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.

medium

The logic for determining the expected proposer index from the head state is duplicated in packages/beacon-node/test/spec/utils/gossipValidation.ts. Consider encapsulating this logic into a shared helper function or using the existing state.getBeaconProposer(slot) method with appropriate error handling. This would improve maintainability and ensure consistency across the codebase when resolving proposers from a given state.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 1f72e27 Previous: 9f5db5b Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 891.14 us/op 1.3821 ms/op 0.64
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.528 us/op 39.546 us/op 1.02
BLS verify - blst 653.12 us/op 748.26 us/op 0.87
BLS verifyMultipleSignatures 3 - blst 1.3694 ms/op 1.3645 ms/op 1.00
BLS verifyMultipleSignatures 8 - blst 2.1822 ms/op 2.1716 ms/op 1.00
BLS verifyMultipleSignatures 32 - blst 6.9329 ms/op 6.9760 ms/op 0.99
BLS verifyMultipleSignatures 64 - blst 13.265 ms/op 13.364 ms/op 0.99
BLS verifyMultipleSignatures 128 - blst 25.787 ms/op 26.049 ms/op 0.99
BLS deserializing 10000 signatures 625.43 ms/op 635.95 ms/op 0.98
BLS deserializing 100000 signatures 6.2163 s/op 6.4979 s/op 0.96
BLS verifyMultipleSignatures - same message - 3 - blst 703.62 us/op 836.73 us/op 0.84
BLS verifyMultipleSignatures - same message - 8 - blst 878.87 us/op 980.10 us/op 0.90
BLS verifyMultipleSignatures - same message - 32 - blst 1.5258 ms/op 1.5695 ms/op 0.97
BLS verifyMultipleSignatures - same message - 64 - blst 2.2980 ms/op 2.4213 ms/op 0.95
BLS verifyMultipleSignatures - same message - 128 - blst 4.0060 ms/op 4.1543 ms/op 0.96
BLS aggregatePubkeys 32 - blst 17.227 us/op 17.909 us/op 0.96
BLS aggregatePubkeys 128 - blst 61.655 us/op 64.032 us/op 0.96
getSlashingsAndExits - default max 51.327 us/op 57.486 us/op 0.89
getSlashingsAndExits - 2k 363.76 us/op 462.79 us/op 0.79
proposeBlockBody type=full, size=empty 803.91 us/op 843.12 us/op 0.95
isKnown best case - 1 super set check 163.00 ns/op 182.00 ns/op 0.90
isKnown normal case - 2 super set checks 164.00 ns/op 168.00 ns/op 0.98
isKnown worse case - 16 super set checks 164.00 ns/op 172.00 ns/op 0.95
validate api signedAggregateAndProof - struct 1.5480 ms/op 1.5655 ms/op 0.99
validate gossip signedAggregateAndProof - struct 1.5396 ms/op 1.5617 ms/op 0.99
batch validate gossip attestation - vc 640000 - chunk 32 106.86 us/op 111.61 us/op 0.96
batch validate gossip attestation - vc 640000 - chunk 64 93.666 us/op 97.734 us/op 0.96
batch validate gossip attestation - vc 640000 - chunk 128 88.864 us/op 92.047 us/op 0.97
batch validate gossip attestation - vc 640000 - chunk 256 84.267 us/op 88.130 us/op 0.96
bytes32 toHexString 279.00 ns/op 292.00 ns/op 0.96
bytes32 Buffer.toString(hex) 172.00 ns/op 182.00 ns/op 0.95
bytes32 Buffer.toString(hex) from Uint8Array 245.00 ns/op 254.00 ns/op 0.96
bytes32 Buffer.toString(hex) + 0x 170.00 ns/op 180.00 ns/op 0.94
Return object 10000 times 0.21540 ns/op 0.21680 ns/op 0.99
Throw Error 10000 times 3.3730 us/op 3.3593 us/op 1.00
toHex 94.045 ns/op 96.769 ns/op 0.97
Buffer.from 86.233 ns/op 87.551 ns/op 0.98
shared Buffer 57.263 ns/op 59.331 ns/op 0.97
fastMsgIdFn sha256 / 200 bytes 1.4890 us/op 1.5370 us/op 0.97
fastMsgIdFn h32 xxhash / 200 bytes 158.00 ns/op 156.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 200 bytes 202.00 ns/op 202.00 ns/op 1.00
fastMsgIdFn sha256 / 1000 bytes 4.7820 us/op 4.8470 us/op 0.99
fastMsgIdFn h32 xxhash / 1000 bytes 252.00 ns/op 257.00 ns/op 0.98
fastMsgIdFn h64 xxhash / 1000 bytes 255.00 ns/op 265.00 ns/op 0.96
fastMsgIdFn sha256 / 10000 bytes 42.379 us/op 42.485 us/op 1.00
fastMsgIdFn h32 xxhash / 10000 bytes 1.2950 us/op 1.2770 us/op 1.01
fastMsgIdFn h64 xxhash / 10000 bytes 836.00 ns/op 825.00 ns/op 1.01
send data - 1000 256B messages 4.4413 ms/op 4.1786 ms/op 1.06
send data - 1000 512B messages 4.3031 ms/op 4.2290 ms/op 1.02
send data - 1000 1024B messages 4.6676 ms/op 4.5719 ms/op 1.02
send data - 1000 1200B messages 4.8160 ms/op 4.6538 ms/op 1.03
send data - 1000 2048B messages 5.2604 ms/op 5.6032 ms/op 0.94
send data - 1000 4096B messages 5.9538 ms/op 6.5677 ms/op 0.91
send data - 1000 16384B messages 68.159 ms/op 44.468 ms/op 1.53
send data - 1000 65536B messages 223.54 ms/op 285.92 ms/op 0.78
enrSubnets - fastDeserialize 64 bits 734.00 ns/op 797.00 ns/op 0.92
enrSubnets - ssz BitVector 64 bits 253.00 ns/op 269.00 ns/op 0.94
enrSubnets - fastDeserialize 4 bits 98.000 ns/op 103.00 ns/op 0.95
enrSubnets - ssz BitVector 4 bits 263.00 ns/op 268.00 ns/op 0.98
prioritizePeers score -10:0 att 32-0.1 sync 2-0 212.51 us/op 216.33 us/op 0.98
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 238.94 us/op 249.01 us/op 0.96
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 357.62 us/op 349.79 us/op 1.02
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 622.89 us/op 599.68 us/op 1.04
prioritizePeers score 0:0 att 64-1 sync 4-1 710.65 us/op 713.15 us/op 1.00
array of 16000 items push then shift 1.2991 us/op 1.3100 us/op 0.99
LinkedList of 16000 items push then shift 7.4580 ns/op 7.2480 ns/op 1.03
array of 16000 items push then pop 68.582 ns/op 71.670 ns/op 0.96
LinkedList of 16000 items push then pop 6.0370 ns/op 6.0030 ns/op 1.01
array of 24000 items push then shift 1.9133 us/op 1.9299 us/op 0.99
LinkedList of 24000 items push then shift 6.5650 ns/op 6.8910 ns/op 0.95
array of 24000 items push then pop 97.339 ns/op 98.782 ns/op 0.99
LinkedList of 24000 items push then pop 5.9790 ns/op 6.0200 ns/op 0.99
intersect bitArray bitLen 8 4.6630 ns/op 4.7970 ns/op 0.97
intersect array and set length 8 29.928 ns/op 33.438 ns/op 0.90
intersect bitArray bitLen 128 23.956 ns/op 24.409 ns/op 0.98
intersect array and set length 128 541.83 ns/op 499.44 ns/op 1.08
bitArray.getTrueBitIndexes() bitLen 128 1.1020 us/op 1.0350 us/op 1.06
bitArray.getTrueBitIndexes() bitLen 248 1.7480 us/op 1.7900 us/op 0.98
bitArray.getTrueBitIndexes() bitLen 512 3.8010 us/op 3.6510 us/op 1.04
Full columns - reconstruct all 6 blobs 106.33 us/op 181.98 us/op 0.58
Full columns - reconstruct half of the blobs out of 6 61.084 us/op 70.320 us/op 0.87
Full columns - reconstruct single blob out of 6 30.853 us/op 71.601 us/op 0.43
Half columns - reconstruct all 6 blobs 393.85 ms/op 402.30 ms/op 0.98
Half columns - reconstruct half of the blobs out of 6 199.82 ms/op 198.37 ms/op 1.01
Half columns - reconstruct single blob out of 6 72.032 ms/op 71.915 ms/op 1.00
Full columns - reconstruct all 10 blobs 165.07 us/op 304.11 us/op 0.54
Full columns - reconstruct half of the blobs out of 10 143.22 us/op 294.43 us/op 0.49
Full columns - reconstruct single blob out of 10 31.963 us/op 59.980 us/op 0.53
Half columns - reconstruct all 10 blobs 649.68 ms/op 674.33 ms/op 0.96
Half columns - reconstruct half of the blobs out of 10 331.49 ms/op 341.60 ms/op 0.97
Half columns - reconstruct single blob out of 10 71.786 ms/op 68.301 ms/op 1.05
Full columns - reconstruct all 20 blobs 1.6946 ms/op 1.8874 ms/op 0.90
Full columns - reconstruct half of the blobs out of 20 283.51 us/op 220.26 us/op 1.29
Full columns - reconstruct single blob out of 20 30.432 us/op 34.450 us/op 0.88
Half columns - reconstruct all 20 blobs 1.2701 s/op 1.3277 s/op 0.96
Half columns - reconstruct half of the blobs out of 20 644.86 ms/op 659.83 ms/op 0.98
Half columns - reconstruct single blob out of 20 71.507 ms/op 70.486 ms/op 1.01
Set add up to 64 items then delete first 2.0058 us/op 2.1920 us/op 0.92
OrderedSet add up to 64 items then delete first 3.1986 us/op 3.4855 us/op 0.92
Set add up to 64 items then delete last 2.0343 us/op 2.1708 us/op 0.94
OrderedSet add up to 64 items then delete last 3.1420 us/op 3.3949 us/op 0.93
Set add up to 64 items then delete middle 2.0329 us/op 2.1708 us/op 0.94
OrderedSet add up to 64 items then delete middle 4.5730 us/op 4.8577 us/op 0.94
Set add up to 128 items then delete first 4.0604 us/op 4.3911 us/op 0.92
OrderedSet add up to 128 items then delete first 6.2124 us/op 6.7053 us/op 0.93
Set add up to 128 items then delete last 3.7401 us/op 3.9796 us/op 0.94
OrderedSet add up to 128 items then delete last 5.6101 us/op 5.8898 us/op 0.95
Set add up to 128 items then delete middle 3.7585 us/op 3.9596 us/op 0.95
OrderedSet add up to 128 items then delete middle 11.784 us/op 11.873 us/op 0.99
Set add up to 256 items then delete first 7.8148 us/op 8.0169 us/op 0.97
OrderedSet add up to 256 items then delete first 12.082 us/op 12.402 us/op 0.97
Set add up to 256 items then delete last 7.4598 us/op 7.7757 us/op 0.96
OrderedSet add up to 256 items then delete last 11.648 us/op 11.794 us/op 0.99
Set add up to 256 items then delete middle 7.4432 us/op 7.7358 us/op 0.96
OrderedSet add up to 256 items then delete middle 35.084 us/op 35.428 us/op 0.99
pass gossip attestations to forkchoice per slot 2.4692 ms/op 2.5756 ms/op 0.96
forkChoice updateHead vc 100000 bc 64 eq 0 378.20 us/op 424.66 us/op 0.89
forkChoice updateHead vc 600000 bc 64 eq 0 2.2601 ms/op 2.5029 ms/op 0.90
forkChoice updateHead vc 1000000 bc 64 eq 0 3.7506 ms/op 4.0971 ms/op 0.92
forkChoice updateHead vc 600000 bc 320 eq 0 2.2625 ms/op 2.4654 ms/op 0.92
forkChoice updateHead vc 600000 bc 1200 eq 0 2.2971 ms/op 2.9142 ms/op 0.79
forkChoice updateHead vc 600000 bc 7200 eq 0 2.9594 ms/op 2.8884 ms/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 1000 3.2481 ms/op 3.0026 ms/op 1.08
forkChoice updateHead vc 600000 bc 64 eq 10000 3.3969 ms/op 3.1097 ms/op 1.09
forkChoice updateHead vc 600000 bc 64 eq 300000 7.4586 ms/op 7.3946 ms/op 1.01
computeDeltas 1400000 validators 0% inactive 14.152 ms/op 13.085 ms/op 1.08
computeDeltas 1400000 validators 10% inactive 12.803 ms/op 12.237 ms/op 1.05
computeDeltas 1400000 validators 20% inactive 11.940 ms/op 11.192 ms/op 1.07
computeDeltas 1400000 validators 50% inactive 8.7913 ms/op 8.5383 ms/op 1.03
computeDeltas 2100000 validators 0% inactive 20.491 ms/op 19.609 ms/op 1.04
computeDeltas 2100000 validators 10% inactive 19.229 ms/op 18.336 ms/op 1.05
computeDeltas 2100000 validators 20% inactive 17.785 ms/op 16.791 ms/op 1.06
computeDeltas 2100000 validators 50% inactive 13.911 ms/op 9.8262 ms/op 1.42
altair processAttestation - 250000 vs - 7PWei normalcase 1.9029 ms/op 2.4809 ms/op 0.77
altair processAttestation - 250000 vs - 7PWei worstcase 2.4861 ms/op 3.1960 ms/op 0.78
altair processAttestation - setStatus - 1/6 committees join 105.33 us/op 104.36 us/op 1.01
altair processAttestation - setStatus - 1/3 committees join 201.60 us/op 213.45 us/op 0.94
altair processAttestation - setStatus - 1/2 committees join 286.53 us/op 293.43 us/op 0.98
altair processAttestation - setStatus - 2/3 committees join 355.20 us/op 385.10 us/op 0.92
altair processAttestation - setStatus - 4/5 committees join 501.31 us/op 539.71 us/op 0.93
altair processAttestation - setStatus - 100% committees join 569.83 us/op 621.65 us/op 0.92
altair processBlock - 250000 vs - 7PWei normalcase 3.8927 ms/op 4.4764 ms/op 0.87
altair processBlock - 250000 vs - 7PWei normalcase hashState 14.328 ms/op 17.574 ms/op 0.82
altair processBlock - 250000 vs - 7PWei worstcase 21.452 ms/op 23.353 ms/op 0.92
altair processBlock - 250000 vs - 7PWei worstcase hashState 42.902 ms/op 50.717 ms/op 0.85
phase0 processBlock - 250000 vs - 7PWei normalcase 1.4536 ms/op 1.5151 ms/op 0.96
phase0 processBlock - 250000 vs - 7PWei worstcase 17.999 ms/op 17.592 ms/op 1.02
altair processEth1Data - 250000 vs - 7PWei normalcase 301.79 us/op 305.08 us/op 0.99
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.2910 us/op 4.7210 us/op 0.70
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 20.026 us/op 22.416 us/op 0.89
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.6330 us/op 8.3250 us/op 0.68
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.5750 us/op 5.9940 us/op 0.60
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 89.509 us/op 99.526 us/op 0.90
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4088 ms/op 1.4624 ms/op 0.96
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8168 ms/op 1.9108 ms/op 0.95
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7457 ms/op 1.9085 ms/op 0.91
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.8800 ms/op 4.2570 ms/op 0.91
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 1.9497 ms/op 2.1628 ms/op 0.90
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.1970 ms/op 6.4604 ms/op 0.65
Tree 40 250000 create 376.45 ms/op 327.49 ms/op 1.15
Tree 40 250000 get(125000) 87.900 ns/op 96.956 ns/op 0.91
Tree 40 250000 set(125000) 999.28 ns/op 1.0548 us/op 0.95
Tree 40 250000 toArray() 12.527 ms/op 12.434 ms/op 1.01
Tree 40 250000 iterate all - toArray() + loop 11.290 ms/op 17.949 ms/op 0.63
Tree 40 250000 iterate all - get(i) 35.721 ms/op 44.721 ms/op 0.80
Array 250000 create 2.0955 ms/op 2.3834 ms/op 0.88
Array 250000 clone - spread 653.50 us/op 856.12 us/op 0.76
Array 250000 get(125000) 0.28500 ns/op 0.30900 ns/op 0.92
Array 250000 set(125000) 0.29700 ns/op 0.31600 ns/op 0.94
Array 250000 iterate all - loop 55.845 us/op 59.581 us/op 0.94
phase0 afterProcessEpoch - 250000 vs - 7PWei 38.160 ms/op 40.218 ms/op 0.95
Array.fill - length 1000000 2.0634 ms/op 2.0798 ms/op 0.99
Array push - length 1000000 7.0361 ms/op 13.821 ms/op 0.51
Array.get 0.19913 ns/op 0.21760 ns/op 0.92
Uint8Array.get 0.25665 ns/op 0.24564 ns/op 1.04
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.030 ms/op 19.802 ms/op 0.76
altair processEpoch - mainnet_e81889 333.39 ms/op 283.11 ms/op 1.18
mainnet_e81889 - altair beforeProcessEpoch 22.636 ms/op 64.871 ms/op 0.35
mainnet_e81889 - altair processJustificationAndFinalization 7.6110 us/op 6.4140 us/op 1.19
mainnet_e81889 - altair processInactivityUpdates 4.5835 ms/op 4.2023 ms/op 1.09
mainnet_e81889 - altair processRewardsAndPenalties 18.654 ms/op 23.395 ms/op 0.80
mainnet_e81889 - altair processRegistryUpdates 531.00 ns/op 591.00 ns/op 0.90
mainnet_e81889 - altair processSlashings 136.00 ns/op 148.00 ns/op 0.92
mainnet_e81889 - altair processEth1DataReset 136.00 ns/op 153.00 ns/op 0.89
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.5929 ms/op 1.6603 ms/op 0.96
mainnet_e81889 - altair processSlashingsReset 691.00 ns/op 756.00 ns/op 0.91
mainnet_e81889 - altair processRandaoMixesReset 1.4290 us/op 1.2630 us/op 1.13
mainnet_e81889 - altair processHistoricalRootsUpdate 129.00 ns/op 148.00 ns/op 0.87
mainnet_e81889 - altair processParticipationFlagUpdates 418.00 ns/op 503.00 ns/op 0.83
mainnet_e81889 - altair processSyncCommitteeUpdates 109.00 ns/op 122.00 ns/op 0.89
mainnet_e81889 - altair afterProcessEpoch 41.373 ms/op 43.395 ms/op 0.95
capella processEpoch - mainnet_e217614 980.10 ms/op 916.75 ms/op 1.07
mainnet_e217614 - capella beforeProcessEpoch 61.411 ms/op 81.554 ms/op 0.75
mainnet_e217614 - capella processJustificationAndFinalization 6.6360 us/op 6.0810 us/op 1.09
mainnet_e217614 - capella processInactivityUpdates 15.798 ms/op 16.832 ms/op 0.94
mainnet_e217614 - capella processRewardsAndPenalties 103.22 ms/op 100.98 ms/op 1.02
mainnet_e217614 - capella processRegistryUpdates 4.5150 us/op 4.6990 us/op 0.96
mainnet_e217614 - capella processSlashings 127.00 ns/op 148.00 ns/op 0.86
mainnet_e217614 - capella processEth1DataReset 125.00 ns/op 142.00 ns/op 0.88
mainnet_e217614 - capella processEffectiveBalanceUpdates 14.467 ms/op 6.8053 ms/op 2.13
mainnet_e217614 - capella processSlashingsReset 658.00 ns/op 752.00 ns/op 0.88
mainnet_e217614 - capella processRandaoMixesReset 1.3420 us/op 1.6370 us/op 0.82
mainnet_e217614 - capella processHistoricalRootsUpdate 131.00 ns/op 147.00 ns/op 0.89
mainnet_e217614 - capella processParticipationFlagUpdates 419.00 ns/op 479.00 ns/op 0.87
mainnet_e217614 - capella afterProcessEpoch 106.49 ms/op 110.33 ms/op 0.97
phase0 processEpoch - mainnet_e58758 298.49 ms/op 348.54 ms/op 0.86
mainnet_e58758 - phase0 beforeProcessEpoch 58.691 ms/op 78.209 ms/op 0.75
mainnet_e58758 - phase0 processJustificationAndFinalization 6.0700 us/op 6.7100 us/op 0.90
mainnet_e58758 - phase0 processRewardsAndPenalties 17.491 ms/op 17.823 ms/op 0.98
mainnet_e58758 - phase0 processRegistryUpdates 2.2300 us/op 2.3480 us/op 0.95
mainnet_e58758 - phase0 processSlashings 125.00 ns/op 147.00 ns/op 0.85
mainnet_e58758 - phase0 processEth1DataReset 127.00 ns/op 142.00 ns/op 0.89
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 785.18 us/op 1.0102 ms/op 0.78
mainnet_e58758 - phase0 processSlashingsReset 831.00 ns/op 1.0420 us/op 0.80
mainnet_e58758 - phase0 processRandaoMixesReset 1.3320 us/op 1.5090 us/op 0.88
mainnet_e58758 - phase0 processHistoricalRootsUpdate 248.00 ns/op 152.00 ns/op 1.63
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.1720 us/op 1.3000 us/op 0.90
mainnet_e58758 - phase0 afterProcessEpoch 33.828 ms/op 34.877 ms/op 0.97
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.0977 ms/op 1.1322 ms/op 0.97
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.7186 ms/op 1.7956 ms/op 0.96
altair processInactivityUpdates - 250000 normalcase 10.593 ms/op 12.886 ms/op 0.82
altair processInactivityUpdates - 250000 worstcase 10.611 ms/op 13.308 ms/op 0.80
phase0 processRegistryUpdates - 250000 normalcase 2.3160 us/op 4.0690 us/op 0.57
phase0 processRegistryUpdates - 250000 badcase_full_deposits 142.34 us/op 158.65 us/op 0.90
phase0 processRegistryUpdates - 250000 worstcase 0.5 60.233 ms/op 70.288 ms/op 0.86
altair processRewardsAndPenalties - 250000 normalcase 15.882 ms/op 16.264 ms/op 0.98
altair processRewardsAndPenalties - 250000 worstcase 15.537 ms/op 15.980 ms/op 0.97
phase0 getAttestationDeltas - 250000 normalcase 5.1848 ms/op 5.8147 ms/op 0.89
phase0 getAttestationDeltas - 250000 worstcase 5.1639 ms/op 5.7397 ms/op 0.90
phase0 processSlashings - 250000 worstcase 68.422 us/op 68.787 us/op 0.99
altair processSyncCommitteeUpdates - 250000 9.7640 ms/op 10.701 ms/op 0.91
BeaconState.hashTreeRoot - No change 210.00 ns/op 209.00 ns/op 1.00
BeaconState.hashTreeRoot - 1 full validator 93.016 us/op 75.273 us/op 1.24
BeaconState.hashTreeRoot - 32 full validator 1.2608 ms/op 1.1809 ms/op 1.07
BeaconState.hashTreeRoot - 512 full validator 7.3354 ms/op 8.6784 ms/op 0.85
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 119.58 us/op 97.196 us/op 1.23
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.3660 ms/op 1.3795 ms/op 0.99
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 16.362 ms/op 14.543 ms/op 1.13
BeaconState.hashTreeRoot - 1 balances 82.407 us/op 78.841 us/op 1.05
BeaconState.hashTreeRoot - 32 balances 922.97 us/op 874.39 us/op 1.06
BeaconState.hashTreeRoot - 512 balances 6.4868 ms/op 5.7948 ms/op 1.12
BeaconState.hashTreeRoot - 250000 balances 155.75 ms/op 152.60 ms/op 1.02
aggregationBits - 2048 els - zipIndexesInBitList 19.945 us/op 21.466 us/op 0.93
regular array get 100000 times 22.752 us/op 23.668 us/op 0.96
wrappedArray get 100000 times 22.861 us/op 23.741 us/op 0.96
arrayWithProxy get 100000 times 10.126 ms/op 10.065 ms/op 1.01
ssz.Root.equals 21.410 ns/op 22.175 ns/op 0.97
byteArrayEquals 21.112 ns/op 22.032 ns/op 0.96
Buffer.compare 8.8660 ns/op 9.1160 ns/op 0.97
processSlot - 1 slots 11.593 us/op 10.135 us/op 1.14
processSlot - 32 slots 2.9149 ms/op 1.7319 ms/op 1.68
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 5.0080 ms/op 3.0860 ms/op 1.62
getCommitteeAssignments - req 1 vs - 250000 vc 1.6669 ms/op 1.7082 ms/op 0.98
getCommitteeAssignments - req 100 vs - 250000 vc 3.4077 ms/op 3.4717 ms/op 0.98
getCommitteeAssignments - req 1000 vs - 250000 vc 3.6693 ms/op 3.7483 ms/op 0.98
findModifiedValidators - 10000 modified validators 813.35 ms/op 770.72 ms/op 1.06
findModifiedValidators - 1000 modified validators 414.65 ms/op 529.31 ms/op 0.78
findModifiedValidators - 100 modified validators 278.55 ms/op 348.35 ms/op 0.80
findModifiedValidators - 10 modified validators 222.65 ms/op 237.64 ms/op 0.94
findModifiedValidators - 1 modified validators 156.72 ms/op 173.19 ms/op 0.90
findModifiedValidators - no difference 143.59 ms/op 171.50 ms/op 0.84
migrate state 1500000 validators, 3400 modified, 2000 new 3.9000 s/op 2.6846 s/op 1.45
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.6800 ns/op 3.8200 ns/op 0.96
state getBlockRootAtSlot - 250000 vs - 7PWei 382.47 ns/op 303.07 ns/op 1.26
computeProposerIndex 100000 validators 1.3183 ms/op 1.3289 ms/op 0.99
getNextSyncCommitteeIndices 1000 validators 2.8668 ms/op 2.8362 ms/op 1.01
getNextSyncCommitteeIndices 10000 validators 24.958 ms/op 25.183 ms/op 0.99
getNextSyncCommitteeIndices 100000 validators 82.626 ms/op 86.752 ms/op 0.95
computeProposers - vc 250000 549.80 us/op 561.12 us/op 0.98
computeEpochShuffling - vc 250000 38.459 ms/op 39.115 ms/op 0.98
getNextSyncCommittee - vc 250000 9.2268 ms/op 9.5636 ms/op 0.96
nodejs block root to RootHex using toHex 93.556 ns/op 95.760 ns/op 0.98
nodejs block root to RootHex using toRootHex 56.939 ns/op 60.459 ns/op 0.94
nodejs fromHex(blob) 893.96 us/op 953.59 us/op 0.94
nodejs fromHexInto(blob) 658.28 us/op 649.92 us/op 1.01
nodejs block root to RootHex using the deprecated toHexString 360.70 ns/op 546.10 ns/op 0.66
nodejs byteArrayEquals 32 bytes (block root) 25.910 ns/op 26.168 ns/op 0.99
nodejs byteArrayEquals 48 bytes (pubkey) 37.548 ns/op 38.063 ns/op 0.99
nodejs byteArrayEquals 96 bytes (signature) 35.684 ns/op 36.603 ns/op 0.97
nodejs byteArrayEquals 1024 bytes 44.320 ns/op 44.443 ns/op 1.00
nodejs byteArrayEquals 131072 bytes (blob) 1.7504 us/op 1.9345 us/op 0.90
browser block root to RootHex using toHex 145.01 ns/op 146.63 ns/op 0.99
browser block root to RootHex using toRootHex 132.14 ns/op 133.55 ns/op 0.99
browser fromHex(blob) 1.6197 ms/op 1.7402 ms/op 0.93
browser fromHexInto(blob) 593.75 us/op 646.68 us/op 0.92
browser block root to RootHex using the deprecated toHexString 440.49 ns/op 376.93 ns/op 1.17
browser byteArrayEquals 32 bytes (block root) 26.665 ns/op 28.567 ns/op 0.93
browser byteArrayEquals 48 bytes (pubkey) 37.698 ns/op 40.140 ns/op 0.94
browser byteArrayEquals 96 bytes (signature) 69.990 ns/op 74.855 ns/op 0.94
browser byteArrayEquals 1024 bytes 716.69 ns/op 766.75 ns/op 0.93
browser byteArrayEquals 131072 bytes (blob) 90.655 us/op 96.329 us/op 0.94

by benchmarkbot/action

The retroactive proposer-boost spec change from v1.7.0-alpha.1 is now
implemented, so `voting_source_beyond_two_epoch`,
`justified_update_always_if_better`, and `justified_update_not_realized_finality`
pass across all forks (altair → gloas, 21 fixtures total).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ensi321 ensi321 marked this pull request as ready for review May 1, 2026 07:46
@ensi321 ensi321 requested a review from a team as a code owner May 1, 2026 07:46
executionStatus,
dataAvailabilityStatus
dataAvailabilityStatus,
orphanedBlock.message.proposerIndex
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.

seems misleading because this requires an "expected proposer index" in terms of head view, may pass null instead?
same to others


let expectedProposerIndex: number | null = null;
const headState = this.getHeadState();
if (headState.epoch === blockEpoch) {
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.

we also have BeaconStateView.getBeaconProposer() but it only query from current epoch
looks like a good chance to clean that up
ideally we should be able to have this logic once

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.

Proposer reorg blocks if is_proposer_equivocation

2 participants