Skip to content

feat: allow multiple bids compatible with the head view - #9739

Merged
nflaig merged 9 commits into
unstablefrom
nflaig/validate-bids-against-head
Aug 3, 2026
Merged

feat: allow multiple bids compatible with the head view#9739
nflaig merged 9 commits into
unstablefrom
nflaig/validate-bids-against-head

Conversation

@nflaig

@nflaig nflaig commented Jul 31, 2026

Copy link
Copy Markdown
Member

implements ethereum/consensus-specs#5497

  • Restricts propagation to bids compatible with the local head view
  • Tracks seen bids per builder and parent tuple
  • Preserves recovery for bids received before their parent block
  • Prevents duplicate validation before regeneration and after signature verification

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Performance Report

鉁旓笍 no performance regression detected

Full benchmark results
Benchmark suite Current: c7c0bae Previous: d9065a2 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1838 ms/op 1.1816 ms/op 1.00
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 41.001 us/op 40.660 us/op 1.01
BLS verify - blst 712.93 us/op 753.88 us/op 0.95
BLS verifyMultipleSignatures 3 - blst 1.3785 ms/op 1.3632 ms/op 1.01
BLS verifyMultipleSignatures 8 - blst 2.2087 ms/op 2.1700 ms/op 1.02
BLS verifyMultipleSignatures 32 - blst 7.1955 ms/op 6.9536 ms/op 1.03
BLS verifyMultipleSignatures 64 - blst 14.142 ms/op 13.400 ms/op 1.06
BLS verifyMultipleSignatures 128 - blst 26.377 ms/op 26.103 ms/op 1.01
BLS deserializing 10000 signatures 636.23 ms/op 632.22 ms/op 1.01
BLS deserializing 100000 signatures 6.4671 s/op 6.3421 s/op 1.02
BLS verifyMultipleSignatures - same message - 3 - blst 798.03 us/op 813.09 us/op 0.98
BLS verifyMultipleSignatures - same message - 8 - blst 954.39 us/op 927.28 us/op 1.03
BLS verifyMultipleSignatures - same message - 32 - blst 1.5454 ms/op 1.5714 ms/op 0.98
BLS verifyMultipleSignatures - same message - 64 - blst 2.3969 ms/op 2.3714 ms/op 1.01
BLS verifyMultipleSignatures - same message - 128 - blst 4.2437 ms/op 4.0171 ms/op 1.06
BLS aggregatePubkeys 32 - blst 17.655 us/op 17.582 us/op 1.00
BLS aggregatePubkeys 128 - blst 63.416 us/op 63.000 us/op 1.01
getSlashingsAndExits - default max 47.860 us/op 53.064 us/op 0.90
getSlashingsAndExits - 2k 359.39 us/op 331.99 us/op 1.08
proposeBlockBody type=full, size=empty 745.92 us/op 712.89 us/op 1.05
isKnown best case - 1 super set check 175.00 ns/op 167.00 ns/op 1.05
isKnown normal case - 2 super set checks 202.00 ns/op 162.00 ns/op 1.25
isKnown worse case - 16 super set checks 170.00 ns/op 163.00 ns/op 1.04
validate api signedAggregateAndProof - struct 1.5827 ms/op 1.5082 ms/op 1.05
validate gossip signedAggregateAndProof - struct 1.5828 ms/op 1.5102 ms/op 1.05
batch validate gossip attestation - vc 640000 - chunk 32 112.67 us/op 106.62 us/op 1.06
batch validate gossip attestation - vc 640000 - chunk 64 100.19 us/op 92.681 us/op 1.08
batch validate gossip attestation - vc 640000 - chunk 128 95.312 us/op 89.420 us/op 1.07
batch validate gossip attestation - vc 640000 - chunk 256 88.879 us/op 84.721 us/op 1.05
bytes32 toHexString 288.00 ns/op 289.00 ns/op 1.00
bytes32 Buffer.toString(hex) 163.00 ns/op 174.00 ns/op 0.94
bytes32 Buffer.toString(hex) from Uint8Array 235.00 ns/op 244.00 ns/op 0.96
bytes32 Buffer.toString(hex) + 0x 160.00 ns/op 172.00 ns/op 0.93
Return object 10000 times 0.21620 ns/op 0.21190 ns/op 1.02
Throw Error 10000 times 3.3809 us/op 3.3427 us/op 1.01
toHex 100.80 ns/op 107.85 ns/op 0.93
Buffer.from 95.845 ns/op 91.670 ns/op 1.05
shared Buffer 61.222 ns/op 65.606 ns/op 0.93
fastMsgIdFn sha256 / 200 bytes 1.4930 us/op 1.4700 us/op 1.02
fastMsgIdFn h32 xxhash / 200 bytes 155.00 ns/op 156.00 ns/op 0.99
fastMsgIdFn h64 xxhash / 200 bytes 207.00 ns/op 199.00 ns/op 1.04
fastMsgIdFn sha256 / 1000 bytes 4.8450 us/op 4.7200 us/op 1.03
fastMsgIdFn h32 xxhash / 1000 bytes 243.00 ns/op 243.00 ns/op 1.00
fastMsgIdFn h64 xxhash / 1000 bytes 259.00 ns/op 253.00 ns/op 1.02
fastMsgIdFn sha256 / 10000 bytes 42.877 us/op 41.856 us/op 1.02
fastMsgIdFn h32 xxhash / 10000 bytes 1.2780 us/op 1.2690 us/op 1.01
fastMsgIdFn h64 xxhash / 10000 bytes 823.00 ns/op 818.00 ns/op 1.01
send data - 1000 256B messages 4.4333 ms/op 4.0620 ms/op 1.09
send data - 1000 512B messages 5.8504 ms/op 4.9401 ms/op 1.18
send data - 1000 1024B messages 6.6631 ms/op 5.2797 ms/op 1.26
send data - 1000 1200B messages 7.5443 ms/op 6.0532 ms/op 1.25
send data - 1000 2048B messages 11.608 ms/op 8.3158 ms/op 1.40
send data - 1000 4096B messages 71.677 ms/op 50.031 ms/op 1.43
send data - 1000 16384B messages 410.20 ms/op 329.07 ms/op 1.25
send data - 1000 65536B messages 1.9851 s/op 1.3266 s/op 1.50
enrSubnets - fastDeserialize 64 bits 811.00 ns/op 764.00 ns/op 1.06
enrSubnets - ssz BitVector 64 bits 273.00 ns/op 258.00 ns/op 1.06
enrSubnets - fastDeserialize 4 bits 105.00 ns/op 102.00 ns/op 1.03
enrSubnets - ssz BitVector 4 bits 275.00 ns/op 261.00 ns/op 1.05
prioritizePeers score -10:0 att 32-0.1 sync 2-0 213.82 us/op 204.74 us/op 1.04
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 243.53 us/op 230.65 us/op 1.06
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 391.92 us/op 332.17 us/op 1.18
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 635.87 us/op 587.67 us/op 1.08
prioritizePeers score 0:0 att 64-1 sync 4-1 781.73 us/op 688.27 us/op 1.14
array of 16000 items push then shift 1.3388 us/op 1.2814 us/op 1.04
LinkedList of 16000 items push then shift 9.0200 ns/op 6.6940 ns/op 1.35
array of 16000 items push then pop 79.085 ns/op 62.640 ns/op 1.26
LinkedList of 16000 items push then pop 6.7710 ns/op 5.9580 ns/op 1.14
array of 24000 items push then shift 1.9379 us/op 1.8997 us/op 1.02
LinkedList of 24000 items push then shift 8.2870 ns/op 6.3200 ns/op 1.31
array of 24000 items push then pop 112.55 ns/op 86.000 ns/op 1.31
LinkedList of 24000 items push then pop 7.2860 ns/op 5.9740 ns/op 1.22
intersect bitArray bitLen 8 4.0450 ns/op 3.8450 ns/op 1.05
intersect array and set length 8 30.583 ns/op 29.856 ns/op 1.02
intersect bitArray bitLen 128 23.876 ns/op 23.399 ns/op 1.02
intersect array and set length 128 529.62 ns/op 504.85 ns/op 1.05
bitArray.getTrueBitIndexes() bitLen 128 1.0380 us/op 899.00 ns/op 1.15
bitArray.getTrueBitIndexes() bitLen 248 1.7670 us/op 1.6140 us/op 1.09
bitArray.getTrueBitIndexes() bitLen 512 3.7700 us/op 3.4120 us/op 1.10
Full columns - reconstruct all 6 blobs 140.52 us/op 118.55 us/op 1.19
Full columns - reconstruct half of the blobs out of 6 74.376 us/op 96.816 us/op 0.77
Full columns - reconstruct single blob out of 6 34.732 us/op 34.891 us/op 1.00
Half columns - reconstruct all 6 blobs 415.39 ms/op 381.20 ms/op 1.09
Half columns - reconstruct half of the blobs out of 6 209.78 ms/op 192.78 ms/op 1.09
Half columns - reconstruct single blob out of 6 74.445 ms/op 67.073 ms/op 1.11
Set add up to 64 items then delete first 2.2569 us/op 1.6884 us/op 1.34
OrderedSet add up to 64 items then delete first 3.4119 us/op 2.5372 us/op 1.34
Set add up to 64 items then delete last 2.3703 us/op 1.8966 us/op 1.25
OrderedSet add up to 64 items then delete last 3.4163 us/op 2.7985 us/op 1.22
Set add up to 64 items then delete middle 2.6348 us/op 1.9035 us/op 1.38
OrderedSet add up to 64 items then delete middle 6.2712 us/op 4.2280 us/op 1.48
Set add up to 128 items then delete first 5.4041 us/op 3.7725 us/op 1.43
OrderedSet add up to 128 items then delete first 8.7932 us/op 5.7349 us/op 1.53
Set add up to 128 items then delete last 5.7147 us/op 3.5948 us/op 1.59
OrderedSet add up to 128 items then delete last 7.9918 us/op 5.3932 us/op 1.48
Set add up to 128 items then delete middle 5.4700 us/op 3.5704 us/op 1.53
OrderedSet add up to 128 items then delete middle 14.966 us/op 11.220 us/op 1.33
Set add up to 256 items then delete first 10.950 us/op 7.6188 us/op 1.44
OrderedSet add up to 256 items then delete first 17.362 us/op 11.809 us/op 1.47
Set add up to 256 items then delete last 10.508 us/op 7.2389 us/op 1.45
OrderedSet add up to 256 items then delete last 14.464 us/op 11.086 us/op 1.30
Set add up to 256 items then delete middle 9.8404 us/op 7.1829 us/op 1.37
OrderedSet add up to 256 items then delete middle 42.892 us/op 34.523 us/op 1.24
runFastConfirmationRules vc:100000 bc:96 eq:0 7.1400 ms/op 4.6577 ms/op 1.53
runFastConfirmationRules vc:600000 bc:96 eq:0 41.412 ms/op 34.794 ms/op 1.19
runFastConfirmationRules vc:1000000 bc:96 eq:0 63.510 ms/op 58.511 ms/op 1.09
runFastConfirmationRules vc:600000 bc:320 eq:0 37.750 ms/op 34.112 ms/op 1.11
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.3217 s/op 1.0845 s/op 1.22
pass gossip attestations to forkchoice per slot 2.7902 ms/op 2.6195 ms/op 1.07
forkChoice updateHead vc 100000 bc 64 eq 0 422.64 us/op 450.32 us/op 0.94
forkChoice updateHead vc 600000 bc 64 eq 0 2.5407 ms/op 2.6304 ms/op 0.97
forkChoice updateHead vc 1000000 bc 64 eq 0 4.2750 ms/op 4.4507 ms/op 0.96
forkChoice updateHead vc 600000 bc 320 eq 0 2.5461 ms/op 2.6572 ms/op 0.96
forkChoice updateHead vc 600000 bc 1200 eq 0 2.5667 ms/op 2.6934 ms/op 0.95
forkChoice updateHead vc 600000 bc 7200 eq 0 2.8032 ms/op 2.9981 ms/op 0.93
forkChoice updateHead vc 600000 bc 64 eq 1000 2.5602 ms/op 2.6644 ms/op 0.96
forkChoice updateHead vc 600000 bc 64 eq 10000 2.6377 ms/op 2.7489 ms/op 0.96
forkChoice updateHead vc 600000 bc 64 eq 300000 6.7953 ms/op 6.5868 ms/op 1.03
computeDeltas 1400000 validators 0% inactive 12.580 ms/op 12.369 ms/op 1.02
computeDeltas 1400000 validators 10% inactive 11.781 ms/op 11.688 ms/op 1.01
computeDeltas 1400000 validators 20% inactive 11.207 ms/op 11.059 ms/op 1.01
computeDeltas 1400000 validators 50% inactive 9.1570 ms/op 9.0644 ms/op 1.01
computeDeltas 2100000 validators 0% inactive 19.219 ms/op 18.977 ms/op 1.01
computeDeltas 2100000 validators 10% inactive 18.083 ms/op 18.800 ms/op 0.96
computeDeltas 2100000 validators 20% inactive 16.821 ms/op 17.547 ms/op 0.96
computeDeltas 2100000 validators 50% inactive 11.206 ms/op 11.539 ms/op 0.97
altair processAttestation - 250000 vs - 7PWei normalcase 3.0563 ms/op 2.1297 ms/op 1.44
altair processAttestation - 250000 vs - 7PWei worstcase 3.0484 ms/op 2.7387 ms/op 1.11
altair processAttestation - setStatus - 1/6 committees join 110.06 us/op 103.92 us/op 1.06
altair processAttestation - setStatus - 1/3 committees join 224.07 us/op 213.45 us/op 1.05
altair processAttestation - setStatus - 1/2 committees join 291.63 us/op 303.49 us/op 0.96
altair processAttestation - setStatus - 2/3 committees join 388.19 us/op 388.38 us/op 1.00
altair processAttestation - setStatus - 4/5 committees join 529.39 us/op 558.66 us/op 0.95
altair processAttestation - setStatus - 100% committees join 620.87 us/op 622.40 us/op 1.00
altair processBlock - 250000 vs - 7PWei normalcase 4.5330 ms/op 4.8352 ms/op 0.94
altair processBlock - 250000 vs - 7PWei normalcase hashState 16.658 ms/op 15.859 ms/op 1.05
altair processBlock - 250000 vs - 7PWei worstcase 25.240 ms/op 23.242 ms/op 1.09
altair processBlock - 250000 vs - 7PWei worstcase hashState 48.907 ms/op 45.651 ms/op 1.07
phase0 processBlock - 250000 vs - 7PWei normalcase 1.8426 ms/op 1.5099 ms/op 1.22
phase0 processBlock - 250000 vs - 7PWei worstcase 20.076 ms/op 17.901 ms/op 1.12
altair processEth1Data - 250000 vs - 7PWei normalcase 298.80 us/op 301.74 us/op 0.99
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.6040 us/op 8.1810 us/op 0.44
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 20.320 us/op 21.187 us/op 0.96
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.7220 us/op 6.1020 us/op 0.94
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 5.1530 us/op 3.7960 us/op 1.36
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 98.474 us/op 93.022 us/op 1.06
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4122 ms/op 1.4382 ms/op 0.98
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.9830 ms/op 1.9044 ms/op 1.04
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.4415 ms/op 1.8857 ms/op 1.29
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.0619 ms/op 3.9695 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.2215 ms/op 2.1835 ms/op 1.02
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.4390 ms/op 4.1996 ms/op 1.06
Tree 40 250000 create 378.85 ms/op 367.49 ms/op 1.03
Tree 40 250000 get(125000) 95.134 ns/op 99.095 ns/op 0.96
Tree 40 250000 set(125000) 1.0588 us/op 1.0610 us/op 1.00
Tree 40 250000 toArray() 19.551 ms/op 19.409 ms/op 1.01
Tree 40 250000 iterate all - toArray() + loop 22.945 ms/op 19.990 ms/op 1.15
Tree 40 250000 iterate all - get(i) 43.128 ms/op 46.517 ms/op 0.93
Array 250000 create 2.6127 ms/op 2.3570 ms/op 1.11
Array 250000 clone - spread 809.66 us/op 723.38 us/op 1.12
Array 250000 get(125000) 0.30800 ns/op 0.30300 ns/op 1.02
Array 250000 set(125000) 0.30900 ns/op 0.30500 ns/op 1.01
Array 250000 iterate all - loop 58.480 us/op 58.694 us/op 1.00
phase0 afterProcessEpoch - 250000 vs - 7PWei 43.389 ms/op 58.433 ms/op 0.74
Array.fill - length 1000000 6.4327 ms/op 2.2632 ms/op 2.84
Array push - length 1000000 12.427 ms/op 9.3337 ms/op 1.33
Array.get 0.20810 ns/op 0.20942 ns/op 0.99
Uint8Array.get 0.23940 ns/op 0.25004 ns/op 0.96
phase0 beforeProcessEpoch - 250000 vs - 7PWei 20.647 ms/op 16.310 ms/op 1.27
altair processEpoch - mainnet_e81889 369.46 ms/op 305.05 ms/op 1.21
mainnet_e81889 - altair beforeProcessEpoch 21.723 ms/op 17.280 ms/op 1.26
mainnet_e81889 - altair processJustificationAndFinalization 8.1260 us/op 6.4780 us/op 1.25
mainnet_e81889 - altair processInactivityUpdates 3.5231 ms/op 3.6075 ms/op 0.98
mainnet_e81889 - altair processRewardsAndPenalties 18.827 ms/op 21.144 ms/op 0.89
mainnet_e81889 - altair processRegistryUpdates 600.00 ns/op 583.00 ns/op 1.03
mainnet_e81889 - altair processSlashings 155.00 ns/op 145.00 ns/op 1.07
mainnet_e81889 - altair processEth1DataReset 144.00 ns/op 143.00 ns/op 1.01
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.3335 ms/op 1.3525 ms/op 0.99
mainnet_e81889 - altair processSlashingsReset 723.00 ns/op 711.00 ns/op 1.02
mainnet_e81889 - altair processRandaoMixesReset 1.4510 us/op 1.4190 us/op 1.02
mainnet_e81889 - altair processHistoricalRootsUpdate 146.00 ns/op 143.00 ns/op 1.02
mainnet_e81889 - altair processParticipationFlagUpdates 461.00 ns/op 455.00 ns/op 1.01
mainnet_e81889 - altair processSyncCommitteeUpdates 115.00 ns/op 114.00 ns/op 1.01
mainnet_e81889 - altair afterProcessEpoch 42.599 ms/op 43.822 ms/op 0.97
capella processEpoch - mainnet_e217614 956.02 ms/op 887.14 ms/op 1.08
mainnet_e217614 - capella beforeProcessEpoch 61.434 ms/op 76.280 ms/op 0.81
mainnet_e217614 - capella processJustificationAndFinalization 7.7000 us/op 6.8500 us/op 1.12
mainnet_e217614 - capella processInactivityUpdates 16.662 ms/op 15.659 ms/op 1.06
mainnet_e217614 - capella processRewardsAndPenalties 98.260 ms/op 94.296 ms/op 1.04
mainnet_e217614 - capella processRegistryUpdates 4.6060 us/op 4.6780 us/op 0.98
mainnet_e217614 - capella processSlashings 154.00 ns/op 156.00 ns/op 0.99
mainnet_e217614 - capella processEth1DataReset 147.00 ns/op 154.00 ns/op 0.95
mainnet_e217614 - capella processEffectiveBalanceUpdates 5.5365 ms/op 18.690 ms/op 0.30
mainnet_e217614 - capella processSlashingsReset 697.00 ns/op 717.00 ns/op 0.97
mainnet_e217614 - capella processRandaoMixesReset 1.3410 us/op 1.4240 us/op 0.94
mainnet_e217614 - capella processHistoricalRootsUpdate 143.00 ns/op 156.00 ns/op 0.92
mainnet_e217614 - capella processParticipationFlagUpdates 486.00 ns/op 477.00 ns/op 1.02
mainnet_e217614 - capella afterProcessEpoch 106.90 ms/op 111.75 ms/op 0.96
phase0 processEpoch - mainnet_e58758 326.71 ms/op 377.34 ms/op 0.87
mainnet_e58758 - phase0 beforeProcessEpoch 60.474 ms/op 74.650 ms/op 0.81
mainnet_e58758 - phase0 processJustificationAndFinalization 6.8300 us/op 6.6240 us/op 1.03
mainnet_e58758 - phase0 processRewardsAndPenalties 15.182 ms/op 17.604 ms/op 0.86
mainnet_e58758 - phase0 processRegistryUpdates 2.2450 us/op 2.3810 us/op 0.94
mainnet_e58758 - phase0 processSlashings 144.00 ns/op 155.00 ns/op 0.93
mainnet_e58758 - phase0 processEth1DataReset 144.00 ns/op 160.00 ns/op 0.90
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 831.30 us/op 841.10 us/op 0.99
mainnet_e58758 - phase0 processSlashingsReset 839.00 ns/op 972.00 ns/op 0.86
mainnet_e58758 - phase0 processRandaoMixesReset 1.3570 us/op 1.3880 us/op 0.98
mainnet_e58758 - phase0 processHistoricalRootsUpdate 153.00 ns/op 156.00 ns/op 0.98
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2960 us/op 1.3580 us/op 0.95
mainnet_e58758 - phase0 afterProcessEpoch 33.945 ms/op 35.517 ms/op 0.96
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.2559 ms/op 1.1307 ms/op 1.11
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.6646 ms/op 1.2642 ms/op 1.32
altair processInactivityUpdates - 250000 normalcase 10.735 ms/op 12.372 ms/op 0.87
altair processInactivityUpdates - 250000 worstcase 10.490 ms/op 12.932 ms/op 0.81
phase0 processRegistryUpdates - 250000 normalcase 2.4830 us/op 2.5660 us/op 0.97
phase0 processRegistryUpdates - 250000 badcase_full_deposits 142.05 us/op 151.60 us/op 0.94
phase0 processRegistryUpdates - 250000 worstcase 0.5 51.733 ms/op 62.434 ms/op 0.83
altair processRewardsAndPenalties - 250000 normalcase 13.444 ms/op 17.422 ms/op 0.77
altair processRewardsAndPenalties - 250000 worstcase 13.556 ms/op 17.165 ms/op 0.79
phase0 getAttestationDeltas - 250000 normalcase 5.5588 ms/op 5.6740 ms/op 0.98
phase0 getAttestationDeltas - 250000 worstcase 5.8316 ms/op 5.6502 ms/op 1.03
phase0 processSlashings - 250000 worstcase 61.614 us/op 65.708 us/op 0.94
altair processSyncCommitteeUpdates - 250000 12.982 ms/op 10.839 ms/op 1.20
BeaconState.hashTreeRoot - No change 187.00 ns/op 173.00 ns/op 1.08
BeaconState.hashTreeRoot - 1 full validator 115.40 us/op 81.363 us/op 1.42
BeaconState.hashTreeRoot - 32 full validator 1.5463 ms/op 900.70 us/op 1.72
BeaconState.hashTreeRoot - 512 full validator 9.6024 ms/op 7.5544 ms/op 1.27
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 128.95 us/op 100.90 us/op 1.28
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.2642 ms/op 1.5253 ms/op 1.48
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 18.901 ms/op 16.678 ms/op 1.13
BeaconState.hashTreeRoot - 1 balances 97.394 us/op 92.121 us/op 1.06
BeaconState.hashTreeRoot - 32 balances 800.99 us/op 794.72 us/op 1.01
BeaconState.hashTreeRoot - 512 balances 8.9734 ms/op 6.0252 ms/op 1.49
BeaconState.hashTreeRoot - 250000 balances 212.35 ms/op 148.04 ms/op 1.43
aggregationBits - 2048 els - zipIndexesInBitList 21.316 us/op 21.654 us/op 0.98
regular array get 100000 times 23.492 us/op 23.695 us/op 0.99
wrappedArray get 100000 times 23.547 us/op 23.733 us/op 0.99
arrayWithProxy get 100000 times 11.724 ms/op 10.590 ms/op 1.11
ssz.Root.equals 21.959 ns/op 22.069 ns/op 1.00
byteArrayEquals 21.704 ns/op 21.828 ns/op 0.99
Buffer.compare 8.9540 ns/op 9.0520 ns/op 0.99
processSlot - 1 slots 11.686 us/op 10.124 us/op 1.15
processSlot - 32 slots 2.5177 ms/op 2.4247 ms/op 1.04
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 9.1632 ms/op 5.3355 ms/op 1.72
getCommitteeAssignments - req 1 vs - 250000 vc 1.7163 ms/op 1.7276 ms/op 0.99
getCommitteeAssignments - req 100 vs - 250000 vc 3.5664 ms/op 3.5068 ms/op 1.02
getCommitteeAssignments - req 1000 vs - 250000 vc 3.8259 ms/op 3.7793 ms/op 1.01
findModifiedValidators - 10000 modified validators 968.52 ms/op 899.44 ms/op 1.08
findModifiedValidators - 1000 modified validators 621.23 ms/op 595.22 ms/op 1.04
findModifiedValidators - 100 modified validators 566.69 ms/op 339.09 ms/op 1.67
findModifiedValidators - 10 modified validators 444.21 ms/op 323.34 ms/op 1.37
findModifiedValidators - 1 modified validators 350.95 ms/op 306.86 ms/op 1.14
findModifiedValidators - no difference 287.58 ms/op 182.37 ms/op 1.58
migrate state 1500000 validators, 3400 modified, 2000 new 4.5990 s/op 2.6662 s/op 1.72
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.7600 ns/op 3.8700 ns/op 0.97
state getBlockRootAtSlot - 250000 vs - 7PWei 602.79 ns/op 309.87 ns/op 1.95
computeProposerIndex 100000 validators 1.4564 ms/op 1.3900 ms/op 1.05
getNextSyncCommitteeIndices 1000 validators 3.0591 ms/op 2.9202 ms/op 1.05
getNextSyncCommitteeIndices 10000 validators 27.558 ms/op 26.265 ms/op 1.05
getNextSyncCommitteeIndices 100000 validators 98.179 ms/op 88.068 ms/op 1.11
computeProposers - vc 250000 620.73 us/op 547.25 us/op 1.13
computeEpochShuffling - vc 250000 41.983 ms/op 38.643 ms/op 1.09
getNextSyncCommittee - vc 250000 10.596 ms/op 9.4331 ms/op 1.12
nodejs block root to RootHex using toHex 100.71 ns/op 102.99 ns/op 0.98
nodejs block root to RootHex using toRootHex 65.639 ns/op 67.636 ns/op 0.97
nodejs fromHex(blob) 1.0788 ms/op 731.63 us/op 1.47
nodejs fromHexInto(blob) 652.74 us/op 666.20 us/op 0.98
nodejs block root to RootHex using the deprecated toHexString 374.74 ns/op 472.57 ns/op 0.79
nodejs byteArrayEquals 32 bytes (block root) 27.301 ns/op 25.839 ns/op 1.06
nodejs byteArrayEquals 48 bytes (pubkey) 39.293 ns/op 37.317 ns/op 1.05
nodejs byteArrayEquals 96 bytes (signature) 36.228 ns/op 39.972 ns/op 0.91
nodejs byteArrayEquals 1024 bytes 43.173 ns/op 45.175 ns/op 0.96
nodejs byteArrayEquals 131072 bytes (blob) 1.8555 us/op 1.7571 us/op 1.06
browser block root to RootHex using toHex 153.63 ns/op 145.52 ns/op 1.06
browser block root to RootHex using toRootHex 135.77 ns/op 130.65 ns/op 1.04
browser fromHex(blob) 1.7971 ms/op 1.6415 ms/op 1.09
browser fromHexInto(blob) 653.20 us/op 646.08 us/op 1.01
browser block root to RootHex using the deprecated toHexString 494.28 ns/op 334.32 ns/op 1.48
browser byteArrayEquals 32 bytes (block root) 29.324 ns/op 28.195 ns/op 1.04
browser byteArrayEquals 48 bytes (pubkey) 41.284 ns/op 39.685 ns/op 1.04
browser byteArrayEquals 96 bytes (signature) 77.141 ns/op 74.927 ns/op 1.03
browser byteArrayEquals 1024 bytes 793.30 ns/op 760.51 ns/op 1.04
browser byteArrayEquals 131072 bytes (blob) 99.940 us/op 96.510 us/op 1.04

by benchmarkbot/action

Comment on lines 463 to 467
case GossipType.execution_payload_bid: {
// instead of searching for the message root, this searches for the parent root
// Search for the parent independently of current head compatibility. A bid may arrive
// before its parent block, so compatibility is checked later during gossip validation.
const parentBlockRoot = getParentBlockRootFromSignedExecutionPayloadBidSerialized(message.msg.data);
const parentBlockHash = getParentBlockHashFromSignedExecutionPayloadBidSerialized(message.msg.data);

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.

@twoeths @wemeetagain curious what are your thoughts about queuing bids in the network processor, I think this could be a potential dos vector

@twoeths twoeths Aug 1, 2026

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 root cause is epoch transition when validating gossip bid
I guess it's not an issue once we have #9739
that would prevent the epoch transition when validating the bid

so we can still run epoch transition when validating bid with this PR
we can avoid that by also front-running epoch transition for parent as well
but that means 2 epoch transition per epoch which affects us heavily

@nflaig nflaig Aug 1, 2026

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.

but that means 2 epoch transition per epoch which affects us heavily

we should disallow this to happen at the epoch boundary somehow, currently the proposer boost reorg spec also prevents this behavior via is_not_at_epoch_boundary, so if we are proposer or others following the spec as is will not use bids for the parent of our head

Comment thread packages/beacon-node/src/chain/validation/executionPayloadBid.ts Outdated
Comment thread packages/fork-choice/test/unit/protoArray/gloas.test.ts
forkChoice: IForkChoice,
head: ProtoBlock,
bidSlot: Slot,
parentBlockRoot: RootHex,

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.

maybe bidParentBlockRoot and bidParentBlockHash would makes it easier to understand

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.

applied that naming more broadly. I think it make sense to avoid confusing

@nflaig

nflaig commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

review comments have been addressed, gonna merge this to prepare for glamsterdam-devnet-8

@nflaig
nflaig merged commit dbe9dc8 into unstable Aug 3, 2026
19 checks passed
@nflaig
nflaig deleted the nflaig/validate-bids-against-head branch August 3, 2026 09:26
markolazic01 pushed a commit to markolazic01/lodestar that referenced this pull request Aug 3, 2026
implements ethereum/consensus-specs#5497
- Restricts propagation to bids compatible with the local head view
- Tracks seen bids per builder and parent tuple
- Preserves recovery for bids received before their parent block
- Prevents duplicate validation before regeneration and after signature
verification
nflaig added a commit that referenced this pull request Aug 4, 2026
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.
@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.

4 participants