Skip to content

feat: add gossip bid selection to block production#9289

Open
ensi321 wants to merge 2 commits intounstablefrom
nc/gloas-bid-selection
Open

feat: add gossip bid selection to block production#9289
ensi321 wants to merge 2 commits intounstablefrom
nc/gloas-bid-selection

Conversation

@ensi321
Copy link
Copy Markdown
Contributor

@ensi321 ensi321 commented Apr 27, 2026

No description provided.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request implements GLOAS block production by introducing the ability to select and build blocks using gossip bids in parallel with local execution engine blocks. It refactors the block production pipeline to support external bids, updates the bid pool to store signed messages, and integrates these changes into the validator API. Feedback focuses on a critical issue where using an external bid fails to populate the block production cache with required execution data, which will break subsequent API calls for the execution payload envelope. Additionally, it is recommended to improve error reporting when both local and gossip block production attempts fail.

Comment thread packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts
Comment thread packages/beacon-node/src/api/impl/validator/index.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 58eba01 Previous: 549a5b8 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 880.99 us/op 862.97 us/op 1.02
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 38.630 us/op 40.493 us/op 0.95
BLS verify - blst 748.56 us/op 705.10 us/op 1.06
BLS verifyMultipleSignatures 3 - blst 1.3874 ms/op 1.3688 ms/op 1.01
BLS verifyMultipleSignatures 8 - blst 2.2083 ms/op 2.1775 ms/op 1.01
BLS verifyMultipleSignatures 32 - blst 7.0470 ms/op 7.0716 ms/op 1.00
BLS verifyMultipleSignatures 64 - blst 13.509 ms/op 13.609 ms/op 0.99
BLS verifyMultipleSignatures 128 - blst 26.346 ms/op 25.590 ms/op 1.03
BLS deserializing 10000 signatures 647.53 ms/op 638.28 ms/op 1.01
BLS deserializing 100000 signatures 6.4295 s/op 6.3572 s/op 1.01
BLS verifyMultipleSignatures - same message - 3 - blst 794.16 us/op 758.16 us/op 1.05
BLS verifyMultipleSignatures - same message - 8 - blst 912.50 us/op 830.07 us/op 1.10
BLS verifyMultipleSignatures - same message - 32 - blst 1.6072 ms/op 1.5758 ms/op 1.02
BLS verifyMultipleSignatures - same message - 64 - blst 2.4405 ms/op 2.4484 ms/op 1.00
BLS verifyMultipleSignatures - same message - 128 - blst 4.0475 ms/op 4.0519 ms/op 1.00
BLS aggregatePubkeys 32 - blst 17.865 us/op 17.723 us/op 1.01
BLS aggregatePubkeys 128 - blst 63.864 us/op 63.481 us/op 1.01
getSlashingsAndExits - default max 50.237 us/op 46.127 us/op 1.09
getSlashingsAndExits - 2k 358.31 us/op 319.63 us/op 1.12
proposeBlockBody type=full, size=empty 1.7279 ms/op 739.55 us/op 2.34
isKnown best case - 1 super set check 168.00 ns/op 191.00 ns/op 0.88
isKnown normal case - 2 super set checks 173.00 ns/op 164.00 ns/op 1.05
isKnown worse case - 16 super set checks 375.00 ns/op 166.00 ns/op 2.26
validate api signedAggregateAndProof - struct 1.5649 ms/op 1.5315 ms/op 1.02
validate gossip signedAggregateAndProof - struct 1.5517 ms/op 1.5328 ms/op 1.01
batch validate gossip attestation - vc 640000 - chunk 32 107.99 us/op 104.44 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 64 95.165 us/op 92.232 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 128 86.662 us/op 85.618 us/op 1.01
batch validate gossip attestation - vc 640000 - chunk 256 84.804 us/op 82.360 us/op 1.03
bytes32 toHexString 290.00 ns/op 293.00 ns/op 0.99
bytes32 Buffer.toString(hex) 174.00 ns/op 177.00 ns/op 0.98
bytes32 Buffer.toString(hex) from Uint8Array 246.00 ns/op 250.00 ns/op 0.98
bytes32 Buffer.toString(hex) + 0x 170.00 ns/op 177.00 ns/op 0.96
Return object 10000 times 0.21530 ns/op 0.21050 ns/op 1.02
Throw Error 10000 times 3.3522 us/op 3.2961 us/op 1.02
toHex 101.02 ns/op 99.855 ns/op 1.01
Buffer.from 92.070 ns/op 88.985 ns/op 1.03
shared Buffer 60.875 ns/op 60.444 ns/op 1.01
fastMsgIdFn sha256 / 200 bytes 1.5000 us/op 1.4890 us/op 1.01
fastMsgIdFn h32 xxhash / 200 bytes 154.00 ns/op 160.00 ns/op 0.96
fastMsgIdFn h64 xxhash / 200 bytes 213.00 ns/op 216.00 ns/op 0.99
fastMsgIdFn sha256 / 1000 bytes 4.8120 us/op 4.8360 us/op 1.00
fastMsgIdFn h32 xxhash / 1000 bytes 246.00 ns/op 255.00 ns/op 0.96
fastMsgIdFn h64 xxhash / 1000 bytes 260.00 ns/op 255.00 ns/op 1.02
fastMsgIdFn sha256 / 10000 bytes 42.179 us/op 42.998 us/op 0.98
fastMsgIdFn h32 xxhash / 10000 bytes 1.2690 us/op 1.2640 us/op 1.00
fastMsgIdFn h64 xxhash / 10000 bytes 827.00 ns/op 827.00 ns/op 1.00
send data - 1000 256B messages 4.5370 ms/op 4.0241 ms/op 1.13
send data - 1000 512B messages 4.1729 ms/op 4.0848 ms/op 1.02
send data - 1000 1024B messages 5.0905 ms/op 4.3001 ms/op 1.18
send data - 1000 1200B messages 5.0830 ms/op 4.5755 ms/op 1.11
send data - 1000 2048B messages 4.8322 ms/op 4.6287 ms/op 1.04
send data - 1000 4096B messages 5.4725 ms/op 5.3582 ms/op 1.02
send data - 1000 16384B messages 17.258 ms/op 12.958 ms/op 1.33
send data - 1000 65536B messages 189.70 ms/op 208.32 ms/op 0.91
enrSubnets - fastDeserialize 64 bits 765.00 ns/op 739.00 ns/op 1.04
enrSubnets - ssz BitVector 64 bits 261.00 ns/op 260.00 ns/op 1.00
enrSubnets - fastDeserialize 4 bits 107.00 ns/op 100.00 ns/op 1.07
enrSubnets - ssz BitVector 4 bits 274.00 ns/op 269.00 ns/op 1.02
prioritizePeers score -10:0 att 32-0.1 sync 2-0 210.62 us/op 207.13 us/op 1.02
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 243.91 us/op 244.97 us/op 1.00
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 357.06 us/op 343.93 us/op 1.04
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 622.37 us/op 605.09 us/op 1.03
prioritizePeers score 0:0 att 64-1 sync 4-1 742.27 us/op 696.72 us/op 1.07
array of 16000 items push then shift 1.2210 us/op 1.2917 us/op 0.95
LinkedList of 16000 items push then shift 7.2550 ns/op 6.6330 ns/op 1.09
array of 16000 items push then pop 67.234 ns/op 65.673 ns/op 1.02
LinkedList of 16000 items push then pop 5.8560 ns/op 5.8970 ns/op 0.99
array of 24000 items push then shift 1.8052 us/op 1.9010 us/op 0.95
LinkedList of 24000 items push then shift 6.8290 ns/op 6.2580 ns/op 1.09
array of 24000 items push then pop 94.922 ns/op 92.984 ns/op 1.02
LinkedList of 24000 items push then pop 5.8950 ns/op 5.9210 ns/op 1.00
intersect bitArray bitLen 8 4.6220 ns/op 4.6980 ns/op 0.98
intersect array and set length 8 28.232 ns/op 31.590 ns/op 0.89
intersect bitArray bitLen 128 23.325 ns/op 24.343 ns/op 0.96
intersect array and set length 128 487.40 ns/op 523.28 ns/op 0.93
bitArray.getTrueBitIndexes() bitLen 128 1.0040 us/op 1.0300 us/op 0.97
bitArray.getTrueBitIndexes() bitLen 248 1.7120 us/op 1.7270 us/op 0.99
bitArray.getTrueBitIndexes() bitLen 512 3.5500 us/op 3.4930 us/op 1.02
Full columns - reconstruct all 6 blobs 111.08 us/op 125.87 us/op 0.88
Full columns - reconstruct half of the blobs out of 6 63.181 us/op 85.475 us/op 0.74
Full columns - reconstruct single blob out of 6 35.089 us/op 34.015 us/op 1.03
Half columns - reconstruct all 6 blobs 392.28 ms/op 375.09 ms/op 1.05
Half columns - reconstruct half of the blobs out of 6 197.92 ms/op 187.89 ms/op 1.05
Half columns - reconstruct single blob out of 6 71.202 ms/op 66.610 ms/op 1.07
Full columns - reconstruct all 10 blobs 289.34 us/op 294.71 us/op 0.98
Full columns - reconstruct half of the blobs out of 10 95.430 us/op 151.61 us/op 0.63
Full columns - reconstruct single blob out of 10 29.766 us/op 31.293 us/op 0.95
Half columns - reconstruct all 10 blobs 651.05 ms/op 620.77 ms/op 1.05
Half columns - reconstruct half of the blobs out of 10 330.60 ms/op 313.24 ms/op 1.06
Half columns - reconstruct single blob out of 10 72.493 ms/op 66.577 ms/op 1.09
Full columns - reconstruct all 20 blobs 1.3593 ms/op 552.30 us/op 2.46
Full columns - reconstruct half of the blobs out of 20 259.24 us/op 162.68 us/op 1.59
Full columns - reconstruct single blob out of 20 26.841 us/op 31.824 us/op 0.84
Half columns - reconstruct all 20 blobs 1.3101 s/op 1.2457 s/op 1.05
Half columns - reconstruct half of the blobs out of 20 661.10 ms/op 627.15 ms/op 1.05
Half columns - reconstruct single blob out of 20 72.699 ms/op 66.929 ms/op 1.09
Set add up to 64 items then delete first 2.0281 us/op 2.6131 us/op 0.78
OrderedSet add up to 64 items then delete first 3.2050 us/op 3.4678 us/op 0.92
Set add up to 64 items then delete last 2.0634 us/op 2.4210 us/op 0.85
OrderedSet add up to 64 items then delete last 3.2710 us/op 3.5809 us/op 0.91
Set add up to 64 items then delete middle 2.0901 us/op 2.2392 us/op 0.93
OrderedSet add up to 64 items then delete middle 4.7676 us/op 5.0919 us/op 0.94
Set add up to 128 items then delete first 4.0516 us/op 4.3249 us/op 0.94
OrderedSet add up to 128 items then delete first 5.8603 us/op 6.4536 us/op 0.91
Set add up to 128 items then delete last 3.7623 us/op 4.3479 us/op 0.87
OrderedSet add up to 128 items then delete last 6.0127 us/op 6.4182 us/op 0.94
Set add up to 128 items then delete middle 3.7941 us/op 4.2406 us/op 0.89
OrderedSet add up to 128 items then delete middle 11.812 us/op 12.740 us/op 0.93
Set add up to 256 items then delete first 7.6484 us/op 8.2061 us/op 0.93
OrderedSet add up to 256 items then delete first 11.542 us/op 12.018 us/op 0.96
Set add up to 256 items then delete last 7.6347 us/op 8.0617 us/op 0.95
OrderedSet add up to 256 items then delete last 12.096 us/op 12.557 us/op 0.96
Set add up to 256 items then delete middle 7.4344 us/op 8.0974 us/op 0.92
OrderedSet add up to 256 items then delete middle 35.432 us/op 36.283 us/op 0.98
pass gossip attestations to forkchoice per slot 2.5944 ms/op 2.8540 ms/op 0.91
forkChoice updateHead vc 100000 bc 64 eq 0 449.77 us/op 500.48 us/op 0.90
forkChoice updateHead vc 600000 bc 64 eq 0 2.6978 ms/op 2.9029 ms/op 0.93
forkChoice updateHead vc 1000000 bc 64 eq 0 4.5273 ms/op 4.6476 ms/op 0.97
forkChoice updateHead vc 600000 bc 320 eq 0 2.8028 ms/op 2.7897 ms/op 1.00
forkChoice updateHead vc 600000 bc 1200 eq 0 2.7922 ms/op 2.8681 ms/op 0.97
forkChoice updateHead vc 600000 bc 7200 eq 0 3.1132 ms/op 3.0377 ms/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 1000 3.4206 ms/op 3.2702 ms/op 1.05
forkChoice updateHead vc 600000 bc 64 eq 10000 3.4885 ms/op 3.3742 ms/op 1.03
forkChoice updateHead vc 600000 bc 64 eq 300000 7.4062 ms/op 7.4018 ms/op 1.00
computeDeltas 1400000 validators 0% inactive 13.746 ms/op 14.213 ms/op 0.97
computeDeltas 1400000 validators 10% inactive 13.026 ms/op 12.713 ms/op 1.02
computeDeltas 1400000 validators 20% inactive 11.731 ms/op 11.812 ms/op 0.99
computeDeltas 1400000 validators 50% inactive 9.0185 ms/op 9.1878 ms/op 0.98
computeDeltas 2100000 validators 0% inactive 21.439 ms/op 20.452 ms/op 1.05
computeDeltas 2100000 validators 10% inactive 18.727 ms/op 19.296 ms/op 0.97
computeDeltas 2100000 validators 20% inactive 16.995 ms/op 18.027 ms/op 0.94
computeDeltas 2100000 validators 50% inactive 13.507 ms/op 13.707 ms/op 0.99
altair processAttestation - 250000 vs - 7PWei normalcase 1.8458 ms/op 1.6968 ms/op 1.09
altair processAttestation - 250000 vs - 7PWei worstcase 2.7734 ms/op 2.5426 ms/op 1.09
altair processAttestation - setStatus - 1/6 committees join 101.64 us/op 103.23 us/op 0.98
altair processAttestation - setStatus - 1/3 committees join 201.10 us/op 207.99 us/op 0.97
altair processAttestation - setStatus - 1/2 committees join 284.22 us/op 286.99 us/op 0.99
altair processAttestation - setStatus - 2/3 committees join 381.33 us/op 379.42 us/op 1.01
altair processAttestation - setStatus - 4/5 committees join 518.07 us/op 521.92 us/op 0.99
altair processAttestation - setStatus - 100% committees join 624.14 us/op 607.79 us/op 1.03
altair processBlock - 250000 vs - 7PWei normalcase 4.0637 ms/op 2.9648 ms/op 1.37
altair processBlock - 250000 vs - 7PWei normalcase hashState 21.312 ms/op 11.918 ms/op 1.79
altair processBlock - 250000 vs - 7PWei worstcase 23.117 ms/op 19.551 ms/op 1.18
altair processBlock - 250000 vs - 7PWei worstcase hashState 50.359 ms/op 42.451 ms/op 1.19
phase0 processBlock - 250000 vs - 7PWei normalcase 1.6938 ms/op 1.3338 ms/op 1.27
phase0 processBlock - 250000 vs - 7PWei worstcase 19.937 ms/op 16.944 ms/op 1.18
altair processEth1Data - 250000 vs - 7PWei normalcase 289.93 us/op 300.10 us/op 0.97
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 4.9280 us/op 3.5730 us/op 1.38
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 23.872 us/op 23.512 us/op 1.02
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 6.7920 us/op 6.2950 us/op 1.08
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 6.2000 us/op 4.0310 us/op 1.54
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 97.113 us/op 103.81 us/op 0.94
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4331 ms/op 1.4297 ms/op 1.00
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.1930 ms/op 1.9138 ms/op 1.15
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.2052 ms/op 1.9027 ms/op 1.16
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 6.0129 ms/op 3.8822 ms/op 1.55
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.1706 ms/op 2.1434 ms/op 1.01
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 6.2822 ms/op 4.2679 ms/op 1.47
Tree 40 250000 create 386.25 ms/op 319.36 ms/op 1.21
Tree 40 250000 get(125000) 106.92 ns/op 101.01 ns/op 1.06
Tree 40 250000 set(125000) 1.0645 us/op 1.0879 us/op 0.98
Tree 40 250000 toArray() 11.590 ms/op 9.6253 ms/op 1.20
Tree 40 250000 iterate all - toArray() + loop 11.949 ms/op 9.2748 ms/op 1.29
Tree 40 250000 iterate all - get(i) 42.514 ms/op 33.947 ms/op 1.25
Array 250000 create 2.2351 ms/op 2.0403 ms/op 1.10
Array 250000 clone - spread 679.24 us/op 646.25 us/op 1.05
Array 250000 get(125000) 0.31000 ns/op 0.29500 ns/op 1.05
Array 250000 set(125000) 0.31200 ns/op 0.30300 ns/op 1.03
Array 250000 iterate all - loop 58.701 us/op 56.367 us/op 1.04
phase0 afterProcessEpoch - 250000 vs - 7PWei 56.320 ms/op 52.975 ms/op 1.06
Array.fill - length 1000000 4.7627 ms/op 2.2783 ms/op 2.09
Array push - length 1000000 9.9227 ms/op 7.6614 ms/op 1.30
Array.get 0.21140 ns/op 0.20296 ns/op 1.04
Uint8Array.get 0.24511 ns/op 0.25417 ns/op 0.96
phase0 beforeProcessEpoch - 250000 vs - 7PWei 21.526 ms/op 13.831 ms/op 1.56
altair processEpoch - mainnet_e81889 356.64 ms/op 246.21 ms/op 1.45
mainnet_e81889 - altair beforeProcessEpoch 38.768 ms/op 15.638 ms/op 2.48
mainnet_e81889 - altair processJustificationAndFinalization 7.8000 us/op 4.8040 us/op 1.62
mainnet_e81889 - altair processInactivityUpdates 5.9801 ms/op 4.3586 ms/op 1.37
mainnet_e81889 - altair processRewardsAndPenalties 22.023 ms/op 17.873 ms/op 1.23
mainnet_e81889 - altair processRegistryUpdates 581.00 ns/op 564.00 ns/op 1.03
mainnet_e81889 - altair processSlashings 143.00 ns/op 133.00 ns/op 1.08
mainnet_e81889 - altair processEth1DataReset 134.00 ns/op 132.00 ns/op 1.02
mainnet_e81889 - altair processEffectiveBalanceUpdates 4.2237 ms/op 1.6664 ms/op 2.53
mainnet_e81889 - altair processSlashingsReset 715.00 ns/op 713.00 ns/op 1.00
mainnet_e81889 - altair processRandaoMixesReset 1.4720 us/op 1.0730 us/op 1.37
mainnet_e81889 - altair processHistoricalRootsUpdate 140.00 ns/op 130.00 ns/op 1.08
mainnet_e81889 - altair processParticipationFlagUpdates 448.00 ns/op 434.00 ns/op 1.03
mainnet_e81889 - altair processSyncCommitteeUpdates 115.00 ns/op 117.00 ns/op 0.98
mainnet_e81889 - altair afterProcessEpoch 42.418 ms/op 42.270 ms/op 1.00
capella processEpoch - mainnet_e217614 1.0125 s/op 788.30 ms/op 1.28
mainnet_e217614 - capella beforeProcessEpoch 62.316 ms/op 73.774 ms/op 0.84
mainnet_e217614 - capella processJustificationAndFinalization 6.6310 us/op 5.1220 us/op 1.29
mainnet_e217614 - capella processInactivityUpdates 13.447 ms/op 14.408 ms/op 0.93
mainnet_e217614 - capella processRewardsAndPenalties 103.31 ms/op 95.818 ms/op 1.08
mainnet_e217614 - capella processRegistryUpdates 4.4850 us/op 4.5220 us/op 0.99
mainnet_e217614 - capella processSlashings 137.00 ns/op 136.00 ns/op 1.01
mainnet_e217614 - capella processEth1DataReset 132.00 ns/op 129.00 ns/op 1.02
mainnet_e217614 - capella processEffectiveBalanceUpdates 17.310 ms/op 5.4466 ms/op 3.18
mainnet_e217614 - capella processSlashingsReset 695.00 ns/op 694.00 ns/op 1.00
mainnet_e217614 - capella processRandaoMixesReset 1.3410 us/op 1.0580 us/op 1.27
mainnet_e217614 - capella processHistoricalRootsUpdate 140.00 ns/op 134.00 ns/op 1.04
mainnet_e217614 - capella processParticipationFlagUpdates 459.00 ns/op 411.00 ns/op 1.12
mainnet_e217614 - capella afterProcessEpoch 106.42 ms/op 106.96 ms/op 0.99
phase0 processEpoch - mainnet_e58758 322.10 ms/op 271.34 ms/op 1.19
mainnet_e58758 - phase0 beforeProcessEpoch 65.240 ms/op 53.747 ms/op 1.21
mainnet_e58758 - phase0 processJustificationAndFinalization 6.4270 us/op 5.5410 us/op 1.16
mainnet_e58758 - phase0 processRewardsAndPenalties 15.972 ms/op 16.404 ms/op 0.97
mainnet_e58758 - phase0 processRegistryUpdates 2.2430 us/op 2.2590 us/op 0.99
mainnet_e58758 - phase0 processSlashings 135.00 ns/op 274.00 ns/op 0.49
mainnet_e58758 - phase0 processEth1DataReset 134.00 ns/op 144.00 ns/op 0.93
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 800.64 us/op 915.39 us/op 0.87
mainnet_e58758 - phase0 processSlashingsReset 872.00 ns/op 837.00 ns/op 1.04
mainnet_e58758 - phase0 processRandaoMixesReset 1.3950 us/op 1.0650 us/op 1.31
mainnet_e58758 - phase0 processHistoricalRootsUpdate 134.00 ns/op 145.00 ns/op 0.92
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.1790 us/op 1.0430 us/op 1.13
mainnet_e58758 - phase0 afterProcessEpoch 32.839 ms/op 34.249 ms/op 0.96
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.0310 ms/op 1.1009 ms/op 0.94
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.6355 ms/op 1.5910 ms/op 1.03
altair processInactivityUpdates - 250000 normalcase 11.529 ms/op 11.047 ms/op 1.04
altair processInactivityUpdates - 250000 worstcase 11.374 ms/op 11.021 ms/op 1.03
phase0 processRegistryUpdates - 250000 normalcase 2.3090 us/op 2.3060 us/op 1.00
phase0 processRegistryUpdates - 250000 badcase_full_deposits 144.71 us/op 158.43 us/op 0.91
phase0 processRegistryUpdates - 250000 worstcase 0.5 59.853 ms/op 56.177 ms/op 1.07
altair processRewardsAndPenalties - 250000 normalcase 16.630 ms/op 14.296 ms/op 1.16
altair processRewardsAndPenalties - 250000 worstcase 15.997 ms/op 13.970 ms/op 1.15
phase0 getAttestationDeltas - 250000 normalcase 5.2031 ms/op 5.2824 ms/op 0.98
phase0 getAttestationDeltas - 250000 worstcase 5.2616 ms/op 5.3335 ms/op 0.99
phase0 processSlashings - 250000 worstcase 58.734 us/op 63.024 us/op 0.93
altair processSyncCommitteeUpdates - 250000 10.546 ms/op 9.9673 ms/op 1.06
BeaconState.hashTreeRoot - No change 203.00 ns/op 193.00 ns/op 1.05
BeaconState.hashTreeRoot - 1 full validator 100.03 us/op 64.607 us/op 1.55
BeaconState.hashTreeRoot - 32 full validator 1.0106 ms/op 700.25 us/op 1.44
BeaconState.hashTreeRoot - 512 full validator 9.7354 ms/op 6.9180 ms/op 1.41
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 134.93 us/op 80.483 us/op 1.68
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.8146 ms/op 1.1663 ms/op 1.56
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 31.887 ms/op 14.009 ms/op 2.28
BeaconState.hashTreeRoot - 1 balances 98.282 us/op 61.830 us/op 1.59
BeaconState.hashTreeRoot - 32 balances 1.0888 ms/op 612.59 us/op 1.78
BeaconState.hashTreeRoot - 512 balances 6.9457 ms/op 5.1706 ms/op 1.34
BeaconState.hashTreeRoot - 250000 balances 214.40 ms/op 104.71 ms/op 2.05
aggregationBits - 2048 els - zipIndexesInBitList 20.632 us/op 20.181 us/op 1.02
regular array get 100000 times 25.598 us/op 22.579 us/op 1.13
wrappedArray get 100000 times 23.361 us/op 22.584 us/op 1.03
arrayWithProxy get 100000 times 10.894 ms/op 20.205 ms/op 0.54
ssz.Root.equals 21.917 ns/op 21.384 ns/op 1.02
byteArrayEquals 21.762 ns/op 21.188 ns/op 1.03
Buffer.compare 9.0870 ns/op 9.4300 ns/op 0.96
processSlot - 1 slots 11.185 us/op 8.6450 us/op 1.29
processSlot - 32 slots 2.5949 ms/op 1.6772 ms/op 1.55
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.3219 ms/op 3.7150 ms/op 1.16
getCommitteeAssignments - req 1 vs - 250000 vc 1.6822 ms/op 1.7120 ms/op 0.98
getCommitteeAssignments - req 100 vs - 250000 vc 3.4918 ms/op 3.4862 ms/op 1.00
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7453 ms/op 3.7197 ms/op 1.01
findModifiedValidators - 10000 modified validators 922.13 ms/op 726.12 ms/op 1.27
findModifiedValidators - 1000 modified validators 533.39 ms/op 404.91 ms/op 1.32
findModifiedValidators - 100 modified validators 301.32 ms/op 276.73 ms/op 1.09
findModifiedValidators - 10 modified validators 174.72 ms/op 224.68 ms/op 0.78
findModifiedValidators - 1 modified validators 181.10 ms/op 188.38 ms/op 0.96
findModifiedValidators - no difference 171.14 ms/op 172.73 ms/op 0.99
migrate state 1500000 validators, 3400 modified, 2000 new 4.1459 s/op 2.7000 s/op 1.54
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.8400 ns/op 3.6900 ns/op 1.04
state getBlockRootAtSlot - 250000 vs - 7PWei 489.36 ns/op 281.53 ns/op 1.74
computeProposerIndex 100000 validators 1.3828 ms/op 1.3228 ms/op 1.05
getNextSyncCommitteeIndices 1000 validators 2.9482 ms/op 2.8349 ms/op 1.04
getNextSyncCommitteeIndices 10000 validators 25.669 ms/op 24.961 ms/op 1.03
getNextSyncCommitteeIndices 100000 validators 89.409 ms/op 87.068 ms/op 1.03
computeProposers - vc 250000 550.78 us/op 543.27 us/op 1.01
computeEpochShuffling - vc 250000 39.042 ms/op 39.385 ms/op 0.99
getNextSyncCommittee - vc 250000 9.6186 ms/op 9.3816 ms/op 1.03
nodejs block root to RootHex using toHex 92.086 ns/op 106.76 ns/op 0.86
nodejs block root to RootHex using toRootHex 56.474 ns/op 62.322 ns/op 0.91
nodejs fromHex(blob) 821.21 us/op 754.72 us/op 1.09
nodejs fromHexInto(blob) 679.30 us/op 666.83 us/op 1.02
nodejs block root to RootHex using the deprecated toHexString 501.31 ns/op 492.95 ns/op 1.02
nodejs byteArrayEquals 32 bytes (block root) 26.352 ns/op 26.290 ns/op 1.00
nodejs byteArrayEquals 48 bytes (pubkey) 37.933 ns/op 37.708 ns/op 1.01
nodejs byteArrayEquals 96 bytes (signature) 39.573 ns/op 39.999 ns/op 0.99
nodejs byteArrayEquals 1024 bytes 46.135 ns/op 45.662 ns/op 1.01
nodejs byteArrayEquals 131072 bytes (blob) 1.7848 us/op 1.7612 us/op 1.01
browser block root to RootHex using toHex 148.09 ns/op 147.79 ns/op 1.00
browser block root to RootHex using toRootHex 133.16 ns/op 133.14 ns/op 1.00
browser fromHex(blob) 1.6685 ms/op 1.6194 ms/op 1.03
browser fromHexInto(blob) 603.22 us/op 671.36 us/op 0.90
browser block root to RootHex using the deprecated toHexString 316.29 ns/op 350.07 ns/op 0.90
browser byteArrayEquals 32 bytes (block root) 27.285 ns/op 28.190 ns/op 0.97
browser byteArrayEquals 48 bytes (pubkey) 38.135 ns/op 39.762 ns/op 0.96
browser byteArrayEquals 96 bytes (signature) 71.426 ns/op 74.184 ns/op 0.96
browser byteArrayEquals 1024 bytes 736.75 ns/op 760.10 ns/op 0.97
browser byteArrayEquals 131072 bytes (blob) 91.804 us/op 95.993 us/op 0.96

by benchmarkbot/action

@ensi321 ensi321 marked this pull request as ready for review April 27, 2026 15:20
@ensi321 ensi321 requested a review from a team as a code owner April 27, 2026 15:20
parentBlock: ProtoBlock;
feeRecipient?: string;
/** When provided, build block with this external bid instead of a self-build bid */
externalBid?: gloas.SignedExecutionPayloadBid;
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.

this name is confusing, if we self-build it's not really a "bid" just a placeholder, I would rather call this builderBid

? chain.executionPayloadBidPool.getBestBid(slot, parentBlockHash, parentBlockRootHex)
: null;

logger.verbose("Producing GLOAS block", {
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.

please remove gloas from the logs, we already have fork in log context

const baseAttrs = {slot, parentBlock, randaoReveal, graffiti: graffitiBytes, feeRecipient, commonBlockBodyPromise};

// Always build local block. If gossip bid available, also build with it in parallel and prefer it.
if (gossipBid) {
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 we need this if check? can't it just resolve null if there is no bid?

@@ -910,68 +1008,7 @@ export function getValidatorApi(
throw new ApiError(400, `produceBlockV4 not supported for pre-gloas fork=${fork}`);
}

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.

can we jus inline the logic for now, the diff is hard to review otherwise

// `(bid.slot, bid.parent_block_hash, bid.parent_block_root)`.
const bestBid = chain.executionPayloadBidPool.getBestBid(bid.slot, parentBlockHashHex, parentBlockRootHex);
if (bestBid !== null && bestBid.value >= bid.value) {
const bestSignedBid = chain.executionPayloadBidPool.getBestBid(bid.slot, parentBlockHashHex, parentBlockRootHex);
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 do we rename this? I feel like prev. name is fine

});
} else {
// External bid: the builder is responsible for broadcasting the execution payload envelope
this.logger.info("Published block with external builder bid, envelope expected from builder", {
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.

I don't think the "external" terminology is correct, it's either a builder bid or self-build, we can later differentiate gossip vs. api builder bids, but the term "external" seems confusing

slot,
parentSlot,
parentBlockRoot: parentBlockRootHex,
fork,
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.

need to also log parent hash everywhere

if (gossipResult.status === "fulfilled") {
metrics?.blockProductionSuccess.inc({source: ProducedBlockSource.builder});
logger.info("Selected gossip bid block", {
slot,
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.

log more bid data to debug later


if (engineResult.status === "fulfilled") {
metrics?.blockProductionSuccess.inc({source: ProducedBlockSource.engine});
logger.warn("Gossip bid block production failed, using local block", {slot});
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.

may want a logCtx to be shared everywhere


this.logger.verbose("Fetching execution payload from engine", {slot: blockSlot, payloadId});
const payloadRes = await this.executionEngine.getPayload(fork, payloadId);
this.logger.verbose("Preparing execution payload from engine", {
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.

may delay this to line 252 below to add more data to log?

Object.assign(logMeta, {executionPayloadPrepType: prepType});

if (prepType !== PayloadPreparationType.Cached) {
await sleep(PAYLOAD_GENERATION_TIME_MS);
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.

not sure why we have to sleep() to wait for EL, may use Promise.race() or something like it if needed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we don't modify this file much in this PR.

This code hasn't changed here. Just the diff shown is messed up. Will work on reducing diff for easier review

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