Skip to content

feat: trigger processExecutionPayload() once#9223

Merged
wemeetagain merged 3 commits intounstablefrom
te/trigger_process_execution_payload
Apr 20, 2026
Merged

feat: trigger processExecutionPayload() once#9223
wemeetagain merged 3 commits intounstablefrom
te/trigger_process_execution_payload

Conversation

@twoeths
Copy link
Copy Markdown
Contributor

@twoeths twoeths commented Apr 16, 2026

Motivation

Post-gloas, chain.processExecutionPayload() was being triggered from 4 sites, including one that fires on every data-column gossip sidecar — up to 128 times per slot. Each call reached the queue only to be silently dropped by a !isComplete() guard while waiting for the envelope or missing columns. A standing TODO in importBlock.ts tracked this same issue.

Description

Mirror the existing BlockInput / verifyBlocksDataAvailability pattern for payload envelopes.

  • Triggers chain.processExecutionPayload() only on envelope arrival (gossip + API publish). Removes the per-column gossip trigger and the getBlobsTracker.triggerGetBlobs onComplete callback from block import.
  • Adds PayloadEnvelopeInput.waitForAllData(timeout, signal) — mirrors BlockInput.waitForAllData; resolves once on the first state.hasAllData transition.
  • Adds verifyPayloadsDataAvailability(payloadInputs, signal) — exact twin of verifyBlocksDataAvailability (array input, PAYLOAD_DATA_AVAILABILITY_TIMEOUT = 12_000). Reusable by future gloas sync services.
  • importExecutionPayload awaits the helper after the ProtoBlock lookup and before claiming a write-queue slot.
  • Removes the !isComplete() early return in PayloadEnvelopeProcessor — the importStatus WeakMap still dedupes duplicate triggers for the same payloadInput.
  • Drops the now-unused onComplete parameter from GetBlobsTracker.triggerGetBlobs.
  • Adds 7 unit tests covering NotRequired / Available / wait-for-columns / reconstruction-threshold / timeout / abort, plus the waitForAllData vs waitForComputedAllData distinction.

Closes #9150

AI Assistance Disclosure

Used Claude Code to assist with codebase exploration, planning, implementation, and tests. The design, code, and review were gone through by me before submission.

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 refactors the payload and data column synchronization logic to decouple envelope arrival from data availability. It introduces a waitForAllData mechanism in PayloadEnvelopeInput and a verifyPayloadsDataAvailability helper, allowing the execution payload import process to wait for necessary data columns—either via sampling or reconstruction—before proceeding. Review feedback highlights the need to properly guard the resolution of the new allDataPromise to ensure it only fires once and suggests a safer way to calculate completion time to avoid potential crashes with incomplete inputs.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 16, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 0f69a0c Previous: 2870b59 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 930.68 us/op 887.57 us/op 1.05
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 39.664 us/op 39.438 us/op 1.01
BLS verify - blst 720.95 us/op 757.37 us/op 0.95
BLS verifyMultipleSignatures 3 - blst 1.3169 ms/op 1.3734 ms/op 0.96
BLS verifyMultipleSignatures 8 - blst 2.0917 ms/op 2.1778 ms/op 0.96
BLS verifyMultipleSignatures 32 - blst 6.6440 ms/op 6.9548 ms/op 0.96
BLS verifyMultipleSignatures 64 - blst 13.787 ms/op 13.408 ms/op 1.03
BLS verifyMultipleSignatures 128 - blst 25.403 ms/op 25.881 ms/op 0.98
BLS deserializing 10000 signatures 624.84 ms/op 643.38 ms/op 0.97
BLS deserializing 100000 signatures 6.2863 s/op 6.4726 s/op 0.97
BLS verifyMultipleSignatures - same message - 3 - blst 794.41 us/op 821.33 us/op 0.97
BLS verifyMultipleSignatures - same message - 8 - blst 929.87 us/op 940.84 us/op 0.99
BLS verifyMultipleSignatures - same message - 32 - blst 1.5167 ms/op 1.5664 ms/op 0.97
BLS verifyMultipleSignatures - same message - 64 - blst 2.3602 ms/op 2.4488 ms/op 0.96
BLS verifyMultipleSignatures - same message - 128 - blst 3.9640 ms/op 4.0844 ms/op 0.97
BLS aggregatePubkeys 32 - blst 17.241 us/op 17.794 us/op 0.97
BLS aggregatePubkeys 128 - blst 61.551 us/op 63.366 us/op 0.97
getSlashingsAndExits - default max 51.748 us/op 45.172 us/op 1.15
getSlashingsAndExits - 2k 380.95 us/op 320.30 us/op 1.19
proposeBlockBody type=full, size=empty 619.10 us/op 674.98 us/op 0.92
isKnown best case - 1 super set check 176.00 ns/op 175.00 ns/op 1.01
isKnown normal case - 2 super set checks 167.00 ns/op 170.00 ns/op 0.98
isKnown worse case - 16 super set checks 169.00 ns/op 173.00 ns/op 0.98
validate api signedAggregateAndProof - struct 1.4815 ms/op 1.5080 ms/op 0.98
validate gossip signedAggregateAndProof - struct 1.4796 ms/op 1.5067 ms/op 0.98
batch validate gossip attestation - vc 640000 - chunk 32 109.61 us/op 106.37 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 64 97.407 us/op 92.119 us/op 1.06
batch validate gossip attestation - vc 640000 - chunk 128 90.038 us/op 85.851 us/op 1.05
batch validate gossip attestation - vc 640000 - chunk 256 89.746 us/op 82.357 us/op 1.09
bytes32 toHexString 287.00 ns/op 300.00 ns/op 0.96
bytes32 Buffer.toString(hex) 177.00 ns/op 189.00 ns/op 0.94
bytes32 Buffer.toString(hex) from Uint8Array 245.00 ns/op 274.00 ns/op 0.89
bytes32 Buffer.toString(hex) + 0x 178.00 ns/op 194.00 ns/op 0.92
Return object 10000 times 0.21550 ns/op 0.21250 ns/op 1.01
Throw Error 10000 times 3.3322 us/op 3.3039 us/op 1.01
toHex 91.508 ns/op 109.36 ns/op 0.84
Buffer.from 84.231 ns/op 93.189 ns/op 0.90
shared Buffer 54.748 ns/op 66.120 ns/op 0.83
fastMsgIdFn sha256 / 200 bytes 1.4610 us/op 1.4790 us/op 0.99
fastMsgIdFn h32 xxhash / 200 bytes 153.00 ns/op 170.00 ns/op 0.90
fastMsgIdFn h64 xxhash / 200 bytes 205.00 ns/op 201.00 ns/op 1.02
fastMsgIdFn sha256 / 1000 bytes 4.6560 us/op 4.7240 us/op 0.99
fastMsgIdFn h32 xxhash / 1000 bytes 241.00 ns/op 262.00 ns/op 0.92
fastMsgIdFn h64 xxhash / 1000 bytes 246.00 ns/op 259.00 ns/op 0.95
fastMsgIdFn sha256 / 10000 bytes 41.318 us/op 41.791 us/op 0.99
fastMsgIdFn h32 xxhash / 10000 bytes 1.2550 us/op 1.2910 us/op 0.97
fastMsgIdFn h64 xxhash / 10000 bytes 807.00 ns/op 840.00 ns/op 0.96
send data - 1000 256B messages 4.3974 ms/op 4.0287 ms/op 1.09
send data - 1000 512B messages 4.5917 ms/op 4.1367 ms/op 1.11
send data - 1000 1024B messages 4.6457 ms/op 4.1591 ms/op 1.12
send data - 1000 1200B messages 5.2447 ms/op 4.3583 ms/op 1.20
send data - 1000 2048B messages 5.2387 ms/op 4.5123 ms/op 1.16
send data - 1000 4096B messages 5.8282 ms/op 5.3349 ms/op 1.09
send data - 1000 16384B messages 14.146 ms/op 14.188 ms/op 1.00
send data - 1000 65536B messages 276.64 ms/op 236.99 ms/op 1.17
enrSubnets - fastDeserialize 64 bits 748.00 ns/op 730.00 ns/op 1.02
enrSubnets - ssz BitVector 64 bits 263.00 ns/op 277.00 ns/op 0.95
enrSubnets - fastDeserialize 4 bits 107.00 ns/op 116.00 ns/op 0.92
enrSubnets - ssz BitVector 4 bits 258.00 ns/op 271.00 ns/op 0.95
prioritizePeers score -10:0 att 32-0.1 sync 2-0 198.86 us/op 202.59 us/op 0.98
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 228.61 us/op 243.22 us/op 0.94
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 340.41 us/op 337.44 us/op 1.01
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 592.47 us/op 598.04 us/op 0.99
prioritizePeers score 0:0 att 64-1 sync 4-1 721.04 us/op 699.42 us/op 1.03
array of 16000 items push then shift 1.2643 us/op 1.2865 us/op 0.98
LinkedList of 16000 items push then shift 7.4630 ns/op 7.0600 ns/op 1.06
array of 16000 items push then pop 68.107 ns/op 65.162 ns/op 1.05
LinkedList of 16000 items push then pop 5.9450 ns/op 5.9250 ns/op 1.00
array of 24000 items push then shift 1.8768 us/op 1.9108 us/op 0.98
LinkedList of 24000 items push then shift 7.5150 ns/op 6.5930 ns/op 1.14
array of 24000 items push then pop 100.37 ns/op 95.465 ns/op 1.05
LinkedList of 24000 items push then pop 6.5040 ns/op 5.9480 ns/op 1.09
intersect bitArray bitLen 8 4.7760 ns/op 4.7590 ns/op 1.00
intersect array and set length 8 29.813 ns/op 29.164 ns/op 1.02
intersect bitArray bitLen 128 24.225 ns/op 24.042 ns/op 1.01
intersect array and set length 128 496.19 ns/op 494.40 ns/op 1.00
bitArray.getTrueBitIndexes() bitLen 128 1.0230 us/op 1.0790 us/op 0.95
bitArray.getTrueBitIndexes() bitLen 248 1.8220 us/op 1.9310 us/op 0.94
bitArray.getTrueBitIndexes() bitLen 512 3.7090 us/op 3.8770 us/op 0.96
Full columns - reconstruct all 6 blobs 162.24 us/op 104.44 us/op 1.55
Full columns - reconstruct half of the blobs out of 6 75.814 us/op 89.304 us/op 0.85
Full columns - reconstruct single blob out of 6 36.393 us/op 32.974 us/op 1.10
Half columns - reconstruct all 6 blobs 393.64 ms/op 372.42 ms/op 1.06
Half columns - reconstruct half of the blobs out of 6 199.63 ms/op 190.67 ms/op 1.05
Half columns - reconstruct single blob out of 6 69.351 ms/op 65.978 ms/op 1.05
Full columns - reconstruct all 10 blobs 235.25 us/op 363.36 us/op 0.65
Full columns - reconstruct half of the blobs out of 10 131.57 us/op 121.49 us/op 1.08
Full columns - reconstruct single blob out of 10 29.159 us/op 30.421 us/op 0.96
Half columns - reconstruct all 10 blobs 643.20 ms/op 630.62 ms/op 1.02
Half columns - reconstruct half of the blobs out of 10 323.13 ms/op 313.11 ms/op 1.03
Half columns - reconstruct single blob out of 10 68.809 ms/op 67.738 ms/op 1.02
Full columns - reconstruct all 20 blobs 651.70 us/op 564.43 us/op 1.15
Full columns - reconstruct half of the blobs out of 20 344.21 us/op 280.25 us/op 1.23
Full columns - reconstruct single blob out of 20 29.463 us/op 30.226 us/op 0.97
Half columns - reconstruct all 20 blobs 1.2674 s/op 1.2997 s/op 0.98
Half columns - reconstruct half of the blobs out of 20 650.40 ms/op 629.47 ms/op 1.03
Half columns - reconstruct single blob out of 20 69.380 ms/op 65.668 ms/op 1.06
Set add up to 64 items then delete first 2.4875 us/op 2.1174 us/op 1.17
OrderedSet add up to 64 items then delete first 3.2718 us/op 3.3463 us/op 0.98
Set add up to 64 items then delete last 2.3171 us/op 3.0195 us/op 0.77
OrderedSet add up to 64 items then delete last 3.4457 us/op 3.7730 us/op 0.91
Set add up to 64 items then delete middle 3.0215 us/op 3.0041 us/op 1.01
OrderedSet add up to 64 items then delete middle 4.7473 us/op 5.1360 us/op 0.92
Set add up to 128 items then delete first 4.1352 us/op 5.6898 us/op 0.73
OrderedSet add up to 128 items then delete first 6.4660 us/op 6.8836 us/op 0.94
Set add up to 128 items then delete last 3.9300 us/op 5.8620 us/op 0.67
OrderedSet add up to 128 items then delete last 5.8667 us/op 6.8396 us/op 0.86
Set add up to 128 items then delete middle 3.7678 us/op 5.6123 us/op 0.67
OrderedSet add up to 128 items then delete middle 11.475 us/op 12.594 us/op 0.91
Set add up to 256 items then delete first 7.6250 us/op 10.733 us/op 0.71
OrderedSet add up to 256 items then delete first 12.328 us/op 12.775 us/op 0.97
Set add up to 256 items then delete last 7.4868 us/op 10.656 us/op 0.70
OrderedSet add up to 256 items then delete last 11.265 us/op 13.125 us/op 0.86
Set add up to 256 items then delete middle 7.4650 us/op 10.756 us/op 0.69
OrderedSet add up to 256 items then delete middle 34.507 us/op 36.653 us/op 0.94
pass gossip attestations to forkchoice per slot 2.4652 ms/op 2.5753 ms/op 0.96
forkChoice updateHead vc 100000 bc 64 eq 0 391.28 us/op 419.15 us/op 0.93
forkChoice updateHead vc 600000 bc 64 eq 0 2.2828 ms/op 2.4958 ms/op 0.91
forkChoice updateHead vc 1000000 bc 64 eq 0 3.9187 ms/op 4.1158 ms/op 0.95
forkChoice updateHead vc 600000 bc 320 eq 0 2.3973 ms/op 2.4261 ms/op 0.99
forkChoice updateHead vc 600000 bc 1200 eq 0 2.2895 ms/op 2.5021 ms/op 0.92
forkChoice updateHead vc 600000 bc 7200 eq 0 2.8800 ms/op 2.8250 ms/op 1.02
forkChoice updateHead vc 600000 bc 64 eq 1000 2.8512 ms/op 2.9515 ms/op 0.97
forkChoice updateHead vc 600000 bc 64 eq 10000 2.9136 ms/op 3.0406 ms/op 0.96
forkChoice updateHead vc 600000 bc 64 eq 300000 6.5177 ms/op 7.0836 ms/op 0.92
computeDeltas 1400000 validators 0% inactive 12.195 ms/op 12.652 ms/op 0.96
computeDeltas 1400000 validators 10% inactive 11.352 ms/op 11.878 ms/op 0.96
computeDeltas 1400000 validators 20% inactive 10.279 ms/op 10.751 ms/op 0.96
computeDeltas 1400000 validators 50% inactive 8.0334 ms/op 8.3382 ms/op 0.96
computeDeltas 2100000 validators 0% inactive 18.385 ms/op 18.936 ms/op 0.97
computeDeltas 2100000 validators 10% inactive 17.437 ms/op 17.962 ms/op 0.97
computeDeltas 2100000 validators 20% inactive 15.797 ms/op 16.352 ms/op 0.97
computeDeltas 2100000 validators 50% inactive 9.2705 ms/op 9.4651 ms/op 0.98
altair processAttestation - 250000 vs - 7PWei normalcase 1.9308 ms/op 1.6680 ms/op 1.16
altair processAttestation - 250000 vs - 7PWei worstcase 2.6556 ms/op 2.4298 ms/op 1.09
altair processAttestation - setStatus - 1/6 committees join 99.282 us/op 97.328 us/op 1.02
altair processAttestation - setStatus - 1/3 committees join 197.18 us/op 197.29 us/op 1.00
altair processAttestation - setStatus - 1/2 committees join 285.47 us/op 286.24 us/op 1.00
altair processAttestation - setStatus - 2/3 committees join 370.69 us/op 377.46 us/op 0.98
altair processAttestation - setStatus - 4/5 committees join 515.66 us/op 502.38 us/op 1.03
altair processAttestation - setStatus - 100% committees join 616.77 us/op 604.00 us/op 1.02
altair processBlock - 250000 vs - 7PWei normalcase 4.6826 ms/op 3.4070 ms/op 1.37
altair processBlock - 250000 vs - 7PWei normalcase hashState 17.182 ms/op 15.927 ms/op 1.08
altair processBlock - 250000 vs - 7PWei worstcase 21.813 ms/op 21.124 ms/op 1.03
altair processBlock - 250000 vs - 7PWei worstcase hashState 42.705 ms/op 42.849 ms/op 1.00
phase0 processBlock - 250000 vs - 7PWei normalcase 1.6972 ms/op 1.3990 ms/op 1.21
phase0 processBlock - 250000 vs - 7PWei worstcase 18.156 ms/op 17.001 ms/op 1.07
altair processEth1Data - 250000 vs - 7PWei normalcase 279.93 us/op 295.62 us/op 0.95
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.3490 us/op 5.4910 us/op 0.61
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 20.551 us/op 20.806 us/op 0.99
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.4130 us/op 5.8650 us/op 0.92
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.6300 us/op 3.6640 us/op 0.99
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 91.419 us/op 94.987 us/op 0.96
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.3990 ms/op 1.3944 ms/op 1.00
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8706 ms/op 1.8539 ms/op 1.01
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7968 ms/op 1.8366 ms/op 0.98
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.6321 ms/op 3.7639 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.0683 ms/op 2.0906 ms/op 0.99
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.1816 ms/op 3.9796 ms/op 1.05
Tree 40 250000 create 362.99 ms/op 333.20 ms/op 1.09
Tree 40 250000 get(125000) 89.112 ns/op 94.943 ns/op 0.94
Tree 40 250000 set(125000) 1.1559 us/op 1.0425 us/op 1.11
Tree 40 250000 toArray() 13.929 ms/op 14.524 ms/op 0.96
Tree 40 250000 iterate all - toArray() + loop 12.851 ms/op 13.052 ms/op 0.98
Tree 40 250000 iterate all - get(i) 38.144 ms/op 41.859 ms/op 0.91
Array 250000 create 2.1082 ms/op 2.2156 ms/op 0.95
Array 250000 clone - spread 663.88 us/op 703.20 us/op 0.94
Array 250000 get(125000) 0.29300 ns/op 0.30300 ns/op 0.97
Array 250000 set(125000) 0.29600 ns/op 0.30500 ns/op 0.97
Array 250000 iterate all - loop 56.669 us/op 58.729 us/op 0.96
phase0 afterProcessEpoch - 250000 vs - 7PWei 40.509 ms/op 41.060 ms/op 0.99
Array.fill - length 1000000 2.4760 ms/op 2.2265 ms/op 1.11
Array push - length 1000000 11.332 ms/op 8.1183 ms/op 1.40
Array.get 0.20475 ns/op 0.21217 ns/op 0.97
Uint8Array.get 0.23541 ns/op 0.24001 ns/op 0.98
phase0 beforeProcessEpoch - 250000 vs - 7PWei 15.214 ms/op 19.411 ms/op 0.78
altair processEpoch - mainnet_e81889 276.25 ms/op 257.66 ms/op 1.07
mainnet_e81889 - altair beforeProcessEpoch 20.479 ms/op 20.602 ms/op 0.99
mainnet_e81889 - altair processJustificationAndFinalization 6.1470 us/op 5.3840 us/op 1.14
mainnet_e81889 - altair processInactivityUpdates 3.5358 ms/op 3.4840 ms/op 1.01
mainnet_e81889 - altair processRewardsAndPenalties 20.181 ms/op 19.875 ms/op 1.02
mainnet_e81889 - altair processRegistryUpdates 526.00 ns/op 553.00 ns/op 0.95
mainnet_e81889 - altair processSlashings 137.00 ns/op 134.00 ns/op 1.02
mainnet_e81889 - altair processEth1DataReset 134.00 ns/op 132.00 ns/op 1.02
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.2197 ms/op 1.7366 ms/op 0.70
mainnet_e81889 - altair processSlashingsReset 701.00 ns/op 822.00 ns/op 0.85
mainnet_e81889 - altair processRandaoMixesReset 1.3010 us/op 1.1420 us/op 1.14
mainnet_e81889 - altair processHistoricalRootsUpdate 139.00 ns/op 134.00 ns/op 1.04
mainnet_e81889 - altair processParticipationFlagUpdates 434.00 ns/op 436.00 ns/op 1.00
mainnet_e81889 - altair processSyncCommitteeUpdates 112.00 ns/op 108.00 ns/op 1.04
mainnet_e81889 - altair afterProcessEpoch 40.964 ms/op 43.834 ms/op 0.93
capella processEpoch - mainnet_e217614 812.26 ms/op 819.73 ms/op 0.99
mainnet_e217614 - capella beforeProcessEpoch 58.521 ms/op 57.596 ms/op 1.02
mainnet_e217614 - capella processJustificationAndFinalization 6.7820 us/op 6.5120 us/op 1.04
mainnet_e217614 - capella processInactivityUpdates 15.382 ms/op 13.150 ms/op 1.17
mainnet_e217614 - capella processRewardsAndPenalties 98.092 ms/op 94.694 ms/op 1.04
mainnet_e217614 - capella processRegistryUpdates 4.4180 us/op 4.6660 us/op 0.95
mainnet_e217614 - capella processSlashings 136.00 ns/op 140.00 ns/op 0.97
mainnet_e217614 - capella processEth1DataReset 134.00 ns/op 133.00 ns/op 1.01
mainnet_e217614 - capella processEffectiveBalanceUpdates 17.778 ms/op 19.915 ms/op 0.89
mainnet_e217614 - capella processSlashingsReset 671.00 ns/op 701.00 ns/op 0.96
mainnet_e217614 - capella processRandaoMixesReset 1.3880 us/op 1.3810 us/op 1.01
mainnet_e217614 - capella processHistoricalRootsUpdate 135.00 ns/op 137.00 ns/op 0.99
mainnet_e217614 - capella processParticipationFlagUpdates 441.00 ns/op 469.00 ns/op 0.94
mainnet_e217614 - capella afterProcessEpoch 107.78 ms/op 112.85 ms/op 0.96
phase0 processEpoch - mainnet_e58758 307.36 ms/op 314.32 ms/op 0.98
mainnet_e58758 - phase0 beforeProcessEpoch 64.496 ms/op 60.478 ms/op 1.07
mainnet_e58758 - phase0 processJustificationAndFinalization 6.4450 us/op 5.8120 us/op 1.11
mainnet_e58758 - phase0 processRewardsAndPenalties 16.280 ms/op 15.289 ms/op 1.06
mainnet_e58758 - phase0 processRegistryUpdates 2.2510 us/op 2.2880 us/op 0.98
mainnet_e58758 - phase0 processSlashings 127.00 ns/op 135.00 ns/op 0.94
mainnet_e58758 - phase0 processEth1DataReset 134.00 ns/op 130.00 ns/op 1.03
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 875.02 us/op 828.25 us/op 1.06
mainnet_e58758 - phase0 processSlashingsReset 911.00 ns/op 854.00 ns/op 1.07
mainnet_e58758 - phase0 processRandaoMixesReset 1.2730 us/op 1.3210 us/op 0.96
mainnet_e58758 - phase0 processHistoricalRootsUpdate 143.00 ns/op 139.00 ns/op 1.03
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.1850 us/op 1.0700 us/op 1.11
mainnet_e58758 - phase0 afterProcessEpoch 34.125 ms/op 34.603 ms/op 0.99
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.0028 ms/op 1.1076 ms/op 0.91
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5711 ms/op 1.6031 ms/op 0.98
altair processInactivityUpdates - 250000 normalcase 33.055 ms/op 12.012 ms/op 2.75
altair processInactivityUpdates - 250000 worstcase 16.106 ms/op 10.717 ms/op 1.50
phase0 processRegistryUpdates - 250000 normalcase 2.2260 us/op 2.9220 us/op 0.76
phase0 processRegistryUpdates - 250000 badcase_full_deposits 145.40 us/op 154.54 us/op 0.94
phase0 processRegistryUpdates - 250000 worstcase 0.5 63.391 ms/op 61.794 ms/op 1.03
altair processRewardsAndPenalties - 250000 normalcase 16.289 ms/op 14.889 ms/op 1.09
altair processRewardsAndPenalties - 250000 worstcase 16.094 ms/op 15.442 ms/op 1.04
phase0 getAttestationDeltas - 250000 normalcase 5.2438 ms/op 5.4735 ms/op 0.96
phase0 getAttestationDeltas - 250000 worstcase 5.2875 ms/op 5.5126 ms/op 0.96
phase0 processSlashings - 250000 worstcase 58.887 us/op 59.234 us/op 0.99
altair processSyncCommitteeUpdates - 250000 10.166 ms/op 10.166 ms/op 1.00
BeaconState.hashTreeRoot - No change 167.00 ns/op 168.00 ns/op 0.99
BeaconState.hashTreeRoot - 1 full validator 78.769 us/op 81.416 us/op 0.97
BeaconState.hashTreeRoot - 32 full validator 854.02 us/op 897.23 us/op 0.95
BeaconState.hashTreeRoot - 512 full validator 8.4412 ms/op 7.5230 ms/op 1.12
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 108.49 us/op 88.642 us/op 1.22
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.4295 ms/op 1.3269 ms/op 1.08
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 21.680 ms/op 15.992 ms/op 1.36
BeaconState.hashTreeRoot - 1 balances 87.490 us/op 78.067 us/op 1.12
BeaconState.hashTreeRoot - 32 balances 798.83 us/op 686.99 us/op 1.16
BeaconState.hashTreeRoot - 512 balances 6.5518 ms/op 5.3913 ms/op 1.22
BeaconState.hashTreeRoot - 250000 balances 139.03 ms/op 130.67 ms/op 1.06
aggregationBits - 2048 els - zipIndexesInBitList 20.079 us/op 19.802 us/op 1.01
regular array get 100000 times 23.871 us/op 23.009 us/op 1.04
wrappedArray get 100000 times 23.697 us/op 22.989 us/op 1.03
arrayWithProxy get 100000 times 9.8200 ms/op 10.438 ms/op 0.94
ssz.Root.equals 22.264 ns/op 21.599 ns/op 1.03
byteArrayEquals 21.956 ns/op 21.426 ns/op 1.02
Buffer.compare 9.0640 ns/op 8.8780 ns/op 1.02
processSlot - 1 slots 8.8940 us/op 9.4480 us/op 0.94
processSlot - 32 slots 2.1246 ms/op 2.1006 ms/op 1.01
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.5855 ms/op 3.5633 ms/op 1.29
getCommitteeAssignments - req 1 vs - 250000 vc 1.6165 ms/op 1.7073 ms/op 0.95
getCommitteeAssignments - req 100 vs - 250000 vc 3.2827 ms/op 3.5055 ms/op 0.94
getCommitteeAssignments - req 1000 vs - 250000 vc 3.5408 ms/op 3.7508 ms/op 0.94
findModifiedValidators - 10000 modified validators 729.99 ms/op 765.31 ms/op 0.95
findModifiedValidators - 1000 modified validators 383.98 ms/op 436.92 ms/op 0.88
findModifiedValidators - 100 modified validators 257.64 ms/op 311.81 ms/op 0.83
findModifiedValidators - 10 modified validators 241.15 ms/op 168.26 ms/op 1.43
findModifiedValidators - 1 modified validators 141.05 ms/op 181.65 ms/op 0.78
findModifiedValidators - no difference 159.88 ms/op 161.35 ms/op 0.99
migrate state 1500000 validators, 3400 modified, 2000 new 2.7321 s/op 3.0806 s/op 0.89
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.7600 ns/op 3.7600 ns/op 1.00
state getBlockRootAtSlot - 250000 vs - 7PWei 336.38 ns/op 377.13 ns/op 0.89
computeProposerIndex 100000 validators 1.2873 ms/op 1.3810 ms/op 0.93
getNextSyncCommitteeIndices 1000 validators 2.7783 ms/op 2.9293 ms/op 0.95
getNextSyncCommitteeIndices 10000 validators 24.423 ms/op 25.820 ms/op 0.95
getNextSyncCommitteeIndices 100000 validators 84.024 ms/op 91.544 ms/op 0.92
computeProposers - vc 250000 545.25 us/op 578.80 us/op 0.94
computeEpochShuffling - vc 250000 37.479 ms/op 42.500 ms/op 0.88
getNextSyncCommittee - vc 250000 9.1890 ms/op 10.012 ms/op 0.92
nodejs block root to RootHex using toHex 89.386 ns/op 113.18 ns/op 0.79
nodejs block root to RootHex using toRootHex 54.318 ns/op 69.415 ns/op 0.78
nodejs fromHex(blob) 706.30 us/op 831.80 us/op 0.85
nodejs fromHexInto(blob) 603.53 us/op 660.95 us/op 0.91
nodejs block root to RootHex using the deprecated toHexString 451.62 ns/op 489.51 ns/op 0.92
nodejs byteArrayEquals 32 bytes (block root) 24.974 ns/op 26.701 ns/op 0.94
nodejs byteArrayEquals 48 bytes (pubkey) 36.353 ns/op 38.563 ns/op 0.94
nodejs byteArrayEquals 96 bytes (signature) 33.019 ns/op 33.916 ns/op 0.97
nodejs byteArrayEquals 1024 bytes 38.767 ns/op 41.668 ns/op 0.93
nodejs byteArrayEquals 131072 bytes (blob) 1.6908 us/op 1.7765 us/op 0.95
browser block root to RootHex using toHex 137.77 ns/op 147.10 ns/op 0.94
browser block root to RootHex using toRootHex 125.12 ns/op 131.63 ns/op 0.95
browser fromHex(blob) 1.4745 ms/op 1.5890 ms/op 0.93
browser fromHexInto(blob) 593.97 us/op 637.06 us/op 0.93
browser block root to RootHex using the deprecated toHexString 453.26 ns/op 336.52 ns/op 1.35
browser byteArrayEquals 32 bytes (block root) 26.871 ns/op 28.235 ns/op 0.95
browser byteArrayEquals 48 bytes (pubkey) 37.838 ns/op 39.826 ns/op 0.95
browser byteArrayEquals 96 bytes (signature) 71.059 ns/op 74.482 ns/op 0.95
browser byteArrayEquals 1024 bytes 722.53 ns/op 762.47 ns/op 0.95
browser byteArrayEquals 131072 bytes (blob) 90.934 us/op 95.930 us/op 0.95

by benchmarkbot/action

@twoeths twoeths marked this pull request as ready for review April 16, 2026 06:32
@twoeths twoeths requested a review from a team as a code owner April 16, 2026 06:32
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

if (this.clock.currentSlot - envelope.slot < EVENTSTREAM_EMIT_RECENT_EXECUTION_PAYLOAD_SLOTS) {
this.emitter.emit(routes.events.EventType.executionPayloadAvailable, {
slot: envelope.slot,

P1 Badge Emit availability event after data availability is confirmed

importExecutionPayload() now runs on envelope arrival before columns are complete, but this block still emits execution_payload_available immediately. That means subscribers can be told a payload is “available” while verifyPayloadsDataAvailability() is still waiting (up to 12s), which breaks the event’s stated semantics and can trigger premature payload-attestation logic in downstream consumers.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

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

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

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

Comment on lines +748 to +750
// NOTE: we do NOT call chain.processExecutionPayload here. That is triggered only by
// envelope arrival (gossip or API). An in-flight importExecutionPayload is awaiting
// payloadInput.waitForAllData(); addColumn above will resolve it once hasAllData flips.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Re-trigger payload import when columns arrive after wait timeout

With the data-column trigger removed here, payload import is now only kicked off on envelope arrival; if that single import attempt times out waiting for columns in verifyPayloadsDataAvailability(), later column arrivals have no path to restart processing. In practice this can leave a valid envelope permanently unimported when columns are delayed beyond the timeout window.

Useful? React with 👍 / 👎.

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.

In this case, unknown block sync should be triggered to gather payloads. This can be triggered via timeout or via new block arrival which builds on the payload.

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.

There should be something added here like the fulu path, which awaits the payload and data, and triggers a chain event in the incomplete case.

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.

addressed in 6d5e9e5

Copy link
Copy Markdown
Contributor Author

@twoeths twoeths left a comment

Choose a reason for hiding this comment

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

the new function verifyPayloadsDataAvailability(payloadInputs: PayloadEnvelopeInput[]) is a preparation for gloas range sync

@wemeetagain wemeetagain merged commit e341cdc into unstable Apr 20, 2026
19 checks passed
@wemeetagain wemeetagain deleted the te/trigger_process_execution_payload branch April 20, 2026 13:55
@twoeths twoeths mentioned this pull request Apr 21, 2026
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.

Better mechanism to trigger processExecutionPayload

2 participants