Skip to content

fix: prune serialized cache by block input keys#9007

Open
nflaig wants to merge 10 commits intounstablefrom
nflaig/serialized-cache
Open

fix: prune serialized cache by block input keys#9007
nflaig wants to merge 10 commits intounstablefrom
nflaig/serialized-cache

Conversation

@nflaig
Copy link
Member

@nflaig nflaig commented Mar 9, 2026

  • add getSerializedCacheKeys() to block input variants
  • more closely couple SerializedCache and SeenBlockInput
  • delete only relevant serialized cache object references after block input is written
  • remove global SerializedCache.clear() usage to avoid premature cache eviction

@nflaig nflaig changed the title fix: prune serialized cache by block input keys instead of global clear fix: prune serialized cache by block input keys Mar 9, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 significantly enhances the cache management strategy for serialized objects within the beacon node. By transitioning from a global cache clear to a more precise, block-input-specific deletion mechanism, it prevents unintended data eviction and improves the reliability of cached serialized data, particularly for complex block types like those involving blobs or columns. This change ensures that cached objects remain available as long as they are potentially needed by other processes, optimizing resource utilization and data consistency.

Highlights

  • Granular Cache Pruning: Introduced a new getSerializedCacheKeys() method to the IBlockInput interface and its concrete implementations. This method allows each block input variant to specify which serialized objects it holds that should be pruned from the cache.
  • Refined Cache Management: Replaced the global SerializedCache.clear() operation with a targeted serializedCache.delete() call. This ensures that only the serialized objects relevant to a specific block input are removed upon finalization, preventing premature eviction of other cached data.
  • SerializedCache API Update: The SerializedCache class was refactored to remove the clear() method and introduce a delete(objs: object[]) method, enabling the new granular pruning strategy. The internal map property was also made private.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • packages/beacon-node/src/chain/blocks/blockInput/blockInput.ts
    • Added abstract getSerializedCacheKeys() method to AbstractBlockInput.
    • Implemented getSerializedCacheKeys() in BlockInputPreData to return the block object.
    • Implemented getSerializedCacheKeys() in BlockInputBlobs to return the block and all blob sidecars.
    • Implemented getSerializedCacheKeys() in BlockInputColumns to return the block and all columns.
    • Implemented getSerializedCacheKeys() in BlockInputNoData to return the block object.
  • packages/beacon-node/src/chain/blocks/blockInput/types.ts
    • Defined getSerializedCacheKeys() method in the IBlockInput interface with JSDoc.
  • packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts
    • Removed isBlockInputNoData import.
    • Replaced global this.serializedCache.clear() with this.serializedCache.delete(blockInput.getSerializedCacheKeys()) for targeted cache pruning.
  • packages/beacon-node/src/network/network.ts
    • Modified createGossipRpc call to pass the this.chain.serializedCache instance.
  • packages/beacon-node/src/util/serializedCache.ts
    • Updated JSDoc for SerializedCache.
    • Changed map property visibility from public to private.
    • Removed the clear() method.
    • Added a new delete(objs: object[]) method to remove specific objects from the cache.
  • packages/beacon-node/test/utils/blockInput.ts
    • Implemented getSerializedCacheKeys() in MockBlockInput for testing purposes.
Activity
  • No specific activity (comments, reviews, progress) was provided in the context for this pull request.
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.

@nflaig nflaig marked this pull request as ready for review March 9, 2026 14:48
@nflaig nflaig requested a review from a team as a code owner March 9, 2026 14:48
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 introduces a more granular cache pruning mechanism for SerializedCache. Instead of clearing the entire cache, it now selectively deletes entries related to a processed block. This is achieved by adding a getSerializedCacheKeys() method to IBlockInput and its implementations, and a delete() method to SerializedCache. The changes are well-implemented and improve both performance and correctness by avoiding premature cache eviction. I've suggested one minor improvement for code consistency.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: 0cc2480 Previous: bb27317 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1022 ms/op 1.0494 ms/op 1.05
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 38.496 us/op 37.590 us/op 1.02
BLS verify - blst 863.20 us/op 886.29 us/op 0.97
BLS verifyMultipleSignatures 3 - blst 1.2307 ms/op 2.2391 ms/op 0.55
BLS verifyMultipleSignatures 8 - blst 1.8576 ms/op 2.2726 ms/op 0.82
BLS verifyMultipleSignatures 32 - blst 5.5736 ms/op 6.8281 ms/op 0.82
BLS verifyMultipleSignatures 64 - blst 11.499 ms/op 11.272 ms/op 1.02
BLS verifyMultipleSignatures 128 - blst 17.024 ms/op 17.019 ms/op 1.00
BLS deserializing 10000 signatures 693.97 ms/op 655.87 ms/op 1.06
BLS deserializing 100000 signatures 7.0200 s/op 6.5495 s/op 1.07
BLS verifyMultipleSignatures - same message - 3 - blst 1.1403 ms/op 1.3390 ms/op 0.85
BLS verifyMultipleSignatures - same message - 8 - blst 1.2032 ms/op 1.6215 ms/op 0.74
BLS verifyMultipleSignatures - same message - 32 - blst 1.8547 ms/op 1.8546 ms/op 1.00
BLS verifyMultipleSignatures - same message - 64 - blst 2.8126 ms/op 2.7301 ms/op 1.03
BLS verifyMultipleSignatures - same message - 128 - blst 4.6606 ms/op 4.4847 ms/op 1.04
BLS aggregatePubkeys 32 - blst 20.134 us/op 19.172 us/op 1.05
BLS aggregatePubkeys 128 - blst 70.935 us/op 68.534 us/op 1.04
getSlashingsAndExits - default max 75.549 us/op 69.291 us/op 1.09
getSlashingsAndExits - 2k 337.46 us/op 323.30 us/op 1.04
isKnown best case - 1 super set check 201.00 ns/op 204.00 ns/op 0.99
isKnown normal case - 2 super set checks 195.00 ns/op 199.00 ns/op 0.98
isKnown worse case - 16 super set checks 197.00 ns/op 202.00 ns/op 0.98
validate api signedAggregateAndProof - struct 1.4187 ms/op 1.5490 ms/op 0.92
validate gossip signedAggregateAndProof - struct 1.4032 ms/op 2.5825 ms/op 0.54
batch validate gossip attestation - vc 640000 - chunk 32 121.59 us/op 154.06 us/op 0.79
batch validate gossip attestation - vc 640000 - chunk 64 109.21 us/op 102.51 us/op 1.07
batch validate gossip attestation - vc 640000 - chunk 128 99.812 us/op 94.695 us/op 1.05
batch validate gossip attestation - vc 640000 - chunk 256 95.025 us/op 88.914 us/op 1.07
bytes32 toHexString 358.00 ns/op 364.00 ns/op 0.98
bytes32 Buffer.toString(hex) 256.00 ns/op 248.00 ns/op 1.03
bytes32 Buffer.toString(hex) from Uint8Array 337.00 ns/op 326.00 ns/op 1.03
bytes32 Buffer.toString(hex) + 0x 284.00 ns/op 245.00 ns/op 1.16
Return object 10000 times 0.23440 ns/op 0.22870 ns/op 1.02
Throw Error 10000 times 4.1969 us/op 4.2105 us/op 1.00
toHex 134.81 ns/op 132.93 ns/op 1.01
Buffer.from 125.64 ns/op 135.42 ns/op 0.93
shared Buffer 84.200 ns/op 84.700 ns/op 0.99
fastMsgIdFn sha256 / 200 bytes 2.1050 us/op 1.8310 us/op 1.15
fastMsgIdFn h32 xxhash / 200 bytes 197.00 ns/op 246.00 ns/op 0.80
fastMsgIdFn h64 xxhash / 200 bytes 315.00 ns/op 254.00 ns/op 1.24
fastMsgIdFn sha256 / 1000 bytes 6.1480 us/op 5.8490 us/op 1.05
fastMsgIdFn h32 xxhash / 1000 bytes 317.00 ns/op 352.00 ns/op 0.90
fastMsgIdFn h64 xxhash / 1000 bytes 349.00 ns/op 290.00 ns/op 1.20
fastMsgIdFn sha256 / 10000 bytes 57.921 us/op 49.235 us/op 1.18
fastMsgIdFn h32 xxhash / 10000 bytes 1.3960 us/op 1.3250 us/op 1.05
fastMsgIdFn h64 xxhash / 10000 bytes 998.00 ns/op 1.3870 us/op 0.72
send data - 1000 256B messages 5.2987 ms/op 4.5429 ms/op 1.17
send data - 1000 512B messages 5.9592 ms/op 4.2621 ms/op 1.40
send data - 1000 1024B messages 5.1728 ms/op 4.5418 ms/op 1.14
send data - 1000 1200B messages 6.1564 ms/op 5.9245 ms/op 1.04
send data - 1000 2048B messages 6.5026 ms/op 5.8836 ms/op 1.11
send data - 1000 4096B messages 6.9882 ms/op 7.5792 ms/op 0.92
send data - 1000 16384B messages 27.978 ms/op 30.810 ms/op 0.91
send data - 1000 65536B messages 107.70 ms/op 88.008 ms/op 1.22
enrSubnets - fastDeserialize 64 bits 938.00 ns/op 900.00 ns/op 1.04
enrSubnets - ssz BitVector 64 bits 351.00 ns/op 328.00 ns/op 1.07
enrSubnets - fastDeserialize 4 bits 151.00 ns/op 130.00 ns/op 1.16
enrSubnets - ssz BitVector 4 bits 391.00 ns/op 322.00 ns/op 1.21
prioritizePeers score -10:0 att 32-0.1 sync 2-0 233.85 us/op 313.47 us/op 0.75
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 261.65 us/op 262.41 us/op 1.00
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 421.20 us/op 574.43 us/op 0.73
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 795.09 us/op 864.68 us/op 0.92
prioritizePeers score 0:0 att 64-1 sync 4-1 840.72 us/op 860.76 us/op 0.98
array of 16000 items push then shift 1.6340 us/op 1.5857 us/op 1.03
LinkedList of 16000 items push then shift 7.6070 ns/op 7.1950 ns/op 1.06
array of 16000 items push then pop 77.968 ns/op 74.283 ns/op 1.05
LinkedList of 16000 items push then pop 7.2510 ns/op 7.0080 ns/op 1.03
array of 24000 items push then shift 2.3912 us/op 2.3714 us/op 1.01
LinkedList of 24000 items push then shift 7.5830 ns/op 7.3110 ns/op 1.04
array of 24000 items push then pop 108.59 ns/op 105.13 ns/op 1.03
LinkedList of 24000 items push then pop 7.2840 ns/op 7.0390 ns/op 1.03
intersect bitArray bitLen 8 5.7060 ns/op 5.5980 ns/op 1.02
intersect array and set length 8 33.674 ns/op 32.787 ns/op 1.03
intersect bitArray bitLen 128 28.770 ns/op 28.047 ns/op 1.03
intersect array and set length 128 552.55 ns/op 538.47 ns/op 1.03
bitArray.getTrueBitIndexes() bitLen 128 1.0760 us/op 1.2910 us/op 0.83
bitArray.getTrueBitIndexes() bitLen 248 1.9140 us/op 1.8630 us/op 1.03
bitArray.getTrueBitIndexes() bitLen 512 3.7920 us/op 3.5960 us/op 1.05
Full columns - reconstruct all 6 blobs 289.52 us/op 225.70 us/op 1.28
Full columns - reconstruct half of the blobs out of 6 99.774 us/op 93.201 us/op 1.07
Full columns - reconstruct single blob out of 6 46.446 us/op 30.721 us/op 1.51
Half columns - reconstruct all 6 blobs 276.27 ms/op 258.21 ms/op 1.07
Half columns - reconstruct half of the blobs out of 6 136.39 ms/op 130.34 ms/op 1.05
Half columns - reconstruct single blob out of 6 50.552 ms/op 47.935 ms/op 1.05
Full columns - reconstruct all 10 blobs 369.60 us/op 291.15 us/op 1.27
Full columns - reconstruct half of the blobs out of 10 173.21 us/op 153.49 us/op 1.13
Full columns - reconstruct single blob out of 10 32.616 us/op 30.648 us/op 1.06
Half columns - reconstruct all 10 blobs 470.24 ms/op 429.18 ms/op 1.10
Half columns - reconstruct half of the blobs out of 10 232.43 ms/op 217.91 ms/op 1.07
Half columns - reconstruct single blob out of 10 52.355 ms/op 48.375 ms/op 1.08
Full columns - reconstruct all 20 blobs 989.67 us/op 469.93 us/op 2.11
Full columns - reconstruct half of the blobs out of 20 406.49 us/op 262.37 us/op 1.55
Full columns - reconstruct single blob out of 20 45.955 us/op 31.091 us/op 1.48
Half columns - reconstruct all 20 blobs 917.55 ms/op 856.12 ms/op 1.07
Half columns - reconstruct half of the blobs out of 20 455.31 ms/op 431.11 ms/op 1.06
Half columns - reconstruct single blob out of 20 52.525 ms/op 48.879 ms/op 1.07
Set add up to 64 items then delete first 2.1350 us/op 1.9732 us/op 1.08
OrderedSet add up to 64 items then delete first 3.2333 us/op 2.9162 us/op 1.11
Set add up to 64 items then delete last 2.4474 us/op 2.2797 us/op 1.07
OrderedSet add up to 64 items then delete last 3.4765 us/op 3.4608 us/op 1.00
Set add up to 64 items then delete middle 2.3866 us/op 2.3071 us/op 1.03
OrderedSet add up to 64 items then delete middle 5.0053 us/op 5.0338 us/op 0.99
Set add up to 128 items then delete first 4.8806 us/op 4.6639 us/op 1.05
OrderedSet add up to 128 items then delete first 7.7848 us/op 6.8959 us/op 1.13
Set add up to 128 items then delete last 4.7857 us/op 4.7076 us/op 1.02
OrderedSet add up to 128 items then delete last 7.2102 us/op 7.0704 us/op 1.02
Set add up to 128 items then delete middle 4.6162 us/op 4.5615 us/op 1.01
OrderedSet add up to 128 items then delete middle 13.725 us/op 13.391 us/op 1.02
Set add up to 256 items then delete first 10.531 us/op 9.9849 us/op 1.05
OrderedSet add up to 256 items then delete first 15.438 us/op 14.846 us/op 1.04
Set add up to 256 items then delete last 9.8401 us/op 9.3386 us/op 1.05
OrderedSet add up to 256 items then delete last 14.055 us/op 14.304 us/op 0.98
Set add up to 256 items then delete middle 9.6976 us/op 9.1153 us/op 1.06
OrderedSet add up to 256 items then delete middle 41.769 us/op 41.142 us/op 1.02
pass gossip attestations to forkchoice per slot 516.41 us/op 480.48 us/op 1.07
computeDeltas 1400000 validators 0% inactive 14.635 ms/op 14.068 ms/op 1.04
computeDeltas 1400000 validators 10% inactive 13.766 ms/op 13.148 ms/op 1.05
computeDeltas 1400000 validators 20% inactive 12.748 ms/op 12.232 ms/op 1.04
computeDeltas 1400000 validators 50% inactive 9.9414 ms/op 9.4831 ms/op 1.05
computeDeltas 2100000 validators 0% inactive 22.251 ms/op 21.069 ms/op 1.06
computeDeltas 2100000 validators 10% inactive 20.305 ms/op 19.733 ms/op 1.03
computeDeltas 2100000 validators 20% inactive 19.235 ms/op 18.345 ms/op 1.05
computeDeltas 2100000 validators 50% inactive 14.846 ms/op 14.224 ms/op 1.04
altair processAttestation - 250000 vs - 7PWei normalcase 2.1613 ms/op 1.9004 ms/op 1.14
altair processAttestation - 250000 vs - 7PWei worstcase 3.0162 ms/op 2.6799 ms/op 1.13
altair processAttestation - setStatus - 1/6 committees join 117.23 us/op 114.56 us/op 1.02
altair processAttestation - setStatus - 1/3 committees join 234.94 us/op 223.75 us/op 1.05
altair processAttestation - setStatus - 1/2 committees join 322.44 us/op 312.45 us/op 1.03
altair processAttestation - setStatus - 2/3 committees join 418.70 us/op 403.15 us/op 1.04
altair processAttestation - setStatus - 4/5 committees join 590.01 us/op 557.26 us/op 1.06
altair processAttestation - setStatus - 100% committees join 679.63 us/op 658.38 us/op 1.03
altair processBlock - 250000 vs - 7PWei normalcase 4.2341 ms/op 3.3717 ms/op 1.26
altair processBlock - 250000 vs - 7PWei normalcase hashState 16.879 ms/op 16.964 ms/op 1.00
altair processBlock - 250000 vs - 7PWei worstcase 25.481 ms/op 24.031 ms/op 1.06
altair processBlock - 250000 vs - 7PWei worstcase hashState 59.643 ms/op 65.117 ms/op 0.92
phase0 processBlock - 250000 vs - 7PWei normalcase 1.6603 ms/op 1.7994 ms/op 0.92
phase0 processBlock - 250000 vs - 7PWei worstcase 23.473 ms/op 21.344 ms/op 1.10
altair processEth1Data - 250000 vs - 7PWei normalcase 373.69 us/op 367.94 us/op 1.02
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 10.004 us/op 5.7320 us/op 1.75
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 46.703 us/op 54.294 us/op 0.86
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 13.855 us/op 16.065 us/op 0.86
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 9.0810 us/op 11.197 us/op 0.81
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 200.44 us/op 238.55 us/op 0.84
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 2.1953 ms/op 2.5312 ms/op 0.87
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 2.4171 ms/op 2.1198 ms/op 1.14
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 2.9460 ms/op 2.1207 ms/op 1.39
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 4.9709 ms/op 4.4411 ms/op 1.12
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.8017 ms/op 2.4907 ms/op 1.12
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 5.5658 ms/op 4.7161 ms/op 1.18
Tree 40 250000 create 381.17 ms/op 385.04 ms/op 0.99
Tree 40 250000 get(125000) 129.49 ns/op 127.44 ns/op 1.02
Tree 40 250000 set(125000) 1.2286 us/op 1.2068 us/op 1.02
Tree 40 250000 toArray() 16.426 ms/op 12.138 ms/op 1.35
Tree 40 250000 iterate all - toArray() + loop 17.122 ms/op 12.230 ms/op 1.40
Tree 40 250000 iterate all - get(i) 47.093 ms/op 41.835 ms/op 1.13
Array 250000 create 2.5126 ms/op 2.4017 ms/op 1.05
Array 250000 clone - spread 827.24 us/op 786.84 us/op 1.05
Array 250000 get(125000) 0.43800 ns/op 0.33300 ns/op 1.32
Array 250000 set(125000) 0.39600 ns/op 0.47100 ns/op 0.84
Array 250000 iterate all - loop 62.493 us/op 57.852 us/op 1.08
phase0 afterProcessEpoch - 250000 vs - 7PWei 42.197 ms/op 39.000 ms/op 1.08
Array.fill - length 1000000 3.1678 ms/op 3.1375 ms/op 1.01
Array push - length 1000000 11.233 ms/op 9.5786 ms/op 1.17
Array.get 0.22251 ns/op 0.21772 ns/op 1.02
Uint8Array.get 0.22189 ns/op 0.27366 ns/op 0.81
phase0 beforeProcessEpoch - 250000 vs - 7PWei 14.846 ms/op 14.429 ms/op 1.03
altair processEpoch - mainnet_e81889 265.79 ms/op 268.57 ms/op 0.99
mainnet_e81889 - altair beforeProcessEpoch 18.203 ms/op 19.756 ms/op 0.92
mainnet_e81889 - altair processJustificationAndFinalization 6.7400 us/op 6.9500 us/op 0.97
mainnet_e81889 - altair processInactivityUpdates 3.8273 ms/op 3.7240 ms/op 1.03
mainnet_e81889 - altair processRewardsAndPenalties 19.724 ms/op 17.884 ms/op 1.10
mainnet_e81889 - altair processRegistryUpdates 640.00 ns/op 751.00 ns/op 0.85
mainnet_e81889 - altair processSlashings 188.00 ns/op 258.00 ns/op 0.73
mainnet_e81889 - altair processEth1DataReset 193.00 ns/op 159.00 ns/op 1.21
mainnet_e81889 - altair processEffectiveBalanceUpdates 3.7292 ms/op 2.1738 ms/op 1.72
mainnet_e81889 - altair processSlashingsReset 884.00 ns/op 798.00 ns/op 1.11
mainnet_e81889 - altair processRandaoMixesReset 1.3620 us/op 1.2790 us/op 1.06
mainnet_e81889 - altair processHistoricalRootsUpdate 166.00 ns/op 162.00 ns/op 1.02
mainnet_e81889 - altair processParticipationFlagUpdates 532.00 ns/op 509.00 ns/op 1.05
mainnet_e81889 - altair processSyncCommitteeUpdates 133.00 ns/op 126.00 ns/op 1.06
mainnet_e81889 - altair afterProcessEpoch 44.737 ms/op 40.959 ms/op 1.09
capella processEpoch - mainnet_e217614 849.09 ms/op 839.13 ms/op 1.01
mainnet_e217614 - capella beforeProcessEpoch 64.591 ms/op 58.774 ms/op 1.10
mainnet_e217614 - capella processJustificationAndFinalization 6.4000 us/op 5.5230 us/op 1.16
mainnet_e217614 - capella processInactivityUpdates 17.344 ms/op 18.177 ms/op 0.95
mainnet_e217614 - capella processRewardsAndPenalties 109.03 ms/op 108.77 ms/op 1.00
mainnet_e217614 - capella processRegistryUpdates 6.0720 us/op 5.7900 us/op 1.05
mainnet_e217614 - capella processSlashings 167.00 ns/op 154.00 ns/op 1.08
mainnet_e217614 - capella processEth1DataReset 182.00 ns/op 178.00 ns/op 1.02
mainnet_e217614 - capella processEffectiveBalanceUpdates 16.345 ms/op 11.399 ms/op 1.43
mainnet_e217614 - capella processSlashingsReset 950.00 ns/op 983.00 ns/op 0.97
mainnet_e217614 - capella processRandaoMixesReset 1.2760 us/op 1.2940 us/op 0.99
mainnet_e217614 - capella processHistoricalRootsUpdate 205.00 ns/op 167.00 ns/op 1.23
mainnet_e217614 - capella processParticipationFlagUpdates 577.00 ns/op 509.00 ns/op 1.13
mainnet_e217614 - capella afterProcessEpoch 116.92 ms/op 113.81 ms/op 1.03
phase0 processEpoch - mainnet_e58758 285.22 ms/op 278.12 ms/op 1.03
mainnet_e58758 - phase0 beforeProcessEpoch 61.484 ms/op 59.170 ms/op 1.04
mainnet_e58758 - phase0 processJustificationAndFinalization 6.9740 us/op 5.5190 us/op 1.26
mainnet_e58758 - phase0 processRewardsAndPenalties 20.816 ms/op 25.187 ms/op 0.83
mainnet_e58758 - phase0 processRegistryUpdates 3.2820 us/op 3.4760 us/op 0.94
mainnet_e58758 - phase0 processSlashings 201.00 ns/op 164.00 ns/op 1.23
mainnet_e58758 - phase0 processEth1DataReset 179.00 ns/op 183.00 ns/op 0.98
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 2.0244 ms/op 930.19 us/op 2.18
mainnet_e58758 - phase0 processSlashingsReset 981.00 ns/op 887.00 ns/op 1.11
mainnet_e58758 - phase0 processRandaoMixesReset 1.3180 us/op 1.3310 us/op 0.99
mainnet_e58758 - phase0 processHistoricalRootsUpdate 188.00 ns/op 203.00 ns/op 0.93
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.0390 us/op 1.2860 us/op 0.81
mainnet_e58758 - phase0 afterProcessEpoch 36.416 ms/op 34.571 ms/op 1.05
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.4268 ms/op 1.8071 ms/op 0.79
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 4.3781 ms/op 1.6442 ms/op 2.66
altair processInactivityUpdates - 250000 normalcase 15.632 ms/op 12.696 ms/op 1.23
altair processInactivityUpdates - 250000 worstcase 16.807 ms/op 12.201 ms/op 1.38
phase0 processRegistryUpdates - 250000 normalcase 4.8620 us/op 4.4480 us/op 1.09
phase0 processRegistryUpdates - 250000 badcase_full_deposits 316.15 us/op 371.28 us/op 0.85
phase0 processRegistryUpdates - 250000 worstcase 0.5 71.006 ms/op 75.733 ms/op 0.94
altair processRewardsAndPenalties - 250000 normalcase 22.029 ms/op 16.023 ms/op 1.37
altair processRewardsAndPenalties - 250000 worstcase 20.672 ms/op 15.476 ms/op 1.34
phase0 getAttestationDeltas - 250000 normalcase 7.3327 ms/op 6.7041 ms/op 1.09
phase0 getAttestationDeltas - 250000 worstcase 6.1540 ms/op 6.7065 ms/op 0.92
phase0 processSlashings - 250000 worstcase 122.08 us/op 119.92 us/op 1.02
altair processSyncCommitteeUpdates - 250000 11.741 ms/op 10.334 ms/op 1.14
BeaconState.hashTreeRoot - No change 208.00 ns/op 228.00 ns/op 0.91
BeaconState.hashTreeRoot - 1 full validator 85.563 us/op 86.230 us/op 0.99
BeaconState.hashTreeRoot - 32 full validator 1.0414 ms/op 1.0438 ms/op 1.00
BeaconState.hashTreeRoot - 512 full validator 8.6706 ms/op 7.2997 ms/op 1.19
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 112.66 us/op 111.66 us/op 1.01
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 1.7599 ms/op 2.3996 ms/op 0.73
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 23.255 ms/op 17.652 ms/op 1.32
BeaconState.hashTreeRoot - 1 balances 102.66 us/op 106.64 us/op 0.96
BeaconState.hashTreeRoot - 32 balances 1.0574 ms/op 1.3363 ms/op 0.79
BeaconState.hashTreeRoot - 512 balances 6.9247 ms/op 5.6906 ms/op 1.22
BeaconState.hashTreeRoot - 250000 balances 159.13 ms/op 161.99 ms/op 0.98
aggregationBits - 2048 els - zipIndexesInBitList 21.625 us/op 20.874 us/op 1.04
regular array get 100000 times 25.020 us/op 24.605 us/op 1.02
wrappedArray get 100000 times 25.020 us/op 24.548 us/op 1.02
arrayWithProxy get 100000 times 14.281 ms/op 17.620 ms/op 0.81
ssz.Root.equals 24.472 ns/op 23.873 ns/op 1.03
byteArrayEquals 24.092 ns/op 23.421 ns/op 1.03
Buffer.compare 10.427 ns/op 10.169 ns/op 1.03
processSlot - 1 slots 12.326 us/op 9.7410 us/op 1.27
processSlot - 32 slots 2.8005 ms/op 2.5681 ms/op 1.09
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 5.9875 ms/op 4.6417 ms/op 1.29
getCommitteeAssignments - req 1 vs - 250000 vc 2.0520 ms/op 1.8681 ms/op 1.10
getCommitteeAssignments - req 100 vs - 250000 vc 3.9094 ms/op 3.6479 ms/op 1.07
getCommitteeAssignments - req 1000 vs - 250000 vc 4.0978 ms/op 3.9317 ms/op 1.04
findModifiedValidators - 10000 modified validators 859.63 ms/op 645.23 ms/op 1.33
findModifiedValidators - 1000 modified validators 494.61 ms/op 501.08 ms/op 0.99
findModifiedValidators - 100 modified validators 317.31 ms/op 301.86 ms/op 1.05
findModifiedValidators - 10 modified validators 284.62 ms/op 153.22 ms/op 1.86
findModifiedValidators - 1 modified validators 171.18 ms/op 158.66 ms/op 1.08
findModifiedValidators - no difference 199.72 ms/op 157.07 ms/op 1.27
migrate state 1500000 validators, 3400 modified, 2000 new 1.2384 s/op 910.89 ms/op 1.36
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.4400 ns/op 4.2700 ns/op 1.04
state getBlockRootAtSlot - 250000 vs - 7PWei 936.61 ns/op 533.27 ns/op 1.76
computeProposerIndex 100000 validators 1.6947 ms/op 1.6570 ms/op 1.02
getNextSyncCommitteeIndices 1000 validators 146.31 ms/op 121.89 ms/op 1.20
getNextSyncCommitteeIndices 10000 validators 151.23 ms/op 123.33 ms/op 1.23
getNextSyncCommitteeIndices 100000 validators 156.47 ms/op 122.46 ms/op 1.28
computeProposers - vc 250000 725.48 us/op 632.49 us/op 1.15
computeEpochShuffling - vc 250000 47.264 ms/op 42.403 ms/op 1.11
getNextSyncCommittee - vc 250000 12.737 ms/op 10.838 ms/op 1.18
nodejs block root to RootHex using toHex 159.86 ns/op 146.73 ns/op 1.09
nodejs block root to RootHex using toRootHex 91.584 ns/op 85.770 ns/op 1.07
nodejs fromHex(blob) 284.67 us/op 447.29 us/op 0.64
nodejs fromHexInto(blob) 727.63 us/op 703.64 us/op 1.03
nodejs block root to RootHex using the deprecated toHexString 595.00 ns/op 401.67 ns/op 1.48
nodejs byteArrayEquals 32 bytes (block root) 29.408 ns/op 28.330 ns/op 1.04
nodejs byteArrayEquals 48 bytes (pubkey) 42.020 ns/op 40.563 ns/op 1.04
nodejs byteArrayEquals 96 bytes (signature) 41.181 ns/op 39.669 ns/op 1.04
nodejs byteArrayEquals 1024 bytes 47.246 ns/op 45.404 ns/op 1.04
nodejs byteArrayEquals 131072 bytes (blob) 1.9394 us/op 1.8589 us/op 1.04
browser block root to RootHex using toHex 177.23 ns/op 161.48 ns/op 1.10
browser block root to RootHex using toRootHex 160.92 ns/op 153.49 ns/op 1.05
browser fromHex(blob) 1.3500 ms/op 1.1672 ms/op 1.16
browser fromHexInto(blob) 731.41 us/op 691.14 us/op 1.06
browser block root to RootHex using the deprecated toHexString 410.31 ns/op 361.55 ns/op 1.13
browser byteArrayEquals 32 bytes (block root) 32.499 ns/op 30.677 ns/op 1.06
browser byteArrayEquals 48 bytes (pubkey) 45.624 ns/op 42.741 ns/op 1.07
browser byteArrayEquals 96 bytes (signature) 89.433 ns/op 83.749 ns/op 1.07
browser byteArrayEquals 1024 bytes 852.27 ns/op 789.89 ns/op 1.08
browser byteArrayEquals 131072 bytes (blob) 107.72 us/op 99.564 us/op 1.08

by benchmarkbot/action

wemeetagain
wemeetagain previously approved these changes Mar 9, 2026
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

Copy link
Contributor

@twoeths twoeths left a comment

Choose a reason for hiding this comment

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

looks good to me
I'd also track the size of serializedCache to make sure we don't have an issue of dangling entries

delete(objs: object[]): void {
for (const obj of objs) {
this.map.delete(obj);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

also check if this.map.size === 0 then create a new WeakMap

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 isn't possible, there is no reliable way to get the size of WeakMap, we can only track entries manually but this would be inaccurate since we wouldn't deduct dangling entries that are dropped automatically

there is also no place in the code where we could do the previous clear() and create a new WeakMap but I don't really think this is necessary, if we want more manual control over the stored items we should just use a normal Map

I would rather keep track of how many items the BlockInput's added to SerializedCache and add more explicit clean up there if entries are pruned automatically to make sure we explicitly clean up dangling BlockInput's

Copy link
Member Author

Choose a reason for hiding this comment

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

see 427cb03, I coupled the serialized cache pruning more closely to block input so there is less of a chance to have dangling entries

@nflaig
Copy link
Member Author

nflaig commented Mar 10, 2026

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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