Skip to content

feat: penalize peers for forwarding REJECTED gossip messages - #10059

Merged
wemeetagain merged 5 commits into
unstablefrom
te/penalize_on_rejected_messages
Sep 17, 2026
Merged

wemeetagain merged 5 commits into
unstablefrom
te/penalize_on_rejected_messages

Conversation

@twoeths

@twoeths twoeths commented Sep 11, 2026

Copy link
Copy Markdown
Member

Motivation

  • there are some spammers on mainnet that forwarded REJECTED blocks recently, we should penalize and gradually disconnect/ban them

Description

  • handle it inside gossipValidatorFn
    • for block/column/payload: penalize peers with LOW tolerance
    • for other topics: penalize peers with MID tolerance

part of #9925

AI Assistance Disclosure

  • created with the help of Claude

@github-actions

github-actions Bot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Performance Report

🚀🚀 Significant benchmark improvement detected

Benchmark suite Current: 59a9b45 Previous: 8d21f7a Ratio
archive index / 1 slots / 8 columns / legacy 162.47 us/op 2.6404 ms/op 0.06
Full benchmark results
Benchmark suite Current: 59a9b45 Previous: 8d21f7a Ratio
getPubkeys - native cache - req 1000 vs - 250000 vc 480.48 us/op 431.16 us/op 1.11
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 34.142 us/op 36.999 us/op 0.92
BLS verify - blst 744.79 us/op 880.40 us/op 0.85
BLS verifyMultipleSignatures 3 - blst 1.1271 ms/op 1.2734 ms/op 0.89
BLS verifyMultipleSignatures 8 - blst 1.8576 ms/op 2.1278 ms/op 0.87
BLS verifyMultipleSignatures 32 - blst 5.9805 ms/op 7.0261 ms/op 0.85
BLS verifyMultipleSignatures 64 - blst 11.011 ms/op 13.337 ms/op 0.83
BLS verifyMultipleSignatures 128 - blst 21.032 ms/op 25.614 ms/op 0.82
BLS deserializing 10000 signatures 518.37 ms/op 609.64 ms/op 0.85
BLS deserializing 100000 signatures 5.2169 s/op 6.1859 s/op 0.84
BLS verifyMultipleSignatures - same message - 3 - blst 832.44 us/op 936.17 us/op 0.89
BLS verifyMultipleSignatures - same message - 8 - blst 926.21 us/op 1.0577 ms/op 0.88
BLS verifyMultipleSignatures - same message - 32 - blst 1.3891 ms/op 1.6556 ms/op 0.84
BLS verifyMultipleSignatures - same message - 64 - blst 2.0136 ms/op 2.4461 ms/op 0.82
BLS verifyMultipleSignatures - same message - 128 - blst 3.2458 ms/op 4.0547 ms/op 0.80
BLS aggregatePubkeys 32 - blst 14.905 us/op 18.948 us/op 0.79
BLS aggregatePubkeys 128 - blst 54.322 us/op 67.148 us/op 0.81
getSlashingsAndExits - default max 40.771 us/op 38.405 us/op 1.06
getSlashingsAndExits - 2k 417.12 us/op 329.95 us/op 1.26
proposeBlockBody type=full, size=empty 794.13 us/op 650.26 us/op 1.22
isKnown best case - 1 super set check 122.00 ns/op 156.00 ns/op 0.78
isKnown normal case - 2 super set checks 124.00 ns/op 165.00 ns/op 0.75
isKnown worse case - 16 super set checks 124.00 ns/op 157.00 ns/op 0.79
validate api signedAggregateAndProof - struct 1.2985 ms/op 1.4198 ms/op 0.91
validate gossip signedAggregateAndProof - struct 1.2461 ms/op 1.4065 ms/op 0.89
batch validate gossip attestation - vc 640000 - chunk 32 104.64 us/op 119.77 us/op 0.87
batch validate gossip attestation - vc 640000 - chunk 64 89.499 us/op 104.09 us/op 0.86
batch validate gossip attestation - vc 640000 - chunk 128 80.633 us/op 93.427 us/op 0.86
batch validate gossip attestation - vc 640000 - chunk 256 80.958 us/op 93.477 us/op 0.87
bytes32 toHexString 241.00 ns/op 281.00 ns/op 0.86
bytes32 Buffer.toString(hex) 133.00 ns/op 162.00 ns/op 0.82
bytes32 Buffer.toString(hex) from Uint8Array 194.00 ns/op 215.00 ns/op 0.90
bytes32 Buffer.toString(hex) + 0x 131.00 ns/op 161.00 ns/op 0.81
Return object 10000 times 0.20520 ns/op 0.20370 ns/op 1.01
Throw Error 10000 times 2.8599 us/op 3.1662 us/op 0.90
toHex 77.003 ns/op 96.439 ns/op 0.80
Buffer.from 64.314 ns/op 81.003 ns/op 0.79
shared Buffer 42.738 ns/op 55.638 ns/op 0.77
fastMsgIdFn sha256 / 200 bytes 1.2020 us/op 1.4140 us/op 0.85
fastMsgIdFn h32 xxhash / 200 bytes 117.00 ns/op 156.00 ns/op 0.75
fastMsgIdFn h64 xxhash / 200 bytes 166.00 ns/op 195.00 ns/op 0.85
fastMsgIdFn sha256 / 1000 bytes 3.7900 us/op 4.6070 us/op 0.82
fastMsgIdFn h32 xxhash / 1000 bytes 184.00 ns/op 238.00 ns/op 0.77
fastMsgIdFn h64 xxhash / 1000 bytes 199.00 ns/op 246.00 ns/op 0.81
fastMsgIdFn sha256 / 10000 bytes 33.178 us/op 41.285 us/op 0.80
fastMsgIdFn h32 xxhash / 10000 bytes 930.00 ns/op 1.2560 us/op 0.74
fastMsgIdFn h64 xxhash / 10000 bytes 587.00 ns/op 814.00 ns/op 0.72
send data - 1000 256B messages 4.0686 ms/op 4.0471 ms/op 1.01
send data - 1000 512B messages 4.9145 ms/op 4.7968 ms/op 1.02
send data - 1000 1024B messages 5.4719 ms/op 5.4621 ms/op 1.00
send data - 1000 1200B messages 6.1821 ms/op 5.9727 ms/op 1.04
send data - 1000 2048B messages 15.151 ms/op 14.952 ms/op 1.01
send data - 1000 4096B messages 24.531 ms/op 25.870 ms/op 0.95
send data - 1000 16384B messages 156.43 ms/op 285.79 ms/op 0.55
send data - 1000 65536B messages 378.73 ms/op 1.3710 s/op 0.28
enrSubnets - fastDeserialize 64 bits 641.00 ns/op 726.00 ns/op 0.88
enrSubnets - ssz BitVector 64 bits 232.00 ns/op 273.00 ns/op 0.85
enrSubnets - fastDeserialize 4 bits 74.000 ns/op 96.000 ns/op 0.77
enrSubnets - ssz BitVector 4 bits 228.00 ns/op 284.00 ns/op 0.80
prioritizePeers score -10:0 att 32-0.1 sync 2-0 168.24 us/op 194.85 us/op 0.86
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 187.94 us/op 224.44 us/op 0.84
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 269.89 us/op 320.23 us/op 0.84
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 485.32 us/op 567.21 us/op 0.86
prioritizePeers score 0:0 att 64-1 sync 4-1 571.88 us/op 672.19 us/op 0.85
archive index / 1 slot / archive root index lookup 42.878 us/op 16.827 us/op 2.55
archive index / 1 slot / archive block lookup, decode and hash 2.2655 ms/op 2.5887 ms/op 0.88
archive index / 1 slots / 1 columns / legacy 46.060 us/op 21.208 us/op 2.17
archive index / 1 slots / 1 columns / flat files 273.68 us/op 141.70 us/op 1.93
archive index / 1 slots / 8 columns / legacy 162.47 us/op 2.6404 ms/op 0.06
archive index / 1 slots / 8 columns / flat files 433.25 us/op 321.46 us/op 1.35
archive index / 1 slots / 128 columns / legacy 3.2072 ms/op 2.2120 ms/op 1.45
archive index / 1 slots / 128 columns / flat files 5.1992 ms/op 5.1852 ms/op 1.00
archive index / 8 slots / 1 columns / legacy 354.15 us/op 266.40 us/op 1.33
archive index / 8 slots / 1 columns / flat files 2.0474 ms/op 968.29 us/op 2.11
archive index / 8 slots / 8 columns / legacy 1.4619 ms/op 5.9373 ms/op 0.25
archive index / 8 slots / 8 columns / flat files 4.3519 ms/op 3.2488 ms/op 1.34
archive index / 8 slots / 128 columns / legacy 28.638 ms/op 94.061 ms/op 0.30
archive index / 8 slots / 128 columns / flat files 82.078 ms/op 178.56 ms/op 0.46
head state / 1 slot / archive root index lookup 40.534 us/op 18.302 us/op 2.21
head state / 1 slot / archive block lookup, decode and hash 2.2760 ms/op 2.6519 ms/op 0.86
head state / 1 slots / 1 columns / legacy 44.977 us/op 20.130 us/op 2.23
head state / 1 slots / 1 columns / flat files 237.00 us/op 110.89 us/op 2.14
head state / 1 slots / 8 columns / legacy 223.42 us/op 93.087 us/op 2.40
head state / 1 slots / 8 columns / flat files 423.76 us/op 324.52 us/op 1.31
head state / 1 slots / 128 columns / legacy 2.8967 ms/op 9.9781 ms/op 0.29
head state / 1 slots / 128 columns / flat files 6.2860 ms/op 4.9863 ms/op 1.26
head state / 8 slots / 1 columns / legacy 371.83 us/op 176.61 us/op 2.11
head state / 8 slots / 1 columns / flat files 1.6014 ms/op 911.67 us/op 1.76
head state / 8 slots / 8 columns / legacy 1.2210 ms/op 1.0382 ms/op 1.18
head state / 8 slots / 8 columns / flat files 3.7907 ms/op 2.8232 ms/op 1.34
head state / 8 slots / 128 columns / legacy 30.659 ms/op 86.879 ms/op 0.35
head state / 8 slots / 128 columns / flat files 78.825 ms/op 208.12 ms/op 0.38
array of 16000 items push then shift 790.50 ns/op 1.2420 us/op 0.64
LinkedList of 16000 items push then shift 4.9480 ns/op 7.6100 ns/op 0.65
array of 16000 items push then pop 48.579 ns/op 78.994 ns/op 0.61
LinkedList of 16000 items push then pop 4.6570 ns/op 5.8420 ns/op 0.80
array of 24000 items push then shift 1.1552 us/op 1.8311 us/op 0.63
LinkedList of 24000 items push then shift 4.8250 ns/op 7.0330 ns/op 0.69
array of 24000 items push then pop 67.072 ns/op 111.01 ns/op 0.60
LinkedList of 24000 items push then pop 4.7380 ns/op 5.8530 ns/op 0.81
intersect bitArray bitLen 8 2.5140 ns/op 3.7470 ns/op 0.67
intersect array and set length 8 22.943 ns/op 28.211 ns/op 0.81
intersect bitArray bitLen 128 16.986 ns/op 22.417 ns/op 0.76
intersect array and set length 128 381.82 ns/op 479.24 ns/op 0.80
bitArray.getTrueBitIndexes() bitLen 128 821.00 ns/op 911.00 ns/op 0.90
bitArray.getTrueBitIndexes() bitLen 248 1.4580 us/op 1.6310 us/op 0.89
bitArray.getTrueBitIndexes() bitLen 512 3.1680 us/op 3.3970 us/op 0.93
Full columns - reconstruct all 6 blobs 195.31 us/op 251.34 us/op 0.78
Full columns - reconstruct half of the blobs out of 6 78.768 us/op 64.522 us/op 1.22
Full columns - reconstruct single blob out of 6 29.932 us/op 30.398 us/op 0.98
Half columns - reconstruct all 6 blobs 298.48 ms/op 375.56 ms/op 0.79
Half columns - reconstruct half of the blobs out of 6 151.00 ms/op 188.54 ms/op 0.80
Half columns - reconstruct single blob out of 6 54.287 ms/op 66.369 ms/op 0.82
Set add up to 64 items then delete first 1.3127 us/op 1.5532 us/op 0.85
OrderedSet add up to 64 items then delete first 1.9676 us/op 2.3851 us/op 0.82
Set add up to 64 items then delete last 1.6004 us/op 1.7575 us/op 0.91
OrderedSet add up to 64 items then delete last 2.4776 us/op 2.7864 us/op 0.89
Set add up to 64 items then delete middle 1.5745 us/op 1.7741 us/op 0.89
OrderedSet add up to 64 items then delete middle 3.2215 us/op 4.2207 us/op 0.76
Set add up to 128 items then delete first 3.6024 us/op 3.4132 us/op 1.06
OrderedSet add up to 128 items then delete first 5.4262 us/op 5.1069 us/op 1.06
Set add up to 128 items then delete last 3.4684 us/op 3.3591 us/op 1.03
OrderedSet add up to 128 items then delete last 5.0012 us/op 5.2738 us/op 0.95
Set add up to 128 items then delete middle 3.6476 us/op 3.3509 us/op 1.09
OrderedSet add up to 128 items then delete middle 9.0978 us/op 10.982 us/op 0.83
Set add up to 256 items then delete first 7.3619 us/op 6.8010 us/op 1.08
OrderedSet add up to 256 items then delete first 11.083 us/op 10.605 us/op 1.05
Set add up to 256 items then delete last 6.9874 us/op 7.0007 us/op 1.00
OrderedSet add up to 256 items then delete last 10.137 us/op 11.186 us/op 0.91
Set add up to 256 items then delete middle 7.3027 us/op 6.9223 us/op 1.05
OrderedSet add up to 256 items then delete middle 28.298 us/op 33.694 us/op 0.84
runFastConfirmationRules vc:100000 bc:96 eq:0 3.6147 ms/op 4.2740 ms/op 0.85
runFastConfirmationRules vc:600000 bc:96 eq:0 26.628 ms/op 33.158 ms/op 0.80
runFastConfirmationRules vc:1000000 bc:96 eq:0 44.081 ms/op 54.704 ms/op 0.81
runFastConfirmationRules vc:600000 bc:320 eq:0 26.718 ms/op 33.089 ms/op 0.81
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.0601 s/op 1.0998 s/op 0.96
pass gossip attestations to forkchoice per slot 2.1049 ms/op 2.5144 ms/op 0.84
forkChoice updateHead vc 100000 bc 64 eq 0 324.84 us/op 388.01 us/op 0.84
forkChoice updateHead vc 600000 bc 64 eq 0 1.9494 ms/op 2.2999 ms/op 0.85
forkChoice updateHead vc 1000000 bc 64 eq 0 3.2309 ms/op 3.8704 ms/op 0.83
forkChoice updateHead vc 600000 bc 320 eq 0 1.9328 ms/op 2.3459 ms/op 0.82
forkChoice updateHead vc 600000 bc 1200 eq 0 1.9692 ms/op 2.6001 ms/op 0.76
forkChoice updateHead vc 600000 bc 7200 eq 0 2.5489 ms/op 2.7588 ms/op 0.92
forkChoice updateHead vc 600000 bc 64 eq 1000 1.9226 ms/op 2.3444 ms/op 0.82
forkChoice updateHead vc 600000 bc 64 eq 10000 2.0139 ms/op 2.4826 ms/op 0.81
forkChoice updateHead vc 600000 bc 64 eq 300000 5.1773 ms/op 6.5811 ms/op 0.79
forkChoice updateHead vc 600000 bc 64 eq 0 gloas boosted 1.9122 ms/op 2.3657 ms/op 0.81
computeDeltas 1400000 validators 0% inactive 8.9950 ms/op 11.692 ms/op 0.77
computeDeltas 1400000 validators 10% inactive 8.3257 ms/op 11.065 ms/op 0.75
computeDeltas 1400000 validators 20% inactive 7.8847 ms/op 10.429 ms/op 0.76
computeDeltas 1400000 validators 50% inactive 6.5499 ms/op 8.5617 ms/op 0.77
computeDeltas 2100000 validators 0% inactive 13.198 ms/op 17.580 ms/op 0.75
computeDeltas 2100000 validators 10% inactive 12.627 ms/op 16.629 ms/op 0.76
computeDeltas 2100000 validators 20% inactive 11.931 ms/op 15.697 ms/op 0.76
computeDeltas 2100000 validators 50% inactive 9.8033 ms/op 10.370 ms/op 0.95
altair processAttestation - 250000 vs - 7PWei normalcase 1.6503 ms/op 1.7091 ms/op 0.97
altair processAttestation - 250000 vs - 7PWei worstcase 2.4129 ms/op 2.6604 ms/op 0.91
altair processAttestation - setStatus - 1/6 committees join 90.199 us/op 96.419 us/op 0.94
altair processAttestation - setStatus - 1/3 committees join 180.00 us/op 189.63 us/op 0.95
altair processAttestation - setStatus - 1/2 committees join 252.23 us/op 266.26 us/op 0.95
altair processAttestation - setStatus - 2/3 committees join 324.54 us/op 352.89 us/op 0.92
altair processAttestation - setStatus - 4/5 committees join 446.80 us/op 490.79 us/op 0.91
altair processAttestation - setStatus - 100% committees join 528.32 us/op 585.22 us/op 0.90
altair processBlock - 250000 vs - 7PWei normalcase 5.1042 ms/op 4.9778 ms/op 1.03
altair processBlock - 250000 vs - 7PWei normalcase hashState 23.401 ms/op 21.490 ms/op 1.09
altair processBlock - 250000 vs - 7PWei worstcase 22.887 ms/op 23.522 ms/op 0.97
altair processBlock - 250000 vs - 7PWei worstcase hashState 54.276 ms/op 51.159 ms/op 1.06
phase0 processBlock - 250000 vs - 7PWei normalcase 1.1911 ms/op 1.2036 ms/op 0.99
phase0 processBlock - 250000 vs - 7PWei worstcase 17.043 ms/op 18.723 ms/op 0.91
altair processEth1Data - 250000 vs - 7PWei normalcase 223.63 us/op 276.43 us/op 0.81
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 5.9140 us/op 2.9150 us/op 2.03
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 21.410 us/op 18.751 us/op 1.14
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 8.9600 us/op 5.4220 us/op 1.65
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 6.6450 us/op 3.4580 us/op 1.92
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 85.012 us/op 85.340 us/op 1.00
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.1105 ms/op 1.3467 ms/op 0.82
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.4953 ms/op 1.8073 ms/op 0.83
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.4315 ms/op 1.7975 ms/op 0.80
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 2.7448 ms/op 3.5094 ms/op 0.78
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 1.6265 ms/op 2.1124 ms/op 0.77
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 2.9467 ms/op 3.9399 ms/op 0.75
Tree 40 250000 create 234.68 ms/op 316.16 ms/op 0.74
Tree 40 250000 get(125000) 71.996 ns/op 87.720 ns/op 0.82
Tree 40 250000 set(125000) 791.03 ns/op 941.13 ns/op 0.84
Tree 40 250000 toArray() 8.5189 ms/op 14.880 ms/op 0.57
Tree 40 250000 iterate all - toArray() + loop 8.4961 ms/op 13.962 ms/op 0.61
Tree 40 250000 iterate all - get(i) 29.439 ms/op 36.745 ms/op 0.80
Array 250000 create 1.4292 ms/op 2.3182 ms/op 0.62
Array 250000 clone - spread 350.30 us/op 746.50 us/op 0.47
Array 250000 get(125000) 0.26600 ns/op 0.27700 ns/op 0.96
Array 250000 set(125000) 0.26700 ns/op 0.28300 ns/op 0.94
Array 250000 iterate all - loop 48.110 us/op 54.523 us/op 0.88
phase0 afterProcessEpoch - 250000 vs - 7PWei 40.198 ms/op 56.802 ms/op 0.71
Array.fill - length 1000000 2.3450 ms/op 4.1456 ms/op 0.57
Array push - length 1000000 7.7041 ms/op 15.570 ms/op 0.49
Array.get 0.19656 ns/op 0.20016 ns/op 0.98
Uint8Array.get 0.21191 ns/op 0.23757 ns/op 0.89
phase0 beforeProcessEpoch - 250000 vs - 7PWei 13.782 ms/op 17.452 ms/op 0.79
altair processEpoch - mainnet_e81889 194.10 ms/op 243.86 ms/op 0.80
mainnet_e81889 - altair beforeProcessEpoch 15.155 ms/op 35.291 ms/op 0.43
mainnet_e81889 - altair processJustificationAndFinalization 3.6470 us/op 5.0950 us/op 0.72
mainnet_e81889 - altair processInactivityUpdates 2.4474 ms/op 4.5145 ms/op 0.54
mainnet_e81889 - altair processRewardsAndPenalties 14.329 ms/op 18.295 ms/op 0.78
mainnet_e81889 - altair processRegistryUpdates 428.00 ns/op 558.00 ns/op 0.77
mainnet_e81889 - altair processSlashings 110.00 ns/op 252.00 ns/op 0.44
mainnet_e81889 - altair processEth1DataReset 110.00 ns/op 141.00 ns/op 0.78
mainnet_e81889 - altair processEffectiveBalanceUpdates 862.67 us/op 1.9066 ms/op 0.45
mainnet_e81889 - altair processSlashingsReset 589.00 ns/op 672.00 ns/op 0.88
mainnet_e81889 - altair processRandaoMixesReset 759.00 ns/op 837.00 ns/op 0.91
mainnet_e81889 - altair processHistoricalRootsUpdate 110.00 ns/op 144.00 ns/op 0.76
mainnet_e81889 - altair processParticipationFlagUpdates 333.00 ns/op 452.00 ns/op 0.74
mainnet_e81889 - altair processSyncCommitteeUpdates 86.000 ns/op 118.00 ns/op 0.73
mainnet_e81889 - altair afterProcessEpoch 41.785 ms/op 39.049 ms/op 1.07
capella processEpoch - mainnet_e217614 631.43 ms/op 755.00 ms/op 0.84
mainnet_e217614 - capella beforeProcessEpoch 69.893 ms/op 63.070 ms/op 1.11
mainnet_e217614 - capella processJustificationAndFinalization 3.7160 us/op 5.4320 us/op 0.68
mainnet_e217614 - capella processInactivityUpdates 8.1408 ms/op 20.176 ms/op 0.40
mainnet_e217614 - capella processRewardsAndPenalties 76.293 ms/op 122.34 ms/op 0.62
mainnet_e217614 - capella processRegistryUpdates 3.4610 us/op 4.5520 us/op 0.76
mainnet_e217614 - capella processSlashings 115.00 ns/op 143.00 ns/op 0.80
mainnet_e217614 - capella processEth1DataReset 110.00 ns/op 143.00 ns/op 0.77
mainnet_e217614 - capella processEffectiveBalanceUpdates 6.8842 ms/op 25.133 ms/op 0.27
mainnet_e217614 - capella processSlashingsReset 557.00 ns/op 846.00 ns/op 0.66
mainnet_e217614 - capella processRandaoMixesReset 767.00 ns/op 1.1720 us/op 0.65
mainnet_e217614 - capella processHistoricalRootsUpdate 112.00 ns/op 145.00 ns/op 0.77
mainnet_e217614 - capella processParticipationFlagUpdates 352.00 ns/op 720.00 ns/op 0.49
mainnet_e217614 - capella afterProcessEpoch 109.92 ms/op 107.84 ms/op 1.02
phase0 processEpoch - mainnet_e58758 206.22 ms/op 233.69 ms/op 0.88
mainnet_e58758 - phase0 beforeProcessEpoch 49.559 ms/op 64.768 ms/op 0.77
mainnet_e58758 - phase0 processJustificationAndFinalization 3.9390 us/op 5.8250 us/op 0.68
mainnet_e58758 - phase0 processRewardsAndPenalties 12.913 ms/op 16.581 ms/op 0.78
mainnet_e58758 - phase0 processRegistryUpdates 1.7490 us/op 2.2110 us/op 0.79
mainnet_e58758 - phase0 processSlashings 112.00 ns/op 143.00 ns/op 0.78
mainnet_e58758 - phase0 processEth1DataReset 110.00 ns/op 139.00 ns/op 0.79
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 582.70 us/op 797.28 us/op 0.73
mainnet_e58758 - phase0 processSlashingsReset 673.00 ns/op 1.4790 us/op 0.46
mainnet_e58758 - phase0 processRandaoMixesReset 847.00 ns/op 1.0410 us/op 0.81
mainnet_e58758 - phase0 processHistoricalRootsUpdate 113.00 ns/op 144.00 ns/op 0.78
mainnet_e58758 - phase0 processParticipationRecordUpdates 927.00 ns/op 1.0210 us/op 0.91
mainnet_e58758 - phase0 afterProcessEpoch 35.562 ms/op 33.396 ms/op 1.06
phase0 processEffectiveBalanceUpdates - 250000 normalcase 715.81 us/op 980.22 us/op 0.73
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 883.03 us/op 2.4055 ms/op 0.37
gloas processInactivityUpdates - 250000 inactivity leak all eligible missed target 9.6406 ms/op 11.270 ms/op 0.86
phase0 processRegistryUpdates - 250000 normalcase 6.6590 us/op 2.3380 us/op 2.85
phase0 processRegistryUpdates - 250000 badcase_full_deposits 123.31 us/op 134.60 us/op 0.92
phase0 processRegistryUpdates - 250000 worstcase 0.5 57.866 ms/op 61.847 ms/op 0.94
altair processRewardsAndPenalties - 250000 normalcase 12.098 ms/op 15.051 ms/op 0.80
altair processRewardsAndPenalties - 250000 worstcase 11.558 ms/op 13.612 ms/op 0.85
phase0 getAttestationDeltas - 250000 normalcase 3.9875 ms/op 5.3003 ms/op 0.75
phase0 getAttestationDeltas - 250000 worstcase 3.6670 ms/op 5.3761 ms/op 0.68
phase0 processSlashings - 250000 worstcase 49.097 us/op 57.546 us/op 0.85
altair processSyncCommitteeUpdates - 250000 8.3074 ms/op 9.7594 ms/op 0.85
BeaconState.hashTreeRoot - No change 143.00 ns/op 172.00 ns/op 0.83
BeaconState.hashTreeRoot - 1 full validator 79.435 us/op 77.325 us/op 1.03
BeaconState.hashTreeRoot - 32 full validator 826.11 us/op 853.81 us/op 0.97
BeaconState.hashTreeRoot - 512 full validator 8.3539 ms/op 8.2688 ms/op 1.01
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 98.665 us/op 95.680 us/op 1.03
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.4235 ms/op 1.4000 ms/op 1.02
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 19.210 ms/op 21.167 ms/op 0.91
BeaconState.hashTreeRoot - 1 balances 78.038 us/op 80.992 us/op 0.96
BeaconState.hashTreeRoot - 32 balances 700.14 us/op 700.84 us/op 1.00
BeaconState.hashTreeRoot - 512 balances 6.6013 ms/op 6.2432 ms/op 1.06
BeaconState.hashTreeRoot - 250000 balances 127.94 ms/op 112.68 ms/op 1.14
aggregationBits - 2048 els - zipIndexesInBitList 16.665 us/op 18.842 us/op 0.88
regular array get 100000 times 19.674 us/op 22.107 us/op 0.89
wrappedArray get 100000 times 19.795 us/op 21.883 us/op 0.90
arrayWithProxy get 100000 times 7.9215 ms/op 9.0914 ms/op 0.87
ssz.Root.equals 53.772 ns/op 20.609 ns/op 2.61
byteArrayEquals 15.384 ns/op 20.336 ns/op 0.76
Buffer.compare 6.5130 ns/op 8.4590 ns/op 0.77
processSlot - 1 slots 10.317 us/op 10.378 us/op 0.99
processSlot - 32 slots 2.0670 ms/op 1.9814 ms/op 1.04
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 6.5503 ms/op 4.5685 ms/op 1.43
getCommitteeAssignments - req 1 vs - 250000 vc 1.5127 ms/op 1.6391 ms/op 0.92
getCommitteeAssignments - req 100 vs - 250000 vc 3.5111 ms/op 3.3231 ms/op 1.06
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7817 ms/op 3.5661 ms/op 1.06
findModifiedValidators - 10000 modified validators 685.48 ms/op 761.07 ms/op 0.90
findModifiedValidators - 1000 modified validators 598.95 ms/op 556.69 ms/op 1.08
findModifiedValidators - 100 modified validators 454.79 ms/op 400.72 ms/op 1.13
findModifiedValidators - 10 modified validators 548.71 ms/op 304.03 ms/op 1.80
findModifiedValidators - 1 modified validators 392.19 ms/op 238.22 ms/op 1.65
findModifiedValidators - no difference 468.34 ms/op 198.09 ms/op 2.36
migrate state 1500000 validators, 3400 modified, 2000 new 2.8620 s/op 3.3405 s/op 0.86
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 2.7000 ns/op 3.4000 ns/op 0.79
state getBlockRootAtSlot - 250000 vs - 7PWei 470.74 ns/op 428.63 ns/op 1.10
computeProposerIndex 100000 validators 1.2542 ms/op 1.3693 ms/op 0.92
getNextSyncCommitteeIndices 1000 validators 2.5244 ms/op 2.8820 ms/op 0.88
getNextSyncCommitteeIndices 10000 validators 22.258 ms/op 25.657 ms/op 0.87
getNextSyncCommitteeIndices 100000 validators 77.462 ms/op 92.450 ms/op 0.84
computeProposers - vc 250000 534.19 us/op 547.67 us/op 0.98
computeEpochShuffling - vc 250000 41.709 ms/op 39.047 ms/op 1.07
getNextSyncCommittee - vc 250000 7.4858 ms/op 10.935 ms/op 0.68
nodejs block root to RootHex using toHex 73.311 ns/op 95.470 ns/op 0.77
nodejs block root to RootHex using toRootHex 45.560 ns/op 62.741 ns/op 0.73
nodejs fromHex(blob) 779.87 us/op 1.0751 ms/op 0.73
nodejs fromHexInto(blob) 498.31 us/op 636.09 us/op 0.78
nodejs block root to RootHex using the deprecated toHexString 637.39 ns/op 612.91 ns/op 1.04
nodejs byteArrayEquals 32 bytes (block root) 20.202 ns/op 25.625 ns/op 0.79
nodejs byteArrayEquals 48 bytes (pubkey) 28.971 ns/op 37.207 ns/op 0.78
nodejs byteArrayEquals 96 bytes (signature) 29.621 ns/op 34.992 ns/op 0.85
nodejs byteArrayEquals 1024 bytes 34.904 ns/op 40.924 ns/op 0.85
nodejs byteArrayEquals 131072 bytes (blob) 1.1767 us/op 1.7859 us/op 0.66
browser block root to RootHex using toHex 123.40 ns/op 146.64 ns/op 0.84
browser block root to RootHex using toRootHex 115.53 ns/op 132.03 ns/op 0.87
browser fromHex(blob) 1.5107 ms/op 1.8381 ms/op 0.82
browser fromHexInto(blob) 497.47 us/op 662.03 us/op 0.75
browser block root to RootHex using the deprecated toHexString 651.73 ns/op 435.81 ns/op 1.50
browser byteArrayEquals 32 bytes (block root) 20.522 ns/op 28.497 ns/op 0.72
browser byteArrayEquals 48 bytes (pubkey) 29.374 ns/op 40.098 ns/op 0.73
browser byteArrayEquals 96 bytes (signature) 54.987 ns/op 74.126 ns/op 0.74
browser byteArrayEquals 1024 bytes 579.81 ns/op 746.37 ns/op 0.78
browser byteArrayEquals 131072 bytes (blob) 72.839 us/op 92.861 us/op 0.78

by benchmarkbot/action

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.73%. Comparing base (e22a22a) to head (004b5cf).
⚠️ Report is 12 commits behind head on unstable.

Additional details and impacted files
@@            Coverage Diff            @@
##           unstable   #10059   +/-   ##
=========================================
  Coverage     52.72%   52.73%           
=========================================
  Files           848      848           
  Lines         59137    59129    -8     
  Branches       4350     4350           
=========================================
  Hits          31180    31180           
+ Misses        27900    27892    -8     
  Partials         57       57           
🚀 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.

spiral-ladder
spiral-ladder previously approved these changes Sep 14, 2026

@spiral-ladder spiral-ladder left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

seems good, should we be more tolerant of certain op pool actions like voluntary_exit?

@matthewkeil matthewkeil moved this from In Progress to Awaiting Author in Lodestar Team Coordination Sep 14, 2026
Comment thread packages/beacon-node/src/network/processor/gossipValidatorFn.ts Outdated
[GossipType.payload_attestation_message]: {default: PeerAction.MidToleranceError},
[GossipType.execution_payload_bid]: {
default: PeerAction.HighToleranceError,
byCode: {[ExecutionPayloadBidErrorCode.INVALID_SIGNATURE]: PeerAction.MidToleranceError},

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.

Should invalid signatures be fatal?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

invalid signature for beacon_block is fatal as in #10087
it seems too much for other topics, but doing that would helpful to disconnect some spammers as we see in mainnnet
@lodekeeper research how other clients behave on this matter

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.

I would not use Lodestar PeerAction.Fatal for invalid signatures generally. Fatal is immediate ban; the analogous #10087 block path is LowToleranceError, which disconnects/bans after repeated offenses.

So my recommendation is:

  • LowToleranceError for block-like/heavy gossip and for attestation/sync invalid signatures.
  • MidToleranceError for invalid signatures on cheap/op-pool topics such as voluntary_exit, BLS-to-exec, execution payload bid, and proposer preferences.
  • HighToleranceError for other cheap-topic rejects.

I pushed that as a signed patch to my fork because I cannot push to the PR branch directly: lodekeeper@fbcb83dbf7. Verification passed: pnpm build, targeted gossipValidatorFn.test.ts, and pnpm lint.

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.

Checked the client behavior and I agree with the shape you suggested: bad block signatures deserve the strongest repeated-offense penalty, but applying that equally to every gossip topic is too aggressive.

What I found:

  • Lighthouse rejects and low-tolerance penalizes invalid attestation/sync signatures; light-client invalid update paths are much more tolerant.
  • Prysm returns pubsub ValidationReject for invalid signatures on block/sync/voluntary-exit validation paths, but I did not find a separate immediate peer-manager fatal action in those validators.
  • Teku returns InternalValidationResult.reject from the equivalent gossip validators for invalid signatures, again without an obvious immediate-ban layer in the validator itself.

So I would keep Lodestar on per-topic scoring: low tolerance for block-like/heavy topics plus attestation/sync invalid signatures, mid tolerance for cheap-topic invalid signatures, and high tolerance for other cheap-topic rejects. I pushed a tested patch here because I cannot write to te/penalize_on_rejected_messages directly: lodekeeper@fbcb83dbf7

@lodekeeper

Copy link
Copy Markdown
Contributor

@spiral-ladder follow-up on the dismissed review body about op-pool tolerance: yes, I agree we should be more tolerant for cheap/op-pool topics like voluntary_exit.

The policy I recommended in the inline threads is per-topic rather than all-topic fatality: keep block-like/heavy topics on low tolerance, move attestation/sync invalid signatures to low tolerance because other clients treat those as strongly invalid, but keep cheap op-pool topics on high-tolerance defaults with invalid signatures only at mid tolerance. I pushed a tested patch to my fork since I cannot write to the PR branch directly: lodekeeper@fbcb83dbf7

@twoeths twoeths left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

the latest consensus from team is to always apply FATAL for all INVALID_SIGNATURE codes because it may cause chain split, even for oppool topics like voluntary_exit, they could be bundled to a beacon block later
I also added INVALID_SIGNATURE codes for slashing topics.

@lodekeeper

Copy link
Copy Markdown
Contributor

@twoeths thanks for pushing this — checked the diff (ffee658d3f) before reacting, want to make sure I'm responding to what's actually there.

This isn't blanket Fatal for every reject: the topic-level default PeerAction (LowTolerance for block-like, MidTolerance for attestation/sync, HighTolerance for op-pool) is untouched — only the INVALID_SIGNATURE-family byCode overrides move to Fatal, across every topic including voluntary_exit / BLS-to-exec / proposer-preferences / execution-payload-bid, plus the new proposer/attester-slashing overrides that previously had none.

That distinction resolves my original pushback (fbcb83dbf7). My concern there was about topics where a REJECT verdict could reflect a timing/state-view race rather than real malice (dependent-root / justified-checkpoint style mismatches that resolve once the local view catches up) — I didn't want those punished as harshly as deliberate bad-signature spam. Signature validity doesn't have that ambiguity: it's a deterministic check against a fixed signing root (fork version + genesis validators root + message contents) and a known pubkey, so an INVALID_SIGNATURE verdict is unambiguous evidence of a bad-faith or broken peer, independent of topic. No false-positive path for legitimate peers there, so I'm fine dropping the per-topic leniency specifically for the signature overrides.

On "bundled into a block later" specifically — worth being precise about what backstops what, since this is the codebase's actual current behavior either way: validateGossipVoluntaryExit throws on invalid signature before chain.opPool.insertVoluntaryExit is ever reached, so a REJECTed exit doesn't enter our own op pool; and process_voluntary_exit's signature assert would independently invalidate any block built by someone who did include a bad-signature exit. So the block-inclusion vector isn't something the PeerAction choice changes — that's a property of REJECT + state-transition either way. The part PeerAction actually controls is how fast we cut off a peer that's clearly forwarding invalid-signature garbage, and Fatal for that, on every topic, seems right regardless of which framing gets us there.

No objection to ffee658d3f + e542c37f62 as-is.

@nflaig

nflaig commented Sep 17, 2026

Copy link
Copy Markdown
Member

@lodekeeper does this look good now? please approve or leave final remarks

@nflaig nflaig left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

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

Re-checked the final diff after the signature-specific Fatal updates. The mapping is now scoped the way I would want it: generic REJECTs keep the topic-level tolerance, while every concrete invalid-signature code is Fatal, including the op-pool topics and the new slashing-specific codes. That matches the deterministic-signature rationale from the earlier thread, and the slashing code split avoids treating all slashing invalidity as signature-invalid. No further remarks from me.

@wemeetagain
wemeetagain merged commit b27f498 into unstable Sep 17, 2026
23 checks passed
@wemeetagain
wemeetagain deleted the te/penalize_on_rejected_messages branch September 17, 2026 18:24
@github-project-automation github-project-automation Bot moved this from Awaiting Author to Done in Lodestar Team Coordination Sep 17, 2026
nflaig added a commit that referenced this pull request Sep 20, 2026
Since #10059 the validator wrapper reports the peer for every REJECT by
topic and code, Fatal for an invalid proposer signature on beacon_block, so
the handler-level LowToleranceError report was a second, weaker penalty for
the same rejection.
ensi321 added a commit that referenced this pull request Sep 28, 2026
Conflicts resolved:
- execution/engine/http.ts: keep both deserializeExecutionPayloadBodyV2 and deserializeInclusionList imports
- metrics/lodestar.ts: drop backfillSync metrics removed upstream (#10147), keep engine_getInclusionListV1 metrics
- network/gossip/topic.ts: adopt required sszType param (upstream), keep MAX_SIGNED_INCLUSION_LIST_SIZE cap
- state-transition shuffling.test.ts: accept upstream deletion (#9829), dropping the computeInclusionListCommittee unit tests with it

Semantic fix: add inclusion_list to the gossip REJECT peer-action table from #10059 (mid tolerance, fatal on invalid signature) and export inclusion list errors from the chain errors barrel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wemeetagain

Copy link
Copy Markdown
Member

🎉 This PR is included in v1.49.0 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants