Skip to content

fix: remove TOO_MANY_SKIPPED_SLOTS block error - #9484

Merged
nflaig merged 1 commit into
unstablefrom
te/avoid_too_many_skipped_slot_block_error
Jun 9, 2026
Merged

fix: remove TOO_MANY_SKIPPED_SLOTS block error#9484
nflaig merged 1 commit into
unstablefrom
te/avoid_too_many_skipped_slot_block_error

Conversation

@twoeths

@twoeths twoeths commented Jun 9, 2026

Copy link
Copy Markdown
Member

Motivation

  • we throw TOO_MANY_SKIPPED_SLOT block error but still let the gossip block run through the sync

Description

  • it's best to just remove it, lighthouse remove a long time ago
  • record in metrics + logs

Closes #9483

AI Assistance Disclosure

  • created with the help of Claude

@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 removes the TOO_MANY_SKIPPED_SLOTS validation check from gossip block validation, preventing legitimate post-skip blocks from being ignored. Instead, the number of skipped slots is now computed, returned by validateGossipBlock, and tracked via a new histogram metric (lodestar_gossip_block_skipped_slots) and debug logs. Corresponding unit tests and error codes have been cleaned up. There are no review comments to address, and the changes look solid.

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.

@twoeths
twoeths marked this pull request as ready for review June 9, 2026 06:42
@twoeths
twoeths requested a review from a team as a code owner June 9, 2026 06:42
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.58%. Comparing base (1b4e24f) to head (57b931f).

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #9484      +/-   ##
============================================
- Coverage     52.59%   52.58%   -0.01%     
============================================
  Files           848      848              
  Lines         60890    60879      -11     
  Branches       4485     4483       -2     
============================================
- Hits          32023    32014       -9     
+ Misses        28805    28803       -2     
  Partials         62       62              
🚀 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.

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Performance Report

🚀🚀 Significant benchmark improvement detected

Benchmark suite Current: 9c9f003 Previous: 3dd09a8 Ratio
enrSubnets - fastDeserialize 64 bits 757.00 ns/op 2.5860 us/op 0.29
Full benchmark results
Benchmark suite Current: 9c9f003 Previous: 3dd09a8 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 933.73 us/op 866.63 us/op 1.08
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 38.965 us/op 38.345 us/op 1.02
BLS verify - blst 740.00 us/op 696.29 us/op 1.06
BLS verifyMultipleSignatures 3 - blst 1.3486 ms/op 1.3459 ms/op 1.00
BLS verifyMultipleSignatures 8 - blst 2.1422 ms/op 2.1408 ms/op 1.00
BLS verifyMultipleSignatures 32 - blst 6.8198 ms/op 6.9159 ms/op 0.99
BLS verifyMultipleSignatures 64 - blst 13.633 ms/op 13.065 ms/op 1.04
BLS verifyMultipleSignatures 128 - blst 25.393 ms/op 25.205 ms/op 1.01
BLS deserializing 10000 signatures 637.95 ms/op 629.33 ms/op 1.01
BLS deserializing 100000 signatures 6.4026 s/op 6.2861 s/op 1.02
BLS verifyMultipleSignatures - same message - 3 - blst 707.60 us/op 754.64 us/op 0.94
BLS verifyMultipleSignatures - same message - 8 - blst 914.65 us/op 884.29 us/op 1.03
BLS verifyMultipleSignatures - same message - 32 - blst 1.5198 ms/op 1.5504 ms/op 0.98
BLS verifyMultipleSignatures - same message - 64 - blst 2.3897 ms/op 2.2683 ms/op 1.05
BLS verifyMultipleSignatures - same message - 128 - blst 4.0489 ms/op 4.0484 ms/op 1.00
BLS aggregatePubkeys 32 - blst 17.606 us/op 17.520 us/op 1.00
BLS aggregatePubkeys 128 - blst 63.118 us/op 62.543 us/op 1.01
getSlashingsAndExits - default max 50.889 us/op 46.321 us/op 1.10
getSlashingsAndExits - 2k 426.22 us/op 320.66 us/op 1.33
proposeBlockBody type=full, size=empty 664.30 us/op 678.35 us/op 0.98
isKnown best case - 1 super set check 171.00 ns/op 179.00 ns/op 0.96
isKnown normal case - 2 super set checks 179.00 ns/op 157.00 ns/op 1.14
isKnown worse case - 16 super set checks 167.00 ns/op 160.00 ns/op 1.04
validate api signedAggregateAndProof - struct 1.5143 ms/op 1.4981 ms/op 1.01
validate gossip signedAggregateAndProof - struct 1.5100 ms/op 1.4985 ms/op 1.01
batch validate gossip attestation - vc 640000 - chunk 32 103.92 us/op 104.56 us/op 0.99
batch validate gossip attestation - vc 640000 - chunk 64 93.653 us/op 90.973 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 128 87.071 us/op 84.132 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 256 84.398 us/op 80.819 us/op 1.04
bytes32 toHexString 281.00 ns/op 282.00 ns/op 1.00
bytes32 Buffer.toString(hex) 162.00 ns/op 163.00 ns/op 0.99
bytes32 Buffer.toString(hex) from Uint8Array 228.00 ns/op 216.00 ns/op 1.06
bytes32 Buffer.toString(hex) + 0x 159.00 ns/op 166.00 ns/op 0.96
Return object 10000 times 0.21190 ns/op 0.20950 ns/op 1.01
Throw Error 10000 times 3.4542 us/op 3.3930 us/op 1.02
toHex 92.079 ns/op 100.85 ns/op 0.91
Buffer.from 83.912 ns/op 84.946 ns/op 0.99
shared Buffer 57.005 ns/op 58.402 ns/op 0.98
fastMsgIdFn sha256 / 200 bytes 1.4510 us/op 1.4380 us/op 1.01
fastMsgIdFn h32 xxhash / 200 bytes 152.00 ns/op 147.00 ns/op 1.03
fastMsgIdFn h64 xxhash / 200 bytes 196.00 ns/op 193.00 ns/op 1.02
fastMsgIdFn sha256 / 1000 bytes 4.7600 us/op 4.6750 us/op 1.02
fastMsgIdFn h32 xxhash / 1000 bytes 244.00 ns/op 237.00 ns/op 1.03
fastMsgIdFn h64 xxhash / 1000 bytes 244.00 ns/op 241.00 ns/op 1.01
fastMsgIdFn sha256 / 10000 bytes 42.223 us/op 40.822 us/op 1.03
fastMsgIdFn h32 xxhash / 10000 bytes 1.2860 us/op 1.2410 us/op 1.04
fastMsgIdFn h64 xxhash / 10000 bytes 834.00 ns/op 802.00 ns/op 1.04
send data - 1000 256B messages 4.3220 ms/op 3.9959 ms/op 1.08
send data - 1000 512B messages 4.1701 ms/op 4.0231 ms/op 1.04
send data - 1000 1024B messages 4.1362 ms/op 4.1303 ms/op 1.00
send data - 1000 1200B messages 4.6309 ms/op 4.2641 ms/op 1.09
send data - 1000 2048B messages 4.7799 ms/op 4.4449 ms/op 1.08
send data - 1000 4096B messages 5.7687 ms/op 5.3791 ms/op 1.07
send data - 1000 16384B messages 26.281 ms/op 18.375 ms/op 1.43
send data - 1000 65536B messages 126.47 ms/op 106.68 ms/op 1.19
enrSubnets - fastDeserialize 64 bits 757.00 ns/op 2.5860 us/op 0.29
enrSubnets - ssz BitVector 64 bits 262.00 ns/op 254.00 ns/op 1.03
enrSubnets - fastDeserialize 4 bits 103.00 ns/op 103.00 ns/op 1.00
enrSubnets - ssz BitVector 4 bits 266.00 ns/op 256.00 ns/op 1.04
prioritizePeers score -10:0 att 32-0.1 sync 2-0 204.48 us/op 203.21 us/op 1.01
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 233.04 us/op 228.74 us/op 1.02
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 356.49 us/op 328.31 us/op 1.09
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 602.40 us/op 582.52 us/op 1.03
prioritizePeers score 0:0 att 64-1 sync 4-1 711.82 us/op 682.01 us/op 1.04
array of 16000 items push then shift 1.3068 us/op 1.2682 us/op 1.03
LinkedList of 16000 items push then shift 7.4910 ns/op 6.7190 ns/op 1.11
array of 16000 items push then pop 66.681 ns/op 64.655 ns/op 1.03
LinkedList of 16000 items push then pop 5.9570 ns/op 5.8570 ns/op 1.02
array of 24000 items push then shift 1.9166 us/op 1.8881 us/op 1.02
LinkedList of 24000 items push then shift 6.9030 ns/op 6.2440 ns/op 1.11
array of 24000 items push then pop 93.489 ns/op 91.426 ns/op 1.02
LinkedList of 24000 items push then pop 5.9580 ns/op 5.8540 ns/op 1.02
intersect bitArray bitLen 8 4.7250 ns/op 4.7180 ns/op 1.00
intersect array and set length 8 29.702 ns/op 29.494 ns/op 1.01
intersect bitArray bitLen 128 24.069 ns/op 23.911 ns/op 1.01
intersect array and set length 128 503.22 ns/op 496.66 ns/op 1.01
bitArray.getTrueBitIndexes() bitLen 128 1.0570 us/op 1.0650 us/op 0.99
bitArray.getTrueBitIndexes() bitLen 248 1.9010 us/op 1.7780 us/op 1.07
bitArray.getTrueBitIndexes() bitLen 512 3.8690 us/op 3.4550 us/op 1.12
Full columns - reconstruct all 6 blobs 120.93 us/op 178.83 us/op 0.68
Full columns - reconstruct half of the blobs out of 6 103.22 us/op 108.16 us/op 0.95
Full columns - reconstruct single blob out of 6 46.697 us/op 35.138 us/op 1.33
Half columns - reconstruct all 6 blobs 392.53 ms/op 374.72 ms/op 1.05
Half columns - reconstruct half of the blobs out of 6 197.05 ms/op 188.04 ms/op 1.05
Half columns - reconstruct single blob out of 6 68.853 ms/op 65.817 ms/op 1.05
Full columns - reconstruct all 10 blobs 191.14 us/op 233.24 us/op 0.82
Full columns - reconstruct half of the blobs out of 10 101.82 us/op 237.86 us/op 0.43
Full columns - reconstruct single blob out of 10 34.839 us/op 34.269 us/op 1.02
Half columns - reconstruct all 10 blobs 651.38 ms/op 621.26 ms/op 1.05
Half columns - reconstruct half of the blobs out of 10 322.75 ms/op 313.05 ms/op 1.03
Half columns - reconstruct single blob out of 10 69.769 ms/op 65.520 ms/op 1.06
Full columns - reconstruct all 20 blobs 2.0181 ms/op 2.5763 ms/op 0.78
Full columns - reconstruct half of the blobs out of 20 314.28 us/op 253.69 us/op 1.24
Full columns - reconstruct single blob out of 20 33.904 us/op 31.535 us/op 1.08
Half columns - reconstruct all 20 blobs 1.2966 s/op 1.2390 s/op 1.05
Half columns - reconstruct half of the blobs out of 20 651.41 ms/op 622.41 ms/op 1.05
Half columns - reconstruct single blob out of 20 69.626 ms/op 65.504 ms/op 1.06
Set add up to 64 items then delete first 2.6204 us/op 2.5615 us/op 1.02
OrderedSet add up to 64 items then delete first 3.4039 us/op 3.3292 us/op 1.02
Set add up to 64 items then delete last 2.4153 us/op 2.4189 us/op 1.00
OrderedSet add up to 64 items then delete last 3.3254 us/op 3.2917 us/op 1.01
Set add up to 64 items then delete middle 2.1430 us/op 2.1729 us/op 0.99
OrderedSet add up to 64 items then delete middle 4.7677 us/op 4.8534 us/op 0.98
Set add up to 128 items then delete first 4.2744 us/op 4.2317 us/op 1.01
OrderedSet add up to 128 items then delete first 6.6263 us/op 6.2607 us/op 1.06
Set add up to 128 items then delete last 3.9111 us/op 3.9739 us/op 0.98
OrderedSet add up to 128 items then delete last 5.8840 us/op 5.9482 us/op 0.99
Set add up to 128 items then delete middle 3.9066 us/op 3.9642 us/op 0.99
OrderedSet add up to 128 items then delete middle 11.809 us/op 11.782 us/op 1.00
Set add up to 256 items then delete first 7.9442 us/op 7.7493 us/op 1.03
OrderedSet add up to 256 items then delete first 12.218 us/op 11.433 us/op 1.07
Set add up to 256 items then delete last 7.7291 us/op 7.8284 us/op 0.99
OrderedSet add up to 256 items then delete last 11.696 us/op 11.810 us/op 0.99
Set add up to 256 items then delete middle 7.6488 us/op 7.8539 us/op 0.97
OrderedSet add up to 256 items then delete middle 34.950 us/op 34.827 us/op 1.00
runFastConfirmationRules vc:100000 bc:96 eq:0 3.3150 us/op 3.0710 us/op 1.08
runFastConfirmationRules vc:600000 bc:96 eq:0 6.0760 us/op 4.4930 us/op 1.35
runFastConfirmationRules vc:1000000 bc:96 eq:0 7.6020 us/op 3.8140 us/op 1.99
runFastConfirmationRules vc:600000 bc:320 eq:0 8.2600 us/op 7.2050 us/op 1.15
runFastConfirmationRules vc:600000 bc:1200 eq:0 33.837 us/op 26.478 us/op 1.28
runFastConfirmationRules vc:600000 bc:96 eq:1000 8.6940 us/op 3.5240 us/op 2.47
runFastConfirmationRules vc:600000 bc:96 eq:10000 5.0890 us/op 3.0790 us/op 1.65
runFastConfirmationRules vc:600000 bc:96 eq:300000 14.025 us/op 5.8290 us/op 2.41
pass gossip attestations to forkchoice per slot 2.5150 ms/op 2.4850 ms/op 1.01
forkChoice updateHead vc 100000 bc 64 eq 0 467.05 us/op 450.77 us/op 1.04
forkChoice updateHead vc 600000 bc 64 eq 0 2.7721 ms/op 2.7159 ms/op 1.02
forkChoice updateHead vc 1000000 bc 64 eq 0 4.6759 ms/op 4.4387 ms/op 1.05
forkChoice updateHead vc 600000 bc 320 eq 0 2.7167 ms/op 2.7152 ms/op 1.00
forkChoice updateHead vc 600000 bc 1200 eq 0 2.8286 ms/op 2.7292 ms/op 1.04
forkChoice updateHead vc 600000 bc 7200 eq 0 3.0154 ms/op 3.0716 ms/op 0.98
forkChoice updateHead vc 600000 bc 64 eq 1000 2.7324 ms/op 2.7732 ms/op 0.99
forkChoice updateHead vc 600000 bc 64 eq 10000 2.9034 ms/op 2.8721 ms/op 1.01
forkChoice updateHead vc 600000 bc 64 eq 300000 7.0394 ms/op 6.9705 ms/op 1.01
computeDeltas 1400000 validators 0% inactive 13.261 ms/op 13.292 ms/op 1.00
computeDeltas 1400000 validators 10% inactive 12.418 ms/op 12.453 ms/op 1.00
computeDeltas 1400000 validators 20% inactive 11.405 ms/op 11.465 ms/op 0.99
computeDeltas 1400000 validators 50% inactive 8.4180 ms/op 8.5535 ms/op 0.98
computeDeltas 2100000 validators 0% inactive 19.624 ms/op 19.993 ms/op 0.98
computeDeltas 2100000 validators 10% inactive 18.545 ms/op 18.585 ms/op 1.00
computeDeltas 2100000 validators 20% inactive 17.240 ms/op 16.935 ms/op 1.02
computeDeltas 2100000 validators 50% inactive 10.242 ms/op 10.149 ms/op 1.01
altair processAttestation - 250000 vs - 7PWei normalcase 1.7717 ms/op 1.6784 ms/op 1.06
altair processAttestation - 250000 vs - 7PWei worstcase 2.7396 ms/op 2.3971 ms/op 1.14
altair processAttestation - setStatus - 1/6 committees join 105.90 us/op 105.16 us/op 1.01
altair processAttestation - setStatus - 1/3 committees join 204.15 us/op 204.19 us/op 1.00
altair processAttestation - setStatus - 1/2 committees join 287.45 us/op 287.20 us/op 1.00
altair processAttestation - setStatus - 2/3 committees join 371.41 us/op 373.17 us/op 1.00
altair processAttestation - setStatus - 4/5 committees join 515.60 us/op 497.87 us/op 1.04
altair processAttestation - setStatus - 100% committees join 609.64 us/op 593.33 us/op 1.03
altair processBlock - 250000 vs - 7PWei normalcase 3.9345 ms/op 2.8062 ms/op 1.40
altair processBlock - 250000 vs - 7PWei normalcase hashState 12.671 ms/op 11.570 ms/op 1.10
altair processBlock - 250000 vs - 7PWei worstcase 22.150 ms/op 19.167 ms/op 1.16
altair processBlock - 250000 vs - 7PWei worstcase hashState 42.052 ms/op 39.154 ms/op 1.07
phase0 processBlock - 250000 vs - 7PWei normalcase 1.3244 ms/op 1.2395 ms/op 1.07
phase0 processBlock - 250000 vs - 7PWei worstcase 16.793 ms/op 17.111 ms/op 0.98
altair processEth1Data - 250000 vs - 7PWei normalcase 304.07 us/op 301.56 us/op 1.01
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 4.1300 us/op 3.5060 us/op 1.18
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 20.616 us/op 26.010 us/op 0.79
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.7960 us/op 8.5230 us/op 0.68
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.7840 us/op 5.2370 us/op 0.72
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 94.280 us/op 99.255 us/op 0.95
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4186 ms/op 1.3322 ms/op 1.06
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8469 ms/op 1.7823 ms/op 1.04
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8283 ms/op 1.7441 ms/op 1.05
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.6829 ms/op 3.5389 ms/op 1.04
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.1512 ms/op 2.0037 ms/op 1.07
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 4.0035 ms/op 4.0071 ms/op 1.00
Tree 40 250000 create 305.68 ms/op 302.74 ms/op 1.01
Tree 40 250000 get(125000) 99.597 ns/op 104.28 ns/op 0.96
Tree 40 250000 set(125000) 1.0262 us/op 1.0360 us/op 0.99
Tree 40 250000 toArray() 9.8686 ms/op 9.0456 ms/op 1.09
Tree 40 250000 iterate all - toArray() + loop 15.276 ms/op 8.9571 ms/op 1.71
Tree 40 250000 iterate all - get(i) 41.044 ms/op 34.001 ms/op 1.21
Array 250000 create 2.1504 ms/op 1.9223 ms/op 1.12
Array 250000 clone - spread 657.70 us/op 614.48 us/op 1.07
Array 250000 get(125000) 0.29400 ns/op 0.28600 ns/op 1.03
Array 250000 set(125000) 0.29500 ns/op 0.29200 ns/op 1.01
Array 250000 iterate all - loop 57.618 us/op 55.340 us/op 1.04
phase0 afterProcessEpoch - 250000 vs - 7PWei 38.906 ms/op 45.467 ms/op 0.86
Array.fill - length 1000000 2.2093 ms/op 2.2090 ms/op 1.00
Array push - length 1000000 8.5607 ms/op 7.3731 ms/op 1.16
Array.get 0.20643 ns/op 0.19794 ns/op 1.04
Uint8Array.get 0.25564 ns/op 0.23507 ns/op 1.09
phase0 beforeProcessEpoch - 250000 vs - 7PWei 16.178 ms/op 11.795 ms/op 1.37
altair processEpoch - mainnet_e81889 250.05 ms/op 218.01 ms/op 1.15
mainnet_e81889 - altair beforeProcessEpoch 17.489 ms/op 13.401 ms/op 1.31
mainnet_e81889 - altair processJustificationAndFinalization 5.5160 us/op 4.6110 us/op 1.20
mainnet_e81889 - altair processInactivityUpdates 3.4794 ms/op 3.4426 ms/op 1.01
mainnet_e81889 - altair processRewardsAndPenalties 18.497 ms/op 15.784 ms/op 1.17
mainnet_e81889 - altair processRegistryUpdates 532.00 ns/op 526.00 ns/op 1.01
mainnet_e81889 - altair processSlashings 133.00 ns/op 135.00 ns/op 0.99
mainnet_e81889 - altair processEth1DataReset 125.00 ns/op 128.00 ns/op 0.98
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.6285 ms/op 1.3047 ms/op 1.25
mainnet_e81889 - altair processSlashingsReset 694.00 ns/op 690.00 ns/op 1.01
mainnet_e81889 - altair processRandaoMixesReset 1.1550 us/op 980.00 ns/op 1.18
mainnet_e81889 - altair processHistoricalRootsUpdate 126.00 ns/op 132.00 ns/op 0.95
mainnet_e81889 - altair processParticipationFlagUpdates 425.00 ns/op 418.00 ns/op 1.02
mainnet_e81889 - altair processSyncCommitteeUpdates 104.00 ns/op 104.00 ns/op 1.00
mainnet_e81889 - altair afterProcessEpoch 42.788 ms/op 39.959 ms/op 1.07
capella processEpoch - mainnet_e217614 845.10 ms/op 681.18 ms/op 1.24
mainnet_e217614 - capella beforeProcessEpoch 55.530 ms/op 61.328 ms/op 0.91
mainnet_e217614 - capella processJustificationAndFinalization 5.1940 us/op 4.7980 us/op 1.08
mainnet_e217614 - capella processInactivityUpdates 11.241 ms/op 10.959 ms/op 1.03
mainnet_e217614 - capella processRewardsAndPenalties 93.654 ms/op 84.163 ms/op 1.11
mainnet_e217614 - capella processRegistryUpdates 4.5290 us/op 4.4090 us/op 1.03
mainnet_e217614 - capella processSlashings 135.00 ns/op 129.00 ns/op 1.05
mainnet_e217614 - capella processEth1DataReset 128.00 ns/op 130.00 ns/op 0.98
mainnet_e217614 - capella processEffectiveBalanceUpdates 10.205 ms/op 5.1027 ms/op 2.00
mainnet_e217614 - capella processSlashingsReset 684.00 ns/op 679.00 ns/op 1.01
mainnet_e217614 - capella processRandaoMixesReset 1.2150 us/op 1.0140 us/op 1.20
mainnet_e217614 - capella processHistoricalRootsUpdate 132.00 ns/op 132.00 ns/op 1.00
mainnet_e217614 - capella processParticipationFlagUpdates 431.00 ns/op 417.00 ns/op 1.03
mainnet_e217614 - capella afterProcessEpoch 107.36 ms/op 109.73 ms/op 0.98
phase0 processEpoch - mainnet_e58758 279.30 ms/op 231.64 ms/op 1.21
mainnet_e58758 - phase0 beforeProcessEpoch 58.105 ms/op 46.055 ms/op 1.26
mainnet_e58758 - phase0 processJustificationAndFinalization 5.7860 us/op 4.6650 us/op 1.24
mainnet_e58758 - phase0 processRewardsAndPenalties 16.953 ms/op 14.798 ms/op 1.15
mainnet_e58758 - phase0 processRegistryUpdates 2.2680 us/op 2.1900 us/op 1.04
mainnet_e58758 - phase0 processSlashings 135.00 ns/op 134.00 ns/op 1.01
mainnet_e58758 - phase0 processEth1DataReset 381.00 ns/op 123.00 ns/op 3.10
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 824.95 us/op 845.41 us/op 0.98
mainnet_e58758 - phase0 processSlashingsReset 912.00 ns/op 769.00 ns/op 1.19
mainnet_e58758 - phase0 processRandaoMixesReset 1.2730 us/op 1.0150 us/op 1.25
mainnet_e58758 - phase0 processHistoricalRootsUpdate 137.00 ns/op 130.00 ns/op 1.05
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.0850 us/op 939.00 ns/op 1.16
mainnet_e58758 - phase0 afterProcessEpoch 32.797 ms/op 32.453 ms/op 1.01
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.0078 ms/op 996.22 us/op 1.01
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5820 ms/op 1.2090 ms/op 1.31
altair processInactivityUpdates - 250000 normalcase 10.672 ms/op 10.308 ms/op 1.04
altair processInactivityUpdates - 250000 worstcase 10.636 ms/op 10.343 ms/op 1.03
phase0 processRegistryUpdates - 250000 normalcase 2.3230 us/op 3.7210 us/op 0.62
phase0 processRegistryUpdates - 250000 badcase_full_deposits 149.69 us/op 144.40 us/op 1.04
phase0 processRegistryUpdates - 250000 worstcase 0.5 63.351 ms/op 54.524 ms/op 1.16
altair processRewardsAndPenalties - 250000 normalcase 16.338 ms/op 13.774 ms/op 1.19
altair processRewardsAndPenalties - 250000 worstcase 15.560 ms/op 13.365 ms/op 1.16
phase0 getAttestationDeltas - 250000 normalcase 5.5037 ms/op 5.3479 ms/op 1.03
phase0 getAttestationDeltas - 250000 worstcase 5.4927 ms/op 5.2939 ms/op 1.04
phase0 processSlashings - 250000 worstcase 60.853 us/op 61.270 us/op 0.99
altair processSyncCommitteeUpdates - 250000 10.167 ms/op 9.8357 ms/op 1.03
BeaconState.hashTreeRoot - No change 167.00 ns/op 168.00 ns/op 0.99
BeaconState.hashTreeRoot - 1 full validator 68.874 us/op 55.911 us/op 1.23
BeaconState.hashTreeRoot - 32 full validator 823.19 us/op 614.51 us/op 1.34
BeaconState.hashTreeRoot - 512 full validator 6.4491 ms/op 5.7515 ms/op 1.12
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 97.142 us/op 68.499 us/op 1.42
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.3365 ms/op 1.0185 ms/op 1.31
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 14.151 ms/op 12.322 ms/op 1.15
BeaconState.hashTreeRoot - 1 balances 68.514 us/op 53.571 us/op 1.28
BeaconState.hashTreeRoot - 32 balances 714.63 us/op 525.06 us/op 1.36
BeaconState.hashTreeRoot - 512 balances 5.4996 ms/op 4.5044 ms/op 1.22
BeaconState.hashTreeRoot - 250000 balances 154.73 ms/op 94.895 ms/op 1.63
aggregationBits - 2048 els - zipIndexesInBitList 20.046 us/op 18.629 us/op 1.08
regular array get 100000 times 23.115 us/op 22.187 us/op 1.04
wrappedArray get 100000 times 23.081 us/op 22.187 us/op 1.04
arrayWithProxy get 100000 times 10.421 ms/op 10.268 ms/op 1.01
ssz.Root.equals 21.493 ns/op 21.029 ns/op 1.02
byteArrayEquals 21.258 ns/op 20.845 ns/op 1.02
Buffer.compare 8.8330 ns/op 8.8320 ns/op 1.00
processSlot - 1 slots 9.6420 us/op 7.6740 us/op 1.26
processSlot - 32 slots 2.1523 ms/op 1.5097 ms/op 1.43
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 3.7298 ms/op 1.8098 ms/op 2.06
getCommitteeAssignments - req 1 vs - 250000 vc 1.6766 ms/op 1.6387 ms/op 1.02
getCommitteeAssignments - req 100 vs - 250000 vc 3.4398 ms/op 3.3402 ms/op 1.03
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7183 ms/op 3.5839 ms/op 1.04
findModifiedValidators - 10000 modified validators 813.84 ms/op 740.08 ms/op 1.10
findModifiedValidators - 1000 modified validators 470.75 ms/op 368.68 ms/op 1.28
findModifiedValidators - 100 modified validators 348.66 ms/op 288.35 ms/op 1.21
findModifiedValidators - 10 modified validators 265.16 ms/op 233.32 ms/op 1.14
findModifiedValidators - 1 modified validators 208.30 ms/op 173.89 ms/op 1.20
findModifiedValidators - no difference 214.72 ms/op 166.24 ms/op 1.29
migrate state 1500000 validators, 3400 modified, 2000 new 3.0734 s/op 3.1308 s/op 0.98
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.6800 ns/op 3.7900 ns/op 0.97
state getBlockRootAtSlot - 250000 vs - 7PWei 346.18 ns/op 290.55 ns/op 1.19
computeProposerIndex 100000 validators 1.3657 ms/op 1.3678 ms/op 1.00
getNextSyncCommitteeIndices 1000 validators 2.9464 ms/op 2.9306 ms/op 1.01
getNextSyncCommitteeIndices 10000 validators 25.674 ms/op 25.626 ms/op 1.00
getNextSyncCommitteeIndices 100000 validators 87.621 ms/op 87.081 ms/op 1.01
computeProposers - vc 250000 560.18 us/op 555.47 us/op 1.01
computeEpochShuffling - vc 250000 40.336 ms/op 39.648 ms/op 1.02
getNextSyncCommittee - vc 250000 9.7429 ms/op 9.4099 ms/op 1.04
nodejs block root to RootHex using toHex 91.486 ns/op 94.637 ns/op 0.97
nodejs block root to RootHex using toRootHex 55.666 ns/op 56.679 ns/op 0.98
nodejs fromHex(blob) 828.54 us/op 744.44 us/op 1.11
nodejs fromHexInto(blob) 635.96 us/op 633.97 us/op 1.00
nodejs block root to RootHex using the deprecated toHexString 508.26 ns/op 496.07 ns/op 1.02
nodejs byteArrayEquals 32 bytes (block root) 26.046 ns/op 26.136 ns/op 1.00
nodejs byteArrayEquals 48 bytes (pubkey) 37.696 ns/op 37.860 ns/op 1.00
nodejs byteArrayEquals 96 bytes (signature) 36.857 ns/op 35.429 ns/op 1.04
nodejs byteArrayEquals 1024 bytes 42.775 ns/op 43.342 ns/op 0.99
nodejs byteArrayEquals 131072 bytes (blob) 1.7813 us/op 1.7513 us/op 1.02
browser block root to RootHex using toHex 146.30 ns/op 145.42 ns/op 1.01
browser block root to RootHex using toRootHex 131.70 ns/op 132.58 ns/op 0.99
browser fromHex(blob) 1.6021 ms/op 1.5521 ms/op 1.03
browser fromHexInto(blob) 633.50 us/op 634.70 us/op 1.00
browser block root to RootHex using the deprecated toHexString 346.82 ns/op 333.39 ns/op 1.04
browser byteArrayEquals 32 bytes (block root) 28.191 ns/op 27.806 ns/op 1.01
browser byteArrayEquals 48 bytes (pubkey) 39.673 ns/op 39.224 ns/op 1.01
browser byteArrayEquals 96 bytes (signature) 74.567 ns/op 73.356 ns/op 1.02
browser byteArrayEquals 1024 bytes 756.09 ns/op 746.83 ns/op 1.01
browser byteArrayEquals 131072 bytes (blob) 95.771 us/op 94.435 us/op 1.01

by benchmarkbot/action

@nflaig

nflaig commented Jun 9, 2026

Copy link
Copy Markdown
Member

@lodekeeper can you double check this against the spec, is there such a rule in the spec? (also would we pass gossip validation spec tests when removing this)

@lodekeeper

Copy link
Copy Markdown
Contributor

Spec-checked — short answer: no such rule in spec, and gossip validation pyspec tests would pass.

Is there a TOO_MANY_SKIPPED_SLOTS rule in spec? No. validate_beacon_block_gossip in specs/phase0/p2p-interface.md (lines ~550-619) has these checks in order:

  1. [IGNORE] not from future slot
  2. [IGNORE] slot > finalized slot
  3. [IGNORE] first valid block for this (proposer, slot) (anti-equivocation)
  4. [REJECT] proposer_index in range
  5. [REJECT] proposer signature valid
  6. [IGNORE] parent has been seen
  7. [REJECT] parent passes validation
  8. [REJECT] block.slot > parent.slot — only slot-distance check, no upper bound
  9. [REJECT] finalized checkpoint is an ancestor
  10. [REJECT] expected proposer for slot

No skip-distance limit anywhere. The diff's own deleted comment (Note: This validation check is not part of the spec.) was right; Lighthouse not having it is consistent with spec.

Would gossip validation spec tests pass? Yes. The pyspec coverage at tests/core/pyspec/eth_consensus_specs/test/{phase0,deneb,fulu}/networking/test_gossip_beacon_block.py covers all 10 spec checks (valid_block, ignore_future_slot, valid_within_clock_disparity, ignore_already_seen_proposer_slot, ignore_slot_not_greater_than_finalized, ignore_parent_not_seen, reject_parent_failed_validation, reject_slot_not_higher_than_parent, reject_finalized_checkpoint_not_ancestor, reject_invalid_proposer_signature, reject_invalid_proposer_index, reject_wrong_proposer_index) — no skip-distance test, because the rule doesn't exist. test_gossip_beacon_block__valid_block uses build_empty_block_for_next_slot (parent+1), so the removal doesn't affect any existing case.

DoS footnote: the original comment was right that a long parent→block gap forces multiple epoch transitions before sig verification (~750ms each per the chain.ts comment), so this gate was load-shedding. The PR trades that local mitigation for spec compliance and instruments the actual skip distribution via lodestar_gossip_block_skipped_slots — if mainnet shows real DoS pressure, the histogram tells us whether a non-gating mitigation is needed.

Unrelated benchmark alert: the proposeBlockBody type=full, size=empty regression (0.57ms→3.38ms, 5.88x) flagged by github-actions looks like CI-noise — proposeBlockBody is on the produce path and the diff only touches gossip validation/metrics/error codes. Worth re-running but not a real signal.

// single bad block can trigger
// Note: Ensure this check is done before calling chain.regen.getBlockSlotStat as this is the function that does various epoch transitions.
// Note: This validation check is not part of the spec.
if (chain.opts.maxSkipSlots != null && parentBlock.slot + chain.opts.maxSkipSlots < blockSlot) {

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.

worth pointing out that this is 32 by default, so with slotImportTolerance being 32 by default, this is very unlikely to happen as we won't be subscribed to gossip if our head is 32 slots behind clock slot, although it can eg. for a block on a different branch

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.

Good point — that's another reason the gate was effectively dead code for our own canonical chain: gossip subscription is already gated by slotImportTolerance = SLOTS_PER_EPOCH = 32, so a block where parent.slot + 32 < block.slot under our canonical head would already be filtered before reaching validateGossipBlock. The different-branch case you flagged is the residual scenario — a peer gossips a block whose parent is on a side fork older than head - slotImportTolerance. The new lodestar_gossip_block_skipped_slots histogram should surface that distribution from mainnet; if a non-trivial tail shows up from competing-branch gossip, that data tells us whether a non-gating mitigation is warranted (peer budget, per-shuffle work cap, etc.).

@nflaig
nflaig merged commit 9666fc8 into unstable Jun 9, 2026
31 of 34 checks passed
@nflaig
nflaig deleted the te/avoid_too_many_skipped_slot_block_error branch June 9, 2026 09:39
@wemeetagain

Copy link
Copy Markdown
Member

🎉 This PR is included in v1.44.0 🎉

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.

glamsterdam-devnet-5: Gossip block validation error code=TOO_MANY_SKIPPED_SLOTS

4 participants