Skip to content

feat: ignore index-1 attestation when payload is missing#9213

Merged
ensi321 merged 6 commits intounstablefrom
nc/alpha4-spec
Apr 16, 2026
Merged

feat: ignore index-1 attestation when payload is missing#9213
ensi321 merged 6 commits intounstablefrom
nc/alpha4-spec

Conversation

@ensi321
Copy link
Copy Markdown
Contributor

@ensi321 ensi321 commented Apr 14, 2026

  • Request missing payload envelopes for index-1 attestation ethereum/consensus-specs#4939: Add IGNORE check for index-1 attestations (beacon_attestation and beacon_aggregate_and_proof) when the execution payload has not been seen. The REJECT check (payload passes validation) is inherently satisfied since FULL variants in fork choice can only have Valid or Syncing execution status. The network-layer plumbing (requesting missing envelopes via ExecutionPayloadEnvelopesByRoot, queuing messages) was already in place.

ensi321 and others added 2 commits April 13, 2026 18:13
Spec PRs:
- #5008: correct field name `block_root` to `beacon_block_root` in
  ExecutionPayloadEnvelopesByRoot validation comment
- #5022: add block-known check in on_payload_attestation_message
  (already handled by gossip validation in payloadAttestationMessage.ts)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When attestation.data.index == 1 (payload present for a past block),
the execution payload for the referenced block must have been seen.
This adds the IGNORE check to both beacon_attestation and
beacon_aggregate_and_proof gossip validation per consensus-specs #4939.

The REJECT check (payload passes validation) is inherently satisfied
since FULL variants in fork choice can only have Valid or Syncing
execution status — invalid payloads never create FULL variants.

The network processor already handles requesting missing payload
envelopes via ExecutionPayloadEnvelopesByRoot and queuing messages
for later processing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ensi321 ensi321 requested a review from a team as a code owner April 14, 2026 01:16
@ensi321 ensi321 changed the title feat: implement consensus-specs v1.7.0-alpha.4 (#5008, #5022, #4939) feat: implement consensus-specs v1.7.0-alpha.4 Apr 14, 2026
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 introduces a new attestation error code, EXECUTION_PAYLOAD_NOT_SEEN, and implements validation logic in aggregateAndProof.ts and attestation.ts to ensure that for attestations with index == 1, the corresponding execution payload has been seen. It also includes a minor documentation fix in executionPayloadEnvelope.ts. The review feedback suggests using the more comprehensive chain.seenPayloadEnvelope method instead of chain.forkChoice.hasPayloadUnsafe to check for the existence of the execution payload, as it better aligns with the specification by checking both gossip caches and fork choice state.

Comment thread packages/beacon-node/src/chain/validation/aggregateAndProof.ts Outdated
Comment thread packages/beacon-node/src/chain/validation/attestation.ts Outdated
@ensi321 ensi321 changed the title feat: implement consensus-specs v1.7.0-alpha.4 feat: miscellaneous changes from v1.7.0-alpha.4 Apr 14, 2026
@ensi321 ensi321 marked this pull request as draft April 14, 2026 01:19
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

Here are some automated review suggestions for this pull request.

Reviewed commit: 4652529094

ℹ️ 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 thread packages/beacon-node/src/chain/validation/attestation.ts Outdated
Comment thread packages/beacon-node/src/chain/validation/aggregateAndProof.ts Outdated
@ensi321 ensi321 changed the title feat: miscellaneous changes from v1.7.0-alpha.4 feat: rejects index-1 attestation when payload is missing Apr 14, 2026
@ensi321 ensi321 changed the title feat: rejects index-1 attestation when payload is missing feat: ignore index-1 attestation when payload is missing Apr 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 14, 2026

Performance Report

🚀🚀 Significant benchmark improvement detected

Benchmark suite Current: 1f45b45 Previous: 2740f92 Ratio
proposeBlockBody type=full, size=empty 655.62 us/op 2.5034 ms/op 0.26
Full benchmark results
Benchmark suite Current: 1f45b45 Previous: 2740f92 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 876.75 us/op 890.89 us/op 0.98
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 37.128 us/op 37.667 us/op 0.99
BLS verify - blst 691.56 us/op 700.60 us/op 0.99
BLS verifyMultipleSignatures 3 - blst 1.2835 ms/op 1.3176 ms/op 0.97
BLS verifyMultipleSignatures 8 - blst 2.0234 ms/op 2.0753 ms/op 0.97
BLS verifyMultipleSignatures 32 - blst 6.3341 ms/op 6.4771 ms/op 0.98
BLS verifyMultipleSignatures 64 - blst 12.326 ms/op 12.607 ms/op 0.98
BLS verifyMultipleSignatures 128 - blst 24.363 ms/op 24.555 ms/op 0.99
BLS deserializing 10000 signatures 610.21 ms/op 620.32 ms/op 0.98
BLS deserializing 100000 signatures 6.1985 s/op 6.2270 s/op 1.00
BLS verifyMultipleSignatures - same message - 3 - blst 743.87 us/op 733.72 us/op 1.01
BLS verifyMultipleSignatures - same message - 8 - blst 879.56 us/op 911.11 us/op 0.97
BLS verifyMultipleSignatures - same message - 32 - blst 1.3950 ms/op 1.5037 ms/op 0.93
BLS verifyMultipleSignatures - same message - 64 - blst 2.2318 ms/op 2.3570 ms/op 0.95
BLS verifyMultipleSignatures - same message - 128 - blst 3.9184 ms/op 3.9645 ms/op 0.99
BLS aggregatePubkeys 32 - blst 16.994 us/op 17.198 us/op 0.99
BLS aggregatePubkeys 128 - blst 59.808 us/op 61.464 us/op 0.97
getSlashingsAndExits - default max 46.723 us/op 44.132 us/op 1.06
getSlashingsAndExits - 2k 344.00 us/op 360.18 us/op 0.96
proposeBlockBody type=full, size=empty 655.62 us/op 2.5034 ms/op 0.26
isKnown best case - 1 super set check 375.00 ns/op 162.00 ns/op 2.31
isKnown normal case - 2 super set checks 379.00 ns/op 163.00 ns/op 2.33
isKnown worse case - 16 super set checks 364.00 ns/op 164.00 ns/op 2.22
validate api signedAggregateAndProof - struct 1.4456 ms/op 1.4873 ms/op 0.97
validate gossip signedAggregateAndProof - struct 1.4418 ms/op 1.4723 ms/op 0.98
batch validate gossip attestation - vc 640000 - chunk 32 102.71 us/op 108.72 us/op 0.94
batch validate gossip attestation - vc 640000 - chunk 64 89.521 us/op 94.267 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 128 82.693 us/op 87.064 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 256 80.062 us/op 82.889 us/op 0.97
bytes32 toHexString 466.00 ns/op 278.00 ns/op 1.68
bytes32 Buffer.toString(hex) 375.00 ns/op 178.00 ns/op 2.11
bytes32 Buffer.toString(hex) from Uint8Array 456.00 ns/op 255.00 ns/op 1.79
bytes32 Buffer.toString(hex) + 0x 386.00 ns/op 180.00 ns/op 2.14
Return object 10000 times 0.22000 ns/op 0.20920 ns/op 1.05
Throw Error 10000 times 3.1657 us/op 3.2624 us/op 0.97
toHex 90.158 ns/op 109.76 ns/op 0.82
Buffer.from 83.409 ns/op 84.059 ns/op 0.99
shared Buffer 56.056 ns/op 58.274 ns/op 0.96
fastMsgIdFn sha256 / 200 bytes 1.6350 us/op 1.4850 us/op 1.10
fastMsgIdFn h32 xxhash / 200 bytes 344.00 ns/op 150.00 ns/op 2.29
fastMsgIdFn h64 xxhash / 200 bytes 395.00 ns/op 208.00 ns/op 1.90
fastMsgIdFn sha256 / 1000 bytes 4.6910 us/op 4.7530 us/op 0.99
fastMsgIdFn h32 xxhash / 1000 bytes 420.00 ns/op 253.00 ns/op 1.66
fastMsgIdFn h64 xxhash / 1000 bytes 436.00 ns/op 255.00 ns/op 1.71
fastMsgIdFn sha256 / 10000 bytes 39.693 us/op 42.347 us/op 0.94
fastMsgIdFn h32 xxhash / 10000 bytes 1.3910 us/op 1.2780 us/op 1.09
fastMsgIdFn h64 xxhash / 10000 bytes 967.00 ns/op 808.00 ns/op 1.20
send data - 1000 256B messages 4.2513 ms/op 4.3736 ms/op 0.97
send data - 1000 512B messages 4.5878 ms/op 4.3910 ms/op 1.04
send data - 1000 1024B messages 4.7685 ms/op 4.5770 ms/op 1.04
send data - 1000 1200B messages 4.7276 ms/op 5.1686 ms/op 0.91
send data - 1000 2048B messages 4.8518 ms/op 5.1081 ms/op 0.95
send data - 1000 4096B messages 5.8751 ms/op 5.8412 ms/op 1.01
send data - 1000 16384B messages 26.426 ms/op 17.065 ms/op 1.55
send data - 1000 65536B messages 174.06 ms/op 213.38 ms/op 0.82
enrSubnets - fastDeserialize 64 bits 931.00 ns/op 737.00 ns/op 1.26
enrSubnets - ssz BitVector 64 bits 468.00 ns/op 277.00 ns/op 1.69
enrSubnets - fastDeserialize 4 bits 284.00 ns/op 107.00 ns/op 2.65
enrSubnets - ssz BitVector 4 bits 477.00 ns/op 272.00 ns/op 1.75
prioritizePeers score -10:0 att 32-0.1 sync 2-0 208.51 us/op 201.80 us/op 1.03
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 238.63 us/op 251.27 us/op 0.95
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 325.96 us/op 346.01 us/op 0.94
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 581.53 us/op 598.95 us/op 0.97
prioritizePeers score 0:0 att 64-1 sync 4-1 680.47 us/op 697.07 us/op 0.98
array of 16000 items push then shift 1.2024 us/op 1.2487 us/op 0.96
LinkedList of 16000 items push then shift 7.5290 ns/op 7.3140 ns/op 1.03
array of 16000 items push then pop 66.438 ns/op 68.135 ns/op 0.98
LinkedList of 16000 items push then pop 6.0840 ns/op 5.9380 ns/op 1.02
array of 24000 items push then shift 1.7901 us/op 1.8453 us/op 0.97
LinkedList of 24000 items push then shift 7.4120 ns/op 6.8570 ns/op 1.08
array of 24000 items push then pop 91.570 ns/op 94.706 ns/op 0.97
LinkedList of 24000 items push then pop 6.1410 ns/op 5.9080 ns/op 1.04
intersect bitArray bitLen 8 4.7720 ns/op 4.6870 ns/op 1.02
intersect array and set length 8 28.187 ns/op 29.579 ns/op 0.95
intersect bitArray bitLen 128 23.251 ns/op 23.669 ns/op 0.98
intersect array and set length 128 477.20 ns/op 488.12 ns/op 0.98
bitArray.getTrueBitIndexes() bitLen 128 1.2740 us/op 1.0220 us/op 1.25
bitArray.getTrueBitIndexes() bitLen 248 1.9200 us/op 1.7480 us/op 1.10
bitArray.getTrueBitIndexes() bitLen 512 3.6380 us/op 3.5770 us/op 1.02
Full columns - reconstruct all 6 blobs 113.23 us/op 141.23 us/op 0.80
Full columns - reconstruct half of the blobs out of 6 99.910 us/op 120.49 us/op 0.83
Full columns - reconstruct single blob out of 6 33.055 us/op 29.962 us/op 1.10
Half columns - reconstruct all 6 blobs 376.36 ms/op 383.65 ms/op 0.98
Half columns - reconstruct half of the blobs out of 6 189.41 ms/op 193.77 ms/op 0.98
Half columns - reconstruct single blob out of 6 67.589 ms/op 68.658 ms/op 0.98
Full columns - reconstruct all 10 blobs 760.92 us/op 367.78 us/op 2.07
Full columns - reconstruct half of the blobs out of 10 141.68 us/op 105.86 us/op 1.34
Full columns - reconstruct single blob out of 10 27.220 us/op 45.443 us/op 0.60
Half columns - reconstruct all 10 blobs 624.68 ms/op 642.46 ms/op 0.97
Half columns - reconstruct half of the blobs out of 10 309.31 ms/op 337.09 ms/op 0.92
Half columns - reconstruct single blob out of 10 66.283 ms/op 70.922 ms/op 0.93
Full columns - reconstruct all 20 blobs 529.33 us/op 547.82 us/op 0.97
Full columns - reconstruct half of the blobs out of 20 394.29 us/op 201.41 us/op 1.96
Full columns - reconstruct single blob out of 20 32.754 us/op 30.920 us/op 1.06
Half columns - reconstruct all 20 blobs 1.2300 s/op 1.2936 s/op 0.95
Half columns - reconstruct half of the blobs out of 20 619.01 ms/op 652.41 ms/op 0.95
Half columns - reconstruct single blob out of 20 66.940 ms/op 71.392 ms/op 0.94
Set add up to 64 items then delete first 2.4542 us/op 2.5557 us/op 0.96
OrderedSet add up to 64 items then delete first 3.2321 us/op 3.3802 us/op 0.96
Set add up to 64 items then delete last 2.2637 us/op 2.2961 us/op 0.99
OrderedSet add up to 64 items then delete last 3.1592 us/op 3.1831 us/op 0.99
Set add up to 64 items then delete middle 2.0110 us/op 2.0845 us/op 0.96
OrderedSet add up to 64 items then delete middle 4.5414 us/op 4.6584 us/op 0.97
Set add up to 128 items then delete first 4.0257 us/op 4.1196 us/op 0.98
OrderedSet add up to 128 items then delete first 6.2326 us/op 6.4086 us/op 0.97
Set add up to 128 items then delete last 3.6665 us/op 3.8061 us/op 0.96
OrderedSet add up to 128 items then delete last 5.5728 us/op 5.6602 us/op 0.98
Set add up to 128 items then delete middle 3.6799 us/op 3.7853 us/op 0.97
OrderedSet add up to 128 items then delete middle 11.141 us/op 11.249 us/op 0.99
Set add up to 256 items then delete first 7.5221 us/op 7.5769 us/op 0.99
OrderedSet add up to 256 items then delete first 11.700 us/op 11.924 us/op 0.98
Set add up to 256 items then delete last 7.3175 us/op 7.3484 us/op 1.00
OrderedSet add up to 256 items then delete last 11.006 us/op 11.255 us/op 0.98
Set add up to 256 items then delete middle 7.2133 us/op 7.3554 us/op 0.98
OrderedSet add up to 256 items then delete middle 33.535 us/op 39.701 us/op 0.84
pass gossip attestations to forkchoice per slot 2.4952 ms/op 2.9549 ms/op 0.84
forkChoice updateHead vc 100000 bc 64 eq 0 378.07 us/op 401.74 us/op 0.94
forkChoice updateHead vc 600000 bc 64 eq 0 2.2379 ms/op 2.4170 ms/op 0.93
forkChoice updateHead vc 1000000 bc 64 eq 0 3.7263 ms/op 4.0550 ms/op 0.92
forkChoice updateHead vc 600000 bc 320 eq 0 2.2923 ms/op 2.4471 ms/op 0.94
forkChoice updateHead vc 600000 bc 1200 eq 0 2.3105 ms/op 2.5533 ms/op 0.90
forkChoice updateHead vc 600000 bc 7200 eq 0 2.5728 ms/op 4.1296 ms/op 0.62
forkChoice updateHead vc 600000 bc 64 eq 1000 2.8268 ms/op 2.9969 ms/op 0.94
forkChoice updateHead vc 600000 bc 64 eq 10000 3.0124 ms/op 3.1105 ms/op 0.97
forkChoice updateHead vc 600000 bc 64 eq 300000 6.6119 ms/op 7.3145 ms/op 0.90
computeDeltas 1400000 validators 0% inactive 12.055 ms/op 12.745 ms/op 0.95
computeDeltas 1400000 validators 10% inactive 11.358 ms/op 11.928 ms/op 0.95
computeDeltas 1400000 validators 20% inactive 10.278 ms/op 10.853 ms/op 0.95
computeDeltas 1400000 validators 50% inactive 8.0084 ms/op 8.3951 ms/op 0.95
computeDeltas 2100000 validators 0% inactive 18.476 ms/op 19.135 ms/op 0.97
computeDeltas 2100000 validators 10% inactive 16.921 ms/op 17.955 ms/op 0.94
computeDeltas 2100000 validators 20% inactive 15.369 ms/op 16.340 ms/op 0.94
computeDeltas 2100000 validators 50% inactive 9.0961 ms/op 9.5426 ms/op 0.95
altair processAttestation - 250000 vs - 7PWei normalcase 1.9104 ms/op 2.7725 ms/op 0.69
altair processAttestation - 250000 vs - 7PWei worstcase 3.0365 ms/op 3.6768 ms/op 0.83
altair processAttestation - setStatus - 1/6 committees join 103.65 us/op 105.93 us/op 0.98
altair processAttestation - setStatus - 1/3 committees join 201.18 us/op 219.64 us/op 0.92
altair processAttestation - setStatus - 1/2 committees join 271.13 us/op 298.31 us/op 0.91
altair processAttestation - setStatus - 2/3 committees join 346.96 us/op 372.63 us/op 0.93
altair processAttestation - setStatus - 4/5 committees join 478.86 us/op 523.74 us/op 0.91
altair processAttestation - setStatus - 100% committees join 571.12 us/op 627.97 us/op 0.91
altair processBlock - 250000 vs - 7PWei normalcase 4.2663 ms/op 4.3605 ms/op 0.98
altair processBlock - 250000 vs - 7PWei normalcase hashState 16.210 ms/op 16.182 ms/op 1.00
altair processBlock - 250000 vs - 7PWei worstcase 20.791 ms/op 21.037 ms/op 0.99
altair processBlock - 250000 vs - 7PWei worstcase hashState 41.506 ms/op 39.532 ms/op 1.05
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3000 ms/op 1.3051 ms/op 1.00
phase0 processBlock - 250000 vs - 7PWei worstcase 16.381 ms/op 16.539 ms/op 0.99
altair processEth1Data - 250000 vs - 7PWei normalcase 275.84 us/op 269.60 us/op 1.02
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.4680 us/op 3.7740 us/op 0.92
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 19.221 us/op 21.543 us/op 0.89
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.6230 us/op 5.5340 us/op 1.02
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.7720 us/op 3.5060 us/op 1.08
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 87.356 us/op 93.674 us/op 0.93
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.3045 ms/op 1.3873 ms/op 0.94
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.7050 ms/op 1.8397 ms/op 0.93
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7146 ms/op 1.7930 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.9142 ms/op 3.5776 ms/op 1.09
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 1.9501 ms/op 2.0759 ms/op 0.94
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 3.9494 ms/op 3.8402 ms/op 1.03
Tree 40 250000 create 355.80 ms/op 301.08 ms/op 1.18
Tree 40 250000 get(125000) 86.585 ns/op 86.878 ns/op 1.00
Tree 40 250000 set(125000) 965.06 ns/op 937.47 ns/op 1.03
Tree 40 250000 toArray() 11.823 ms/op 11.247 ms/op 1.05
Tree 40 250000 iterate all - toArray() + loop 12.553 ms/op 13.607 ms/op 0.92
Tree 40 250000 iterate all - get(i) 35.425 ms/op 36.078 ms/op 0.98
Array 250000 create 2.2210 ms/op 2.0997 ms/op 1.06
Array 250000 clone - spread 678.49 us/op 649.95 us/op 1.04
Array 250000 get(125000) 0.47100 ns/op 0.29300 ns/op 1.61
Array 250000 set(125000) 0.47900 ns/op 0.29400 ns/op 1.63
Array 250000 iterate all - loop 54.914 us/op 54.801 us/op 1.00
phase0 afterProcessEpoch - 250000 vs - 7PWei 49.840 ms/op 38.560 ms/op 1.29
Array.fill - length 1000000 2.1478 ms/op 1.9010 ms/op 1.13
Array push - length 1000000 9.8763 ms/op 9.6563 ms/op 1.02
Array.get 0.20425 ns/op 0.20112 ns/op 1.02
Uint8Array.get 0.23142 ns/op 0.22302 ns/op 1.04
phase0 beforeProcessEpoch - 250000 vs - 7PWei 16.212 ms/op 13.539 ms/op 1.20
altair processEpoch - mainnet_e81889 258.27 ms/op 245.77 ms/op 1.05
mainnet_e81889 - altair beforeProcessEpoch 18.897 ms/op 14.486 ms/op 1.30
mainnet_e81889 - altair processJustificationAndFinalization 6.1030 us/op 5.3250 us/op 1.15
mainnet_e81889 - altair processInactivityUpdates 3.6259 ms/op 3.4336 ms/op 1.06
mainnet_e81889 - altair processRewardsAndPenalties 18.733 ms/op 18.675 ms/op 1.00
mainnet_e81889 - altair processRegistryUpdates 764.00 ns/op 527.00 ns/op 1.45
mainnet_e81889 - altair processSlashings 349.00 ns/op 144.00 ns/op 2.42
mainnet_e81889 - altair processEth1DataReset 347.00 ns/op 139.00 ns/op 2.50
mainnet_e81889 - altair processEffectiveBalanceUpdates 3.3434 ms/op 1.6731 ms/op 2.00
mainnet_e81889 - altair processSlashingsReset 908.00 ns/op 689.00 ns/op 1.32
mainnet_e81889 - altair processRandaoMixesReset 1.4170 us/op 1.1070 us/op 1.28
mainnet_e81889 - altair processHistoricalRootsUpdate 338.00 ns/op 142.00 ns/op 2.38
mainnet_e81889 - altair processParticipationFlagUpdates 658.00 ns/op 427.00 ns/op 1.54
mainnet_e81889 - altair processSyncCommitteeUpdates 315.00 ns/op 123.00 ns/op 2.56
mainnet_e81889 - altair afterProcessEpoch 39.350 ms/op 39.942 ms/op 0.99
capella processEpoch - mainnet_e217614 771.99 ms/op 802.62 ms/op 0.96
mainnet_e217614 - capella beforeProcessEpoch 56.183 ms/op 60.981 ms/op 0.92
mainnet_e217614 - capella processJustificationAndFinalization 6.0510 us/op 6.4730 us/op 0.93
mainnet_e217614 - capella processInactivityUpdates 14.493 ms/op 16.354 ms/op 0.89
mainnet_e217614 - capella processRewardsAndPenalties 86.572 ms/op 86.178 ms/op 1.00
mainnet_e217614 - capella processRegistryUpdates 4.5870 us/op 4.4590 us/op 1.03
mainnet_e217614 - capella processSlashings 348.00 ns/op 146.00 ns/op 2.38
mainnet_e217614 - capella processEth1DataReset 340.00 ns/op 145.00 ns/op 2.34
mainnet_e217614 - capella processEffectiveBalanceUpdates 12.631 ms/op 17.547 ms/op 0.72
mainnet_e217614 - capella processSlashingsReset 884.00 ns/op 688.00 ns/op 1.28
mainnet_e217614 - capella processRandaoMixesReset 1.4820 us/op 1.3130 us/op 1.13
mainnet_e217614 - capella processHistoricalRootsUpdate 346.00 ns/op 146.00 ns/op 2.37
mainnet_e217614 - capella processParticipationFlagUpdates 655.00 ns/op 460.00 ns/op 1.42
mainnet_e217614 - capella afterProcessEpoch 106.18 ms/op 108.91 ms/op 0.97
phase0 processEpoch - mainnet_e58758 288.75 ms/op 325.47 ms/op 0.89
mainnet_e58758 - phase0 beforeProcessEpoch 60.296 ms/op 68.907 ms/op 0.88
mainnet_e58758 - phase0 processJustificationAndFinalization 6.4260 us/op 6.4380 us/op 1.00
mainnet_e58758 - phase0 processRewardsAndPenalties 15.477 ms/op 16.231 ms/op 0.95
mainnet_e58758 - phase0 processRegistryUpdates 2.4360 us/op 2.2590 us/op 1.08
mainnet_e58758 - phase0 processSlashings 354.00 ns/op 247.00 ns/op 1.43
mainnet_e58758 - phase0 processEth1DataReset 347.00 ns/op 152.00 ns/op 2.28
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 798.23 us/op 2.4895 ms/op 0.32
mainnet_e58758 - phase0 processSlashingsReset 1.1130 us/op 924.00 ns/op 1.20
mainnet_e58758 - phase0 processRandaoMixesReset 1.5080 us/op 1.3030 us/op 1.16
mainnet_e58758 - phase0 processHistoricalRootsUpdate 359.00 ns/op 148.00 ns/op 2.43
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.3460 us/op 1.1840 us/op 1.14
mainnet_e58758 - phase0 afterProcessEpoch 32.901 ms/op 33.365 ms/op 0.99
phase0 processEffectiveBalanceUpdates - 250000 normalcase 961.50 us/op 979.11 us/op 0.98
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5189 ms/op 1.5875 ms/op 0.96
altair processInactivityUpdates - 250000 normalcase 10.586 ms/op 10.379 ms/op 1.02
altair processInactivityUpdates - 250000 worstcase 11.018 ms/op 10.286 ms/op 1.07
phase0 processRegistryUpdates - 250000 normalcase 2.6470 us/op 2.1180 us/op 1.25
phase0 processRegistryUpdates - 250000 badcase_full_deposits 134.62 us/op 136.68 us/op 0.98
phase0 processRegistryUpdates - 250000 worstcase 0.5 56.718 ms/op 55.524 ms/op 1.02
altair processRewardsAndPenalties - 250000 normalcase 15.544 ms/op 15.406 ms/op 1.01
altair processRewardsAndPenalties - 250000 worstcase 15.532 ms/op 15.046 ms/op 1.03
phase0 getAttestationDeltas - 250000 normalcase 5.1255 ms/op 5.2284 ms/op 0.98
phase0 getAttestationDeltas - 250000 worstcase 5.1646 ms/op 5.2676 ms/op 0.98
phase0 processSlashings - 250000 worstcase 57.873 us/op 58.319 us/op 0.99
altair processSyncCommitteeUpdates - 250000 9.7963 ms/op 10.018 ms/op 0.98
BeaconState.hashTreeRoot - No change 389.00 ns/op 180.00 ns/op 2.16
BeaconState.hashTreeRoot - 1 full validator 67.111 us/op 63.611 us/op 1.06
BeaconState.hashTreeRoot - 32 full validator 846.49 us/op 812.00 us/op 1.04
BeaconState.hashTreeRoot - 512 full validator 6.5556 ms/op 6.7127 ms/op 0.98
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 89.893 us/op 90.634 us/op 0.99
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.3190 ms/op 1.3262 ms/op 0.99
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 13.716 ms/op 14.664 ms/op 0.94
BeaconState.hashTreeRoot - 1 balances 60.693 us/op 68.440 us/op 0.89
BeaconState.hashTreeRoot - 32 balances 670.54 us/op 711.38 us/op 0.94
BeaconState.hashTreeRoot - 512 balances 4.7800 ms/op 5.1583 ms/op 0.93
BeaconState.hashTreeRoot - 250000 balances 105.04 ms/op 102.42 ms/op 1.03
aggregationBits - 2048 els - zipIndexesInBitList 19.272 us/op 18.921 us/op 1.02
regular array get 100000 times 22.263 us/op 22.320 us/op 1.00
wrappedArray get 100000 times 22.514 us/op 22.514 us/op 1.00
arrayWithProxy get 100000 times 9.3596 ms/op 11.588 ms/op 0.81
ssz.Root.equals 20.618 ns/op 20.929 ns/op 0.99
byteArrayEquals 20.424 ns/op 20.747 ns/op 0.98
Buffer.compare 8.5910 ns/op 8.6420 ns/op 0.99
processSlot - 1 slots 8.3560 us/op 9.0690 us/op 0.92
processSlot - 32 slots 1.8157 ms/op 1.9778 ms/op 0.92
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.6599 ms/op 4.9768 ms/op 0.94
getCommitteeAssignments - req 1 vs - 250000 vc 1.6182 ms/op 1.6269 ms/op 0.99
getCommitteeAssignments - req 100 vs - 250000 vc 3.2943 ms/op 3.3358 ms/op 0.99
getCommitteeAssignments - req 1000 vs - 250000 vc 3.5371 ms/op 3.5696 ms/op 0.99
findModifiedValidators - 10000 modified validators 707.42 ms/op 703.19 ms/op 1.01
findModifiedValidators - 1000 modified validators 580.88 ms/op 487.76 ms/op 1.19
findModifiedValidators - 100 modified validators 315.07 ms/op 278.81 ms/op 1.13
findModifiedValidators - 10 modified validators 291.79 ms/op 219.13 ms/op 1.33
findModifiedValidators - 1 modified validators 257.78 ms/op 153.93 ms/op 1.67
findModifiedValidators - no difference 199.23 ms/op 147.56 ms/op 1.35
migrate state 1500000 validators, 3400 modified, 2000 new 2.7858 s/op 2.8880 s/op 0.96
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 5.4300 ns/op 3.4400 ns/op 1.58
state getBlockRootAtSlot - 250000 vs - 7PWei 337.75 ns/op 350.04 ns/op 0.96
computeProposerIndex 100000 validators 1.2925 ms/op 1.3216 ms/op 0.98
getNextSyncCommitteeIndices 1000 validators 2.8105 ms/op 2.8623 ms/op 0.98
getNextSyncCommitteeIndices 10000 validators 24.449 ms/op 24.944 ms/op 0.98
getNextSyncCommitteeIndices 100000 validators 81.245 ms/op 86.507 ms/op 0.94
computeProposers - vc 250000 535.00 us/op 546.16 us/op 0.98
computeEpochShuffling - vc 250000 38.363 ms/op 40.351 ms/op 0.95
getNextSyncCommittee - vc 250000 9.0510 ms/op 9.2745 ms/op 0.98
nodejs block root to RootHex using toHex 103.39 ns/op 105.90 ns/op 0.98
nodejs block root to RootHex using toRootHex 64.176 ns/op 67.324 ns/op 0.95
nodejs fromHex(blob) 728.17 us/op 723.37 us/op 1.01
nodejs fromHexInto(blob) 613.47 us/op 612.84 us/op 1.00
nodejs block root to RootHex using the deprecated toHexString 468.02 ns/op 479.28 ns/op 0.98
nodejs byteArrayEquals 32 bytes (block root) 24.889 ns/op 25.569 ns/op 0.97
nodejs byteArrayEquals 48 bytes (pubkey) 35.954 ns/op 37.000 ns/op 0.97
nodejs byteArrayEquals 96 bytes (signature) 31.091 ns/op 31.776 ns/op 0.98
nodejs byteArrayEquals 1024 bytes 38.131 ns/op 38.933 ns/op 0.98
nodejs byteArrayEquals 131072 bytes (blob) 1.6845 us/op 1.7125 us/op 0.98
browser block root to RootHex using toHex 137.84 ns/op 140.53 ns/op 0.98
browser block root to RootHex using toRootHex 124.12 ns/op 128.79 ns/op 0.96
browser fromHex(blob) 1.4582 ms/op 1.4838 ms/op 0.98
browser fromHexInto(blob) 596.14 us/op 610.66 us/op 0.98
browser block root to RootHex using the deprecated toHexString 460.31 ns/op 473.94 ns/op 0.97
browser byteArrayEquals 32 bytes (block root) 26.509 ns/op 27.468 ns/op 0.97
browser byteArrayEquals 48 bytes (pubkey) 37.106 ns/op 38.864 ns/op 0.95
browser byteArrayEquals 96 bytes (signature) 69.417 ns/op 71.936 ns/op 0.96
browser byteArrayEquals 1024 bytes 713.70 ns/op 745.69 ns/op 0.96
browser byteArrayEquals 131072 bytes (blob) 90.254 us/op 92.656 us/op 0.97

by benchmarkbot/action

ensi321 and others added 2 commits April 13, 2026 18:37
- Only check payload-seen when block is known; unknown blocks are
  handled later by verifyHeadBlockAndTargetRoot which enables the
  API retry path for unknown roots
- Use chain.seenPayloadEnvelope which checks both the gossip cache
  (seenPayloadEnvelopeInputCache) and fork choice FULL variant

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ensi321 ensi321 marked this pull request as ready for review April 14, 2026 01:40
@ensi321
Copy link
Copy Markdown
Contributor Author

ensi321 commented Apr 14, 2026

@lodekeeper can you do a review please

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

Here are some automated review suggestions for this pull request.

Reviewed commit: da26e3413d

ℹ️ 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".

// the corresponding execution payload for `block` has been seen (a client MAY queue
// attestations for processing once the payload is retrieved and SHOULD request the
// payload envelope via `ExecutionPayloadEnvelopesByRoot`).
if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
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 Retry API attestation after payload envelope arrives

Throwing EXECUTION_PAYLOAD_NOT_SEEN here causes submitPoolAttestationsV2 to fail index-1 submissions whenever the block is known but the payload envelope is still in flight, because its retry helper only catches UNKNOWN_OR_PREFINALIZED_BEACON_BLOCK_ROOT (validateGossipFnRetryUnknownRoot in network/processor/gossipHandlers.ts) and only waits for block availability. In fallback/DVT setups (multiple beacon nodes), this creates a regression where valid attestations are dropped instead of being retried once the envelope is imported.

Useful? React with 👍 / 👎.

// the corresponding execution payload for `block` has been seen (a client MAY queue
// attestations for processing once the payload is retrieved and SHOULD request the
// payload envelope via `ExecutionPayloadEnvelopesByRoot`).
if (block !== null && attData.index === 1 && !chain.seenPayloadEnvelope(toRootHex(attData.beaconBlockRoot))) {
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 Retry API aggregates after payload envelope arrives

This new IGNORE branch introduces the same failure mode for publishAggregateAndProofsV2: index-1 aggregates now error out when the block is present but payload envelope import has not completed, yet the API retry path only handles unknown block roots and does not retry on EXECUTION_PAYLOAD_NOT_SEEN. As a result, valid aggregates from external/fallback beacon nodes can be rejected instead of being processed after envelope retrieval.

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.

Sounds like both of these codex messages are saying that our queuing needs to handle these failed attestations / aggregates

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 it is out of the scope of this PR. Tracking this issue at #9224

Comment thread packages/beacon-node/src/chain/validation/aggregateAndProof.ts
@ensi321 ensi321 mentioned this pull request Apr 15, 2026
5 tasks
Copy link
Copy Markdown
Contributor

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

looks good to me
note that the error can only happens on api path with a fallback node
we already handle the gossip path in network processor

@ensi321 ensi321 merged commit 2870b59 into unstable Apr 16, 2026
19 checks passed
@ensi321 ensi321 deleted the nc/alpha4-spec branch April 16, 2026 15:14
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.53%. Comparing base (6641fd7) to head (25b65a8).
⚠️ Report is 4 commits behind head on unstable.

Additional details and impacted files
@@            Coverage Diff            @@
##           unstable    #9213   +/-   ##
=========================================
  Coverage     52.53%   52.53%           
=========================================
  Files           848      848           
  Lines         61424    61424           
  Branches       4528     4528           
=========================================
  Hits          32269    32269           
  Misses        29090    29090           
  Partials         65       65           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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