Skip to content

fix: ignore parent bids at epoch boundary - #9756

Merged
nflaig merged 4 commits into
unstablefrom
nflaig/drop-parent-bids-at-epoch-boundary
Aug 4, 2026
Merged

fix: ignore parent bids at epoch boundary#9756
nflaig merged 4 commits into
unstablefrom
nflaig/drop-parent-bids-at-epoch-boundary

Conversation

@nflaig

@nflaig nflaig commented Aug 3, 2026

Copy link
Copy Markdown
Member

Follow-up to #9739

Ignore bids building on the head parent at epoch boundaries, since proposer-boost reorgs are disabled and validating them would regenerate an unusable parent state through the epoch transition.

@nflaig
nflaig marked this pull request as ready for review August 3, 2026 11:12
@nflaig
nflaig requested a review from a team as a code owner August 3, 2026 11:12
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Performance Report

鉁旓笍 no performance regression detected

Full benchmark results
Benchmark suite Current: 2d15e3e Previous: cae84b6 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 878.06 us/op 1.3213 ms/op 0.66
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.003 us/op 41.199 us/op 0.97
BLS verify - blst 759.68 us/op 783.89 us/op 0.97
BLS verifyMultipleSignatures 3 - blst 1.3744 ms/op 1.3795 ms/op 1.00
BLS verifyMultipleSignatures 8 - blst 2.1871 ms/op 2.1870 ms/op 1.00
BLS verifyMultipleSignatures 32 - blst 6.8677 ms/op 6.9897 ms/op 0.98
BLS verifyMultipleSignatures 64 - blst 13.281 ms/op 13.805 ms/op 0.96
BLS verifyMultipleSignatures 128 - blst 25.743 ms/op 26.036 ms/op 0.99
BLS deserializing 10000 signatures 641.86 ms/op 696.07 ms/op 0.92
BLS deserializing 100000 signatures 6.3945 s/op 6.8769 s/op 0.93
BLS verifyMultipleSignatures - same message - 3 - blst 821.79 us/op 811.28 us/op 1.01
BLS verifyMultipleSignatures - same message - 8 - blst 938.78 us/op 963.34 us/op 0.97
BLS verifyMultipleSignatures - same message - 32 - blst 1.4531 ms/op 1.5604 ms/op 0.93
BLS verifyMultipleSignatures - same message - 64 - blst 2.3781 ms/op 2.4622 ms/op 0.97
BLS verifyMultipleSignatures - same message - 128 - blst 4.0966 ms/op 4.1505 ms/op 0.99
BLS aggregatePubkeys 32 - blst 17.841 us/op 17.794 us/op 1.00
BLS aggregatePubkeys 128 - blst 63.564 us/op 63.382 us/op 1.00
getSlashingsAndExits - default max 46.431 us/op 50.375 us/op 0.92
getSlashingsAndExits - 2k 327.50 us/op 377.31 us/op 0.87
proposeBlockBody type=full, size=empty 709.49 us/op 766.41 us/op 0.93
isKnown best case - 1 super set check 177.00 ns/op 176.00 ns/op 1.01
isKnown normal case - 2 super set checks 168.00 ns/op 164.00 ns/op 1.02
isKnown worse case - 16 super set checks 168.00 ns/op 163.00 ns/op 1.03
validate api signedAggregateAndProof - struct 1.5355 ms/op 1.5427 ms/op 1.00
validate gossip signedAggregateAndProof - struct 1.5334 ms/op 1.5382 ms/op 1.00
batch validate gossip attestation - vc 640000 - chunk 32 105.33 us/op 107.64 us/op 0.98
batch validate gossip attestation - vc 640000 - chunk 64 93.082 us/op 93.464 us/op 1.00
batch validate gossip attestation - vc 640000 - chunk 128 86.923 us/op 87.474 us/op 0.99
batch validate gossip attestation - vc 640000 - chunk 256 84.874 us/op 83.311 us/op 1.02
bytes32 toHexString 289.00 ns/op 289.00 ns/op 1.00
bytes32 Buffer.toString(hex) 169.00 ns/op 167.00 ns/op 1.01
bytes32 Buffer.toString(hex) from Uint8Array 237.00 ns/op 234.00 ns/op 1.01
bytes32 Buffer.toString(hex) + 0x 169.00 ns/op 172.00 ns/op 0.98
Return object 10000 times 0.21410 ns/op 0.21450 ns/op 1.00
Throw Error 10000 times 3.3696 us/op 3.4112 us/op 0.99
toHex 99.764 ns/op 99.839 ns/op 1.00
Buffer.from 92.318 ns/op 89.679 ns/op 1.03
shared Buffer 64.695 ns/op 63.600 ns/op 1.02
fastMsgIdFn sha256 / 200 bytes 1.4900 us/op 1.4680 us/op 1.01
fastMsgIdFn h32 xxhash / 200 bytes 156.00 ns/op 154.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 200 bytes 209.00 ns/op 231.00 ns/op 0.90
fastMsgIdFn sha256 / 1000 bytes 4.7600 us/op 4.8080 us/op 0.99
fastMsgIdFn h32 xxhash / 1000 bytes 247.00 ns/op 245.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 1000 bytes 259.00 ns/op 253.00 ns/op 1.02
fastMsgIdFn sha256 / 10000 bytes 42.109 us/op 42.291 us/op 1.00
fastMsgIdFn h32 xxhash / 10000 bytes 1.2720 us/op 1.3380 us/op 0.95
fastMsgIdFn h64 xxhash / 10000 bytes 826.00 ns/op 880.00 ns/op 0.94
send data - 1000 256B messages 4.2872 ms/op 4.6133 ms/op 0.93
send data - 1000 512B messages 5.0893 ms/op 5.6682 ms/op 0.90
send data - 1000 1024B messages 5.4989 ms/op 5.4200 ms/op 1.01
send data - 1000 1200B messages 6.1870 ms/op 9.2144 ms/op 0.67
send data - 1000 2048B messages 9.7917 ms/op 20.524 ms/op 0.48
send data - 1000 4096B messages 63.962 ms/op 119.45 ms/op 0.54
send data - 1000 16384B messages 328.75 ms/op 339.24 ms/op 0.97
send data - 1000 65536B messages 1.4083 s/op 1.5108 s/op 0.93
enrSubnets - fastDeserialize 64 bits 753.00 ns/op 757.00 ns/op 0.99
enrSubnets - ssz BitVector 64 bits 267.00 ns/op 263.00 ns/op 1.02
enrSubnets - fastDeserialize 4 bits 100.00 ns/op 96.000 ns/op 1.04
enrSubnets - ssz BitVector 4 bits 264.00 ns/op 266.00 ns/op 0.99
prioritizePeers score -10:0 att 32-0.1 sync 2-0 203.10 us/op 201.38 us/op 1.01
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 230.08 us/op 230.13 us/op 1.00
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 335.97 us/op 331.09 us/op 1.01
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 599.98 us/op 591.28 us/op 1.01
prioritizePeers score 0:0 att 64-1 sync 4-1 697.85 us/op 690.49 us/op 1.01
array of 16000 items push then shift 1.3087 us/op 1.3075 us/op 1.00
LinkedList of 16000 items push then shift 7.0650 ns/op 6.8310 ns/op 1.03
array of 16000 items push then pop 63.859 ns/op 68.475 ns/op 0.93
LinkedList of 16000 items push then pop 6.0130 ns/op 6.0010 ns/op 1.00
array of 24000 items push then shift 1.9243 us/op 1.9393 us/op 0.99
LinkedList of 24000 items push then shift 6.3800 ns/op 6.5780 ns/op 0.97
array of 24000 items push then pop 87.464 ns/op 95.239 ns/op 0.92
LinkedList of 24000 items push then pop 5.9640 ns/op 6.0470 ns/op 0.99
intersect bitArray bitLen 8 3.8660 ns/op 3.9120 ns/op 0.99
intersect array and set length 8 30.131 ns/op 30.019 ns/op 1.00
intersect bitArray bitLen 128 23.265 ns/op 23.555 ns/op 0.99
intersect array and set length 128 504.81 ns/op 503.76 ns/op 1.00
bitArray.getTrueBitIndexes() bitLen 128 919.00 ns/op 928.00 ns/op 0.99
bitArray.getTrueBitIndexes() bitLen 248 1.6330 us/op 1.6640 us/op 0.98
bitArray.getTrueBitIndexes() bitLen 512 3.3990 us/op 3.5090 us/op 0.97
Full columns - reconstruct all 6 blobs 112.78 us/op 188.71 us/op 0.60
Full columns - reconstruct half of the blobs out of 6 112.20 us/op 72.858 us/op 1.54
Full columns - reconstruct single blob out of 6 34.624 us/op 32.741 us/op 1.06
Half columns - reconstruct all 6 blobs 379.00 ms/op 385.88 ms/op 0.98
Half columns - reconstruct half of the blobs out of 6 191.51 ms/op 195.85 ms/op 0.98
Half columns - reconstruct single blob out of 6 67.200 ms/op 69.763 ms/op 0.96
Set add up to 64 items then delete first 1.6708 us/op 1.6815 us/op 0.99
OrderedSet add up to 64 items then delete first 2.5355 us/op 2.5333 us/op 1.00
Set add up to 64 items then delete last 1.8985 us/op 1.8921 us/op 1.00
OrderedSet add up to 64 items then delete last 2.7836 us/op 2.8121 us/op 0.99
Set add up to 64 items then delete middle 1.9076 us/op 1.8922 us/op 1.01
OrderedSet add up to 64 items then delete middle 4.2410 us/op 4.3004 us/op 0.99
Set add up to 128 items then delete first 3.7633 us/op 3.7887 us/op 0.99
OrderedSet add up to 128 items then delete first 5.9120 us/op 5.7929 us/op 1.02
Set add up to 128 items then delete last 3.6355 us/op 3.7757 us/op 0.96
OrderedSet add up to 128 items then delete last 5.3442 us/op 5.4196 us/op 0.99
Set add up to 128 items then delete middle 3.6546 us/op 3.6416 us/op 1.00
OrderedSet add up to 128 items then delete middle 11.458 us/op 11.343 us/op 1.01
Set add up to 256 items then delete first 7.4360 us/op 7.8472 us/op 0.95
OrderedSet add up to 256 items then delete first 11.694 us/op 12.387 us/op 0.94
Set add up to 256 items then delete last 7.3519 us/op 7.1955 us/op 1.02
OrderedSet add up to 256 items then delete last 11.465 us/op 11.391 us/op 1.01
Set add up to 256 items then delete middle 7.2710 us/op 7.3116 us/op 0.99
OrderedSet add up to 256 items then delete middle 34.819 us/op 35.325 us/op 0.99
runFastConfirmationRules vc:100000 bc:96 eq:0 4.7947 ms/op 5.7360 ms/op 0.84
runFastConfirmationRules vc:600000 bc:96 eq:0 34.457 ms/op 34.704 ms/op 0.99
runFastConfirmationRules vc:1000000 bc:96 eq:0 58.586 ms/op 57.868 ms/op 1.01
runFastConfirmationRules vc:600000 bc:320 eq:0 33.770 ms/op 34.917 ms/op 0.97
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.0862 s/op 1.2857 s/op 0.84
pass gossip attestations to forkchoice per slot 2.5880 ms/op 2.6365 ms/op 0.98
forkChoice updateHead vc 100000 bc 64 eq 0 448.48 us/op 429.30 us/op 1.04
forkChoice updateHead vc 600000 bc 64 eq 0 2.6503 ms/op 2.5568 ms/op 1.04
forkChoice updateHead vc 1000000 bc 64 eq 0 4.5120 ms/op 4.2154 ms/op 1.07
forkChoice updateHead vc 600000 bc 320 eq 0 2.7225 ms/op 2.5412 ms/op 1.07
forkChoice updateHead vc 600000 bc 1200 eq 0 2.7399 ms/op 2.5738 ms/op 1.06
forkChoice updateHead vc 600000 bc 7200 eq 0 3.0811 ms/op 3.0221 ms/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 1000 2.6821 ms/op 2.6705 ms/op 1.00
forkChoice updateHead vc 600000 bc 64 eq 10000 2.7761 ms/op 2.7830 ms/op 1.00
forkChoice updateHead vc 600000 bc 64 eq 300000 6.7133 ms/op 6.5625 ms/op 1.02
computeDeltas 1400000 validators 0% inactive 13.239 ms/op 13.093 ms/op 1.01
computeDeltas 1400000 validators 10% inactive 12.406 ms/op 12.239 ms/op 1.01
computeDeltas 1400000 validators 20% inactive 11.695 ms/op 11.578 ms/op 1.01
computeDeltas 1400000 validators 50% inactive 9.4848 ms/op 9.2188 ms/op 1.03
computeDeltas 2100000 validators 0% inactive 20.186 ms/op 19.122 ms/op 1.06
computeDeltas 2100000 validators 10% inactive 18.934 ms/op 18.206 ms/op 1.04
computeDeltas 2100000 validators 20% inactive 17.892 ms/op 17.362 ms/op 1.03
computeDeltas 2100000 validators 50% inactive 14.434 ms/op 13.964 ms/op 1.03
altair processAttestation - 250000 vs - 7PWei normalcase 1.6757 ms/op 1.6031 ms/op 1.05
altair processAttestation - 250000 vs - 7PWei worstcase 2.4430 ms/op 2.4303 ms/op 1.01
altair processAttestation - setStatus - 1/6 committees join 101.66 us/op 99.542 us/op 1.02
altair processAttestation - setStatus - 1/3 committees join 210.10 us/op 203.08 us/op 1.03
altair processAttestation - setStatus - 1/2 committees join 293.41 us/op 285.47 us/op 1.03
altair processAttestation - setStatus - 2/3 committees join 375.95 us/op 368.87 us/op 1.02
altair processAttestation - setStatus - 4/5 committees join 512.05 us/op 500.14 us/op 1.02
altair processAttestation - setStatus - 100% committees join 612.55 us/op 591.07 us/op 1.04
altair processBlock - 250000 vs - 7PWei normalcase 2.8807 ms/op 2.9231 ms/op 0.99
altair processBlock - 250000 vs - 7PWei normalcase hashState 14.760 ms/op 11.980 ms/op 1.23
altair processBlock - 250000 vs - 7PWei worstcase 19.664 ms/op 20.360 ms/op 0.97
altair processBlock - 250000 vs - 7PWei worstcase hashState 38.461 ms/op 40.699 ms/op 0.94
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3486 ms/op 1.3383 ms/op 1.01
phase0 processBlock - 250000 vs - 7PWei worstcase 17.885 ms/op 17.387 ms/op 1.03
altair processEth1Data - 250000 vs - 7PWei normalcase 296.76 us/op 314.49 us/op 0.94
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 5.1680 us/op 3.6160 us/op 1.43
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 21.304 us/op 22.238 us/op 0.96
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.7280 us/op 6.4820 us/op 0.88
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.5520 us/op 4.4990 us/op 0.79
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 95.775 us/op 101.57 us/op 0.94
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.3787 ms/op 1.4358 ms/op 0.96
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8154 ms/op 1.9006 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8143 ms/op 1.8793 ms/op 0.97
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.6841 ms/op 3.7384 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0929 ms/op 2.0744 ms/op 1.01
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.0663 ms/op 4.0258 ms/op 1.01
Tree 40 250000 create 314.08 ms/op 309.88 ms/op 1.01
Tree 40 250000 get(125000) 103.20 ns/op 102.83 ns/op 1.00
Tree 40 250000 set(125000) 1.0832 us/op 1.0458 us/op 1.04
Tree 40 250000 toArray() 9.4102 ms/op 9.4809 ms/op 0.99
Tree 40 250000 iterate all - toArray() + loop 9.2945 ms/op 9.6840 ms/op 0.96
Tree 40 250000 iterate all - get(i) 35.829 ms/op 35.625 ms/op 1.01
Array 250000 create 2.0813 ms/op 2.1359 ms/op 0.97
Array 250000 clone - spread 656.35 us/op 690.89 us/op 0.95
Array 250000 get(125000) 0.29700 ns/op 0.29500 ns/op 1.01
Array 250000 set(125000) 0.29800 ns/op 0.29800 ns/op 1.00
Array 250000 iterate all - loop 57.310 us/op 57.563 us/op 1.00
phase0 afterProcessEpoch - 250000 vs - 7PWei 42.139 ms/op 39.454 ms/op 1.07
Array.fill - length 1000000 2.2188 ms/op 2.2669 ms/op 0.98
Array push - length 1000000 7.8424 ms/op 7.9199 ms/op 0.99
Array.get 0.21075 ns/op 0.20333 ns/op 1.04
Uint8Array.get 0.24101 ns/op 0.24538 ns/op 0.98
phase0 beforeProcessEpoch - 250000 vs - 7PWei 16.740 ms/op 11.979 ms/op 1.40
altair processEpoch - mainnet_e81889 266.05 ms/op 241.53 ms/op 1.10
mainnet_e81889 - altair beforeProcessEpoch 36.102 ms/op 14.061 ms/op 2.57
mainnet_e81889 - altair processJustificationAndFinalization 6.0130 us/op 5.1870 us/op 1.16
mainnet_e81889 - altair processInactivityUpdates 3.6208 ms/op 3.5402 ms/op 1.02
mainnet_e81889 - altair processRewardsAndPenalties 20.389 ms/op 16.717 ms/op 1.22
mainnet_e81889 - altair processRegistryUpdates 572.00 ns/op 562.00 ns/op 1.02
mainnet_e81889 - altair processSlashings 158.00 ns/op 145.00 ns/op 1.09
mainnet_e81889 - altair processEth1DataReset 148.00 ns/op 138.00 ns/op 1.07
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.2338 ms/op 1.3458 ms/op 0.92
mainnet_e81889 - altair processSlashingsReset 721.00 ns/op 710.00 ns/op 1.02
mainnet_e81889 - altair processRandaoMixesReset 1.1650 us/op 1.0230 us/op 1.14
mainnet_e81889 - altair processHistoricalRootsUpdate 148.00 ns/op 141.00 ns/op 1.05
mainnet_e81889 - altair processParticipationFlagUpdates 461.00 ns/op 442.00 ns/op 1.04
mainnet_e81889 - altair processSyncCommitteeUpdates 115.00 ns/op 110.00 ns/op 1.05
mainnet_e81889 - altair afterProcessEpoch 42.519 ms/op 42.273 ms/op 1.01
capella processEpoch - mainnet_e217614 735.12 ms/op 739.38 ms/op 0.99
mainnet_e217614 - capella beforeProcessEpoch 56.819 ms/op 56.807 ms/op 1.00
mainnet_e217614 - capella processJustificationAndFinalization 5.3860 us/op 5.2760 us/op 1.02
mainnet_e217614 - capella processInactivityUpdates 12.641 ms/op 11.632 ms/op 1.09
mainnet_e217614 - capella processRewardsAndPenalties 84.726 ms/op 85.280 ms/op 0.99
mainnet_e217614 - capella processRegistryUpdates 4.5720 us/op 4.4460 us/op 1.03
mainnet_e217614 - capella processSlashings 160.00 ns/op 143.00 ns/op 1.12
mainnet_e217614 - capella processEth1DataReset 155.00 ns/op 136.00 ns/op 1.14
mainnet_e217614 - capella processEffectiveBalanceUpdates 5.2753 ms/op 5.6245 ms/op 0.94
mainnet_e217614 - capella processSlashingsReset 697.00 ns/op 676.00 ns/op 1.03
mainnet_e217614 - capella processRandaoMixesReset 1.1700 us/op 1.0570 us/op 1.11
mainnet_e217614 - capella processHistoricalRootsUpdate 148.00 ns/op 137.00 ns/op 1.08
mainnet_e217614 - capella processParticipationFlagUpdates 461.00 ns/op 442.00 ns/op 1.04
mainnet_e217614 - capella afterProcessEpoch 110.21 ms/op 109.46 ms/op 1.01
phase0 processEpoch - mainnet_e58758 264.74 ms/op 261.84 ms/op 1.01
mainnet_e58758 - phase0 beforeProcessEpoch 49.343 ms/op 55.796 ms/op 0.88
mainnet_e58758 - phase0 processJustificationAndFinalization 5.4930 us/op 5.7200 us/op 0.96
mainnet_e58758 - phase0 processRewardsAndPenalties 16.632 ms/op 14.809 ms/op 1.12
mainnet_e58758 - phase0 processRegistryUpdates 2.2470 us/op 2.3010 us/op 0.98
mainnet_e58758 - phase0 processSlashings 148.00 ns/op 143.00 ns/op 1.03
mainnet_e58758 - phase0 processEth1DataReset 153.00 ns/op 135.00 ns/op 1.13
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 882.28 us/op 1.1598 ms/op 0.76
mainnet_e58758 - phase0 processSlashingsReset 807.00 ns/op 834.00 ns/op 0.97
mainnet_e58758 - phase0 processRandaoMixesReset 1.1220 us/op 1.1740 us/op 0.96
mainnet_e58758 - phase0 processHistoricalRootsUpdate 148.00 ns/op 139.00 ns/op 1.06
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.0430 us/op 1.0090 us/op 1.03
mainnet_e58758 - phase0 afterProcessEpoch 32.741 ms/op 33.672 ms/op 0.97
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.1182 ms/op 1.0918 ms/op 1.02
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.2284 ms/op 1.6316 ms/op 0.75
altair processInactivityUpdates - 250000 normalcase 10.541 ms/op 10.452 ms/op 1.01
altair processInactivityUpdates - 250000 worstcase 10.559 ms/op 10.430 ms/op 1.01
phase0 processRegistryUpdates - 250000 normalcase 2.4270 us/op 2.3420 us/op 1.04
phase0 processRegistryUpdates - 250000 badcase_full_deposits 148.81 us/op 142.94 us/op 1.04
phase0 processRegistryUpdates - 250000 worstcase 0.5 62.631 ms/op 53.058 ms/op 1.18
altair processRewardsAndPenalties - 250000 normalcase 13.638 ms/op 13.127 ms/op 1.04
altair processRewardsAndPenalties - 250000 worstcase 12.860 ms/op 12.470 ms/op 1.03
phase0 getAttestationDeltas - 250000 normalcase 5.3948 ms/op 5.4389 ms/op 0.99
phase0 getAttestationDeltas - 250000 worstcase 5.3429 ms/op 5.5022 ms/op 0.97
phase0 processSlashings - 250000 worstcase 59.107 us/op 60.603 us/op 0.98
altair processSyncCommitteeUpdates - 250000 9.9340 ms/op 10.151 ms/op 0.98
BeaconState.hashTreeRoot - No change 175.00 ns/op 173.00 ns/op 1.01
BeaconState.hashTreeRoot - 1 full validator 59.836 us/op 56.270 us/op 1.06
BeaconState.hashTreeRoot - 32 full validator 633.95 us/op 643.28 us/op 0.99
BeaconState.hashTreeRoot - 512 full validator 6.6126 ms/op 6.0530 ms/op 1.09
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 71.265 us/op 72.206 us/op 0.99
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.0566 ms/op 1.0200 ms/op 1.04
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 12.693 ms/op 13.193 ms/op 0.96
BeaconState.hashTreeRoot - 1 balances 55.880 us/op 54.848 us/op 1.02
BeaconState.hashTreeRoot - 32 balances 562.24 us/op 551.61 us/op 1.02
BeaconState.hashTreeRoot - 512 balances 4.7043 ms/op 4.7189 ms/op 1.00
BeaconState.hashTreeRoot - 250000 balances 104.20 ms/op 90.273 ms/op 1.15
aggregationBits - 2048 els - zipIndexesInBitList 20.231 us/op 19.164 us/op 1.06
regular array get 100000 times 23.019 us/op 22.897 us/op 1.01
wrappedArray get 100000 times 23.030 us/op 22.778 us/op 1.01
arrayWithProxy get 100000 times 11.207 ms/op 10.839 ms/op 1.03
ssz.Root.equals 21.703 ns/op 21.529 ns/op 1.01
byteArrayEquals 21.426 ns/op 21.300 ns/op 1.01
Buffer.compare 8.9940 ns/op 9.0040 ns/op 1.00
processSlot - 1 slots 8.0880 us/op 8.1000 us/op 1.00
processSlot - 32 slots 1.6280 ms/op 1.5581 ms/op 1.04
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 2.4209 ms/op 3.6599 ms/op 0.66
getCommitteeAssignments - req 1 vs - 250000 vc 1.6896 ms/op 1.6790 ms/op 1.01
getCommitteeAssignments - req 100 vs - 250000 vc 3.4439 ms/op 3.4250 ms/op 1.01
getCommitteeAssignments - req 1000 vs - 250000 vc 3.6982 ms/op 3.6891 ms/op 1.00
findModifiedValidators - 10000 modified validators 743.28 ms/op 707.67 ms/op 1.05
findModifiedValidators - 1000 modified validators 518.48 ms/op 497.62 ms/op 1.04
findModifiedValidators - 100 modified validators 327.57 ms/op 327.92 ms/op 1.00
findModifiedValidators - 10 modified validators 258.77 ms/op 282.30 ms/op 0.92
findModifiedValidators - 1 modified validators 185.79 ms/op 199.36 ms/op 0.93
findModifiedValidators - no difference 186.82 ms/op 189.46 ms/op 0.99
migrate state 1500000 validators, 3400 modified, 2000 new 2.8542 s/op 2.8672 s/op 1.00
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.8400 ns/op 3.6900 ns/op 1.04
state getBlockRootAtSlot - 250000 vs - 7PWei 271.26 ns/op 271.86 ns/op 1.00
computeProposerIndex 100000 validators 1.3312 ms/op 1.3223 ms/op 1.01
getNextSyncCommitteeIndices 1000 validators 2.8818 ms/op 2.8905 ms/op 1.00
getNextSyncCommitteeIndices 10000 validators 25.517 ms/op 25.232 ms/op 1.01
getNextSyncCommitteeIndices 100000 validators 83.695 ms/op 89.451 ms/op 0.94
computeProposers - vc 250000 554.51 us/op 557.10 us/op 1.00
computeEpochShuffling - vc 250000 38.991 ms/op 40.477 ms/op 0.96
getNextSyncCommittee - vc 250000 9.4784 ms/op 9.5494 ms/op 0.99
nodejs block root to RootHex using toHex 102.14 ns/op 102.98 ns/op 0.99
nodejs block root to RootHex using toRootHex 67.639 ns/op 67.533 ns/op 1.00
nodejs fromHex(blob) 765.74 us/op 775.94 us/op 0.99
nodejs fromHexInto(blob) 669.27 us/op 645.64 us/op 1.04
nodejs block root to RootHex using the deprecated toHexString 477.14 ns/op 502.56 ns/op 0.95
nodejs byteArrayEquals 32 bytes (block root) 26.096 ns/op 26.312 ns/op 0.99
nodejs byteArrayEquals 48 bytes (pubkey) 37.779 ns/op 37.244 ns/op 1.01
nodejs byteArrayEquals 96 bytes (signature) 39.159 ns/op 40.086 ns/op 0.98
nodejs byteArrayEquals 1024 bytes 45.930 ns/op 45.592 ns/op 1.01
nodejs byteArrayEquals 131072 bytes (blob) 1.7733 us/op 1.7575 us/op 1.01
browser block root to RootHex using toHex 146.56 ns/op 146.59 ns/op 1.00
browser block root to RootHex using toRootHex 131.92 ns/op 130.89 ns/op 1.01
browser fromHex(blob) 1.6595 ms/op 1.6023 ms/op 1.04
browser fromHexInto(blob) 662.47 us/op 668.20 us/op 0.99
browser block root to RootHex using the deprecated toHexString 338.16 ns/op 340.30 ns/op 0.99
browser byteArrayEquals 32 bytes (block root) 28.385 ns/op 28.114 ns/op 1.01
browser byteArrayEquals 48 bytes (pubkey) 39.627 ns/op 39.791 ns/op 1.00
browser byteArrayEquals 96 bytes (signature) 74.315 ns/op 73.759 ns/op 1.01
browser byteArrayEquals 1024 bytes 755.76 ns/op 754.29 ns/op 1.00
browser byteArrayEquals 131072 bytes (blob) 94.889 us/op 94.883 us/op 1.00

by benchmarkbot/action

Comment thread packages/beacon-node/src/chain/validation/executionPayloadBid.ts
@nflaig
nflaig requested a review from twoeths August 3, 2026 13:54

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

lgtm, spec deviation comment looks good

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

The epoch-boundary drop itself looks safe for Lodestar's local production path and avoids the expensive unusable parent-state regen. I found one adjacent-policy gap in the broader direct-parent compatibility branch.

return true;
// The spec allows this at epoch boundaries, but Lodestar does not propagate these bids because validating
// them requires an epoch transition for a parent state that cannot be used for proposer-boost reorgs.
return !isStartSlotOfEpoch(bidSlot);

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.

馃煛 This direct-parent branch should also require bidSlot === head.slot + 1. Lodestar can only build on head.parentRoot for the single-slot proposer-boost reorg case; ForkChoice.getProposerHead() returns the parent only when head.slot + 1 === slot and the slot is not an epoch boundary. As written, a stale-head/skipped-slot bid, or a same-slot bid after a same-slot head is already cached, can pass validation and be pooled/propagated even though produceBlockV4 will never query this (slot, head.parentRoot, head.parentBlockHash) tuple. Tightening this to bidSlot === head.slot + 1 && !isStartSlotOfEpoch(bidSlot) would keep the validation policy aligned with the only direct-parent case block production can actually use.

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.

Correction: after the propagation-goal clarification, I think this adjacency requirement is too strict for gossip validation. I was mixing Lodestar local selection with network propagation policy.

For this PR, the useful filter is the narrower one already here: drop the direct-parent case at epoch boundaries because it can force the expensive parent-state epoch-transition path for a bid Lodestar cannot use for proposer-boost reorg. Non-adjacent direct-parent bids may still be worth propagating to peers even if this node will not select them locally, so I consider my slot-adjacency suggestion retracted.

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.

this is somewhat true, we will only return getProposerHead() for head.parentRoot if bid.slot === head.slot + 1, but as lodekeeper pointed out, this is about bid propagation, I do think though that we could limit the bids we let through for head.parentRoot based on a few more cheap checks

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.

Implemented this as a narrow cheap check without going back to strict local-selection adjacency: direct-parent bids now pass only when bid.slot is head.slot or head.slot + 1, plus the existing epoch-boundary ignore. That keeps same-slot/next-slot propagation useful for peers while rejecting stale or far-ahead parent-of-head bids before regen.

I could not push directly to ChainSafe/lodestar:nflaig/drop-parent-bids-at-epoch-boundary as lodekeeper (403), so the signed commit is available on my fork: lodekeeper@b2c7f70

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.

@lodekeeper if anything, this should be a separate PR, I have merged this one now

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.

Ack, agreed. I won鈥檛 try to carry this as part of the already-merged PR.

I鈥檓 also not opening a separate PR from b2c7f70a03 right now: after the later propagation-policy clarification, the slot-adjacency tightening is not obviously desirable for gossip validation. It would align acceptance with what this local node can select, but it could also under-propagate cheap direct-parent bids that may still be useful to peers. So I鈥檓 parking that fork commit as optional follow-up material unless we decide we want the stricter local-policy behavior separately.

@nflaig
nflaig merged commit f6a0d68 into unstable Aug 4, 2026
24 of 26 checks passed
@nflaig
nflaig deleted the nflaig/drop-parent-bids-at-epoch-boundary branch August 4, 2026 08:57
@wemeetagain

Copy link
Copy Markdown
Member

馃帀 This PR is included in v1.46.0 馃帀

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.

5 participants