Skip to content

feat: reorg weak head when the proposer equivocated - #9929

Merged
nflaig merged 3 commits into
unstablefrom
nflaig/proposer-equivocation-reorg
Aug 31, 2026
Merged

feat: reorg weak head when the proposer equivocated#9929
nflaig merged 3 commits into
unstablefrom
nflaig/proposer-equivocation-reorg

Conversation

@nflaig

@nflaig nflaig commented Aug 27, 2026

Copy link
Copy Markdown
Member

Implement the proposer equivocation branch of get_proposer_head from ethereum/consensus-specs#4807, which reorgs a weak previous-slot head whose proposer is known to have equivocated:

elif all([head_weak, current_time_ok, proposer_equivocation]):
    return parent_node

This is the proposer side of the builder reveal safety argument that #9233 implemented the attester side of. A builder reveals once it sees a block with enough weight and no equivocation. If the proposer then publishes an equivocating block and the next proposer extends it, attesters withhold the boost via should_apply_proposer_boost, but for the equivocating block to actually be reorged the next proposer has to build on the parent, which is this branch. It lives in the phase0 spec so it applies pre-gloas as well.

  • getProposerHead returns the parent when the head is weak, from the previous slot and another block at the same slot from the same proposer is in fork choice, skipping the regular reorg conditions (head_late, ffg_competitive, finalization_ok, proposing_on_time, parent_strong). The boost worn off check stays a precondition for both branches, the spec asserts it before either
  • shouldOverrideForkChoiceUpdate mirrors the branch so the fcu skip at import and the payload attributes prediction in prepareNextSlot follow getProposerHead. It does not check is_head_weak, the head slot's attestations are still queued when it runs so the head is assumed weak, same as the regular branch
  • hasEquivocatingBlock takes a ptcTimelyOnly flag, should_apply_proposer_boost only counts PTC-timely siblings while is_proposer_equivocation counts any known block
  • the gloas parent payload status is preserved, parentBlock is already resolved via getParentPayloadStatus
  • link the is_proposer_equivocation, should_apply_proposer_boost and record_block_timeliness specrefs to their implementations and bump the get_proposer_head spec link, v1.4.0-beta.4 predates this branch

The existing check order and notReorgedReason values are unchanged, the new branch only runs ahead of them. Equivocating blocks reach fork choice since #9805, before that this could only trigger for blocks fetched via unknown block sync.

There are no spec vectors for this branch upstream, coverage is via the getProposerHead and shouldOverrideForkChoiceUpdate unit tables. The four reorg cases fail on unstable and pass here, and the get_proposer_head, reorg, should_override, ex_ante and should_apply_proposer_boost fork choice spec tests still pass.

Closes #9764

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

Copy link
Copy Markdown

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: d4e105d65c

鈩癸笍 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/fork-choice/src/forkChoice/forkChoice.ts
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Performance Report

鉁旓笍 no performance regression detected

Full benchmark results
Benchmark suite Current: 72acb29 Previous: 2fba076 Ratio
getPubkeys - native cache - req 1000 vs - 250000 vc 1.2411 ms/op 443.50 us/op 2.80
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.448 us/op 39.681 us/op 1.02
BLS verify - blst 928.46 us/op 889.45 us/op 1.04
BLS verifyMultipleSignatures 3 - blst 1.3547 ms/op 1.3302 ms/op 1.02
BLS verifyMultipleSignatures 8 - blst 2.3098 ms/op 2.2217 ms/op 1.04
BLS verifyMultipleSignatures 32 - blst 7.5447 ms/op 7.3459 ms/op 1.03
BLS verifyMultipleSignatures 64 - blst 14.358 ms/op 14.154 ms/op 1.01
BLS verifyMultipleSignatures 128 - blst 27.569 ms/op 26.647 ms/op 1.03
BLS deserializing 10000 signatures 639.38 ms/op 641.58 ms/op 1.00
BLS deserializing 100000 signatures 6.3354 s/op 6.3971 s/op 0.99
BLS verifyMultipleSignatures - same message - 3 - blst 913.02 us/op 967.32 us/op 0.94
BLS verifyMultipleSignatures - same message - 8 - blst 1.0321 ms/op 1.0940 ms/op 0.94
BLS verifyMultipleSignatures - same message - 32 - blst 1.6327 ms/op 1.7115 ms/op 0.95
BLS verifyMultipleSignatures - same message - 64 - blst 2.4101 ms/op 2.5360 ms/op 0.95
BLS verifyMultipleSignatures - same message - 128 - blst 3.9970 ms/op 4.1975 ms/op 0.95
BLS aggregatePubkeys 32 - blst 18.506 us/op 19.403 us/op 0.95
BLS aggregatePubkeys 128 - blst 66.823 us/op 70.292 us/op 0.95
getSlashingsAndExits - default max 37.492 us/op 54.189 us/op 0.69
getSlashingsAndExits - 2k 336.45 us/op 388.86 us/op 0.87
proposeBlockBody type=full, size=empty 721.30 us/op 1.0092 ms/op 0.71
isKnown best case - 1 super set check 194.00 ns/op 202.00 ns/op 0.96
isKnown normal case - 2 super set checks 165.00 ns/op 158.00 ns/op 1.04
isKnown worse case - 16 super set checks 164.00 ns/op 156.00 ns/op 1.05
validate api signedAggregateAndProof - struct 1.4675 ms/op 1.5161 ms/op 0.97
validate gossip signedAggregateAndProof - struct 1.4922 ms/op 1.5112 ms/op 0.99
batch validate gossip attestation - vc 640000 - chunk 32 130.08 us/op 131.12 us/op 0.99
batch validate gossip attestation - vc 640000 - chunk 64 108.32 us/op 111.90 us/op 0.97
batch validate gossip attestation - vc 640000 - chunk 128 98.170 us/op 103.64 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 256 96.078 us/op 101.55 us/op 0.95
bytes32 toHexString 272.00 ns/op 288.00 ns/op 0.94
bytes32 Buffer.toString(hex) 159.00 ns/op 168.00 ns/op 0.95
bytes32 Buffer.toString(hex) from Uint8Array 229.00 ns/op 246.00 ns/op 0.93
bytes32 Buffer.toString(hex) + 0x 161.00 ns/op 171.00 ns/op 0.94
Return object 10000 times 0.21780 ns/op 0.21690 ns/op 1.00
Throw Error 10000 times 3.3000 us/op 3.3541 us/op 0.98
toHex 97.641 ns/op 94.182 ns/op 1.04
Buffer.from 86.699 ns/op 85.076 ns/op 1.02
shared Buffer 59.321 ns/op 58.399 ns/op 1.02
fastMsgIdFn sha256 / 200 bytes 1.4920 us/op 1.4820 us/op 1.01
fastMsgIdFn h32 xxhash / 200 bytes 158.00 ns/op 155.00 ns/op 1.02
fastMsgIdFn h64 xxhash / 200 bytes 216.00 ns/op 200.00 ns/op 1.08
fastMsgIdFn sha256 / 1000 bytes 4.8090 us/op 4.7950 us/op 1.00
fastMsgIdFn h32 xxhash / 1000 bytes 246.00 ns/op 244.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 1000 bytes 269.00 ns/op 248.00 ns/op 1.08
fastMsgIdFn sha256 / 10000 bytes 42.472 us/op 42.326 us/op 1.00
fastMsgIdFn h32 xxhash / 10000 bytes 1.2820 us/op 1.3100 us/op 0.98
fastMsgIdFn h64 xxhash / 10000 bytes 833.00 ns/op 842.00 ns/op 0.99
send data - 1000 256B messages 4.0535 ms/op 4.3171 ms/op 0.94
send data - 1000 512B messages 5.0456 ms/op 5.6444 ms/op 0.89
send data - 1000 1024B messages 5.2734 ms/op 5.7523 ms/op 0.92
send data - 1000 1200B messages 6.0271 ms/op 7.9585 ms/op 0.76
send data - 1000 2048B messages 11.153 ms/op 12.103 ms/op 0.92
send data - 1000 4096B messages 36.745 ms/op 72.461 ms/op 0.51
send data - 1000 16384B messages 277.57 ms/op 355.80 ms/op 0.78
send data - 1000 65536B messages 1.8400 s/op 2.0484 s/op 0.90
enrSubnets - fastDeserialize 64 bits 711.00 ns/op 722.00 ns/op 0.98
enrSubnets - ssz BitVector 64 bits 257.00 ns/op 260.00 ns/op 0.99
enrSubnets - fastDeserialize 4 bits 94.000 ns/op 100.00 ns/op 0.94
enrSubnets - ssz BitVector 4 bits 264.00 ns/op 256.00 ns/op 1.03
prioritizePeers score -10:0 att 32-0.1 sync 2-0 201.65 us/op 200.44 us/op 1.01
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 231.73 us/op 227.90 us/op 1.02
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 335.37 us/op 325.03 us/op 1.03
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 571.14 us/op 588.59 us/op 0.97
prioritizePeers score 0:0 att 64-1 sync 4-1 726.99 us/op 691.75 us/op 1.05
array of 16000 items push then shift 1.3231 us/op 1.2560 us/op 1.05
LinkedList of 16000 items push then shift 7.2090 ns/op 7.7110 ns/op 0.93
array of 16000 items push then pop 78.776 ns/op 82.624 ns/op 0.95
LinkedList of 16000 items push then pop 6.0650 ns/op 6.1450 ns/op 0.99
array of 24000 items push then shift 1.9498 us/op 1.8776 us/op 1.04
LinkedList of 24000 items push then shift 6.9700 ns/op 7.0650 ns/op 0.99
array of 24000 items push then pop 114.06 ns/op 112.90 ns/op 1.01
LinkedList of 24000 items push then pop 6.0750 ns/op 6.0500 ns/op 1.00
intersect bitArray bitLen 8 3.9440 ns/op 3.9170 ns/op 1.01
intersect array and set length 8 29.732 ns/op 29.132 ns/op 1.02
intersect bitArray bitLen 128 23.794 ns/op 23.252 ns/op 1.02
intersect array and set length 128 506.89 ns/op 495.48 ns/op 1.02
bitArray.getTrueBitIndexes() bitLen 128 934.00 ns/op 922.00 ns/op 1.01
bitArray.getTrueBitIndexes() bitLen 248 1.6780 us/op 1.6710 us/op 1.00
bitArray.getTrueBitIndexes() bitLen 512 3.5250 us/op 3.6310 us/op 0.97
Full columns - reconstruct all 6 blobs 176.47 us/op 182.72 us/op 0.97
Full columns - reconstruct half of the blobs out of 6 74.124 us/op 77.658 us/op 0.95
Full columns - reconstruct single blob out of 6 35.612 us/op 83.725 us/op 0.43
Half columns - reconstruct all 6 blobs 382.96 ms/op 386.41 ms/op 0.99
Half columns - reconstruct half of the blobs out of 6 194.21 ms/op 194.79 ms/op 1.00
Half columns - reconstruct single blob out of 6 69.854 ms/op 71.562 ms/op 0.98
Set add up to 64 items then delete first 2.1187 us/op 1.6268 us/op 1.30
OrderedSet add up to 64 items then delete first 3.3122 us/op 2.4744 us/op 1.34
Set add up to 64 items then delete last 2.1631 us/op 1.8044 us/op 1.20
OrderedSet add up to 64 items then delete last 3.2568 us/op 2.7134 us/op 1.20
Set add up to 64 items then delete middle 2.0235 us/op 1.8159 us/op 1.11
OrderedSet add up to 64 items then delete middle 4.6751 us/op 4.1604 us/op 1.12
Set add up to 128 items then delete first 4.1073 us/op 3.6554 us/op 1.12
OrderedSet add up to 128 items then delete first 6.2609 us/op 5.6584 us/op 1.11
Set add up to 128 items then delete last 3.6770 us/op 3.4933 us/op 1.05
OrderedSet add up to 128 items then delete last 5.6475 us/op 5.2929 us/op 1.07
Set add up to 128 items then delete middle 3.6979 us/op 3.5401 us/op 1.04
OrderedSet add up to 128 items then delete middle 11.396 us/op 11.193 us/op 1.02
Set add up to 256 items then delete first 7.5873 us/op 7.3303 us/op 1.04
OrderedSet add up to 256 items then delete first 11.804 us/op 12.564 us/op 0.94
Set add up to 256 items then delete last 7.2539 us/op 7.1332 us/op 1.02
OrderedSet add up to 256 items then delete last 11.041 us/op 11.185 us/op 0.99
Set add up to 256 items then delete middle 7.1489 us/op 6.9831 us/op 1.02
OrderedSet add up to 256 items then delete middle 33.602 us/op 35.566 us/op 0.94
runFastConfirmationRules vc:100000 bc:96 eq:0 4.6928 ms/op 4.5803 ms/op 1.02
runFastConfirmationRules vc:600000 bc:96 eq:0 34.147 ms/op 37.173 ms/op 0.92
runFastConfirmationRules vc:1000000 bc:96 eq:0 57.872 ms/op 60.177 ms/op 0.96
runFastConfirmationRules vc:600000 bc:320 eq:0 35.026 ms/op 36.458 ms/op 0.96
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.1043 s/op 1.1408 s/op 0.97
pass gossip attestations to forkchoice per slot 2.6524 ms/op 3.1092 ms/op 0.85
forkChoice updateHead vc 100000 bc 64 eq 0 419.29 us/op 412.23 us/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 0 2.5147 ms/op 2.4526 ms/op 1.03
forkChoice updateHead vc 1000000 bc 64 eq 0 4.1860 ms/op 4.1496 ms/op 1.01
forkChoice updateHead vc 600000 bc 320 eq 0 2.5274 ms/op 2.5074 ms/op 1.01
forkChoice updateHead vc 600000 bc 1200 eq 0 2.5595 ms/op 2.5223 ms/op 1.01
forkChoice updateHead vc 600000 bc 7200 eq 0 2.9332 ms/op 4.2443 ms/op 0.69
forkChoice updateHead vc 600000 bc 64 eq 1000 2.3622 ms/op 2.4567 ms/op 0.96
forkChoice updateHead vc 600000 bc 64 eq 10000 2.4790 ms/op 2.5594 ms/op 0.97
forkChoice updateHead vc 600000 bc 64 eq 300000 7.0891 ms/op 7.0040 ms/op 1.01
forkChoice updateHead vc 600000 bc 64 eq 0 gloas boosted 2.4950 ms/op 2.4315 ms/op 1.03
computeDeltas 1400000 validators 0% inactive 12.319 ms/op 12.113 ms/op 1.02
computeDeltas 1400000 validators 10% inactive 11.653 ms/op 11.474 ms/op 1.02
computeDeltas 1400000 validators 20% inactive 10.993 ms/op 10.848 ms/op 1.01
computeDeltas 1400000 validators 50% inactive 8.9996 ms/op 8.8474 ms/op 1.02
computeDeltas 2100000 validators 0% inactive 18.516 ms/op 18.085 ms/op 1.02
computeDeltas 2100000 validators 10% inactive 17.523 ms/op 17.258 ms/op 1.02
computeDeltas 2100000 validators 20% inactive 16.511 ms/op 16.215 ms/op 1.02
computeDeltas 2100000 validators 50% inactive 11.075 ms/op 10.754 ms/op 1.03
altair processAttestation - 250000 vs - 7PWei normalcase 1.8478 ms/op 2.0965 ms/op 0.88
altair processAttestation - 250000 vs - 7PWei worstcase 2.4357 ms/op 2.9403 ms/op 0.83
altair processAttestation - setStatus - 1/6 committees join 105.05 us/op 100.14 us/op 1.05
altair processAttestation - setStatus - 1/3 committees join 198.92 us/op 192.47 us/op 1.03
altair processAttestation - setStatus - 1/2 committees join 281.18 us/op 291.87 us/op 0.96
altair processAttestation - setStatus - 2/3 committees join 353.64 us/op 357.36 us/op 0.99
altair processAttestation - setStatus - 4/5 committees join 505.85 us/op 528.69 us/op 0.96
altair processAttestation - setStatus - 100% committees join 589.75 us/op 605.13 us/op 0.97
altair processBlock - 250000 vs - 7PWei normalcase 4.6655 ms/op 5.7661 ms/op 0.81
altair processBlock - 250000 vs - 7PWei normalcase hashState 27.659 ms/op 22.666 ms/op 1.22
altair processBlock - 250000 vs - 7PWei worstcase 24.029 ms/op 26.392 ms/op 0.91
altair processBlock - 250000 vs - 7PWei worstcase hashState 58.245 ms/op 55.470 ms/op 1.05
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3957 ms/op 1.4003 ms/op 1.00
phase0 processBlock - 250000 vs - 7PWei worstcase 20.057 ms/op 21.843 ms/op 0.92
altair processEth1Data - 250000 vs - 7PWei normalcase 301.94 us/op 295.72 us/op 1.02
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.2230 us/op 3.1470 us/op 1.02
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 18.659 us/op 20.483 us/op 0.91
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.4070 us/op 5.8400 us/op 0.93
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.5530 us/op 3.6910 us/op 0.96
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 88.604 us/op 91.836 us/op 0.96
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4267 ms/op 1.5035 ms/op 0.95
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8469 ms/op 1.9254 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8544 ms/op 1.9099 ms/op 0.97
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.7541 ms/op 3.6537 ms/op 1.03
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.1900 ms/op 2.1256 ms/op 1.03
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.0064 ms/op 4.3866 ms/op 0.91
Tree 40 250000 create 349.15 ms/op 357.72 ms/op 0.98
Tree 40 250000 get(125000) 89.298 ns/op 92.136 ns/op 0.97
Tree 40 250000 set(125000) 967.52 ns/op 1.0036 us/op 0.96
Tree 40 250000 toArray() 16.674 ms/op 16.851 ms/op 0.99
Tree 40 250000 iterate all - toArray() + loop 14.004 ms/op 15.617 ms/op 0.90
Tree 40 250000 iterate all - get(i) 41.096 ms/op 40.154 ms/op 1.02
Array 250000 create 2.5392 ms/op 2.5397 ms/op 1.00
Array 250000 clone - spread 784.41 us/op 798.61 us/op 0.98
Array 250000 get(125000) 0.29100 ns/op 0.29400 ns/op 0.99
Array 250000 set(125000) 0.29200 ns/op 0.29600 ns/op 0.99
Array 250000 iterate all - loop 57.195 us/op 57.533 us/op 0.99
phase0 afterProcessEpoch - 250000 vs - 7PWei 65.224 ms/op 41.712 ms/op 1.56
Array.fill - length 1000000 4.4895 ms/op 5.0233 ms/op 0.89
Array push - length 1000000 16.129 ms/op 16.100 ms/op 1.00
Array.get 0.20209 ns/op 0.20599 ns/op 0.98
Uint8Array.get 0.24173 ns/op 0.25132 ns/op 0.96
phase0 beforeProcessEpoch - 250000 vs - 7PWei 17.485 ms/op 18.990 ms/op 0.92
altair processEpoch - mainnet_e81889 251.40 ms/op 251.03 ms/op 1.00
mainnet_e81889 - altair beforeProcessEpoch 40.627 ms/op 36.718 ms/op 1.11
mainnet_e81889 - altair processJustificationAndFinalization 5.3760 us/op 5.4030 us/op 1.00
mainnet_e81889 - altair processInactivityUpdates 4.2871 ms/op 6.9639 ms/op 0.62
mainnet_e81889 - altair processRewardsAndPenalties 18.239 ms/op 18.875 ms/op 0.97
mainnet_e81889 - altair processRegistryUpdates 555.00 ns/op 553.00 ns/op 1.00
mainnet_e81889 - altair processSlashings 137.00 ns/op 143.00 ns/op 0.96
mainnet_e81889 - altair processEth1DataReset 135.00 ns/op 136.00 ns/op 0.99
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.2951 ms/op 3.4364 ms/op 0.38
mainnet_e81889 - altair processSlashingsReset 691.00 ns/op 686.00 ns/op 1.01
mainnet_e81889 - altair processRandaoMixesReset 1.0170 us/op 936.00 ns/op 1.09
mainnet_e81889 - altair processHistoricalRootsUpdate 137.00 ns/op 138.00 ns/op 0.99
mainnet_e81889 - altair processParticipationFlagUpdates 445.00 ns/op 441.00 ns/op 1.01
mainnet_e81889 - altair processSyncCommitteeUpdates 111.00 ns/op 112.00 ns/op 0.99
mainnet_e81889 - altair afterProcessEpoch 41.721 ms/op 41.756 ms/op 1.00
capella processEpoch - mainnet_e217614 777.12 ms/op 841.19 ms/op 0.92
mainnet_e217614 - capella beforeProcessEpoch 81.174 ms/op 100.04 ms/op 0.81
mainnet_e217614 - capella processJustificationAndFinalization 5.1180 us/op 5.7720 us/op 0.89
mainnet_e217614 - capella processInactivityUpdates 12.853 ms/op 16.328 ms/op 0.79
mainnet_e217614 - capella processRewardsAndPenalties 96.128 ms/op 102.39 ms/op 0.94
mainnet_e217614 - capella processRegistryUpdates 4.3840 us/op 4.4980 us/op 0.97
mainnet_e217614 - capella processSlashings 143.00 ns/op 152.00 ns/op 0.94
mainnet_e217614 - capella processEth1DataReset 133.00 ns/op 143.00 ns/op 0.93
mainnet_e217614 - capella processEffectiveBalanceUpdates 14.493 ms/op 19.844 ms/op 0.73
mainnet_e217614 - capella processSlashingsReset 667.00 ns/op 708.00 ns/op 0.94
mainnet_e217614 - capella processRandaoMixesReset 1.0110 us/op 1.0150 us/op 1.00
mainnet_e217614 - capella processHistoricalRootsUpdate 136.00 ns/op 145.00 ns/op 0.94
mainnet_e217614 - capella processParticipationFlagUpdates 438.00 ns/op 465.00 ns/op 0.94
mainnet_e217614 - capella afterProcessEpoch 110.15 ms/op 112.84 ms/op 0.98
phase0 processEpoch - mainnet_e58758 241.65 ms/op 231.41 ms/op 1.04
mainnet_e58758 - phase0 beforeProcessEpoch 48.138 ms/op 58.386 ms/op 0.82
mainnet_e58758 - phase0 processJustificationAndFinalization 5.5610 us/op 5.3400 us/op 1.04
mainnet_e58758 - phase0 processRewardsAndPenalties 16.783 ms/op 17.008 ms/op 0.99
mainnet_e58758 - phase0 processRegistryUpdates 2.3010 us/op 2.2930 us/op 1.00
mainnet_e58758 - phase0 processSlashings 144.00 ns/op 144.00 ns/op 1.00
mainnet_e58758 - phase0 processEth1DataReset 141.00 ns/op 140.00 ns/op 1.01
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 955.55 us/op 831.46 us/op 1.15
mainnet_e58758 - phase0 processSlashingsReset 809.00 ns/op 907.00 ns/op 0.89
mainnet_e58758 - phase0 processRandaoMixesReset 1.0680 us/op 1.0210 us/op 1.05
mainnet_e58758 - phase0 processHistoricalRootsUpdate 143.00 ns/op 143.00 ns/op 1.00
mainnet_e58758 - phase0 processParticipationRecordUpdates 980.00 ns/op 986.00 ns/op 0.99
mainnet_e58758 - phase0 afterProcessEpoch 33.962 ms/op 34.351 ms/op 0.99
phase0 processEffectiveBalanceUpdates - 250000 normalcase 936.87 us/op 1.0932 ms/op 0.86
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5242 ms/op 1.6487 ms/op 0.92
altair processInactivityUpdates - 250000 normalcase 10.488 ms/op 12.301 ms/op 0.85
altair processInactivityUpdates - 250000 worstcase 10.577 ms/op 12.730 ms/op 0.83
phase0 processRegistryUpdates - 250000 normalcase 2.1330 us/op 2.4190 us/op 0.88
phase0 processRegistryUpdates - 250000 badcase_full_deposits 141.07 us/op 143.06 us/op 0.99
phase0 processRegistryUpdates - 250000 worstcase 0.5 49.929 ms/op 67.042 ms/op 0.74
altair processRewardsAndPenalties - 250000 normalcase 14.042 ms/op 15.601 ms/op 0.90
altair processRewardsAndPenalties - 250000 worstcase 13.587 ms/op 15.067 ms/op 0.90
phase0 getAttestationDeltas - 250000 normalcase 5.7200 ms/op 5.6268 ms/op 1.02
phase0 getAttestationDeltas - 250000 worstcase 14.410 ms/op 8.9656 ms/op 1.61
phase0 processSlashings - 250000 worstcase 56.848 us/op 62.723 us/op 0.91
altair processSyncCommitteeUpdates - 250000 9.3723 ms/op 11.271 ms/op 0.83
BeaconState.hashTreeRoot - No change 165.00 ns/op 174.00 ns/op 0.95
BeaconState.hashTreeRoot - 1 full validator 76.204 us/op 85.625 us/op 0.89
BeaconState.hashTreeRoot - 32 full validator 902.55 us/op 864.40 us/op 1.04
BeaconState.hashTreeRoot - 512 full validator 7.5543 ms/op 8.5757 ms/op 0.88
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 99.389 us/op 106.28 us/op 0.94
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.4801 ms/op 1.4935 ms/op 0.99
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 14.273 ms/op 19.649 ms/op 0.73
BeaconState.hashTreeRoot - 1 balances 88.670 us/op 81.789 us/op 1.08
BeaconState.hashTreeRoot - 32 balances 819.28 us/op 799.02 us/op 1.03
BeaconState.hashTreeRoot - 512 balances 5.8515 ms/op 6.6912 ms/op 0.87
BeaconState.hashTreeRoot - 250000 balances 158.12 ms/op 134.58 ms/op 1.17
aggregationBits - 2048 els - zipIndexesInBitList 19.324 us/op 19.706 us/op 0.98
regular array get 100000 times 23.180 us/op 23.188 us/op 1.00
wrappedArray get 100000 times 23.210 us/op 23.318 us/op 1.00
arrayWithProxy get 100000 times 10.099 ms/op 9.5666 ms/op 1.06
ssz.Root.equals 21.915 ns/op 21.711 ns/op 1.01
byteArrayEquals 21.699 ns/op 21.433 ns/op 1.01
Buffer.compare 9.0180 ns/op 8.9110 ns/op 1.01
processSlot - 1 slots 10.289 us/op 9.8560 us/op 1.04
processSlot - 32 slots 2.3814 ms/op 2.2350 ms/op 1.07
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 5.2911 ms/op 5.1954 ms/op 1.02
getCommitteeAssignments - req 1 vs - 250000 vc 1.7028 ms/op 1.6957 ms/op 1.00
getCommitteeAssignments - req 100 vs - 250000 vc 3.4738 ms/op 3.4891 ms/op 1.00
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7318 ms/op 3.7160 ms/op 1.00
findModifiedValidators - 10000 modified validators 843.37 ms/op 917.88 ms/op 0.92
findModifiedValidators - 1000 modified validators 435.32 ms/op 579.90 ms/op 0.75
findModifiedValidators - 100 modified validators 302.42 ms/op 402.31 ms/op 0.75
findModifiedValidators - 10 modified validators 266.84 ms/op 339.45 ms/op 0.79
findModifiedValidators - 1 modified validators 238.90 ms/op 209.28 ms/op 1.14
findModifiedValidators - no difference 229.83 ms/op 205.10 ms/op 1.12
migrate state 1500000 validators, 3400 modified, 2000 new 3.6699 s/op 3.1018 s/op 1.18
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.5500 ns/op 3.4400 ns/op 1.03
state getBlockRootAtSlot - 250000 vs - 7PWei 475.90 ns/op 412.57 ns/op 1.15
computeProposerIndex 100000 validators 1.4005 ms/op 1.3721 ms/op 1.02
getNextSyncCommitteeIndices 1000 validators 2.9661 ms/op 2.8958 ms/op 1.02
getNextSyncCommitteeIndices 10000 validators 26.864 ms/op 26.157 ms/op 1.03
getNextSyncCommitteeIndices 100000 validators 91.230 ms/op 88.619 ms/op 1.03
computeProposers - vc 250000 557.43 us/op 590.69 us/op 0.94
computeEpochShuffling - vc 250000 40.346 ms/op 38.721 ms/op 1.04
getNextSyncCommittee - vc 250000 9.7776 ms/op 9.5283 ms/op 1.03
nodejs block root to RootHex using toHex 99.859 ns/op 96.411 ns/op 1.04
nodejs block root to RootHex using toRootHex 65.685 ns/op 63.909 ns/op 1.03
nodejs fromHex(blob) 915.64 us/op 882.83 us/op 1.04
nodejs fromHexInto(blob) 663.06 us/op 626.83 us/op 1.06
nodejs block root to RootHex using the deprecated toHexString 599.03 ns/op 562.03 ns/op 1.07
nodejs byteArrayEquals 32 bytes (block root) 26.873 ns/op 26.131 ns/op 1.03
nodejs byteArrayEquals 48 bytes (pubkey) 38.644 ns/op 37.978 ns/op 1.02
nodejs byteArrayEquals 96 bytes (signature) 35.811 ns/op 34.857 ns/op 1.03
nodejs byteArrayEquals 1024 bytes 42.464 ns/op 41.839 ns/op 1.01
nodejs byteArrayEquals 131072 bytes (blob) 1.8013 us/op 1.7599 us/op 1.02
browser block root to RootHex using toHex 148.71 ns/op 144.16 ns/op 1.03
browser block root to RootHex using toRootHex 135.74 ns/op 131.10 ns/op 1.04
browser fromHex(blob) 1.7761 ms/op 1.7780 ms/op 1.00
browser fromHexInto(blob) 627.77 us/op 641.24 us/op 0.98
browser block root to RootHex using the deprecated toHexString 360.96 ns/op 385.75 ns/op 0.94
browser byteArrayEquals 32 bytes (block root) 26.789 ns/op 28.675 ns/op 0.93
browser byteArrayEquals 48 bytes (pubkey) 37.861 ns/op 40.370 ns/op 0.94
browser byteArrayEquals 96 bytes (signature) 71.450 ns/op 76.037 ns/op 0.94
browser byteArrayEquals 1024 bytes 722.88 ns/op 770.26 ns/op 0.94
browser byteArrayEquals 131072 bytes (blob) 91.988 us/op 97.578 us/op 0.94

by benchmarkbot/action

@nflaig

nflaig commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 2d72796b11

鈩癸笍 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".

@twoeths twoeths left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good to me
shouldOverrideForkChoiceUpdate() was not in the spec so we should also remove to avoid maintenance cost like in this PR cc @ensi321

@nflaig

nflaig commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

shouldOverrideForkChoiceUpdate() was not in the spec so we should also remove to avoid maintenance cost like in this PR

we need to keep this at least until after gloas since we cannot be sure that ELs allow to reorg back to parent block, I also don't really like that we do a FCU for a block that we know with high certainty that we will reorg anyways. After gloas this won't matter since right now we call FCU all the time when importing the execution payload and going back to EMPTY rather would depend on PTC votes

@ensi321

ensi321 commented Sep 2, 2026

Copy link
Copy Markdown
Member

looks good to me shouldOverrideForkChoiceUpdate() was not in the spec so we should also remove to avoid maintenance cost like in this PR cc @ensi321

@twoeths we have #9441 to track this. Should be done after gloas goes live

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Implement proposer-equivocation reorg in getProposerHead

3 participants