这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@matthewkeil
Copy link
Member

@matthewkeil matthewkeil commented Sep 29, 2025

Motivation

Found two small bugs while looking through devnet logs

Sep-25 13:49:19.674[sync]          verbose: Batch download error id=Head-35, startEpoch=14392, status=Downloading, peer=16...wUr9yu - Cannot read properties of undefined (reading 'signedBlockHeader')
TypeError: Cannot read properties of undefined (reading 'signedBlockHeader')
    at cacheByRangeResponses (file:///usr/app/packages/beacon-node/src/sync/utils/downloadByRange.ts:146:63)
    at SyncChain.downloadByRange (file:///usr/app/packages/beacon-node/src/sync/range/range.ts:213:20)
    at wrapError (file:///usr/app/packages/beacon-node/src/util/wrapError.ts:18:32)
    at SyncChain.sendBatch (file:///usr/app/packages/beacon-node/src/sync/range/chain.ts:470:19)

and

Sep-30 15:39:03.738[sync]          verbose: Batch download error id=Head-12, startEpoch=15436, status=Downloading, peer=16...3aErhh - Cannot read properties of undefined (reading 'message')
TypeError: Cannot read properties of undefined (reading 'message')
    at validateBlockByRangeResponse (file:///usr/app/packages/beacon-node/src/sync/utils/downloadByRange.ts:432:46)
    at validateResponses (file:///usr/app/packages/beacon-node/src/sync/utils/downloadByRange.ts:304:42)
    at downloadByRange (file:///usr/app/packages/beacon-node/src/sync/utils/downloadByRange.ts:206:27)
    at SyncChain.downloadByRange (file:///usr/app/packages/beacon-node/src/sync/range/range.ts:205:32)
    at wrapError (file:///usr/app/packages/beacon-node/src/util/wrapError.ts:18:32)
    at SyncChain.sendBatch (file:///usr/app/packages/beacon-node/src/sync/range/chain.ts:470:19)

There is a bug in validateColumnsByRangeResponse that is passing through an empty array of blockColumnSidecars on this line

columnSidecars: blockColumnSidecars,
that is throwing in cacheByRangeResponses. While going through the validation with a fine toothed comb I noticed that there were a couple of conditions that we are not checking per spec.

Scope
Changed heuristic for how columns are validated in ByRange and added in checks for column delivery in (slot, column_index) order.

@matthewkeil matthewkeil self-assigned this Sep 29, 2025
@matthewkeil matthewkeil force-pushed the mkeil/fix-by-range-validation branch from eb8b77f to af8b5db Compare October 14, 2025 06:50
@github-actions
Copy link
Contributor

github-actions bot commented Oct 14, 2025

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 8f6cc1b Previous: 277758e Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1299 ms/op 912.14 us/op 1.24
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 45.417 us/op 37.755 us/op 1.20
BLS verify - blst 1.1502 ms/op 894.58 us/op 1.29
BLS verifyMultipleSignatures 3 - blst 1.8108 ms/op 1.2919 ms/op 1.40
BLS verifyMultipleSignatures 8 - blst 2.1555 ms/op 2.0277 ms/op 1.06
BLS verifyMultipleSignatures 32 - blst 6.9513 ms/op 5.0254 ms/op 1.38
BLS verifyMultipleSignatures 64 - blst 12.944 ms/op 9.4904 ms/op 1.36
BLS verifyMultipleSignatures 128 - blst 22.864 ms/op 18.091 ms/op 1.26
BLS deserializing 10000 signatures 833.13 ms/op 719.22 ms/op 1.16
BLS deserializing 100000 signatures 7.9963 s/op 7.2253 s/op 1.11
BLS verifyMultipleSignatures - same message - 3 - blst 913.30 us/op 1.0042 ms/op 0.91
BLS verifyMultipleSignatures - same message - 8 - blst 1.0207 ms/op 1.1305 ms/op 0.90
BLS verifyMultipleSignatures - same message - 32 - blst 2.0253 ms/op 1.8340 ms/op 1.10
BLS verifyMultipleSignatures - same message - 64 - blst 2.9890 ms/op 2.7762 ms/op 1.08
BLS verifyMultipleSignatures - same message - 128 - blst 4.8346 ms/op 4.6455 ms/op 1.04
BLS aggregatePubkeys 32 - blst 19.586 us/op 20.126 us/op 0.97
BLS aggregatePubkeys 128 - blst 70.689 us/op 72.304 us/op 0.98
notSeenSlots=1 numMissedVotes=1 numBadVotes=10 60.525 ms/op 55.797 ms/op 1.08
notSeenSlots=1 numMissedVotes=0 numBadVotes=4 62.688 ms/op 52.709 ms/op 1.19
notSeenSlots=2 numMissedVotes=1 numBadVotes=10 45.655 ms/op 39.830 ms/op 1.15
getSlashingsAndExits - default max 73.920 us/op 76.144 us/op 0.97
getSlashingsAndExits - 2k 338.75 us/op 340.78 us/op 0.99
isKnown best case - 1 super set check 227.00 ns/op 226.00 ns/op 1.00
isKnown normal case - 2 super set checks 216.00 ns/op 224.00 ns/op 0.96
isKnown worse case - 16 super set checks 231.00 ns/op 215.00 ns/op 1.07
InMemoryCheckpointStateCache - add get delete 2.2940 us/op 2.5090 us/op 0.91
validate api signedAggregateAndProof - struct 2.5708 ms/op 1.5123 ms/op 1.70
validate gossip signedAggregateAndProof - struct 1.6101 ms/op 1.5199 ms/op 1.06
batch validate gossip attestation - vc 640000 - chunk 32 125.36 us/op 122.09 us/op 1.03
batch validate gossip attestation - vc 640000 - chunk 64 109.91 us/op 105.87 us/op 1.04
batch validate gossip attestation - vc 640000 - chunk 128 106.80 us/op 98.394 us/op 1.09
batch validate gossip attestation - vc 640000 - chunk 256 115.80 us/op 102.21 us/op 1.13
pickEth1Vote - no votes 1.1207 ms/op 977.04 us/op 1.15
pickEth1Vote - max votes 8.9159 ms/op 7.6606 ms/op 1.16
pickEth1Vote - Eth1Data hashTreeRoot value x2048 15.653 ms/op 12.487 ms/op 1.25
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 22.836 ms/op 18.444 ms/op 1.24
pickEth1Vote - Eth1Data fastSerialize value x2048 520.48 us/op 451.28 us/op 1.15
pickEth1Vote - Eth1Data fastSerialize tree x2048 2.9199 ms/op 2.1731 ms/op 1.34
bytes32 toHexString 426.00 ns/op 372.00 ns/op 1.15
bytes32 Buffer.toString(hex) 268.00 ns/op 245.00 ns/op 1.09
bytes32 Buffer.toString(hex) from Uint8Array 394.00 ns/op 330.00 ns/op 1.19
bytes32 Buffer.toString(hex) + 0x 297.00 ns/op 248.00 ns/op 1.20
Object access 1 prop 0.13400 ns/op 0.12100 ns/op 1.11
Map access 1 prop 0.13400 ns/op 0.12400 ns/op 1.08
Object get x1000 6.7020 ns/op 5.8500 ns/op 1.15
Map get x1000 7.1810 ns/op 6.4180 ns/op 1.12
Object set x1000 34.931 ns/op 29.492 ns/op 1.18
Map set x1000 23.175 ns/op 20.764 ns/op 1.12
Return object 10000 times 0.31220 ns/op 0.29520 ns/op 1.06
Throw Error 10000 times 4.7299 us/op 4.4600 us/op 1.06
toHex 147.05 ns/op 141.34 ns/op 1.04
Buffer.from 141.54 ns/op 130.41 ns/op 1.09
shared Buffer 86.881 ns/op 84.976 ns/op 1.02
fastMsgIdFn sha256 / 200 bytes 2.3700 us/op 2.2200 us/op 1.07
fastMsgIdFn h32 xxhash / 200 bytes 246.00 ns/op 208.00 ns/op 1.18
fastMsgIdFn h64 xxhash / 200 bytes 301.00 ns/op 262.00 ns/op 1.15
fastMsgIdFn sha256 / 1000 bytes 8.4500 us/op 7.2650 us/op 1.16
fastMsgIdFn h32 xxhash / 1000 bytes 452.00 ns/op 341.00 ns/op 1.33
fastMsgIdFn h64 xxhash / 1000 bytes 384.00 ns/op 334.00 ns/op 1.15
fastMsgIdFn sha256 / 10000 bytes 75.074 us/op 65.760 us/op 1.14
fastMsgIdFn h32 xxhash / 10000 bytes 2.1800 us/op 1.8290 us/op 1.19
fastMsgIdFn h64 xxhash / 10000 bytes 1.5130 us/op 1.2050 us/op 1.26
100 bytes - compress - snappyjs 1.8292 us/op 1.7706 us/op 1.03
100 bytes - compress - snappy 1.4379 us/op 1.0807 us/op 1.33
100 bytes - compress - #snappy 2.1782 us/op 1.4177 us/op 1.54
200 bytes - compress - snappyjs 2.7810 us/op 1.9378 us/op 1.44
200 bytes - compress - snappy 1.3772 us/op 1.2478 us/op 1.10
200 bytes - compress - #snappy 2.5190 us/op 1.7212 us/op 1.46
300 bytes - compress - snappyjs 2.9012 us/op 2.2796 us/op 1.27
300 bytes - compress - snappy 1.7752 us/op 1.2104 us/op 1.47
300 bytes - compress - #snappy 3.0563 us/op 2.2298 us/op 1.37
400 bytes - compress - snappyjs 3.3029 us/op 2.4502 us/op 1.35
400 bytes - compress - snappy 1.7069 us/op 1.2790 us/op 1.33
400 bytes - compress - #snappy 2.9540 us/op 2.5385 us/op 1.16
500 bytes - compress - snappyjs 3.3331 us/op 2.9679 us/op 1.12
500 bytes - compress - snappy 1.5457 us/op 1.3913 us/op 1.11
500 bytes - compress - #snappy 3.6512 us/op 2.8394 us/op 1.29
1000 bytes - compress - snappyjs 5.9763 us/op 4.4610 us/op 1.34
1000 bytes - compress - snappy 2.7970 us/op 1.7990 us/op 1.55
1000 bytes - compress - #snappy 5.3232 us/op 4.8867 us/op 1.09
10000 bytes - compress - snappyjs 33.980 us/op 31.979 us/op 1.06
10000 bytes - compress - snappy 42.404 us/op 38.596 us/op 1.10
10000 bytes - compress - #snappy 35.798 us/op 30.152 us/op 1.19
100 bytes - uncompress - snappyjs 1.2723 us/op 924.17 ns/op 1.38
100 bytes - uncompress - snappy 1.2392 us/op 981.96 ns/op 1.26
100 bytes - uncompress - #snappy 871.87 ns/op 1.1007 us/op 0.79
200 bytes - uncompress - snappyjs 1.4051 us/op 1.3316 us/op 1.06
200 bytes - uncompress - snappy 1.2539 us/op 1.0529 us/op 1.19
200 bytes - uncompress - #snappy 1.3994 us/op 1.2782 us/op 1.09
300 bytes - uncompress - snappyjs 1.8665 us/op 1.2612 us/op 1.48
300 bytes - uncompress - snappy 1.2541 us/op 1.0930 us/op 1.15
300 bytes - uncompress - #snappy 1.5377 us/op 1.3558 us/op 1.13
400 bytes - uncompress - snappyjs 1.8801 us/op 1.3035 us/op 1.44
400 bytes - uncompress - snappy 1.3736 us/op 1.1248 us/op 1.22
400 bytes - uncompress - #snappy 1.3123 us/op 1.6060 us/op 0.82
500 bytes - uncompress - snappyjs 1.8488 us/op 2.1054 us/op 0.88
500 bytes - uncompress - snappy 1.7121 us/op 1.1723 us/op 1.46
500 bytes - uncompress - #snappy 1.5978 us/op 1.7454 us/op 0.92
1000 bytes - uncompress - snappyjs 2.8787 us/op 2.3304 us/op 1.24
1000 bytes - uncompress - snappy 1.8868 us/op 1.4647 us/op 1.29
1000 bytes - uncompress - #snappy 2.8371 us/op 2.1936 us/op 1.29
10000 bytes - uncompress - snappyjs 17.003 us/op 13.865 us/op 1.23
10000 bytes - uncompress - snappy 39.587 us/op 31.081 us/op 1.27
10000 bytes - uncompress - #snappy 18.118 us/op 14.217 us/op 1.27
send data - 1000 256B messages 20.612 ms/op 16.642 ms/op 1.24
send data - 1000 512B messages 24.449 ms/op 20.081 ms/op 1.22
send data - 1000 1024B messages 35.614 ms/op 28.186 ms/op 1.26
send data - 1000 1200B messages 34.437 ms/op 25.938 ms/op 1.33
send data - 1000 2048B messages 36.032 ms/op 28.799 ms/op 1.25
send data - 1000 4096B messages 40.642 ms/op 32.719 ms/op 1.24
send data - 1000 16384B messages 60.765 ms/op 49.454 ms/op 1.23
send data - 1000 65536B messages 144.93 ms/op 111.80 ms/op 1.30
enrSubnets - fastDeserialize 64 bits 1.0420 us/op 873.00 ns/op 1.19
enrSubnets - ssz BitVector 64 bits 382.00 ns/op 329.00 ns/op 1.16
enrSubnets - fastDeserialize 4 bits 161.00 ns/op 126.00 ns/op 1.28
enrSubnets - ssz BitVector 4 bits 376.00 ns/op 339.00 ns/op 1.11
prioritizePeers score -10:0 att 32-0.1 sync 2-0 284.61 us/op 237.19 us/op 1.20
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 305.41 us/op 267.18 us/op 1.14
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 461.88 us/op 372.42 us/op 1.24
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 982.06 us/op 692.76 us/op 1.42
prioritizePeers score 0:0 att 64-1 sync 4-1 1.0470 ms/op 873.55 us/op 1.20
array of 16000 items push then shift 1.9201 us/op 1.6057 us/op 1.20
LinkedList of 16000 items push then shift 9.8430 ns/op 7.6930 ns/op 1.28
array of 16000 items push then pop 103.99 ns/op 83.907 ns/op 1.24
LinkedList of 16000 items push then pop 9.1270 ns/op 7.6140 ns/op 1.20
array of 24000 items push then shift 2.8700 us/op 2.4108 us/op 1.19
LinkedList of 24000 items push then shift 9.9730 ns/op 7.7720 ns/op 1.28
array of 24000 items push then pop 125.69 ns/op 109.67 ns/op 1.15
LinkedList of 24000 items push then pop 8.5870 ns/op 7.3320 ns/op 1.17
intersect bitArray bitLen 8 7.4870 ns/op 6.5000 ns/op 1.15
intersect array and set length 8 44.795 ns/op 40.587 ns/op 1.10
intersect bitArray bitLen 128 33.981 ns/op 30.754 ns/op 1.10
intersect array and set length 128 732.38 ns/op 642.13 ns/op 1.14
bitArray.getTrueBitIndexes() bitLen 128 1.2590 us/op 1.0270 us/op 1.23
bitArray.getTrueBitIndexes() bitLen 248 2.4120 us/op 1.8150 us/op 1.33
bitArray.getTrueBitIndexes() bitLen 512 4.1680 us/op 3.7380 us/op 1.12
Full columns - reconstruct all 6 blobs 107.75 us/op 131.81 us/op 0.82
Full columns - reconstruct half of the blobs out of 6 58.848 us/op 48.148 us/op 1.22
Full columns - reconstruct single blob out of 6 24.269 us/op 21.381 us/op 1.14
Half columns - reconstruct all 6 blobs 331.27 ms/op 272.87 ms/op 1.21
Half columns - reconstruct half of the blobs out of 6 152.73 ms/op 137.25 ms/op 1.11
Half columns - reconstruct single blob out of 6 57.228 ms/op 50.738 ms/op 1.13
Full columns - reconstruct all 10 blobs 173.99 us/op 115.78 us/op 1.50
Full columns - reconstruct half of the blobs out of 10 94.909 us/op 62.047 us/op 1.53
Full columns - reconstruct single blob out of 10 25.981 us/op 20.046 us/op 1.30
Half columns - reconstruct all 10 blobs 527.56 ms/op 456.30 ms/op 1.16
Half columns - reconstruct half of the blobs out of 10 271.95 ms/op 225.90 ms/op 1.20
Half columns - reconstruct single blob out of 10 59.013 ms/op 49.229 ms/op 1.20
Full columns - reconstruct all 20 blobs 379.01 us/op 210.63 us/op 1.80
Full columns - reconstruct half of the blobs out of 20 202.80 us/op 105.59 us/op 1.92
Full columns - reconstruct single blob out of 20 28.932 us/op 19.559 us/op 1.48
Half columns - reconstruct all 20 blobs 1.0430 s/op 895.16 ms/op 1.17
Half columns - reconstruct half of the blobs out of 20 512.01 ms/op 452.31 ms/op 1.13
Half columns - reconstruct single blob out of 20 58.841 ms/op 54.231 ms/op 1.09
Buffer.concat 32 items 711.00 ns/op 670.00 ns/op 1.06
Uint8Array.set 32 items 1.2920 us/op 1.2570 us/op 1.03
Buffer.copy 2.5790 us/op 2.0570 us/op 1.25
Uint8Array.set - with subarray 1.7960 us/op 2.0300 us/op 0.88
Uint8Array.set - without subarray 1.0380 us/op 931.00 ns/op 1.11
getUint32 - dataview 214.00 ns/op 201.00 ns/op 1.06
getUint32 - manual 133.00 ns/op 124.00 ns/op 1.07
Set add up to 64 items then delete first 2.4749 us/op 2.3214 us/op 1.07
OrderedSet add up to 64 items then delete first 3.7671 us/op 3.5729 us/op 1.05
Set add up to 64 items then delete last 2.5394 us/op 2.6870 us/op 0.95
OrderedSet add up to 64 items then delete last 4.3150 us/op 4.0596 us/op 1.06
Set add up to 64 items then delete middle 3.2649 us/op 2.7608 us/op 1.18
OrderedSet add up to 64 items then delete middle 6.7141 us/op 6.2207 us/op 1.08
Set add up to 128 items then delete first 5.9726 us/op 5.4351 us/op 1.10
OrderedSet add up to 128 items then delete first 8.3876 us/op 8.2100 us/op 1.02
Set add up to 128 items then delete last 5.8798 us/op 5.2086 us/op 1.13
OrderedSet add up to 128 items then delete last 8.8769 us/op 8.0793 us/op 1.10
Set add up to 128 items then delete middle 5.8662 us/op 5.0402 us/op 1.16
OrderedSet add up to 128 items then delete middle 17.157 us/op 16.185 us/op 1.06
Set add up to 256 items then delete first 10.779 us/op 10.898 us/op 0.99
OrderedSet add up to 256 items then delete first 16.835 us/op 17.589 us/op 0.96
Set add up to 256 items then delete last 10.638 us/op 10.210 us/op 1.04
OrderedSet add up to 256 items then delete last 16.893 us/op 15.361 us/op 1.10
Set add up to 256 items then delete middle 11.342 us/op 9.7826 us/op 1.16
OrderedSet add up to 256 items then delete middle 46.864 us/op 43.059 us/op 1.09
transfer serialized Status (84 B) 2.3320 us/op 2.2270 us/op 1.05
copy serialized Status (84 B) 1.3160 us/op 1.2220 us/op 1.08
transfer serialized SignedVoluntaryExit (112 B) 2.4000 us/op 2.3560 us/op 1.02
copy serialized SignedVoluntaryExit (112 B) 1.4060 us/op 1.2640 us/op 1.11
transfer serialized ProposerSlashing (416 B) 3.3020 us/op 2.4940 us/op 1.32
copy serialized ProposerSlashing (416 B) 1.6680 us/op 2.3930 us/op 0.70
transfer serialized Attestation (485 B) 3.4690 us/op 3.6540 us/op 0.95
copy serialized Attestation (485 B) 1.9360 us/op 2.3000 us/op 0.84
transfer serialized AttesterSlashing (33232 B) 3.1340 us/op 2.6310 us/op 1.19
copy serialized AttesterSlashing (33232 B) 4.5780 us/op 5.8130 us/op 0.79
transfer serialized Small SignedBeaconBlock (128000 B) 5.2700 us/op 3.8090 us/op 1.38
copy serialized Small SignedBeaconBlock (128000 B) 14.694 us/op 14.549 us/op 1.01
transfer serialized Avg SignedBeaconBlock (200000 B) 6.9720 us/op 4.3850 us/op 1.59
copy serialized Avg SignedBeaconBlock (200000 B) 20.165 us/op 20.833 us/op 0.97
transfer serialized BlobsSidecar (524380 B) 5.7730 us/op 4.7980 us/op 1.20
copy serialized BlobsSidecar (524380 B) 63.746 us/op 64.895 us/op 0.98
transfer serialized Big SignedBeaconBlock (1000000 B) 5.8680 us/op 5.4520 us/op 1.08
copy serialized Big SignedBeaconBlock (1000000 B) 129.00 us/op 144.22 us/op 0.89
pass gossip attestations to forkchoice per slot 2.8632 ms/op 3.0112 ms/op 0.95
forkChoice updateHead vc 100000 bc 64 eq 0 529.62 us/op 505.54 us/op 1.05
forkChoice updateHead vc 600000 bc 64 eq 0 3.2316 ms/op 2.9089 ms/op 1.11
forkChoice updateHead vc 1000000 bc 64 eq 0 5.2370 ms/op 4.8172 ms/op 1.09
forkChoice updateHead vc 600000 bc 320 eq 0 3.1531 ms/op 2.8704 ms/op 1.10
forkChoice updateHead vc 600000 bc 1200 eq 0 3.2476 ms/op 2.9224 ms/op 1.11
forkChoice updateHead vc 600000 bc 7200 eq 0 3.4303 ms/op 3.3313 ms/op 1.03
forkChoice updateHead vc 600000 bc 64 eq 1000 3.0968 ms/op 2.9057 ms/op 1.07
forkChoice updateHead vc 600000 bc 64 eq 10000 3.1660 ms/op 3.0534 ms/op 1.04
forkChoice updateHead vc 600000 bc 64 eq 300000 9.7911 ms/op 9.6720 ms/op 1.01
computeDeltas 1400000 validators 0% inactive 16.153 ms/op 14.067 ms/op 1.15
computeDeltas 1400000 validators 10% inactive 14.775 ms/op 13.264 ms/op 1.11
computeDeltas 1400000 validators 20% inactive 12.879 ms/op 11.853 ms/op 1.09
computeDeltas 1400000 validators 50% inactive 9.7905 ms/op 9.0564 ms/op 1.08
computeDeltas 2100000 validators 0% inactive 23.147 ms/op 21.067 ms/op 1.10
computeDeltas 2100000 validators 10% inactive 22.395 ms/op 19.624 ms/op 1.14
computeDeltas 2100000 validators 20% inactive 20.122 ms/op 18.742 ms/op 1.07
computeDeltas 2100000 validators 50% inactive 14.324 ms/op 14.339 ms/op 1.00
altair processAttestation - 250000 vs - 7PWei normalcase 2.6593 ms/op 3.2221 ms/op 0.83
altair processAttestation - 250000 vs - 7PWei worstcase 3.7043 ms/op 5.3092 ms/op 0.70
altair processAttestation - setStatus - 1/6 committees join 142.13 us/op 162.01 us/op 0.88
altair processAttestation - setStatus - 1/3 committees join 281.53 us/op 367.87 us/op 0.77
altair processAttestation - setStatus - 1/2 committees join 376.82 us/op 404.11 us/op 0.93
altair processAttestation - setStatus - 2/3 committees join 490.79 us/op 573.53 us/op 0.86
altair processAttestation - setStatus - 4/5 committees join 641.74 us/op 1.1841 ms/op 0.54
altair processAttestation - setStatus - 100% committees join 800.55 us/op 907.86 us/op 0.88
altair processBlock - 250000 vs - 7PWei normalcase 5.1360 ms/op 6.2906 ms/op 0.82
altair processBlock - 250000 vs - 7PWei normalcase hashState 31.209 ms/op 38.043 ms/op 0.82
altair processBlock - 250000 vs - 7PWei worstcase 41.480 ms/op 50.674 ms/op 0.82
altair processBlock - 250000 vs - 7PWei worstcase hashState 85.621 ms/op 104.22 ms/op 0.82
phase0 processBlock - 250000 vs - 7PWei normalcase 2.0477 ms/op 2.1941 ms/op 0.93
phase0 processBlock - 250000 vs - 7PWei worstcase 31.268 ms/op 31.445 ms/op 0.99
altair processEth1Data - 250000 vs - 7PWei normalcase 421.79 us/op 431.45 us/op 0.98
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 8.4150 us/op 11.389 us/op 0.74
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 50.122 us/op 66.906 us/op 0.75
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 11.943 us/op 21.116 us/op 0.57
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 7.9210 us/op 13.015 us/op 0.61
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 215.09 us/op 248.51 us/op 0.87
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 2.1160 ms/op 2.0348 ms/op 1.04
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.8735 ms/op 2.9791 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.7872 ms/op 2.8952 ms/op 0.96
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 5.4498 ms/op 7.1546 ms/op 0.76
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.9369 ms/op 3.4651 ms/op 0.85
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 5.2981 ms/op 7.0260 ms/op 0.75
Tree 40 250000 create 562.81 ms/op 824.91 ms/op 0.68
Tree 40 250000 get(125000) 181.90 ns/op 149.49 ns/op 1.22
Tree 40 250000 set(125000) 2.1985 us/op 2.3899 us/op 0.92
Tree 40 250000 toArray() 24.328 ms/op 25.209 ms/op 0.97
Tree 40 250000 iterate all - toArray() + loop 23.979 ms/op 25.327 ms/op 0.95
Tree 40 250000 iterate all - get(i) 63.386 ms/op 63.618 ms/op 1.00
Array 250000 create 4.4830 ms/op 5.0096 ms/op 0.89
Array 250000 clone - spread 1.8041 ms/op 1.8014 ms/op 1.00
Array 250000 get(125000) 0.46800 ns/op 0.48800 ns/op 0.96
Array 250000 set(125000) 0.48500 ns/op 0.47900 ns/op 1.01
Array 250000 iterate all - loop 124.43 us/op 92.724 us/op 1.34
phase0 afterProcessEpoch - 250000 vs - 7PWei 45.760 ms/op 44.639 ms/op 1.03
Array.fill - length 1000000 5.3189 ms/op 8.1775 ms/op 0.65
Array push - length 1000000 17.707 ms/op 18.548 ms/op 0.95
Array.get 0.29689 ns/op 0.29097 ns/op 1.02
Uint8Array.get 0.48255 ns/op 0.46787 ns/op 1.03
phase0 beforeProcessEpoch - 250000 vs - 7PWei 19.975 ms/op 20.125 ms/op 0.99
altair processEpoch - mainnet_e81889 373.30 ms/op 299.65 ms/op 1.25
mainnet_e81889 - altair beforeProcessEpoch 25.135 ms/op 19.201 ms/op 1.31
mainnet_e81889 - altair processJustificationAndFinalization 8.3000 us/op 5.9850 us/op 1.39
mainnet_e81889 - altair processInactivityUpdates 8.7827 ms/op 6.7164 ms/op 1.31
mainnet_e81889 - altair processRewardsAndPenalties 58.731 ms/op 45.051 ms/op 1.30
mainnet_e81889 - altair processRegistryUpdates 1.0540 us/op 703.00 ns/op 1.50
mainnet_e81889 - altair processSlashings 269.00 ns/op 192.00 ns/op 1.40
mainnet_e81889 - altair processEth1DataReset 261.00 ns/op 229.00 ns/op 1.14
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.3626 ms/op 1.2715 ms/op 1.07
mainnet_e81889 - altair processSlashingsReset 1.2190 us/op 908.00 ns/op 1.34
mainnet_e81889 - altair processRandaoMixesReset 1.5600 us/op 1.5040 us/op 1.04
mainnet_e81889 - altair processHistoricalRootsUpdate 225.00 ns/op 189.00 ns/op 1.19
mainnet_e81889 - altair processParticipationFlagUpdates 787.00 ns/op 542.00 ns/op 1.45
mainnet_e81889 - altair processSyncCommitteeUpdates 191.00 ns/op 146.00 ns/op 1.31
mainnet_e81889 - altair afterProcessEpoch 50.292 ms/op 46.701 ms/op 1.08
capella processEpoch - mainnet_e217614 1.3499 s/op 1.1733 s/op 1.15
mainnet_e217614 - capella beforeProcessEpoch 82.295 ms/op 74.679 ms/op 1.10
mainnet_e217614 - capella processJustificationAndFinalization 7.5180 us/op 6.3750 us/op 1.18
mainnet_e217614 - capella processInactivityUpdates 18.667 ms/op 16.893 ms/op 1.10
mainnet_e217614 - capella processRewardsAndPenalties 243.75 ms/op 195.49 ms/op 1.25
mainnet_e217614 - capella processRegistryUpdates 10.001 us/op 6.9300 us/op 1.44
mainnet_e217614 - capella processSlashings 261.00 ns/op 223.00 ns/op 1.17
mainnet_e217614 - capella processEth1DataReset 245.00 ns/op 203.00 ns/op 1.21
mainnet_e217614 - capella processEffectiveBalanceUpdates 5.1479 ms/op 4.6678 ms/op 1.10
mainnet_e217614 - capella processSlashingsReset 1.1180 us/op 909.00 ns/op 1.23
mainnet_e217614 - capella processRandaoMixesReset 1.6070 us/op 1.2390 us/op 1.30
mainnet_e217614 - capella processHistoricalRootsUpdate 218.00 ns/op 196.00 ns/op 1.11
mainnet_e217614 - capella processParticipationFlagUpdates 781.00 ns/op 547.00 ns/op 1.43
mainnet_e217614 - capella afterProcessEpoch 136.56 ms/op 132.53 ms/op 1.03
phase0 processEpoch - mainnet_e58758 511.97 ms/op 332.60 ms/op 1.54
mainnet_e58758 - phase0 beforeProcessEpoch 146.39 ms/op 101.57 ms/op 1.44
mainnet_e58758 - phase0 processJustificationAndFinalization 11.275 us/op 6.0870 us/op 1.85
mainnet_e58758 - phase0 processRewardsAndPenalties 55.897 ms/op 44.307 ms/op 1.26
mainnet_e58758 - phase0 processRegistryUpdates 4.3530 us/op 3.4270 us/op 1.27
mainnet_e58758 - phase0 processSlashings 271.00 ns/op 196.00 ns/op 1.38
mainnet_e58758 - phase0 processEth1DataReset 217.00 ns/op 191.00 ns/op 1.14
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 4.8358 ms/op 3.6898 ms/op 1.31
mainnet_e58758 - phase0 processSlashingsReset 1.7390 us/op 1.0940 us/op 1.59
mainnet_e58758 - phase0 processRandaoMixesReset 2.0060 us/op 1.5370 us/op 1.31
mainnet_e58758 - phase0 processHistoricalRootsUpdate 222.00 ns/op 258.00 ns/op 0.86
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2530 us/op 1.2600 us/op 0.99
mainnet_e58758 - phase0 afterProcessEpoch 39.953 ms/op 37.979 ms/op 1.05
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.9267 ms/op 1.4141 ms/op 1.36
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 6.2234 ms/op 5.4948 ms/op 1.13
altair processInactivityUpdates - 250000 normalcase 24.768 ms/op 19.391 ms/op 1.28
altair processInactivityUpdates - 250000 worstcase 26.062 ms/op 21.053 ms/op 1.24
phase0 processRegistryUpdates - 250000 normalcase 10.013 us/op 11.382 us/op 0.88
phase0 processRegistryUpdates - 250000 badcase_full_deposits 389.30 us/op 407.02 us/op 0.96
phase0 processRegistryUpdates - 250000 worstcase 0.5 157.26 ms/op 154.36 ms/op 1.02
altair processRewardsAndPenalties - 250000 normalcase 35.058 ms/op 37.644 ms/op 0.93
altair processRewardsAndPenalties - 250000 worstcase 36.043 ms/op 34.259 ms/op 1.05
phase0 getAttestationDeltas - 250000 normalcase 15.704 ms/op 6.8293 ms/op 2.30
phase0 getAttestationDeltas - 250000 worstcase 7.0416 ms/op 6.7276 ms/op 1.05
phase0 processSlashings - 250000 worstcase 101.46 us/op 137.24 us/op 0.74
altair processSyncCommitteeUpdates - 250000 15.444 ms/op 13.840 ms/op 1.12
BeaconState.hashTreeRoot - No change 312.00 ns/op 255.00 ns/op 1.22
BeaconState.hashTreeRoot - 1 full validator 104.63 us/op 103.02 us/op 1.02
BeaconState.hashTreeRoot - 32 full validator 1.7534 ms/op 1.5607 ms/op 1.12
BeaconState.hashTreeRoot - 512 full validator 13.071 ms/op 19.012 ms/op 0.69
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 123.73 us/op 146.91 us/op 0.84
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.0830 ms/op 2.5439 ms/op 0.82
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 32.559 ms/op 33.953 ms/op 0.96
BeaconState.hashTreeRoot - 1 balances 103.69 us/op 115.99 us/op 0.89
BeaconState.hashTreeRoot - 32 balances 920.05 us/op 1.0530 ms/op 0.87
BeaconState.hashTreeRoot - 512 balances 9.8069 ms/op 10.848 ms/op 0.90
BeaconState.hashTreeRoot - 250000 balances 234.93 ms/op 224.26 ms/op 1.05
aggregationBits - 2048 els - zipIndexesInBitList 31.126 us/op 25.253 us/op 1.23
byteArrayEquals 32 63.774 ns/op 58.049 ns/op 1.10
Buffer.compare 32 21.537 ns/op 18.644 ns/op 1.16
byteArrayEquals 1024 1.8200 us/op 1.7335 us/op 1.05
Buffer.compare 1024 29.856 ns/op 27.990 ns/op 1.07
byteArrayEquals 16384 29.430 us/op 28.003 us/op 1.05
Buffer.compare 16384 234.06 ns/op 225.26 ns/op 1.04
byteArrayEquals 123687377 220.41 ms/op 223.45 ms/op 0.99
Buffer.compare 123687377 10.557 ms/op 12.011 ms/op 0.88
byteArrayEquals 32 - diff last byte 55.952 ns/op 58.242 ns/op 0.96
Buffer.compare 32 - diff last byte 18.159 ns/op 38.716 ns/op 0.47
byteArrayEquals 1024 - diff last byte 1.7308 us/op 1.7282 us/op 1.00
Buffer.compare 1024 - diff last byte 28.056 ns/op 28.997 ns/op 0.97
byteArrayEquals 16384 - diff last byte 28.245 us/op 27.422 us/op 1.03
Buffer.compare 16384 - diff last byte 223.24 ns/op 202.11 ns/op 1.10
byteArrayEquals 123687377 - diff last byte 210.91 ms/op 218.00 ms/op 0.97
Buffer.compare 123687377 - diff last byte 10.383 ms/op 14.464 ms/op 0.72
byteArrayEquals 32 - random bytes 5.8110 ns/op 7.6090 ns/op 0.76
Buffer.compare 32 - random bytes 20.179 ns/op 19.328 ns/op 1.04
byteArrayEquals 1024 - random bytes 5.8160 ns/op 5.5920 ns/op 1.04
Buffer.compare 1024 - random bytes 20.534 ns/op 18.956 ns/op 1.08
byteArrayEquals 16384 - random bytes 5.8820 ns/op 6.0410 ns/op 0.97
Buffer.compare 16384 - random bytes 20.306 ns/op 24.248 ns/op 0.84
byteArrayEquals 123687377 - random bytes 7.2000 ns/op 10.080 ns/op 0.71
Buffer.compare 123687377 - random bytes 21.210 ns/op 20.140 ns/op 1.05
regular array get 100000 times 49.178 us/op 46.137 us/op 1.07
wrappedArray get 100000 times 36.116 us/op 36.804 us/op 0.98
arrayWithProxy get 100000 times 16.150 ms/op 14.643 ms/op 1.10
ssz.Root.equals 52.614 ns/op 49.866 ns/op 1.06
byteArrayEquals 51.473 ns/op 49.754 ns/op 1.03
Buffer.compare 12.136 ns/op 11.267 ns/op 1.08
processSlot - 1 slots 11.828 us/op 14.176 us/op 0.83
processSlot - 32 slots 2.9430 ms/op 3.6539 ms/op 0.81
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.2566 ms/op 6.1510 ms/op 0.69
getCommitteeAssignments - req 1 vs - 250000 vc 2.1996 ms/op 2.4037 ms/op 0.92
getCommitteeAssignments - req 100 vs - 250000 vc 4.2368 ms/op 4.6560 ms/op 0.91
getCommitteeAssignments - req 1000 vs - 250000 vc 4.5366 ms/op 5.1779 ms/op 0.88
findModifiedValidators - 10000 modified validators 764.98 ms/op 935.74 ms/op 0.82
findModifiedValidators - 1000 modified validators 717.96 ms/op 873.19 ms/op 0.82
findModifiedValidators - 100 modified validators 236.66 ms/op 366.41 ms/op 0.65
findModifiedValidators - 10 modified validators 138.23 ms/op 217.82 ms/op 0.63
findModifiedValidators - 1 modified validators 144.04 ms/op 158.32 ms/op 0.91
findModifiedValidators - no difference 209.63 ms/op 240.27 ms/op 0.87
compare ViewDUs 6.4967 s/op 7.6708 s/op 0.85
compare each validator Uint8Array 1.4850 s/op 1.4962 s/op 0.99
compare ViewDU to Uint8Array 1.3069 s/op 1.4657 s/op 0.89
migrate state 1000000 validators, 24 modified, 0 new 974.75 ms/op 1.1346 s/op 0.86
migrate state 1000000 validators, 1700 modified, 1000 new 1.4075 s/op 1.5617 s/op 0.90
migrate state 1000000 validators, 3400 modified, 2000 new 1.6691 s/op 1.7965 s/op 0.93
migrate state 1500000 validators, 24 modified, 0 new 1.0081 s/op 1.1543 s/op 0.87
migrate state 1500000 validators, 1700 modified, 1000 new 1.2032 s/op 1.3295 s/op 0.91
migrate state 1500000 validators, 3400 modified, 2000 new 1.4330 s/op 1.6041 s/op 0.89
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.8300 ns/op 4.6500 ns/op 1.04
state getBlockRootAtSlot - 250000 vs - 7PWei 797.92 ns/op 683.16 ns/op 1.17
naive computeProposerIndex 100000 validators 79.834 ms/op 54.609 ms/op 1.46
computeProposerIndex 100000 validators 1.8623 ms/op 1.5823 ms/op 1.18
naiveGetNextSyncCommitteeIndices 1000 validators 9.0806 s/op 8.0543 s/op 1.13
getNextSyncCommitteeIndices 1000 validators 125.47 ms/op 136.59 ms/op 0.92
naiveGetNextSyncCommitteeIndices 10000 validators 9.2806 s/op 7.8514 s/op 1.18
getNextSyncCommitteeIndices 10000 validators 119.58 ms/op 124.13 ms/op 0.96
naiveGetNextSyncCommitteeIndices 100000 validators 8.3156 s/op 7.5533 s/op 1.10
getNextSyncCommitteeIndices 100000 validators 118.56 ms/op 125.22 ms/op 0.95
naive computeShuffledIndex 100000 validators 23.940 s/op 25.794 s/op 0.93
cached computeShuffledIndex 100000 validators 589.21 ms/op 595.70 ms/op 0.99
naive computeShuffledIndex 2000000 validators 583.63 s/op 513.30 s/op 1.14
cached computeShuffledIndex 2000000 validators 41.359 s/op 54.188 s/op 0.76
computeProposers - vc 250000 730.50 us/op 678.62 us/op 1.08
computeEpochShuffling - vc 250000 48.878 ms/op 46.864 ms/op 1.04
getNextSyncCommittee - vc 250000 11.767 ms/op 14.643 ms/op 0.80
computeSigningRoot for AttestationData 20.675 us/op 35.165 us/op 0.59
hash AttestationData serialized data then Buffer.toString(base64) 1.5858 us/op 1.6744 us/op 0.95
toHexString serialized data 1.1470 us/op 1.4046 us/op 0.82
Buffer.toString(base64) 155.82 ns/op 178.12 ns/op 0.87
nodejs block root to RootHex using toHex 153.81 ns/op 157.67 ns/op 0.98
nodejs block root to RootHex using toRootHex 93.951 ns/op 93.483 ns/op 1.01
nodejs fromHex(blob) 121.57 us/op 119.58 us/op 1.02
nodejs fromHexInto(blob) 850.61 us/op 880.44 us/op 0.97
nodejs block root to RootHex using the deprecated toHexString 229.45 ns/op 232.13 ns/op 0.99
browser block root to RootHex using toHex 186.85 ns/op 183.01 ns/op 1.02
browser block root to RootHex using toRootHex 174.47 ns/op 185.09 ns/op 0.94
browser fromHex(blob) 832.30 us/op 867.59 us/op 0.96
browser fromHexInto(blob) 846.31 us/op 897.88 us/op 0.94
browser block root to RootHex using the deprecated toHexString 840.80 ns/op 1.0228 us/op 0.82

by benchmarkbot/action

@matthewkeil matthewkeil marked this pull request as ready for review October 14, 2025 19:56
@matthewkeil matthewkeil requested a review from a team as a code owner October 14, 2025 19:56
@codecov
Copy link

codecov bot commented Oct 21, 2025

Codecov Report

❌ Patch coverage is 6.59898% with 184 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.93%. Comparing base (21fbdc9) to head (711b94d).
⚠️ Report is 15 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #8482      +/-   ##
============================================
- Coverage     52.18%   51.93%   -0.26%     
============================================
  Files           852      848       -4     
  Lines         65317    65732     +415     
  Branches       4793     4792       -1     
============================================
+ Hits          34083    34135      +52     
- Misses        31165    31528     +363     
  Partials         69       69              
🚀 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.

@nflaig
Copy link
Member

nflaig commented Oct 22, 2025

/gemini review

Copy link
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 fixes two bugs related to range downloads and refactors the column validation logic to be more robust against out-of-order or incomplete data from peers. The changes look solid and significantly improve the validation heuristics. I've found one area where the error reporting could be clearer, but overall this is a great improvement.

@wemeetagain wemeetagain changed the title fix: rough out validateColumnsByRangeResponse fix: refactor validateColumnsByRangeResponse Oct 23, 2025
@philknows philknows added this to the v1.36.0 milestone Oct 23, 2025
**Motivation**

- reviewing #8482
- the review was getting quite detailed, seemed to be more direct to
just PR into it

**Description**

- review of validateColumnsByRangeResponse
  - simplify the duplicate/order checking loop
    - use a map to deduplicate the various cases
  - minor updates to the index checking loop
    - reuse map from ^, use non-nullish array

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
wemeetagain
wemeetagain previously approved these changes Oct 23, 2025
Copy link
Member

@wemeetagain wemeetagain left a comment

Choose a reason for hiding this comment

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

lgtm, will leave open for more confirmation from others

@matthewkeil
Copy link
Member Author

/gemini review

Copy link
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 effectively addresses two crashes observed in devnet logs by adding safety checks for empty sidecar arrays in cacheByRangeResponses and empty block arrays in validateBlockByRangeResponse. The core of the change is a significant and well-executed refactoring of validateColumnsByRangeResponse to improve validation of column sidecars. The new implementation is more robust, checking for duplicates and correct (slot, index) ordering as per the spec, and handles partial responses more gracefully.

My review includes a few suggestions. I've identified a high-severity bug in the new column ordering validation logic that would prevent it from correctly detecting out-of-order indices. I've also included a couple of medium-severity suggestions to improve the readability of error messages for better debugging. Overall, this is a solid improvement to the sync process's stability and correctness.

Comment on lines +665 to +671
if (currentSlot !== slot) {
// a new slot has started, reset index
currentIndex = -1;
} else {
currentIndex = columnSidecar.index;
}
currentSlot = slot;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The logic for updating currentSlot and currentIndex is flawed and will fail to detect out-of-order column indices within a slot.

Specifically, on the first item of a new slot, currentIndex is not updated to that item's index. In the next iteration for the same slot, the check currentIndex > columnSidecar.index will use an incorrect (stale or reset) value for currentIndex, causing the out-of-order check to fail.

The logic can be simplified to correctly update the state for the next iteration's check.

    if (currentSlot !== slot) {
      currentSlot = slot;
    }
    currentIndex = columnSidecar.index;

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the issue I raised in #8560. Left as is it will cause extra errors, fixing to the suggestion will bury out of order errors. Kinda not sure which way to go but open to suggestions. I tend to think leaving this unless anyone thinks it should be changed to the above.

nflaig
nflaig previously approved these changes Oct 23, 2025
Copy link
Member

@nflaig nflaig left a comment

Choose a reason for hiding this comment

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

didn't do another pass but all my previous comments are addressed

if (expectedColumns === 0) {
continue;
let blobCount: number;
if (!isForkPostFulu(forkName)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

since we're checking fork of block slot, looks like it should belong to validateBlockByRangeResponse() logic?

Copy link
Member Author

Choose a reason for hiding this comment

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

You are correct, there should not be a case where this happens. I had it with a default parameter but @nflaig wanted it fork gated so I added that check and threw the error. It will likely not ever get thrown though unless there is a code bug. The conditional will be needed below though as handling of columns will be different isPostGloas

/**
* If no columns are found for a block and there are commitments on the block then stop checking and just
* return early. Even if there were columns returned for subsequent slots that doesn't matter because
* we will be re-requesting them again anyway. Leftovers just get ignored
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this comment here
I expect this function to either throw error, or return result with some warnings
the below break breaks that contract/assumption, it only returns some first blocks of the whole response

I suppose in this case we just need to throw error instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the by-range code can pull partial epochs now. So its possible to pull part of the epoch and then on the next go around the rest of the epoch gets downloaded

@nflaig nflaig merged commit b992c32 into unstable Oct 27, 2025
19 of 20 checks passed
@nflaig nflaig deleted the mkeil/fix-by-range-validation branch October 27, 2025 18:02
@wemeetagain
Copy link
Member

🎉 This PR is included in v1.36.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.

6 participants