Skip to content

Conversation

@nflaig
Copy link
Member

@nflaig nflaig commented Dec 3, 2025

Motivation

When requesting a future slot the node tries to dial the state from head which allows to quite easily DoS the node as it's unbounded amount of work if the slot is very far away from head.

We should not allow to request states that are in the future (> clock slot) and return a 404 instead.

Description

In case state is request by slot, check if it's a slot from the future based on clock slot and return 404 state not found error.

I didn't use forkChoice.getHead().slot because we should still be able to serve the state if all slots between the requested slot and the head slot are skipped.

Related discord discussion, thanks to @guha-rahul for catching and reporting this.

@nflaig nflaig requested a review from a team as a code owner December 3, 2025 10:56
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @nflaig, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a critical security enhancement by preventing beacon nodes from attempting to serve state data for future blockchain slots. Previously, requesting a state for a slot far ahead of the current head could lead to an unbounded amount of computational work, making the node vulnerable to Denial-of-Service attacks. The changes ensure that any such requests are immediately rejected with a "not found" error, thereby safeguarding the node's resources and stability.

Highlights

  • DoS Prevention: Implemented a mechanism to prevent Denial-of-Service attacks by disallowing requests for future blockchain states.
  • Future Slot Handling: Requests for state data corresponding to slots beyond the current clock slot will now result in a "not found" (404) response.
  • Accurate Slot Check: The check for future slots utilizes chain.clock.currentSlot to correctly account for skipped slots, ensuring valid historical or current states can still be served.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

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 correctly addresses a potential denial-of-service vulnerability by preventing state lookups for future slots. The logic is sound and the change is targeted. I have one suggestion to refactor the nested ternary operators into a more readable if/else structure, which should improve the maintainability of the code.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 3, 2025

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 69e8714 Previous: 548d7aa Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 953.13 us/op 930.42 us/op 1.02
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 44.565 us/op 36.236 us/op 1.23
BLS verify - blst 1.0177 ms/op 867.99 us/op 1.17
BLS verifyMultipleSignatures 3 - blst 1.3855 ms/op 1.3086 ms/op 1.06
BLS verifyMultipleSignatures 8 - blst 2.0570 ms/op 1.9669 ms/op 1.05
BLS verifyMultipleSignatures 32 - blst 5.8503 ms/op 4.9972 ms/op 1.17
BLS verifyMultipleSignatures 64 - blst 11.094 ms/op 9.8835 ms/op 1.12
BLS verifyMultipleSignatures 128 - blst 18.443 ms/op 17.016 ms/op 1.08
BLS deserializing 10000 signatures 714.08 ms/op 697.03 ms/op 1.02
BLS deserializing 100000 signatures 6.9755 s/op 7.0000 s/op 1.00
BLS verifyMultipleSignatures - same message - 3 - blst 888.03 us/op 973.61 us/op 0.91
BLS verifyMultipleSignatures - same message - 8 - blst 1.0126 ms/op 1.0901 ms/op 0.93
BLS verifyMultipleSignatures - same message - 32 - blst 1.7000 ms/op 1.7495 ms/op 0.97
BLS verifyMultipleSignatures - same message - 64 - blst 2.6232 ms/op 2.6695 ms/op 0.98
BLS verifyMultipleSignatures - same message - 128 - blst 4.5216 ms/op 4.4582 ms/op 1.01
BLS aggregatePubkeys 32 - blst 21.601 us/op 19.749 us/op 1.09
BLS aggregatePubkeys 128 - blst 71.343 us/op 71.079 us/op 1.00
notSeenSlots=1 numMissedVotes=1 numBadVotes=10 61.738 ms/op 51.693 ms/op 1.19
notSeenSlots=1 numMissedVotes=0 numBadVotes=4 51.744 ms/op 49.032 ms/op 1.06
notSeenSlots=2 numMissedVotes=1 numBadVotes=10 43.637 ms/op 38.568 ms/op 1.13
getSlashingsAndExits - default max 74.057 us/op 73.504 us/op 1.01
getSlashingsAndExits - 2k 356.15 us/op 367.92 us/op 0.97
isKnown best case - 1 super set check 214.00 ns/op 206.00 ns/op 1.04
isKnown normal case - 2 super set checks 215.00 ns/op 202.00 ns/op 1.06
isKnown worse case - 16 super set checks 213.00 ns/op 202.00 ns/op 1.05
InMemoryCheckpointStateCache - add get delete 2.3940 us/op 2.3890 us/op 1.00
validate api signedAggregateAndProof - struct 1.3852 ms/op 1.4865 ms/op 0.93
validate gossip signedAggregateAndProof - struct 1.3964 ms/op 1.4470 ms/op 0.97
batch validate gossip attestation - vc 640000 - chunk 32 116.30 us/op 122.01 us/op 0.95
batch validate gossip attestation - vc 640000 - chunk 64 101.59 us/op 108.23 us/op 0.94
batch validate gossip attestation - vc 640000 - chunk 128 91.912 us/op 102.72 us/op 0.89
batch validate gossip attestation - vc 640000 - chunk 256 91.333 us/op 110.17 us/op 0.83
pickEth1Vote - no votes 933.58 us/op 980.74 us/op 0.95
pickEth1Vote - max votes 6.1467 ms/op 7.7709 ms/op 0.79
pickEth1Vote - Eth1Data hashTreeRoot value x2048 12.044 ms/op 13.349 ms/op 0.90
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 22.735 ms/op 19.900 ms/op 1.14
pickEth1Vote - Eth1Data fastSerialize value x2048 433.70 us/op 433.52 us/op 1.00
pickEth1Vote - Eth1Data fastSerialize tree x2048 5.2209 ms/op 2.4563 ms/op 2.13
bytes32 toHexString 372.00 ns/op 373.00 ns/op 1.00
bytes32 Buffer.toString(hex) 252.00 ns/op 247.00 ns/op 1.02
bytes32 Buffer.toString(hex) from Uint8Array 365.00 ns/op 336.00 ns/op 1.09
bytes32 Buffer.toString(hex) + 0x 396.00 ns/op 249.00 ns/op 1.59
Object access 1 prop 0.12700 ns/op 0.12500 ns/op 1.02
Map access 1 prop 0.13300 ns/op 0.13400 ns/op 0.99
Object get x1000 5.9050 ns/op 5.8220 ns/op 1.01
Map get x1000 6.3740 ns/op 6.5170 ns/op 0.98
Object set x1000 29.691 ns/op 31.877 ns/op 0.93
Map set x1000 20.060 ns/op 21.298 ns/op 0.94
Return object 10000 times 0.28900 ns/op 0.29410 ns/op 0.98
Throw Error 10000 times 4.2142 us/op 4.3822 us/op 0.96
toHex 147.72 ns/op 140.82 ns/op 1.05
Buffer.from 132.46 ns/op 127.75 ns/op 1.04
shared Buffer 89.371 ns/op 88.892 ns/op 1.01
fastMsgIdFn sha256 / 200 bytes 2.1460 us/op 2.2150 us/op 0.97
fastMsgIdFn h32 xxhash / 200 bytes 213.00 ns/op 203.00 ns/op 1.05
fastMsgIdFn h64 xxhash / 200 bytes 256.00 ns/op 262.00 ns/op 0.98
fastMsgIdFn sha256 / 1000 bytes 7.1770 us/op 7.4480 us/op 0.96
fastMsgIdFn h32 xxhash / 1000 bytes 346.00 ns/op 342.00 ns/op 1.01
fastMsgIdFn h64 xxhash / 1000 bytes 334.00 ns/op 339.00 ns/op 0.99
fastMsgIdFn sha256 / 10000 bytes 64.780 us/op 66.840 us/op 0.97
fastMsgIdFn h32 xxhash / 10000 bytes 1.7960 us/op 1.8390 us/op 0.98
fastMsgIdFn h64 xxhash / 10000 bytes 1.1880 us/op 1.2170 us/op 0.98
100 bytes - compress - snappyjs 1.3527 us/op 1.5388 us/op 0.88
100 bytes - compress - snappy 1.0897 us/op 1.1514 us/op 0.95
200 bytes - compress - snappyjs 2.1173 us/op 1.9755 us/op 1.07
200 bytes - compress - snappy 1.1326 us/op 1.3096 us/op 0.86
300 bytes - compress - snappyjs 2.4132 us/op 2.9092 us/op 0.83
300 bytes - compress - snappy 1.2707 us/op 1.3695 us/op 0.93
400 bytes - compress - snappyjs 2.6218 us/op 3.1368 us/op 0.84
400 bytes - compress - snappy 1.2897 us/op 1.3746 us/op 0.94
500 bytes - compress - snappyjs 2.8382 us/op 3.2497 us/op 0.87
500 bytes - compress - snappy 1.2789 us/op 1.4557 us/op 0.88
1000 bytes - compress - snappyjs 4.2717 us/op 4.4018 us/op 0.97
1000 bytes - compress - snappy 1.6920 us/op 1.9490 us/op 0.87
10000 bytes - compress - snappyjs 30.290 us/op 33.173 us/op 0.91
10000 bytes - compress - snappy 29.010 us/op 41.044 us/op 0.71
100 bytes - uncompress - snappyjs 802.67 ns/op 1.2104 us/op 0.66
100 bytes - uncompress - snappy 987.69 ns/op 1.1073 us/op 0.89
200 bytes - uncompress - snappyjs 1.6305 us/op 1.6762 us/op 0.97
200 bytes - uncompress - snappy 1.0507 us/op 1.0698 us/op 0.98
300 bytes - uncompress - snappyjs 1.3558 us/op 1.4565 us/op 0.93
300 bytes - uncompress - snappy 1.1625 us/op 1.1131 us/op 1.04
400 bytes - uncompress - snappyjs 1.2799 us/op 1.5967 us/op 0.80
400 bytes - uncompress - snappy 1.2018 us/op 1.2693 us/op 0.95
500 bytes - uncompress - snappyjs 2.0025 us/op 1.8874 us/op 1.06
500 bytes - uncompress - snappy 1.2284 us/op 1.2474 us/op 0.98
1000 bytes - uncompress - snappyjs 2.4396 us/op 2.7853 us/op 0.88
1000 bytes - uncompress - snappy 1.4905 us/op 1.5457 us/op 0.96
10000 bytes - uncompress - snappyjs 14.858 us/op 14.725 us/op 1.01
10000 bytes - uncompress - snappy 35.317 us/op 30.164 us/op 1.17
send data - 1000 256B messages 17.979 ms/op 17.988 ms/op 1.00
send data - 1000 512B messages 22.688 ms/op 22.664 ms/op 1.00
send data - 1000 1024B messages 30.839 ms/op 32.989 ms/op 0.93
send data - 1000 1200B messages 35.774 ms/op 32.566 ms/op 1.10
send data - 1000 2048B messages 28.994 ms/op 28.950 ms/op 1.00
send data - 1000 4096B messages 33.367 ms/op 34.075 ms/op 0.98
send data - 1000 16384B messages 45.797 ms/op 51.049 ms/op 0.90
send data - 1000 65536B messages 117.89 ms/op 119.80 ms/op 0.98
enrSubnets - fastDeserialize 64 bits 928.00 ns/op 901.00 ns/op 1.03
enrSubnets - ssz BitVector 64 bits 341.00 ns/op 331.00 ns/op 1.03
enrSubnets - fastDeserialize 4 bits 142.00 ns/op 126.00 ns/op 1.13
enrSubnets - ssz BitVector 4 bits 331.00 ns/op 333.00 ns/op 0.99
prioritizePeers score -10:0 att 32-0.1 sync 2-0 243.89 us/op 238.96 us/op 1.02
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 271.06 us/op 268.03 us/op 1.01
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 398.62 us/op 392.07 us/op 1.02
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 748.04 us/op 726.23 us/op 1.03
prioritizePeers score 0:0 att 64-1 sync 4-1 857.30 us/op 874.15 us/op 0.98
array of 16000 items push then shift 1.6841 us/op 1.6738 us/op 1.01
LinkedList of 16000 items push then shift 7.8920 ns/op 7.5640 ns/op 1.04
array of 16000 items push then pop 81.820 ns/op 84.294 ns/op 0.97
LinkedList of 16000 items push then pop 7.5430 ns/op 8.0060 ns/op 0.94
array of 24000 items push then shift 2.4911 us/op 2.3882 us/op 1.04
LinkedList of 24000 items push then shift 8.7060 ns/op 7.5790 ns/op 1.15
array of 24000 items push then pop 110.05 ns/op 111.10 ns/op 0.99
LinkedList of 24000 items push then pop 8.2640 ns/op 8.5430 ns/op 0.97
intersect bitArray bitLen 8 6.3840 ns/op 6.4600 ns/op 0.99
intersect array and set length 8 38.451 ns/op 37.644 ns/op 1.02
intersect bitArray bitLen 128 29.924 ns/op 29.570 ns/op 1.01
intersect array and set length 128 637.06 ns/op 627.74 ns/op 1.01
bitArray.getTrueBitIndexes() bitLen 128 1.0490 us/op 1.0170 us/op 1.03
bitArray.getTrueBitIndexes() bitLen 248 1.8610 us/op 1.7850 us/op 1.04
bitArray.getTrueBitIndexes() bitLen 512 3.8040 us/op 3.7850 us/op 1.01
Full columns - reconstruct all 6 blobs 80.415 us/op 112.83 us/op 0.71
Full columns - reconstruct half of the blobs out of 6 46.225 us/op 44.118 us/op 1.05
Full columns - reconstruct single blob out of 6 20.609 us/op 20.005 us/op 1.03
Half columns - reconstruct all 6 blobs 289.63 ms/op 279.40 ms/op 1.04
Half columns - reconstruct half of the blobs out of 6 142.26 ms/op 137.91 ms/op 1.03
Half columns - reconstruct single blob out of 6 52.406 ms/op 57.368 ms/op 0.91
Full columns - reconstruct all 10 blobs 144.43 us/op 153.69 us/op 0.94
Full columns - reconstruct half of the blobs out of 10 76.530 us/op 72.639 us/op 1.05
Full columns - reconstruct single blob out of 10 25.358 us/op 21.622 us/op 1.17
Half columns - reconstruct all 10 blobs 494.82 ms/op 488.60 ms/op 1.01
Half columns - reconstruct half of the blobs out of 10 243.96 ms/op 243.56 ms/op 1.00
Half columns - reconstruct single blob out of 10 54.086 ms/op 51.053 ms/op 1.06
Full columns - reconstruct all 20 blobs 398.24 us/op 301.38 us/op 1.32
Full columns - reconstruct half of the blobs out of 20 142.94 us/op 145.38 us/op 0.98
Full columns - reconstruct single blob out of 20 21.986 us/op 21.550 us/op 1.02
Half columns - reconstruct all 20 blobs 939.95 ms/op 907.67 ms/op 1.04
Half columns - reconstruct half of the blobs out of 20 466.89 ms/op 460.94 ms/op 1.01
Half columns - reconstruct single blob out of 20 52.357 ms/op 51.574 ms/op 1.02
Buffer.concat 32 items 688.00 ns/op 618.00 ns/op 1.11
Uint8Array.set 32 items 1.7790 us/op 1.3590 us/op 1.31
Buffer.copy 2.2760 us/op 2.1440 us/op 1.06
Uint8Array.set - with subarray 1.7910 us/op 1.6900 us/op 1.06
Uint8Array.set - without subarray 1.0610 us/op 1.2770 us/op 0.83
getUint32 - dataview 199.00 ns/op 200.00 ns/op 0.99
getUint32 - manual 125.00 ns/op 125.00 ns/op 1.00
Set add up to 64 items then delete first 2.2368 us/op 2.3611 us/op 0.95
OrderedSet add up to 64 items then delete first 3.8797 us/op 3.3344 us/op 1.16
Set add up to 64 items then delete last 2.4499 us/op 2.5730 us/op 0.95
OrderedSet add up to 64 items then delete last 3.9251 us/op 4.2142 us/op 0.93
Set add up to 64 items then delete middle 2.8357 us/op 2.8116 us/op 1.01
OrderedSet add up to 64 items then delete middle 6.3673 us/op 6.2742 us/op 1.01
Set add up to 128 items then delete first 5.9179 us/op 5.7595 us/op 1.03
OrderedSet add up to 128 items then delete first 9.5534 us/op 8.9823 us/op 1.06
Set add up to 128 items then delete last 6.2014 us/op 5.3006 us/op 1.17
OrderedSet add up to 128 items then delete last 8.7667 us/op 8.8718 us/op 0.99
Set add up to 128 items then delete middle 5.9825 us/op 5.3215 us/op 1.12
OrderedSet add up to 128 items then delete middle 16.837 us/op 14.919 us/op 1.13
Set add up to 256 items then delete first 12.618 us/op 11.655 us/op 1.08
OrderedSet add up to 256 items then delete first 19.759 us/op 16.590 us/op 1.19
Set add up to 256 items then delete last 11.959 us/op 10.198 us/op 1.17
OrderedSet add up to 256 items then delete last 18.822 us/op 15.086 us/op 1.25
Set add up to 256 items then delete middle 11.009 us/op 9.4703 us/op 1.16
OrderedSet add up to 256 items then delete middle 44.744 us/op 43.032 us/op 1.04
transfer serialized Status (84 B) 2.3680 us/op 2.1850 us/op 1.08
copy serialized Status (84 B) 1.2520 us/op 1.1910 us/op 1.05
transfer serialized SignedVoluntaryExit (112 B) 2.4320 us/op 2.2380 us/op 1.09
copy serialized SignedVoluntaryExit (112 B) 1.2720 us/op 1.2140 us/op 1.05
transfer serialized ProposerSlashing (416 B) 2.4240 us/op 2.2860 us/op 1.06
copy serialized ProposerSlashing (416 B) 1.8390 us/op 1.2600 us/op 1.46
transfer serialized Attestation (485 B) 2.5110 us/op 2.3140 us/op 1.09
copy serialized Attestation (485 B) 1.6180 us/op 1.2850 us/op 1.26
transfer serialized AttesterSlashing (33232 B) 3.8820 us/op 2.5190 us/op 1.54
copy serialized AttesterSlashing (33232 B) 5.9070 us/op 4.3090 us/op 1.37
transfer serialized Small SignedBeaconBlock (128000 B) 4.1360 us/op 4.1020 us/op 1.01
copy serialized Small SignedBeaconBlock (128000 B) 17.330 us/op 14.120 us/op 1.23
transfer serialized Avg SignedBeaconBlock (200000 B) 4.4220 us/op 4.2770 us/op 1.03
copy serialized Avg SignedBeaconBlock (200000 B) 23.563 us/op 18.530 us/op 1.27
transfer serialized BlobsSidecar (524380 B) 4.9580 us/op 5.1500 us/op 0.96
copy serialized BlobsSidecar (524380 B) 65.623 us/op 110.96 us/op 0.59
transfer serialized Big SignedBeaconBlock (1000000 B) 6.2960 us/op 5.2780 us/op 1.19
copy serialized Big SignedBeaconBlock (1000000 B) 120.75 us/op 126.67 us/op 0.95
pass gossip attestations to forkchoice per slot 2.8598 ms/op 2.7269 ms/op 1.05
forkChoice updateHead vc 100000 bc 64 eq 0 517.44 us/op 471.24 us/op 1.10
forkChoice updateHead vc 600000 bc 64 eq 0 3.1338 ms/op 2.8099 ms/op 1.12
forkChoice updateHead vc 1000000 bc 64 eq 0 5.1569 ms/op 4.6809 ms/op 1.10
forkChoice updateHead vc 600000 bc 320 eq 0 3.0859 ms/op 2.8330 ms/op 1.09
forkChoice updateHead vc 600000 bc 1200 eq 0 3.2898 ms/op 2.8651 ms/op 1.15
forkChoice updateHead vc 600000 bc 7200 eq 0 3.3310 ms/op 3.1782 ms/op 1.05
forkChoice updateHead vc 600000 bc 64 eq 1000 3.2159 ms/op 2.9129 ms/op 1.10
forkChoice updateHead vc 600000 bc 64 eq 10000 3.3608 ms/op 3.0470 ms/op 1.10
forkChoice updateHead vc 600000 bc 64 eq 300000 11.125 ms/op 9.5957 ms/op 1.16
computeDeltas 1400000 validators 0% inactive 14.925 ms/op 13.791 ms/op 1.08
computeDeltas 1400000 validators 10% inactive 14.135 ms/op 12.810 ms/op 1.10
computeDeltas 1400000 validators 20% inactive 13.314 ms/op 11.513 ms/op 1.16
computeDeltas 1400000 validators 50% inactive 9.9420 ms/op 8.7964 ms/op 1.13
computeDeltas 2100000 validators 0% inactive 23.231 ms/op 20.615 ms/op 1.13
computeDeltas 2100000 validators 10% inactive 21.756 ms/op 18.817 ms/op 1.16
computeDeltas 2100000 validators 20% inactive 19.675 ms/op 17.006 ms/op 1.16
computeDeltas 2100000 validators 50% inactive 14.859 ms/op 13.015 ms/op 1.14
altair processAttestation - 250000 vs - 7PWei normalcase 4.2734 ms/op 2.0712 ms/op 2.06
altair processAttestation - 250000 vs - 7PWei worstcase 5.5877 ms/op 2.8745 ms/op 1.94
altair processAttestation - setStatus - 1/6 committees join 254.49 us/op 121.54 us/op 2.09
altair processAttestation - setStatus - 1/3 committees join 312.12 us/op 245.14 us/op 1.27
altair processAttestation - setStatus - 1/2 committees join 836.93 us/op 327.93 us/op 2.55
altair processAttestation - setStatus - 2/3 committees join 525.94 us/op 425.43 us/op 1.24
altair processAttestation - setStatus - 4/5 committees join 872.42 us/op 588.04 us/op 1.48
altair processAttestation - setStatus - 100% committees join 825.21 us/op 688.86 us/op 1.20
altair processBlock - 250000 vs - 7PWei normalcase 6.3426 ms/op 4.1833 ms/op 1.52
altair processBlock - 250000 vs - 7PWei normalcase hashState 38.117 ms/op 32.414 ms/op 1.18
altair processBlock - 250000 vs - 7PWei worstcase 41.566 ms/op 32.092 ms/op 1.30
altair processBlock - 250000 vs - 7PWei worstcase hashState 93.145 ms/op 67.404 ms/op 1.38
phase0 processBlock - 250000 vs - 7PWei normalcase 3.7075 ms/op 1.6079 ms/op 2.31
phase0 processBlock - 250000 vs - 7PWei worstcase 33.561 ms/op 21.154 ms/op 1.59
altair processEth1Data - 250000 vs - 7PWei normalcase 396.60 us/op 329.68 us/op 1.20
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 12.971 us/op 6.4230 us/op 2.02
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 57.812 us/op 45.606 us/op 1.27
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 20.320 us/op 11.790 us/op 1.72
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 15.485 us/op 6.4040 us/op 2.42
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 278.01 us/op 146.44 us/op 1.90
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 2.1576 ms/op 1.8073 ms/op 1.19
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.9297 ms/op 2.3754 ms/op 1.23
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 3.7089 ms/op 2.2702 ms/op 1.63
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 6.5187 ms/op 4.6174 ms/op 1.41
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 3.6162 ms/op 2.3823 ms/op 1.52
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 10.388 ms/op 4.5779 ms/op 2.27
Tree 40 250000 create 835.43 ms/op 427.18 ms/op 1.96
Tree 40 250000 get(125000) 156.89 ns/op 135.06 ns/op 1.16
Tree 40 250000 set(125000) 3.8726 us/op 1.4687 us/op 2.64
Tree 40 250000 toArray() 31.047 ms/op 15.538 ms/op 2.00
Tree 40 250000 iterate all - toArray() + loop 34.861 ms/op 15.381 ms/op 2.27
Tree 40 250000 iterate all - get(i) 73.934 ms/op 49.062 ms/op 1.51
Array 250000 create 5.3528 ms/op 3.6792 ms/op 1.45
Array 250000 clone - spread 6.1189 ms/op 784.59 us/op 7.80
Array 250000 get(125000) 0.50000 ns/op 0.40600 ns/op 1.23
Array 250000 set(125000) 0.50600 ns/op 0.43000 ns/op 1.18
Array 250000 iterate all - loop 91.584 us/op 100.67 us/op 0.91
phase0 afterProcessEpoch - 250000 vs - 7PWei 47.039 ms/op 39.972 ms/op 1.18
Array.fill - length 1000000 7.6089 ms/op 3.2827 ms/op 2.32
Array push - length 1000000 25.067 ms/op 13.586 ms/op 1.85
Array.get 0.41236 ns/op 0.27835 ns/op 1.48
Uint8Array.get 0.52044 ns/op 0.43404 ns/op 1.20
phase0 beforeProcessEpoch - 250000 vs - 7PWei 28.612 ms/op 16.106 ms/op 1.78
altair processEpoch - mainnet_e81889 380.05 ms/op 278.45 ms/op 1.36
mainnet_e81889 - altair beforeProcessEpoch 20.783 ms/op 18.917 ms/op 1.10
mainnet_e81889 - altair processJustificationAndFinalization 7.7740 us/op 5.4360 us/op 1.43
mainnet_e81889 - altair processInactivityUpdates 6.8462 ms/op 4.2138 ms/op 1.62
mainnet_e81889 - altair processRewardsAndPenalties 46.721 ms/op 37.470 ms/op 1.25
mainnet_e81889 - altair processRegistryUpdates 994.00 ns/op 651.00 ns/op 1.53
mainnet_e81889 - altair processSlashings 249.00 ns/op 180.00 ns/op 1.38
mainnet_e81889 - altair processEth1DataReset 334.00 ns/op 175.00 ns/op 1.91
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.4408 ms/op 1.2018 ms/op 1.20
mainnet_e81889 - altair processSlashingsReset 1.6400 us/op 832.00 ns/op 1.97
mainnet_e81889 - altair processRandaoMixesReset 2.5660 us/op 1.0900 us/op 2.35
mainnet_e81889 - altair processHistoricalRootsUpdate 284.00 ns/op 174.00 ns/op 1.63
mainnet_e81889 - altair processParticipationFlagUpdates 753.00 ns/op 503.00 ns/op 1.50
mainnet_e81889 - altair processSyncCommitteeUpdates 238.00 ns/op 141.00 ns/op 1.69
mainnet_e81889 - altair afterProcessEpoch 52.058 ms/op 43.873 ms/op 1.19
capella processEpoch - mainnet_e217614 1.3500 s/op 831.10 ms/op 1.62
mainnet_e217614 - capella beforeProcessEpoch 71.832 ms/op 60.844 ms/op 1.18
mainnet_e217614 - capella processJustificationAndFinalization 6.4300 us/op 5.1700 us/op 1.24
mainnet_e217614 - capella processInactivityUpdates 19.014 ms/op 14.075 ms/op 1.35
mainnet_e217614 - capella processRewardsAndPenalties 218.27 ms/op 175.72 ms/op 1.24
mainnet_e217614 - capella processRegistryUpdates 8.1590 us/op 6.2760 us/op 1.30
mainnet_e217614 - capella processSlashings 196.00 ns/op 173.00 ns/op 1.13
mainnet_e217614 - capella processEth1DataReset 186.00 ns/op 172.00 ns/op 1.08
mainnet_e217614 - capella processEffectiveBalanceUpdates 4.6069 ms/op 10.310 ms/op 0.45
mainnet_e217614 - capella processSlashingsReset 1.1700 us/op 858.00 ns/op 1.36
mainnet_e217614 - capella processRandaoMixesReset 1.2670 us/op 1.1130 us/op 1.14
mainnet_e217614 - capella processHistoricalRootsUpdate 192.00 ns/op 172.00 ns/op 1.12
mainnet_e217614 - capella processParticipationFlagUpdates 569.00 ns/op 517.00 ns/op 1.10
mainnet_e217614 - capella afterProcessEpoch 126.59 ms/op 112.62 ms/op 1.12
phase0 processEpoch - mainnet_e58758 331.35 ms/op 276.32 ms/op 1.20
mainnet_e58758 - phase0 beforeProcessEpoch 79.179 ms/op 73.257 ms/op 1.08
mainnet_e58758 - phase0 processJustificationAndFinalization 6.3740 us/op 5.5570 us/op 1.15
mainnet_e58758 - phase0 processRewardsAndPenalties 42.105 ms/op 39.694 ms/op 1.06
mainnet_e58758 - phase0 processRegistryUpdates 3.2320 us/op 3.1000 us/op 1.04
mainnet_e58758 - phase0 processSlashings 211.00 ns/op 178.00 ns/op 1.19
mainnet_e58758 - phase0 processEth1DataReset 210.00 ns/op 172.00 ns/op 1.22
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.4965 ms/op 1.1940 ms/op 1.25
mainnet_e58758 - phase0 processSlashingsReset 1.0050 us/op 935.00 ns/op 1.07
mainnet_e58758 - phase0 processRandaoMixesReset 1.2570 us/op 1.2050 us/op 1.04
mainnet_e58758 - phase0 processHistoricalRootsUpdate 204.00 ns/op 177.00 ns/op 1.15
mainnet_e58758 - phase0 processParticipationRecordUpdates 973.00 ns/op 891.00 ns/op 1.09
mainnet_e58758 - phase0 afterProcessEpoch 37.070 ms/op 41.204 ms/op 0.90
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.4464 ms/op 1.3691 ms/op 1.06
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 2.5927 ms/op 2.5541 ms/op 1.02
altair processInactivityUpdates - 250000 normalcase 21.310 ms/op 16.882 ms/op 1.26
altair processInactivityUpdates - 250000 worstcase 23.683 ms/op 18.353 ms/op 1.29
phase0 processRegistryUpdates - 250000 normalcase 7.6430 us/op 6.7410 us/op 1.13
phase0 processRegistryUpdates - 250000 badcase_full_deposits 283.34 us/op 255.95 us/op 1.11
phase0 processRegistryUpdates - 250000 worstcase 0.5 158.51 ms/op 96.545 ms/op 1.64
altair processRewardsAndPenalties - 250000 normalcase 31.276 ms/op 26.161 ms/op 1.20
altair processRewardsAndPenalties - 250000 worstcase 29.876 ms/op 25.134 ms/op 1.19
phase0 getAttestationDeltas - 250000 normalcase 9.3627 ms/op 6.8177 ms/op 1.37
phase0 getAttestationDeltas - 250000 worstcase 7.4720 ms/op 5.8273 ms/op 1.28
phase0 processSlashings - 250000 worstcase 93.043 us/op 85.852 us/op 1.08
altair processSyncCommitteeUpdates - 250000 12.326 ms/op 10.980 ms/op 1.12
BeaconState.hashTreeRoot - No change 225.00 ns/op 210.00 ns/op 1.07
BeaconState.hashTreeRoot - 1 full validator 84.238 us/op 97.167 us/op 0.87
BeaconState.hashTreeRoot - 32 full validator 961.42 us/op 775.74 us/op 1.24
BeaconState.hashTreeRoot - 512 full validator 13.026 ms/op 9.0847 ms/op 1.43
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 154.57 us/op 92.188 us/op 1.68
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.7173 ms/op 1.3500 ms/op 1.27
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 20.854 ms/op 22.820 ms/op 0.91
BeaconState.hashTreeRoot - 1 balances 104.91 us/op 74.885 us/op 1.40
BeaconState.hashTreeRoot - 32 balances 784.35 us/op 805.19 us/op 0.97
BeaconState.hashTreeRoot - 512 balances 8.5271 ms/op 8.2607 ms/op 1.03
BeaconState.hashTreeRoot - 250000 balances 204.75 ms/op 168.03 ms/op 1.22
aggregationBits - 2048 els - zipIndexesInBitList 24.330 us/op 21.714 us/op 1.12
byteArrayEquals 32 57.732 ns/op 53.562 ns/op 1.08
Buffer.compare 32 19.582 ns/op 16.989 ns/op 1.15
byteArrayEquals 1024 1.6984 us/op 1.5795 us/op 1.08
Buffer.compare 1024 26.543 ns/op 25.180 ns/op 1.05
byteArrayEquals 16384 26.130 us/op 25.041 us/op 1.04
Buffer.compare 16384 206.09 ns/op 225.83 ns/op 0.91
byteArrayEquals 123687377 218.31 ms/op 192.24 ms/op 1.14
Buffer.compare 123687377 8.5199 ms/op 7.0428 ms/op 1.21
byteArrayEquals 32 - diff last byte 60.757 ns/op 51.878 ns/op 1.17
Buffer.compare 32 - diff last byte 18.929 ns/op 16.821 ns/op 1.13
byteArrayEquals 1024 - diff last byte 1.7851 us/op 1.5819 us/op 1.13
Buffer.compare 1024 - diff last byte 27.179 ns/op 24.712 ns/op 1.10
byteArrayEquals 16384 - diff last byte 26.230 us/op 25.204 us/op 1.04
Buffer.compare 16384 - diff last byte 195.95 ns/op 194.10 ns/op 1.01
byteArrayEquals 123687377 - diff last byte 202.47 ms/op 187.06 ms/op 1.08
Buffer.compare 123687377 - diff last byte 7.7894 ms/op 6.3965 ms/op 1.22
byteArrayEquals 32 - random bytes 5.3770 ns/op 4.9590 ns/op 1.08
Buffer.compare 32 - random bytes 17.605 ns/op 16.636 ns/op 1.06
byteArrayEquals 1024 - random bytes 5.4380 ns/op 4.9450 ns/op 1.10
Buffer.compare 1024 - random bytes 17.629 ns/op 16.554 ns/op 1.06
byteArrayEquals 16384 - random bytes 5.3180 ns/op 4.9260 ns/op 1.08
Buffer.compare 16384 - random bytes 17.596 ns/op 16.457 ns/op 1.07
byteArrayEquals 123687377 - random bytes 6.4900 ns/op 6.2500 ns/op 1.04
Buffer.compare 123687377 - random bytes 18.540 ns/op 17.830 ns/op 1.04
regular array get 100000 times 46.027 us/op 42.507 us/op 1.08
wrappedArray get 100000 times 33.673 us/op 31.602 us/op 1.07
arrayWithProxy get 100000 times 13.817 ms/op 17.787 ms/op 0.78
ssz.Root.equals 48.018 ns/op 44.705 ns/op 1.07
byteArrayEquals 46.892 ns/op 43.852 ns/op 1.07
Buffer.compare 10.500 ns/op 10.072 ns/op 1.04
processSlot - 1 slots 11.896 us/op 10.122 us/op 1.18
processSlot - 32 slots 2.1731 ms/op 3.3013 ms/op 0.66
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 3.4572 ms/op 2.8532 ms/op 1.21
getCommitteeAssignments - req 1 vs - 250000 vc 2.1886 ms/op 2.0683 ms/op 1.06
getCommitteeAssignments - req 100 vs - 250000 vc 4.6335 ms/op 4.0247 ms/op 1.15
getCommitteeAssignments - req 1000 vs - 250000 vc 4.5708 ms/op 4.3005 ms/op 1.06
findModifiedValidators - 10000 modified validators 776.32 ms/op 728.18 ms/op 1.07
findModifiedValidators - 1000 modified validators 722.10 ms/op 668.63 ms/op 1.08
findModifiedValidators - 100 modified validators 311.81 ms/op 212.87 ms/op 1.46
findModifiedValidators - 10 modified validators 147.43 ms/op 139.00 ms/op 1.06
findModifiedValidators - 1 modified validators 145.14 ms/op 159.02 ms/op 0.91
findModifiedValidators - no difference 219.45 ms/op 208.95 ms/op 1.05
compare ViewDUs 6.4030 s/op 6.0907 s/op 1.05
compare each validator Uint8Array 1.4540 s/op 1.5051 s/op 0.97
compare ViewDU to Uint8Array 1.1503 s/op 1.0481 s/op 1.10
migrate state 1000000 validators, 24 modified, 0 new 899.24 ms/op 890.15 ms/op 1.01
migrate state 1000000 validators, 1700 modified, 1000 new 1.1878 s/op 1.4564 s/op 0.82
migrate state 1000000 validators, 3400 modified, 2000 new 1.4195 s/op 1.7953 s/op 0.79
migrate state 1500000 validators, 24 modified, 0 new 975.24 ms/op 1.1681 s/op 0.83
migrate state 1500000 validators, 1700 modified, 1000 new 1.2336 s/op 1.5469 s/op 0.80
migrate state 1500000 validators, 3400 modified, 2000 new 1.3074 s/op 1.9849 s/op 0.66
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.0400 ns/op 4.4400 ns/op 0.91
state getBlockRootAtSlot - 250000 vs - 7PWei 498.27 ns/op 572.49 ns/op 0.87
naive computeProposerIndex 100000 validators 49.786 ms/op 79.483 ms/op 0.63
computeProposerIndex 100000 validators 1.4406 ms/op 1.6447 ms/op 0.88
naiveGetNextSyncCommitteeIndices 1000 validators 7.5138 s/op 11.225 s/op 0.67
getNextSyncCommitteeIndices 1000 validators 106.03 ms/op 140.63 ms/op 0.75
naiveGetNextSyncCommitteeIndices 10000 validators 7.5164 s/op 10.201 s/op 0.74
getNextSyncCommitteeIndices 10000 validators 106.32 ms/op 122.97 ms/op 0.86
naiveGetNextSyncCommitteeIndices 100000 validators 7.2628 s/op 9.4836 s/op 0.77
getNextSyncCommitteeIndices 100000 validators 110.75 ms/op 143.47 ms/op 0.77
naive computeShuffledIndex 100000 validators 23.321 s/op 31.771 s/op 0.73
cached computeShuffledIndex 100000 validators 519.98 ms/op 574.19 ms/op 0.91
naive computeShuffledIndex 2000000 validators 488.49 s/op 483.44 s/op 1.01
cached computeShuffledIndex 2000000 validators 41.282 s/op 41.901 s/op 0.99
computeProposers - vc 250000 611.25 us/op 760.07 us/op 0.80
computeEpochShuffling - vc 250000 41.798 ms/op 42.008 ms/op 0.99
getNextSyncCommittee - vc 250000 10.453 ms/op 10.535 ms/op 0.99
computeSigningRoot for AttestationData 22.963 us/op 21.442 us/op 1.07
hash AttestationData serialized data then Buffer.toString(base64) 1.6352 us/op 1.6005 us/op 1.02
toHexString serialized data 1.2255 us/op 1.2181 us/op 1.01
Buffer.toString(base64) 152.66 ns/op 169.04 ns/op 0.90
nodejs block root to RootHex using toHex 161.20 ns/op 152.79 ns/op 1.06
nodejs block root to RootHex using toRootHex 88.215 ns/op 87.425 ns/op 1.01
nodejs fromHex(blob) 120.52 us/op 120.97 us/op 1.00
nodejs fromHexInto(blob) 845.40 us/op 829.29 us/op 1.02
nodejs block root to RootHex using the deprecated toHexString 217.06 ns/op 218.28 ns/op 0.99
browser block root to RootHex using toHex 177.51 ns/op 176.33 ns/op 1.01
browser block root to RootHex using toRootHex 167.70 ns/op 166.35 ns/op 1.01
browser fromHex(blob) 799.27 us/op 799.93 us/op 1.00
browser fromHexInto(blob) 832.19 us/op 827.60 us/op 1.01
browser block root to RootHex using the deprecated toHexString 804.05 ns/op 837.78 ns/op 0.96

by benchmarkbot/action

@wemeetagain wemeetagain merged commit 6938ce2 into unstable Dec 3, 2025
21 checks passed
@wemeetagain wemeetagain deleted the nflaig/future-slot branch December 3, 2025 14:59
@codecov
Copy link

codecov bot commented Dec 3, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.02%. Comparing base (548d7aa) to head (23a8297).
⚠️ Report is 4 commits behind head on unstable.

Additional details and impacted files
@@            Coverage Diff            @@
##           unstable    #8665   +/-   ##
=========================================
  Coverage     52.02%   52.02%           
=========================================
  Files           848      848           
  Lines         65837    65834    -3     
  Branches       4811     4810    -1     
=========================================
- Hits          34250    34249    -1     
+ Misses        31518    31516    -2     
  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.

@wemeetagain
Copy link
Member

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

4 participants