Skip to content

feat: broadcast proposer preferences before the gloas fork#9571

Merged
nflaig merged 1 commit into
unstablefrom
nflaig/proposer-preferences-pre-fork-submission
Jul 4, 2026
Merged

feat: broadcast proposer preferences before the gloas fork#9571
nflaig merged 1 commit into
unstablefrom
nflaig/proposer-preferences-pre-fork-submission

Conversation

@nflaig

@nflaig nflaig commented Jun 30, 2026

Copy link
Copy Markdown
Member

As per ethereum/beacon-APIs#608

Validator clients SHOULD begin submitting signed proposer preferences one epoch before the
Gloas fork activates, so the proposer preference caches kept by both beacon nodes and
builders are warm at the fork boundary, letting builders prepare valid bids for the first
Gloas slots.

Also related to ethereum/consensus-specs#4947 but we already do this since we subscribe to new gossip topics 2 epochs before the fork (SUBSCRIPTIONS_LOOKAHEAD_EPOCHS = 2).

@nflaig nflaig requested a review from a team as a code owner June 30, 2026 12:03

@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 updates the ProposerPreferencesService to enable broadcasting proposer preferences prior to the Gloas fork, ensuring caches are warm for the initial Gloas slots. The task now initiates when the submission window (slot + SUBMIT_BEFORE_PROPOSAL_SLOTS) reaches Gloas, and a check has been added to skip duties that are not post-Gloas. There are no review comments, so no feedback is provided.

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.

@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: af6acda441

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// Start running once the submission window (`slot + SUBMIT_BEFORE_PROPOSAL_SLOTS`) reaches
// Gloas, i.e. already in the epoch before the fork. This allows builders to prepare and
// submit bids for the first Gloas slots.
if (!isForkPostGloas(this.config.getForkName(slot + SUBMIT_BEFORE_PROPOSAL_SLOTS))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh upcoming Gloas duties before pre-fork submissions

Once this pre-fork path is enabled, the task consumes getProposersAtEpoch(currentEpoch + 1) while the clock is still in the final pre-Gloas epoch. I checked BlockDutiesService.onNewHead: in the pre-Gloas branch it only refetches currentEpoch, so if a reorg changes the dependent root for the upcoming Gloas epoch after the epoch-start prefetch, the cached Gloas duties remain under the old root. In that scenario these early submissions are signed with a stale dependentRoot, causing the beacon node to ignore/reject them and leaving builders without valid preferences for the first Gloas slots.

Useful? React with 👍 / 👎.

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 I don't think this edge case is worth handling, a reorg in the last SUBMIT_BEFORE_PROPOSAL_SLOTS of the pre-gloas epoch is very unlikely and we will still submit correctly at slot 0 of gloas

@github-actions

Copy link
Copy Markdown
Contributor

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 6218868 Previous: 171f602 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.2320 ms/op 1.0786 ms/op 1.14
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 40.059 us/op 39.823 us/op 1.01
BLS verify - blst 741.54 us/op 766.29 us/op 0.97
BLS verifyMultipleSignatures 3 - blst 1.3289 ms/op 1.3692 ms/op 0.97
BLS verifyMultipleSignatures 8 - blst 2.1106 ms/op 2.1691 ms/op 0.97
BLS verifyMultipleSignatures 32 - blst 6.5646 ms/op 6.7801 ms/op 0.97
BLS verifyMultipleSignatures 64 - blst 12.828 ms/op 13.128 ms/op 0.98
BLS verifyMultipleSignatures 128 - blst 25.099 ms/op 25.614 ms/op 0.98
BLS deserializing 10000 signatures 634.56 ms/op 635.37 ms/op 1.00
BLS deserializing 100000 signatures 6.4047 s/op 6.3895 s/op 1.00
BLS verifyMultipleSignatures - same message - 3 - blst 752.09 us/op 828.68 us/op 0.91
BLS verifyMultipleSignatures - same message - 8 - blst 910.89 us/op 898.42 us/op 1.01
BLS verifyMultipleSignatures - same message - 32 - blst 1.5527 ms/op 1.5799 ms/op 0.98
BLS verifyMultipleSignatures - same message - 64 - blst 2.4170 ms/op 2.4534 ms/op 0.99
BLS verifyMultipleSignatures - same message - 128 - blst 4.0778 ms/op 4.0641 ms/op 1.00
BLS aggregatePubkeys 32 - blst 17.848 us/op 17.715 us/op 1.01
BLS aggregatePubkeys 128 - blst 63.337 us/op 63.464 us/op 1.00
getSlashingsAndExits - default max 54.104 us/op 52.724 us/op 1.03
getSlashingsAndExits - 2k 433.73 us/op 338.71 us/op 1.28
proposeBlockBody type=full, size=empty 671.61 us/op 738.20 us/op 0.91
isKnown best case - 1 super set check 195.00 ns/op 181.00 ns/op 1.08
isKnown normal case - 2 super set checks 168.00 ns/op 170.00 ns/op 0.99
isKnown worse case - 16 super set checks 164.00 ns/op 172.00 ns/op 0.95
validate api signedAggregateAndProof - struct 1.5126 ms/op 1.5296 ms/op 0.99
validate gossip signedAggregateAndProof - struct 1.5185 ms/op 1.5252 ms/op 1.00
batch validate gossip attestation - vc 640000 - chunk 32 119.57 us/op 106.97 us/op 1.12
batch validate gossip attestation - vc 640000 - chunk 64 105.20 us/op 96.390 us/op 1.09
batch validate gossip attestation - vc 640000 - chunk 128 96.776 us/op 88.638 us/op 1.09
batch validate gossip attestation - vc 640000 - chunk 256 92.454 us/op 84.643 us/op 1.09
bytes32 toHexString 282.00 ns/op 289.00 ns/op 0.98
bytes32 Buffer.toString(hex) 168.00 ns/op 167.00 ns/op 1.01
bytes32 Buffer.toString(hex) from Uint8Array 230.00 ns/op 240.00 ns/op 0.96
bytes32 Buffer.toString(hex) + 0x 166.00 ns/op 169.00 ns/op 0.98
Return object 10000 times 0.21250 ns/op 0.21350 ns/op 1.00
Throw Error 10000 times 3.4280 us/op 3.5591 us/op 0.96
toHex 94.948 ns/op 101.57 ns/op 0.93
Buffer.from 85.860 ns/op 91.185 ns/op 0.94
shared Buffer 57.955 ns/op 64.074 ns/op 0.90
fastMsgIdFn sha256 / 200 bytes 1.4910 us/op 1.4870 us/op 1.00
fastMsgIdFn h32 xxhash / 200 bytes 159.00 ns/op 157.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 200 bytes 199.00 ns/op 204.00 ns/op 0.98
fastMsgIdFn sha256 / 1000 bytes 4.7350 us/op 4.7570 us/op 1.00
fastMsgIdFn h32 xxhash / 1000 bytes 247.00 ns/op 245.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 1000 bytes 248.00 ns/op 249.00 ns/op 1.00
fastMsgIdFn sha256 / 10000 bytes 41.498 us/op 42.000 us/op 0.99
fastMsgIdFn h32 xxhash / 10000 bytes 1.2730 us/op 1.2900 us/op 0.99
fastMsgIdFn h64 xxhash / 10000 bytes 824.00 ns/op 833.00 ns/op 0.99
send data - 1000 256B messages 4.7728 ms/op 4.4161 ms/op 1.08
send data - 1000 512B messages 6.2820 ms/op 5.2045 ms/op 1.21
send data - 1000 1024B messages 6.0344 ms/op 5.3687 ms/op 1.12
send data - 1000 1200B messages 6.8490 ms/op 6.1498 ms/op 1.11
send data - 1000 2048B messages 19.233 ms/op 9.0268 ms/op 2.13
send data - 1000 4096B messages 63.173 ms/op 29.443 ms/op 2.15
send data - 1000 16384B messages 302.52 ms/op 227.87 ms/op 1.33
send data - 1000 65536B messages 682.60 ms/op 1.1219 s/op 0.61
enrSubnets - fastDeserialize 64 bits 742.00 ns/op 758.00 ns/op 0.98
enrSubnets - ssz BitVector 64 bits 257.00 ns/op 261.00 ns/op 0.98
enrSubnets - fastDeserialize 4 bits 103.00 ns/op 107.00 ns/op 0.96
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 206.94 us/op 206.79 us/op 1.00
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 251.61 us/op 246.68 us/op 1.02
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 349.31 us/op 342.27 us/op 1.02
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 619.39 us/op 595.36 us/op 1.04
prioritizePeers score 0:0 att 64-1 sync 4-1 719.44 us/op 695.53 us/op 1.03
array of 16000 items push then shift 1.2589 us/op 1.2961 us/op 0.97
LinkedList of 16000 items push then shift 8.0250 ns/op 6.8370 ns/op 1.17
array of 16000 items push then pop 73.064 ns/op 66.475 ns/op 1.10
LinkedList of 16000 items push then pop 6.1770 ns/op 6.0250 ns/op 1.03
array of 24000 items push then shift 1.8605 us/op 1.9117 us/op 0.97
LinkedList of 24000 items push then shift 8.1070 ns/op 6.3120 ns/op 1.28
array of 24000 items push then pop 104.92 ns/op 93.889 ns/op 1.12
LinkedList of 24000 items push then pop 6.1780 ns/op 5.9980 ns/op 1.03
intersect bitArray bitLen 8 4.7510 ns/op 4.7390 ns/op 1.00
intersect array and set length 8 29.436 ns/op 30.054 ns/op 0.98
intersect bitArray bitLen 128 23.909 ns/op 24.022 ns/op 1.00
intersect array and set length 128 503.54 ns/op 503.02 ns/op 1.00
bitArray.getTrueBitIndexes() bitLen 128 1.0460 us/op 1.0060 us/op 1.04
bitArray.getTrueBitIndexes() bitLen 248 1.7680 us/op 1.7440 us/op 1.01
bitArray.getTrueBitIndexes() bitLen 512 3.6580 us/op 3.5620 us/op 1.03
Full columns - reconstruct all 6 blobs 122.84 us/op 182.87 us/op 0.67
Full columns - reconstruct half of the blobs out of 6 100.08 us/op 68.143 us/op 1.47
Full columns - reconstruct single blob out of 6 31.202 us/op 35.210 us/op 0.89
Half columns - reconstruct all 6 blobs 387.70 ms/op 380.02 ms/op 1.02
Half columns - reconstruct half of the blobs out of 6 195.18 ms/op 193.11 ms/op 1.01
Half columns - reconstruct single blob out of 6 69.198 ms/op 69.374 ms/op 1.00
Set add up to 64 items then delete first 1.6034 us/op 1.6918 us/op 0.95
OrderedSet add up to 64 items then delete first 2.4844 us/op 2.5612 us/op 0.97
Set add up to 64 items then delete last 1.8482 us/op 1.9545 us/op 0.95
OrderedSet add up to 64 items then delete last 2.8608 us/op 2.8440 us/op 1.01
Set add up to 64 items then delete middle 1.8760 us/op 1.9388 us/op 0.97
OrderedSet add up to 64 items then delete middle 4.3740 us/op 4.3127 us/op 1.01
Set add up to 128 items then delete first 3.6209 us/op 3.9439 us/op 0.92
OrderedSet add up to 128 items then delete first 5.4164 us/op 5.8370 us/op 0.93
Set add up to 128 items then delete last 3.6191 us/op 3.7517 us/op 0.96
OrderedSet add up to 128 items then delete last 6.1746 us/op 5.4641 us/op 1.13
Set add up to 128 items then delete middle 3.6226 us/op 3.7511 us/op 0.97
OrderedSet add up to 128 items then delete middle 11.608 us/op 11.409 us/op 1.02
Set add up to 256 items then delete first 7.2525 us/op 7.6860 us/op 0.94
OrderedSet add up to 256 items then delete first 11.984 us/op 11.899 us/op 1.01
Set add up to 256 items then delete last 7.3074 us/op 7.5252 us/op 0.97
OrderedSet add up to 256 items then delete last 12.186 us/op 11.118 us/op 1.10
Set add up to 256 items then delete middle 7.6781 us/op 7.3772 us/op 1.04
OrderedSet add up to 256 items then delete middle 35.559 us/op 34.465 us/op 1.03
runFastConfirmationRules vc:100000 bc:96 eq:0 3.6140 us/op 4.0630 us/op 0.89
runFastConfirmationRules vc:600000 bc:96 eq:0 3.2640 us/op 3.8610 us/op 0.85
runFastConfirmationRules vc:1000000 bc:96 eq:0 3.6840 us/op 3.5420 us/op 1.04
runFastConfirmationRules vc:600000 bc:320 eq:0 9.8890 us/op 10.905 us/op 0.91
runFastConfirmationRules vc:600000 bc:1200 eq:0 35.225 us/op 35.030 us/op 1.01
runFastConfirmationRules vc:600000 bc:96 eq:1000 3.5000 us/op 3.4210 us/op 1.02
runFastConfirmationRules vc:600000 bc:96 eq:10000 3.4590 us/op 3.7120 us/op 0.93
runFastConfirmationRules vc:600000 bc:96 eq:300000 3.5710 us/op 3.8360 us/op 0.93
pass gossip attestations to forkchoice per slot 2.6214 ms/op 2.5391 ms/op 1.03
forkChoice updateHead vc 100000 bc 64 eq 0 406.79 us/op 487.42 us/op 0.83
forkChoice updateHead vc 600000 bc 64 eq 0 2.4559 ms/op 2.9132 ms/op 0.84
forkChoice updateHead vc 1000000 bc 64 eq 0 4.0853 ms/op 4.7725 ms/op 0.86
forkChoice updateHead vc 600000 bc 320 eq 0 2.4751 ms/op 2.9108 ms/op 0.85
forkChoice updateHead vc 600000 bc 1200 eq 0 2.5526 ms/op 2.9074 ms/op 0.88
forkChoice updateHead vc 600000 bc 7200 eq 0 3.7581 ms/op 3.2480 ms/op 1.16
forkChoice updateHead vc 600000 bc 64 eq 1000 2.4601 ms/op 3.0121 ms/op 0.82
forkChoice updateHead vc 600000 bc 64 eq 10000 2.5940 ms/op 3.1024 ms/op 0.84
forkChoice updateHead vc 600000 bc 64 eq 300000 7.0921 ms/op 7.4545 ms/op 0.95
computeDeltas 1400000 validators 0% inactive 12.761 ms/op 14.075 ms/op 0.91
computeDeltas 1400000 validators 10% inactive 11.939 ms/op 12.879 ms/op 0.93
computeDeltas 1400000 validators 20% inactive 10.737 ms/op 11.959 ms/op 0.90
computeDeltas 1400000 validators 50% inactive 8.3337 ms/op 9.3386 ms/op 0.89
computeDeltas 2100000 validators 0% inactive 18.906 ms/op 20.481 ms/op 0.92
computeDeltas 2100000 validators 10% inactive 17.857 ms/op 19.307 ms/op 0.92
computeDeltas 2100000 validators 20% inactive 16.322 ms/op 17.965 ms/op 0.91
computeDeltas 2100000 validators 50% inactive 9.4020 ms/op 14.050 ms/op 0.67
altair processAttestation - 250000 vs - 7PWei normalcase 2.5983 ms/op 1.6945 ms/op 1.53
altair processAttestation - 250000 vs - 7PWei worstcase 3.4258 ms/op 2.4819 ms/op 1.38
altair processAttestation - setStatus - 1/6 committees join 101.33 us/op 108.78 us/op 0.93
altair processAttestation - setStatus - 1/3 committees join 199.36 us/op 201.77 us/op 0.99
altair processAttestation - setStatus - 1/2 committees join 289.46 us/op 292.05 us/op 0.99
altair processAttestation - setStatus - 2/3 committees join 366.14 us/op 382.40 us/op 0.96
altair processAttestation - setStatus - 4/5 committees join 520.07 us/op 517.82 us/op 1.00
altair processAttestation - setStatus - 100% committees join 614.14 us/op 603.90 us/op 1.02
altair processBlock - 250000 vs - 7PWei normalcase 4.7709 ms/op 2.9269 ms/op 1.63
altair processBlock - 250000 vs - 7PWei normalcase hashState 15.428 ms/op 11.663 ms/op 1.32
altair processBlock - 250000 vs - 7PWei worstcase 23.097 ms/op 19.070 ms/op 1.21
altair processBlock - 250000 vs - 7PWei worstcase hashState 45.555 ms/op 39.162 ms/op 1.16
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3021 ms/op 1.2940 ms/op 1.01
phase0 processBlock - 250000 vs - 7PWei worstcase 18.370 ms/op 16.764 ms/op 1.10
altair processEth1Data - 250000 vs - 7PWei normalcase 307.61 us/op 316.96 us/op 0.97
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 4.4710 us/op 3.3790 us/op 1.32
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 21.238 us/op 22.090 us/op 0.96
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 6.9540 us/op 6.6530 us/op 1.05
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 4.9660 us/op 4.5750 us/op 1.09
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 91.688 us/op 100.05 us/op 0.92
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.3707 ms/op 1.3762 ms/op 1.00
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8156 ms/op 1.8302 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7889 ms/op 1.8236 ms/op 0.98
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.7603 ms/op 3.5969 ms/op 1.05
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0376 ms/op 2.0500 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.1448 ms/op 3.9557 ms/op 1.05
Tree 40 250000 create 353.40 ms/op 318.91 ms/op 1.11
Tree 40 250000 get(125000) 93.146 ns/op 109.20 ns/op 0.85
Tree 40 250000 set(125000) 1.0139 us/op 1.0922 us/op 0.93
Tree 40 250000 toArray() 16.376 ms/op 9.6024 ms/op 1.71
Tree 40 250000 iterate all - toArray() + loop 17.535 ms/op 9.7012 ms/op 1.81
Tree 40 250000 iterate all - get(i) 39.852 ms/op 34.353 ms/op 1.16
Array 250000 create 2.2169 ms/op 2.0771 ms/op 1.07
Array 250000 clone - spread 695.86 us/op 655.26 us/op 1.06
Array 250000 get(125000) 0.29300 ns/op 0.29600 ns/op 0.99
Array 250000 set(125000) 0.29300 ns/op 0.30200 ns/op 0.97
Array 250000 iterate all - loop 57.520 us/op 56.621 us/op 1.02
phase0 afterProcessEpoch - 250000 vs - 7PWei 40.846 ms/op 39.247 ms/op 1.04
Array.fill - length 1000000 2.8694 ms/op 2.2222 ms/op 1.29
Array push - length 1000000 9.9523 ms/op 7.3663 ms/op 1.35
Array.get 0.20707 ns/op 0.20440 ns/op 1.01
Uint8Array.get 0.24029 ns/op 0.26171 ns/op 0.92
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.704 ms/op 11.822 ms/op 1.33
altair processEpoch - mainnet_e81889 274.16 ms/op 239.62 ms/op 1.14
mainnet_e81889 - altair beforeProcessEpoch 21.098 ms/op 14.171 ms/op 1.49
mainnet_e81889 - altair processJustificationAndFinalization 6.2680 us/op 4.6360 us/op 1.35
mainnet_e81889 - altair processInactivityUpdates 4.6055 ms/op 3.6174 ms/op 1.27
mainnet_e81889 - altair processRewardsAndPenalties 20.179 ms/op 17.253 ms/op 1.17
mainnet_e81889 - altair processRegistryUpdates 531.00 ns/op 533.00 ns/op 1.00
mainnet_e81889 - altair processSlashings 126.00 ns/op 143.00 ns/op 0.88
mainnet_e81889 - altair processEth1DataReset 125.00 ns/op 137.00 ns/op 0.91
mainnet_e81889 - altair processEffectiveBalanceUpdates 2.6033 ms/op 1.5262 ms/op 1.71
mainnet_e81889 - altair processSlashingsReset 672.00 ns/op 689.00 ns/op 0.98
mainnet_e81889 - altair processRandaoMixesReset 1.2460 us/op 970.00 ns/op 1.28
mainnet_e81889 - altair processHistoricalRootsUpdate 134.00 ns/op 136.00 ns/op 0.99
mainnet_e81889 - altair processParticipationFlagUpdates 432.00 ns/op 422.00 ns/op 1.02
mainnet_e81889 - altair processSyncCommitteeUpdates 103.00 ns/op 113.00 ns/op 0.91
mainnet_e81889 - altair afterProcessEpoch 41.502 ms/op 41.093 ms/op 1.01
capella processEpoch - mainnet_e217614 841.53 ms/op 724.23 ms/op 1.16
mainnet_e217614 - capella beforeProcessEpoch 56.401 ms/op 60.214 ms/op 0.94
mainnet_e217614 - capella processJustificationAndFinalization 6.3970 us/op 5.1180 us/op 1.25
mainnet_e217614 - capella processInactivityUpdates 16.970 ms/op 11.866 ms/op 1.43
mainnet_e217614 - capella processRewardsAndPenalties 93.843 ms/op 92.862 ms/op 1.01
mainnet_e217614 - capella processRegistryUpdates 4.3660 us/op 4.4280 us/op 0.99
mainnet_e217614 - capella processSlashings 128.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 16.345 ms/op 5.3985 ms/op 3.03
mainnet_e217614 - capella processSlashingsReset 667.00 ns/op 667.00 ns/op 1.00
mainnet_e217614 - capella processRandaoMixesReset 1.3200 us/op 1.0470 us/op 1.26
mainnet_e217614 - capella processHistoricalRootsUpdate 128.00 ns/op 140.00 ns/op 0.91
mainnet_e217614 - capella processParticipationFlagUpdates 433.00 ns/op 434.00 ns/op 1.00
mainnet_e217614 - capella afterProcessEpoch 107.48 ms/op 105.68 ms/op 1.02
phase0 processEpoch - mainnet_e58758 315.82 ms/op 264.49 ms/op 1.19
mainnet_e58758 - phase0 beforeProcessEpoch 68.305 ms/op 50.519 ms/op 1.35
mainnet_e58758 - phase0 processJustificationAndFinalization 6.5520 us/op 5.1460 us/op 1.27
mainnet_e58758 - phase0 processRewardsAndPenalties 16.868 ms/op 14.888 ms/op 1.13
mainnet_e58758 - phase0 processRegistryUpdates 2.2260 us/op 2.2520 us/op 0.99
mainnet_e58758 - phase0 processSlashings 132.00 ns/op 142.00 ns/op 0.93
mainnet_e58758 - phase0 processEth1DataReset 127.00 ns/op 135.00 ns/op 0.94
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.1397 ms/op 918.66 us/op 1.24
mainnet_e58758 - phase0 processSlashingsReset 882.00 ns/op 1.4500 us/op 0.61
mainnet_e58758 - phase0 processRandaoMixesReset 1.3040 us/op 998.00 ns/op 1.31
mainnet_e58758 - phase0 processHistoricalRootsUpdate 131.00 ns/op 147.00 ns/op 0.89
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2250 us/op 1.0140 us/op 1.21
mainnet_e58758 - phase0 afterProcessEpoch 32.892 ms/op 32.811 ms/op 1.00
phase0 processEffectiveBalanceUpdates - 250000 normalcase 992.62 us/op 1.0084 ms/op 0.98
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.6391 ms/op 1.6338 ms/op 1.00
altair processInactivityUpdates - 250000 normalcase 12.442 ms/op 10.523 ms/op 1.18
altair processInactivityUpdates - 250000 worstcase 12.625 ms/op 10.694 ms/op 1.18
phase0 processRegistryUpdates - 250000 normalcase 3.3590 us/op 2.1630 us/op 1.55
phase0 processRegistryUpdates - 250000 badcase_full_deposits 141.05 us/op 140.52 us/op 1.00
phase0 processRegistryUpdates - 250000 worstcase 0.5 67.519 ms/op 64.034 ms/op 1.05
altair processRewardsAndPenalties - 250000 normalcase 16.629 ms/op 13.156 ms/op 1.26
altair processRewardsAndPenalties - 250000 worstcase 16.141 ms/op 13.069 ms/op 1.24
phase0 getAttestationDeltas - 250000 normalcase 5.3291 ms/op 5.4714 ms/op 0.97
phase0 getAttestationDeltas - 250000 worstcase 5.3616 ms/op 5.4796 ms/op 0.98
phase0 processSlashings - 250000 worstcase 62.404 us/op 61.274 us/op 1.02
altair processSyncCommitteeUpdates - 250000 12.221 ms/op 10.056 ms/op 1.22
BeaconState.hashTreeRoot - No change 168.00 ns/op 179.00 ns/op 0.94
BeaconState.hashTreeRoot - 1 full validator 73.737 us/op 59.593 us/op 1.24
BeaconState.hashTreeRoot - 32 full validator 807.46 us/op 667.03 us/op 1.21
BeaconState.hashTreeRoot - 512 full validator 8.7348 ms/op 6.3604 ms/op 1.37
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 102.64 us/op 72.012 us/op 1.43
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.5145 ms/op 1.5054 ms/op 1.01
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 21.002 ms/op 18.732 ms/op 1.12
BeaconState.hashTreeRoot - 1 balances 86.348 us/op 79.534 us/op 1.09
BeaconState.hashTreeRoot - 32 balances 811.63 us/op 740.72 us/op 1.10
BeaconState.hashTreeRoot - 512 balances 6.6582 ms/op 5.5332 ms/op 1.20
BeaconState.hashTreeRoot - 250000 balances 126.35 ms/op 123.81 ms/op 1.02
aggregationBits - 2048 els - zipIndexesInBitList 20.214 us/op 21.433 us/op 0.94
regular array get 100000 times 23.220 us/op 23.436 us/op 0.99
wrappedArray get 100000 times 23.111 us/op 23.379 us/op 0.99
arrayWithProxy get 100000 times 10.726 ms/op 12.999 ms/op 0.83
ssz.Root.equals 21.578 ns/op 21.881 ns/op 0.99
byteArrayEquals 21.364 ns/op 21.641 ns/op 0.99
Buffer.compare 8.8570 ns/op 9.0050 ns/op 0.98
processSlot - 1 slots 10.888 us/op 10.161 us/op 1.07
processSlot - 32 slots 2.2019 ms/op 2.1868 ms/op 1.01
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.0323 ms/op 2.5608 ms/op 1.57
getCommitteeAssignments - req 1 vs - 250000 vc 1.6685 ms/op 1.6941 ms/op 0.98
getCommitteeAssignments - req 100 vs - 250000 vc 3.4598 ms/op 3.4729 ms/op 1.00
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7132 ms/op 3.7385 ms/op 0.99
findModifiedValidators - 10000 modified validators 700.66 ms/op 827.19 ms/op 0.85
findModifiedValidators - 1000 modified validators 432.00 ms/op 603.32 ms/op 0.72
findModifiedValidators - 100 modified validators 307.36 ms/op 356.02 ms/op 0.86
findModifiedValidators - 10 modified validators 251.26 ms/op 300.57 ms/op 0.84
findModifiedValidators - 1 modified validators 149.50 ms/op 168.85 ms/op 0.89
findModifiedValidators - no difference 157.15 ms/op 185.11 ms/op 0.85
migrate state 1500000 validators, 3400 modified, 2000 new 2.9985 s/op 3.1717 s/op 0.95
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.6600 ns/op 3.8100 ns/op 0.96
state getBlockRootAtSlot - 250000 vs - 7PWei 384.36 ns/op 271.96 ns/op 1.41
computeProposerIndex 100000 validators 1.3094 ms/op 1.3654 ms/op 0.96
getNextSyncCommitteeIndices 1000 validators 2.8316 ms/op 2.9089 ms/op 0.97
getNextSyncCommitteeIndices 10000 validators 25.198 ms/op 25.663 ms/op 0.98
getNextSyncCommitteeIndices 100000 validators 83.888 ms/op 89.292 ms/op 0.94
computeProposers - vc 250000 546.62 us/op 581.08 us/op 0.94
computeEpochShuffling - vc 250000 39.461 ms/op 41.454 ms/op 0.95
getNextSyncCommittee - vc 250000 9.6332 ms/op 9.6061 ms/op 1.00
nodejs block root to RootHex using toHex 96.820 ns/op 102.04 ns/op 0.95
nodejs block root to RootHex using toRootHex 62.529 ns/op 66.874 ns/op 0.94
nodejs fromHex(blob) 724.25 us/op 853.01 us/op 0.85
nodejs fromHexInto(blob) 623.27 us/op 649.89 us/op 0.96
nodejs block root to RootHex using the deprecated toHexString 514.36 ns/op 484.48 ns/op 1.06
nodejs byteArrayEquals 32 bytes (block root) 25.708 ns/op 26.438 ns/op 0.97
nodejs byteArrayEquals 48 bytes (pubkey) 37.067 ns/op 38.212 ns/op 0.97
nodejs byteArrayEquals 96 bytes (signature) 33.450 ns/op 38.061 ns/op 0.88
nodejs byteArrayEquals 1024 bytes 41.715 ns/op 45.206 ns/op 0.92
nodejs byteArrayEquals 131072 bytes (blob) 1.7333 us/op 1.7797 us/op 0.97
browser block root to RootHex using toHex 141.71 ns/op 148.14 ns/op 0.96
browser block root to RootHex using toRootHex 128.65 ns/op 131.54 ns/op 0.98
browser fromHex(blob) 1.5512 ms/op 1.7388 ms/op 0.89
browser fromHexInto(blob) 630.44 us/op 665.57 us/op 0.95
browser block root to RootHex using the deprecated toHexString 359.90 ns/op 338.51 ns/op 1.06
browser byteArrayEquals 32 bytes (block root) 27.924 ns/op 28.260 ns/op 0.99
browser byteArrayEquals 48 bytes (pubkey) 39.222 ns/op 39.885 ns/op 0.98
browser byteArrayEquals 96 bytes (signature) 73.535 ns/op 74.583 ns/op 0.99
browser byteArrayEquals 1024 bytes 747.63 ns/op 755.39 ns/op 0.99
browser byteArrayEquals 131072 bytes (blob) 94.402 us/op 95.488 us/op 0.99

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 to me
one thing found during the review is we never prune the submitted map
we can either do it now or in a separate PR @nflaig

@nflaig nflaig merged commit 9d930bd into unstable Jul 4, 2026
19 checks passed
@nflaig nflaig deleted the nflaig/proposer-preferences-pre-fork-submission branch July 4, 2026 20:16
nflaig added a commit that referenced this pull request Jul 6, 2026
### Motivation

Follow-up to #9571. The `submitted` map in `ProposerPreferencesService`
tracks which preferences were sent per epoch but was never pruned, so it
grows by one entry each epoch for the lifetime of the process. Raised in
review by @twoeths.

### Description

Drop tracking for past epochs at the start of each task run; only
`currentEpoch` and `currentEpoch + 1` are ever processed.
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.

2 participants