Skip to content

feat: add dependent root check when giving out proposer boost#9565

Merged
ensi321 merged 3 commits into
unstablefrom
nc/proposer-boost-dependent-root
Jul 3, 2026
Merged

feat: add dependent root check when giving out proposer boost#9565
ensi321 merged 3 commits into
unstablefrom
nc/proposer-boost-dependent-root

Conversation

@ensi321

@ensi321 ensi321 commented Jun 30, 2026

Copy link
Copy Markdown
Member

ensi321 and others added 2 commits June 29, 2026 20:49
Implements `is_same_dependent_root` condition in `update_proposer_boost_root`
(consensus-specs #5306). Proposer boost is now granted only when the imported
block shares the canonical head's proposer-shuffling dependent root for the
current epoch, withholding boost from blocks built on a divergent shuffling
branch. Falls back to granting the boost on ancestor-lookup failure to preserve
prior behavior.

Unskips the 3 altair fork_choice spec tests that exercised the changed condition
(justified_update_always_if_better, justified_update_not_realized_finality,
voting_source_beyond_two_epoch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ensi321 ensi321 requested a review from a team as a code owner June 30, 2026 07:02
@ensi321 ensi321 changed the title feat: add dependent root check when giving up proposer boost feat: add dependent root check when giving out proposer boost Jun 30, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements the "apply proposer boost if dependent roots match" condition (consensus-specs #5306) in the fork choice logic and re-enables the corresponding spec tests. A critical bug was identified in the newly added isProposerBoostSameDependentRoot helper, where a lookup failure returns true (granting the boost) instead of false (withholding the boost), which contradicts the inline comment and intended behavior.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/fork-choice/src/forkChoice/forkChoice.ts
const headDependentRoot = this.protoArray.getAncestorOrNull(headRootHex, dependentSlot)?.blockRoot;
const blockDependentRoot = this.protoArray.getAncestorOrNull(blockParentRootHex, dependentSlot)?.blockRoot;
// On lookup failure, we lean on the conservative side and withold the boost
if (headDependentRoot === undefined || blockDependentRoot === undefined) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think this happens only when the ancestor gets pruned. Not sure if we return true or false in this case. I think either is fine. Any thought? @twoeths

@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: 22203c0606

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/fork-choice/src/forkChoice/forkChoice.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Performance Alert ⚠️

Possible performance regression was detected for some benchmarks.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold.

Benchmark suite Current: de76c37 Previous: 171f602 Ratio
Full columns - reconstruct all 6 blobs 557.72 us/op 182.87 us/op 3.05
Full benchmark results
Benchmark suite Current: de76c37 Previous: 171f602 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.4381 ms/op 1.0786 ms/op 1.33
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 42.275 us/op 39.823 us/op 1.06
BLS verify - blst 759.35 us/op 766.29 us/op 0.99
BLS verifyMultipleSignatures 3 - blst 1.3586 ms/op 1.3692 ms/op 0.99
BLS verifyMultipleSignatures 8 - blst 2.1562 ms/op 2.1691 ms/op 0.99
BLS verifyMultipleSignatures 32 - blst 6.9300 ms/op 6.7801 ms/op 1.02
BLS verifyMultipleSignatures 64 - blst 13.728 ms/op 13.128 ms/op 1.05
BLS verifyMultipleSignatures 128 - blst 25.730 ms/op 25.614 ms/op 1.00
BLS deserializing 10000 signatures 652.10 ms/op 635.37 ms/op 1.03
BLS deserializing 100000 signatures 6.2794 s/op 6.3895 s/op 0.98
BLS verifyMultipleSignatures - same message - 3 - blst 733.78 us/op 828.68 us/op 0.89
BLS verifyMultipleSignatures - same message - 8 - blst 909.61 us/op 898.42 us/op 1.01
BLS verifyMultipleSignatures - same message - 32 - blst 1.4536 ms/op 1.5799 ms/op 0.92
BLS verifyMultipleSignatures - same message - 64 - blst 2.2387 ms/op 2.4534 ms/op 0.91
BLS verifyMultipleSignatures - same message - 128 - blst 3.9152 ms/op 4.0641 ms/op 0.96
BLS aggregatePubkeys 32 - blst 17.187 us/op 17.715 us/op 0.97
BLS aggregatePubkeys 128 - blst 61.066 us/op 63.464 us/op 0.96
getSlashingsAndExits - default max 52.172 us/op 52.724 us/op 0.99
getSlashingsAndExits - 2k 437.30 us/op 338.71 us/op 1.29
proposeBlockBody type=full, size=empty 600.94 us/op 738.20 us/op 0.81
isKnown best case - 1 super set check 173.00 ns/op 181.00 ns/op 0.96
isKnown normal case - 2 super set checks 160.00 ns/op 170.00 ns/op 0.94
isKnown worse case - 16 super set checks 158.00 ns/op 172.00 ns/op 0.92
validate api signedAggregateAndProof - struct 1.4779 ms/op 1.5296 ms/op 0.97
validate gossip signedAggregateAndProof - struct 1.4511 ms/op 1.5252 ms/op 0.95
batch validate gossip attestation - vc 640000 - chunk 32 108.78 us/op 106.97 us/op 1.02
batch validate gossip attestation - vc 640000 - chunk 64 98.282 us/op 96.390 us/op 1.02
batch validate gossip attestation - vc 640000 - chunk 128 90.513 us/op 88.638 us/op 1.02
batch validate gossip attestation - vc 640000 - chunk 256 90.472 us/op 84.643 us/op 1.07
bytes32 toHexString 280.00 ns/op 289.00 ns/op 0.97
bytes32 Buffer.toString(hex) 166.00 ns/op 167.00 ns/op 0.99
bytes32 Buffer.toString(hex) from Uint8Array 238.00 ns/op 240.00 ns/op 0.99
bytes32 Buffer.toString(hex) + 0x 166.00 ns/op 169.00 ns/op 0.98
Return object 10000 times 0.21030 ns/op 0.21350 ns/op 0.99
Throw Error 10000 times 3.3383 us/op 3.5591 us/op 0.94
toHex 95.844 ns/op 101.57 ns/op 0.94
Buffer.from 84.652 ns/op 91.185 ns/op 0.93
shared Buffer 58.150 ns/op 64.074 ns/op 0.91
fastMsgIdFn sha256 / 200 bytes 1.4540 us/op 1.4870 us/op 0.98
fastMsgIdFn h32 xxhash / 200 bytes 147.00 ns/op 157.00 ns/op 0.94
fastMsgIdFn h64 xxhash / 200 bytes 213.00 ns/op 204.00 ns/op 1.04
fastMsgIdFn sha256 / 1000 bytes 4.6000 us/op 4.7570 us/op 0.97
fastMsgIdFn h32 xxhash / 1000 bytes 237.00 ns/op 245.00 ns/op 0.97
fastMsgIdFn h64 xxhash / 1000 bytes 261.00 ns/op 249.00 ns/op 1.05
fastMsgIdFn sha256 / 10000 bytes 40.511 us/op 42.000 us/op 0.96
fastMsgIdFn h32 xxhash / 10000 bytes 1.2300 us/op 1.2900 us/op 0.95
fastMsgIdFn h64 xxhash / 10000 bytes 795.00 ns/op 833.00 ns/op 0.95
send data - 1000 256B messages 4.2438 ms/op 4.4161 ms/op 0.96
send data - 1000 512B messages 5.8906 ms/op 5.2045 ms/op 1.13
send data - 1000 1024B messages 5.5294 ms/op 5.3687 ms/op 1.03
send data - 1000 1200B messages 6.6777 ms/op 6.1498 ms/op 1.09
send data - 1000 2048B messages 10.359 ms/op 9.0268 ms/op 1.15
send data - 1000 4096B messages 23.942 ms/op 29.443 ms/op 0.81
send data - 1000 16384B messages 407.18 ms/op 227.87 ms/op 1.79
send data - 1000 65536B messages 1.3590 s/op 1.1219 s/op 1.21
enrSubnets - fastDeserialize 64 bits 729.00 ns/op 758.00 ns/op 0.96
enrSubnets - ssz BitVector 64 bits 255.00 ns/op 261.00 ns/op 0.98
enrSubnets - fastDeserialize 4 bits 96.000 ns/op 107.00 ns/op 0.90
enrSubnets - ssz BitVector 4 bits 257.00 ns/op 262.00 ns/op 0.98
prioritizePeers score -10:0 att 32-0.1 sync 2-0 202.84 us/op 206.79 us/op 0.98
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 232.85 us/op 246.68 us/op 0.94
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 342.09 us/op 342.27 us/op 1.00
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 596.30 us/op 595.36 us/op 1.00
prioritizePeers score 0:0 att 64-1 sync 4-1 702.76 us/op 695.53 us/op 1.01
array of 16000 items push then shift 1.2232 us/op 1.2961 us/op 0.94
LinkedList of 16000 items push then shift 7.4160 ns/op 6.8370 ns/op 1.08
array of 16000 items push then pop 68.715 ns/op 66.475 ns/op 1.03
LinkedList of 16000 items push then pop 5.9340 ns/op 6.0250 ns/op 0.98
array of 24000 items push then shift 1.8346 us/op 1.9117 us/op 0.96
LinkedList of 24000 items push then shift 7.2330 ns/op 6.3120 ns/op 1.15
array of 24000 items push then pop 97.801 ns/op 93.889 ns/op 1.04
LinkedList of 24000 items push then pop 6.1210 ns/op 5.9980 ns/op 1.02
intersect bitArray bitLen 8 4.7010 ns/op 4.7390 ns/op 0.99
intersect array and set length 8 29.755 ns/op 30.054 ns/op 0.99
intersect bitArray bitLen 128 23.812 ns/op 24.022 ns/op 0.99
intersect array and set length 128 495.37 ns/op 503.02 ns/op 0.98
bitArray.getTrueBitIndexes() bitLen 128 1.0110 us/op 1.0060 us/op 1.00
bitArray.getTrueBitIndexes() bitLen 248 1.7680 us/op 1.7440 us/op 1.01
bitArray.getTrueBitIndexes() bitLen 512 3.7010 us/op 3.5620 us/op 1.04
Full columns - reconstruct all 6 blobs 557.72 us/op 182.87 us/op 3.05
Full columns - reconstruct half of the blobs out of 6 202.37 us/op 68.143 us/op 2.97
Full columns - reconstruct single blob out of 6 36.710 us/op 35.210 us/op 1.04
Half columns - reconstruct all 6 blobs 394.33 ms/op 380.02 ms/op 1.04
Half columns - reconstruct half of the blobs out of 6 192.62 ms/op 193.11 ms/op 1.00
Half columns - reconstruct single blob out of 6 70.197 ms/op 69.374 ms/op 1.01
Set add up to 64 items then delete first 1.6302 us/op 1.6918 us/op 0.96
OrderedSet add up to 64 items then delete first 2.5399 us/op 2.5612 us/op 0.99
Set add up to 64 items then delete last 1.8837 us/op 1.9545 us/op 0.96
OrderedSet add up to 64 items then delete last 2.8370 us/op 2.8440 us/op 1.00
Set add up to 64 items then delete middle 1.8894 us/op 1.9388 us/op 0.97
OrderedSet add up to 64 items then delete middle 4.3022 us/op 4.3127 us/op 1.00
Set add up to 128 items then delete first 3.7363 us/op 3.9439 us/op 0.95
OrderedSet add up to 128 items then delete first 5.8172 us/op 5.8370 us/op 1.00
Set add up to 128 items then delete last 3.6201 us/op 3.7517 us/op 0.96
OrderedSet add up to 128 items then delete last 5.4023 us/op 5.4641 us/op 0.99
Set add up to 128 items then delete middle 3.5891 us/op 3.7511 us/op 0.96
OrderedSet add up to 128 items then delete middle 11.272 us/op 11.409 us/op 0.99
Set add up to 256 items then delete first 7.8080 us/op 7.6860 us/op 1.02
OrderedSet add up to 256 items then delete first 12.293 us/op 11.899 us/op 1.03
Set add up to 256 items then delete last 7.6636 us/op 7.5252 us/op 1.02
OrderedSet add up to 256 items then delete last 11.326 us/op 11.118 us/op 1.02
Set add up to 256 items then delete middle 7.2943 us/op 7.3772 us/op 0.99
OrderedSet add up to 256 items then delete middle 34.910 us/op 34.465 us/op 1.01
runFastConfirmationRules vc:100000 bc:96 eq:0 3.6230 us/op 4.0630 us/op 0.89
runFastConfirmationRules vc:600000 bc:96 eq:0 3.8930 us/op 3.8610 us/op 1.01
runFastConfirmationRules vc:1000000 bc:96 eq:0 4.0890 us/op 3.5420 us/op 1.15
runFastConfirmationRules vc:600000 bc:320 eq:0 9.3110 us/op 10.905 us/op 0.85
runFastConfirmationRules vc:600000 bc:1200 eq:0 40.906 us/op 35.030 us/op 1.17
runFastConfirmationRules vc:600000 bc:96 eq:1000 3.9660 us/op 3.4210 us/op 1.16
runFastConfirmationRules vc:600000 bc:96 eq:10000 3.8120 us/op 3.7120 us/op 1.03
runFastConfirmationRules vc:600000 bc:96 eq:300000 3.9420 us/op 3.8360 us/op 1.03
pass gossip attestations to forkchoice per slot 2.5821 ms/op 2.5391 ms/op 1.02
forkChoice updateHead vc 100000 bc 64 eq 0 402.11 us/op 487.42 us/op 0.82
forkChoice updateHead vc 600000 bc 64 eq 0 2.4132 ms/op 2.9132 ms/op 0.83
forkChoice updateHead vc 1000000 bc 64 eq 0 4.0316 ms/op 4.7725 ms/op 0.84
forkChoice updateHead vc 600000 bc 320 eq 0 2.4373 ms/op 2.9108 ms/op 0.84
forkChoice updateHead vc 600000 bc 1200 eq 0 2.4783 ms/op 2.9074 ms/op 0.85
forkChoice updateHead vc 600000 bc 7200 eq 0 3.0198 ms/op 3.2480 ms/op 0.93
forkChoice updateHead vc 600000 bc 64 eq 1000 2.4436 ms/op 3.0121 ms/op 0.81
forkChoice updateHead vc 600000 bc 64 eq 10000 2.4675 ms/op 3.1024 ms/op 0.80
forkChoice updateHead vc 600000 bc 64 eq 300000 6.6980 ms/op 7.4545 ms/op 0.90
computeDeltas 1400000 validators 0% inactive 12.291 ms/op 14.075 ms/op 0.87
computeDeltas 1400000 validators 10% inactive 11.478 ms/op 12.879 ms/op 0.89
computeDeltas 1400000 validators 20% inactive 10.494 ms/op 11.959 ms/op 0.88
computeDeltas 1400000 validators 50% inactive 8.1437 ms/op 9.3386 ms/op 0.87
computeDeltas 2100000 validators 0% inactive 18.386 ms/op 20.481 ms/op 0.90
computeDeltas 2100000 validators 10% inactive 17.061 ms/op 19.307 ms/op 0.88
computeDeltas 2100000 validators 20% inactive 15.628 ms/op 17.965 ms/op 0.87
computeDeltas 2100000 validators 50% inactive 10.559 ms/op 14.050 ms/op 0.75
altair processAttestation - 250000 vs - 7PWei normalcase 2.0014 ms/op 1.6945 ms/op 1.18
altair processAttestation - 250000 vs - 7PWei worstcase 3.0950 ms/op 2.4819 ms/op 1.25
altair processAttestation - setStatus - 1/6 committees join 93.981 us/op 108.78 us/op 0.86
altair processAttestation - setStatus - 1/3 committees join 185.63 us/op 201.77 us/op 0.92
altair processAttestation - setStatus - 1/2 committees join 273.41 us/op 292.05 us/op 0.94
altair processAttestation - setStatus - 2/3 committees join 351.19 us/op 382.40 us/op 0.92
altair processAttestation - setStatus - 4/5 committees join 500.95 us/op 517.82 us/op 0.97
altair processAttestation - setStatus - 100% committees join 588.69 us/op 603.90 us/op 0.97
altair processBlock - 250000 vs - 7PWei normalcase 4.1329 ms/op 2.9269 ms/op 1.41
altair processBlock - 250000 vs - 7PWei normalcase hashState 15.881 ms/op 11.663 ms/op 1.36
altair processBlock - 250000 vs - 7PWei worstcase 20.664 ms/op 19.070 ms/op 1.08
altair processBlock - 250000 vs - 7PWei worstcase hashState 40.627 ms/op 39.162 ms/op 1.04
phase0 processBlock - 250000 vs - 7PWei normalcase 1.2576 ms/op 1.2940 ms/op 0.97
phase0 processBlock - 250000 vs - 7PWei worstcase 16.228 ms/op 16.764 ms/op 0.97
altair processEth1Data - 250000 vs - 7PWei normalcase 300.24 us/op 316.96 us/op 0.95
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.3450 us/op 3.3790 us/op 0.99
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 23.505 us/op 22.090 us/op 1.06
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 7.2400 us/op 6.6530 us/op 1.09
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.5440 us/op 4.5750 us/op 0.77
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 93.601 us/op 100.05 us/op 0.94
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4466 ms/op 1.3762 ms/op 1.05
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8079 ms/op 1.8302 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8594 ms/op 1.8236 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.5885 ms/op 3.5969 ms/op 1.00
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0207 ms/op 2.0500 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 3.8865 ms/op 3.9557 ms/op 0.98
Tree 40 250000 create 310.61 ms/op 318.91 ms/op 0.97
Tree 40 250000 get(125000) 90.741 ns/op 109.20 ns/op 0.83
Tree 40 250000 set(125000) 962.10 ns/op 1.0922 us/op 0.88
Tree 40 250000 toArray() 12.478 ms/op 9.6024 ms/op 1.30
Tree 40 250000 iterate all - toArray() + loop 14.228 ms/op 9.7012 ms/op 1.47
Tree 40 250000 iterate all - get(i) 38.891 ms/op 34.353 ms/op 1.13
Array 250000 create 2.1506 ms/op 2.0771 ms/op 1.04
Array 250000 clone - spread 665.24 us/op 655.26 us/op 1.02
Array 250000 get(125000) 0.28500 ns/op 0.29600 ns/op 0.96
Array 250000 set(125000) 0.29200 ns/op 0.30200 ns/op 0.97
Array 250000 iterate all - loop 56.662 us/op 56.621 us/op 1.00
phase0 afterProcessEpoch - 250000 vs - 7PWei 39.397 ms/op 39.247 ms/op 1.00
Array.fill - length 1000000 1.9696 ms/op 2.2222 ms/op 0.89
Array push - length 1000000 10.168 ms/op 7.3663 ms/op 1.38
Array.get 0.20602 ns/op 0.20440 ns/op 1.01
Uint8Array.get 0.23309 ns/op 0.26171 ns/op 0.89
phase0 beforeProcessEpoch - 250000 vs - 7PWei 17.167 ms/op 11.822 ms/op 1.45
altair processEpoch - mainnet_e81889 245.57 ms/op 239.62 ms/op 1.02
mainnet_e81889 - altair beforeProcessEpoch 15.239 ms/op 14.171 ms/op 1.08
mainnet_e81889 - altair processJustificationAndFinalization 5.9560 us/op 4.6360 us/op 1.28
mainnet_e81889 - altair processInactivityUpdates 3.4874 ms/op 3.6174 ms/op 0.96
mainnet_e81889 - altair processRewardsAndPenalties 19.674 ms/op 17.253 ms/op 1.14
mainnet_e81889 - altair processRegistryUpdates 530.00 ns/op 533.00 ns/op 0.99
mainnet_e81889 - altair processSlashings 129.00 ns/op 143.00 ns/op 0.90
mainnet_e81889 - altair processEth1DataReset 131.00 ns/op 137.00 ns/op 0.96
mainnet_e81889 - altair processEffectiveBalanceUpdates 2.8153 ms/op 1.5262 ms/op 1.84
mainnet_e81889 - altair processSlashingsReset 676.00 ns/op 689.00 ns/op 0.98
mainnet_e81889 - altair processRandaoMixesReset 1.2050 us/op 970.00 ns/op 1.24
mainnet_e81889 - altair processHistoricalRootsUpdate 129.00 ns/op 136.00 ns/op 0.95
mainnet_e81889 - altair processParticipationFlagUpdates 435.00 ns/op 422.00 ns/op 1.03
mainnet_e81889 - altair processSyncCommitteeUpdates 104.00 ns/op 113.00 ns/op 0.92
mainnet_e81889 - altair afterProcessEpoch 41.385 ms/op 41.093 ms/op 1.01
capella processEpoch - mainnet_e217614 837.64 ms/op 724.23 ms/op 1.16
mainnet_e217614 - capella beforeProcessEpoch 58.171 ms/op 60.214 ms/op 0.97
mainnet_e217614 - capella processJustificationAndFinalization 6.0560 us/op 5.1180 us/op 1.18
mainnet_e217614 - capella processInactivityUpdates 13.765 ms/op 11.866 ms/op 1.16
mainnet_e217614 - capella processRewardsAndPenalties 91.229 ms/op 92.862 ms/op 0.98
mainnet_e217614 - capella processRegistryUpdates 4.2680 us/op 4.4280 us/op 0.96
mainnet_e217614 - capella processSlashings 127.00 ns/op 150.00 ns/op 0.85
mainnet_e217614 - capella processEth1DataReset 126.00 ns/op 139.00 ns/op 0.91
mainnet_e217614 - capella processEffectiveBalanceUpdates 12.863 ms/op 5.3985 ms/op 2.38
mainnet_e217614 - capella processSlashingsReset 661.00 ns/op 667.00 ns/op 0.99
mainnet_e217614 - capella processRandaoMixesReset 1.3830 us/op 1.0470 us/op 1.32
mainnet_e217614 - capella processHistoricalRootsUpdate 127.00 ns/op 140.00 ns/op 0.91
mainnet_e217614 - capella processParticipationFlagUpdates 426.00 ns/op 434.00 ns/op 0.98
mainnet_e217614 - capella afterProcessEpoch 105.47 ms/op 105.68 ms/op 1.00
phase0 processEpoch - mainnet_e58758 294.85 ms/op 264.49 ms/op 1.11
mainnet_e58758 - phase0 beforeProcessEpoch 66.461 ms/op 50.519 ms/op 1.32
mainnet_e58758 - phase0 processJustificationAndFinalization 6.2710 us/op 5.1460 us/op 1.22
mainnet_e58758 - phase0 processRewardsAndPenalties 15.728 ms/op 14.888 ms/op 1.06
mainnet_e58758 - phase0 processRegistryUpdates 2.1710 us/op 2.2520 us/op 0.96
mainnet_e58758 - phase0 processSlashings 248.00 ns/op 142.00 ns/op 1.75
mainnet_e58758 - phase0 processEth1DataReset 125.00 ns/op 135.00 ns/op 0.93
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 795.81 us/op 918.66 us/op 0.87
mainnet_e58758 - phase0 processSlashingsReset 864.00 ns/op 1.4500 us/op 0.60
mainnet_e58758 - phase0 processRandaoMixesReset 1.2740 us/op 998.00 ns/op 1.28
mainnet_e58758 - phase0 processHistoricalRootsUpdate 134.00 ns/op 147.00 ns/op 0.91
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.1660 us/op 1.0140 us/op 1.15
mainnet_e58758 - phase0 afterProcessEpoch 31.809 ms/op 32.811 ms/op 0.97
phase0 processEffectiveBalanceUpdates - 250000 normalcase 955.77 us/op 1.0084 ms/op 0.95
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5329 ms/op 1.6338 ms/op 0.94
altair processInactivityUpdates - 250000 normalcase 12.726 ms/op 10.523 ms/op 1.21
altair processInactivityUpdates - 250000 worstcase 11.190 ms/op 10.694 ms/op 1.05
phase0 processRegistryUpdates - 250000 normalcase 2.3910 us/op 2.1630 us/op 1.11
phase0 processRegistryUpdates - 250000 badcase_full_deposits 141.21 us/op 140.52 us/op 1.00
phase0 processRegistryUpdates - 250000 worstcase 0.5 68.764 ms/op 64.034 ms/op 1.07
altair processRewardsAndPenalties - 250000 normalcase 15.783 ms/op 13.156 ms/op 1.20
altair processRewardsAndPenalties - 250000 worstcase 15.191 ms/op 13.069 ms/op 1.16
phase0 getAttestationDeltas - 250000 normalcase 5.2535 ms/op 5.4714 ms/op 0.96
phase0 getAttestationDeltas - 250000 worstcase 5.3875 ms/op 5.4796 ms/op 0.98
phase0 processSlashings - 250000 worstcase 57.756 us/op 61.274 us/op 0.94
altair processSyncCommitteeUpdates - 250000 10.818 ms/op 10.056 ms/op 1.08
BeaconState.hashTreeRoot - No change 167.00 ns/op 179.00 ns/op 0.93
BeaconState.hashTreeRoot - 1 full validator 69.890 us/op 59.593 us/op 1.17
BeaconState.hashTreeRoot - 32 full validator 904.23 us/op 667.03 us/op 1.36
BeaconState.hashTreeRoot - 512 full validator 9.7722 ms/op 6.3604 ms/op 1.54
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 100.73 us/op 72.012 us/op 1.40
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.4128 ms/op 1.5054 ms/op 0.94
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 22.903 ms/op 18.732 ms/op 1.22
BeaconState.hashTreeRoot - 1 balances 87.182 us/op 79.534 us/op 1.10
BeaconState.hashTreeRoot - 32 balances 733.22 us/op 740.72 us/op 0.99
BeaconState.hashTreeRoot - 512 balances 7.5077 ms/op 5.5332 ms/op 1.36
BeaconState.hashTreeRoot - 250000 balances 130.84 ms/op 123.81 ms/op 1.06
aggregationBits - 2048 els - zipIndexesInBitList 20.932 us/op 21.433 us/op 0.98
regular array get 100000 times 23.223 us/op 23.436 us/op 0.99
wrappedArray get 100000 times 23.405 us/op 23.379 us/op 1.00
arrayWithProxy get 100000 times 9.9680 ms/op 12.999 ms/op 0.77
ssz.Root.equals 21.408 ns/op 21.881 ns/op 0.98
byteArrayEquals 21.358 ns/op 21.641 ns/op 0.99
Buffer.compare 8.7950 ns/op 9.0050 ns/op 0.98
processSlot - 1 slots 9.2090 us/op 10.161 us/op 0.91
processSlot - 32 slots 2.1807 ms/op 2.1868 ms/op 1.00
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.8144 ms/op 2.5608 ms/op 1.88
getCommitteeAssignments - req 1 vs - 250000 vc 1.6965 ms/op 1.6941 ms/op 1.00
getCommitteeAssignments - req 100 vs - 250000 vc 3.4606 ms/op 3.4729 ms/op 1.00
getCommitteeAssignments - req 1000 vs - 250000 vc 3.6938 ms/op 3.7385 ms/op 0.99
findModifiedValidators - 10000 modified validators 671.15 ms/op 827.19 ms/op 0.81
findModifiedValidators - 1000 modified validators 420.87 ms/op 603.32 ms/op 0.70
findModifiedValidators - 100 modified validators 341.69 ms/op 356.02 ms/op 0.96
findModifiedValidators - 10 modified validators 283.77 ms/op 300.57 ms/op 0.94
findModifiedValidators - 1 modified validators 173.31 ms/op 168.85 ms/op 1.03
findModifiedValidators - no difference 191.81 ms/op 185.11 ms/op 1.04
migrate state 1500000 validators, 3400 modified, 2000 new 3.3102 s/op 3.1717 s/op 1.04
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.6800 ns/op 3.8100 ns/op 0.97
state getBlockRootAtSlot - 250000 vs - 7PWei 419.98 ns/op 271.96 ns/op 1.54
computeProposerIndex 100000 validators 1.3785 ms/op 1.3654 ms/op 1.01
getNextSyncCommitteeIndices 1000 validators 2.9821 ms/op 2.9089 ms/op 1.03
getNextSyncCommitteeIndices 10000 validators 25.150 ms/op 25.663 ms/op 0.98
getNextSyncCommitteeIndices 100000 validators 86.721 ms/op 89.292 ms/op 0.97
computeProposers - vc 250000 553.67 us/op 581.08 us/op 0.95
computeEpochShuffling - vc 250000 39.830 ms/op 41.454 ms/op 0.96
getNextSyncCommittee - vc 250000 9.9311 ms/op 9.6061 ms/op 1.03
nodejs block root to RootHex using toHex 101.18 ns/op 102.04 ns/op 0.99
nodejs block root to RootHex using toRootHex 61.691 ns/op 66.874 ns/op 0.92
nodejs fromHex(blob) 815.88 us/op 853.01 us/op 0.96
nodejs fromHexInto(blob) 611.50 us/op 649.89 us/op 0.94
nodejs block root to RootHex using the deprecated toHexString 511.40 ns/op 484.48 ns/op 1.06
nodejs byteArrayEquals 32 bytes (block root) 25.174 ns/op 26.438 ns/op 0.95
nodejs byteArrayEquals 48 bytes (pubkey) 36.689 ns/op 38.212 ns/op 0.96
nodejs byteArrayEquals 96 bytes (signature) 33.269 ns/op 38.061 ns/op 0.87
nodejs byteArrayEquals 1024 bytes 39.570 ns/op 45.206 ns/op 0.88
nodejs byteArrayEquals 131072 bytes (blob) 1.7440 us/op 1.7797 us/op 0.98
browser block root to RootHex using toHex 142.97 ns/op 148.14 ns/op 0.97
browser block root to RootHex using toRootHex 128.47 ns/op 131.54 ns/op 0.98
browser fromHex(blob) 1.5660 ms/op 1.7388 ms/op 0.90
browser fromHexInto(blob) 619.22 us/op 665.57 us/op 0.93
browser block root to RootHex using the deprecated toHexString 517.52 ns/op 338.51 ns/op 1.53
browser byteArrayEquals 32 bytes (block root) 27.241 ns/op 28.260 ns/op 0.96
browser byteArrayEquals 48 bytes (pubkey) 39.176 ns/op 39.885 ns/op 0.98
browser byteArrayEquals 96 bytes (signature) 72.826 ns/op 74.583 ns/op 0.98
browser byteArrayEquals 1024 bytes 732.19 ns/op 755.39 ns/op 0.97
browser byteArrayEquals 131072 bytes (blob) 93.043 us/op 95.488 us/op 0.97

by benchmarkbot/action

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

the change looks good
one thing I found is we update proposer_boost_root before we call protoArray.onBlock(), which may fail
it makes more sense to update proposer_boost_root after protoArray.onBlock() similar to the spec (can assign a temp variable for that), same to updateCheckpoints()
could be done in a separate PR through

@ensi321 ensi321 merged commit d7859e9 into unstable Jul 3, 2026
18 of 19 checks passed
@ensi321 ensi321 deleted the nc/proposer-boost-dependent-root branch July 3, 2026 03:28
ensi321 added a commit that referenced this pull request Jul 3, 2026
`ProtoArray.onBlock` can potentially reject the block to be imported. So
we should update our fork choice store only after the import is
complete.

See
#9565 (review)
for more context

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
this.proposerBoostRoot === null &&
expectedProposerIndex !== null &&
block.proposerIndex === expectedProposerIndex
block.proposerIndex === expectedProposerIndex &&

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.

why are we still checking the proposer index, this should no longer be required, and allows us to remove some code we added in #9313

@ensi321 any reason you kept the index check?


/**
* Spec: phase0/fork-choice.md#update_proposer_boost_root (`is_same_dependent_root` condition,
* consensus-specs #5306). Proposer boost is only granted when the imported block shares the same

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.

consensus-specs #5306 we need to avoid these kind of reference imo, either add a full url or no reference at all

name.endsWith("altair/fork_choice/on_block/pyspec_tests/justified_update_always_if_better") ||
name.endsWith("altair/fork_choice/on_block/pyspec_tests/justified_update_not_realized_finality") ||
name.endsWith("altair/fork_choice/get_head/pyspec_tests/voting_source_beyond_two_epoch"),
name.includes("include_votes_another_empty_chain_without_enough_ffg_votes_current_epoch"))),

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.

@ensi321 do you know what's missing to pass the remaining tests?

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.

3 participants