Skip to content

refactor: generalize NetworkProcessor awaiting-block mechanism for all gossip types - #9059

Merged
ensi321 merged 4 commits into
unstablefrom
te/refactor_network_processor
Mar 23, 2026
Merged

refactor: generalize NetworkProcessor awaiting-block mechanism for all gossip types#9059
ensi321 merged 4 commits into
unstablefrom
te/refactor_network_processor

Conversation

@twoeths

@twoeths twoeths commented Mar 18, 2026

Copy link
Copy Markdown
Member

Motivation

This PR is a step toward #9025 where we enhance NetworkProcessor for GLOAS.

The network processor's "await unknown block" mechanism was originally built specifically for attestation messages. As we add support for more gossip types that depend on block availability (and eventually payload envelopes in GLOAS), the code needs to be generalized before those new types are introduced.

Description

Generalizes the network processor's unknown-block-waiting mechanism from attestation-specific to all gossip message types:

  • Rename searchUnknownSlotRootsearchUnknownBlock across INetwork, Network, NetworkProcessor, and all call sites
  • Flatten the two-level awaitingGossipsubMessagesByRootBySlot: MapDef<Slot, MapDef<RootHex, Set<...>>> into a single awaitingBlockByRoot: MapDef<RootHex, Set<...>>, using a separate unknownBlocksBySlot map for slot-based pruning
  • Rename metric group reprocessGossipAttestationsawaitingBlockGossipMessages; add a topic label so per-topic breakdown is visible in dashboards
  • Add BlockInputSource.network_processor to distinguish messages queued by the processor itself
  • Update Grafana dashboard panels to use the new metric names and {{topic}} legend format
  • Changed:
    • we cannot track pending messages by slot by root because message slot is not the same to block slot starting gloas
    • based on that, expiry windows are changed from 1 slot to 3 slots, to prepare for gloas. I think this does not affect much because we should have find the block in the same slot, if not it'll never arrive.

AI Assistance Disclosure

Used Claude Code to assist with implementation.

…ll gossip messages

- Rename `searchUnknownSlotRoot` → `searchUnknownBlock` across network interface
- Flatten `awaitingGossipsubMessagesByRootBySlot` (MapDef of MapDef) into `awaitingBlockByRoot` (single MapDef) for simpler lookups
- Rename `unknownRootsBySlot` → `unknownBlocksBySlot` for clarity
- Rename metrics `reprocessGossipAttestations` → `awaitingBlockGossipMessages` with added `topic` label
- Add `BlockInputSource.network_processor` to label messages queued internally
- Update dashboard panels to use new metric names and topic breakdowns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
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 refactors the NetworkProcessor to generalize its handling of gossip messages that depend on the availability of an unknown block. Previously tailored for attestation messages, the updated system now provides a more flexible and scalable approach to managing messages that require a block to be processed before they can be fully validated. This change is a foundational step towards supporting a wider array of gossip types and future protocol upgrades, ensuring that the network layer can efficiently queue and reprocess messages as their dependencies are met.

Highlights

  • Generalization of Unknown Block Awaiting Mechanism: The NetworkProcessor's mechanism for awaiting unknown blocks has been generalized from being specific to attestation messages to support all gossip message types. This prepares the system for new gossip types and future enhancements like GLOAS.
  • Renaming and Refactoring: The function searchUnknownSlotRoot has been renamed to searchUnknownBlock across INetwork, Network, NetworkProcessor, and all its call sites for better clarity and generalization. The two-level map awaitingGossipsubMessagesByRootBySlot was flattened into awaitingBlockByRoot, with a new unknownBlocksBySlot map introduced for slot-based pruning.
  • Metrics and Monitoring Updates: The metric group reprocessGossipAttestations has been renamed to awaitingBlockGossipMessages. A topic label was added to these metrics to enable per-topic breakdown in dashboards, and Grafana panels were updated to reflect these new names and legend formats.
  • New Block Input Source: A new BlockInputSource.network_processor enum member was added to distinguish messages queued by the network processor itself.

🧠 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.

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.

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request does a great job of generalizing the awaiting-block mechanism in the NetworkProcessor, which is a solid step towards supporting more gossip types. The refactoring simplifies the data structures by flattening the awaiting messages map and improves metrics by adding more granularity with the topic label. The code is cleaner and more maintainable as a result. I've found one potential issue where the generic message age check might be too strict for Deneb attestations, possibly leading to the rejection of valid messages. Please see my detailed comment.

Comment thread packages/beacon-node/src/network/processor/index.ts
@github-actions

github-actions Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: bd6099a Previous: d73eccf Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 1.1423 ms/op 1.0433 ms/op 1.09
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 38.012 us/op 35.272 us/op 1.08
BLS verify - blst 1.3080 ms/op 1.3011 ms/op 1.01
BLS verifyMultipleSignatures 3 - blst 1.9179 ms/op 2.5309 ms/op 0.76
BLS verifyMultipleSignatures 8 - blst 2.5734 ms/op 2.4777 ms/op 1.04
BLS verifyMultipleSignatures 32 - blst 8.3371 ms/op 7.3886 ms/op 1.13
BLS verifyMultipleSignatures 64 - blst 13.020 ms/op 10.764 ms/op 1.21
BLS verifyMultipleSignatures 128 - blst 18.781 ms/op 17.222 ms/op 1.09
BLS deserializing 10000 signatures 724.84 ms/op 691.85 ms/op 1.05
BLS deserializing 100000 signatures 7.3497 s/op 6.8929 s/op 1.07
BLS verifyMultipleSignatures - same message - 3 - blst 1.0281 ms/op 853.42 us/op 1.20
BLS verifyMultipleSignatures - same message - 8 - blst 1.1199 ms/op 1.0659 ms/op 1.05
BLS verifyMultipleSignatures - same message - 32 - blst 1.8388 ms/op 1.8221 ms/op 1.01
BLS verifyMultipleSignatures - same message - 64 - blst 3.1142 ms/op 2.7490 ms/op 1.13
BLS verifyMultipleSignatures - same message - 128 - blst 5.2013 ms/op 4.5499 ms/op 1.14
BLS aggregatePubkeys 32 - blst 22.197 us/op 19.318 us/op 1.15
BLS aggregatePubkeys 128 - blst 79.078 us/op 69.282 us/op 1.14
getSlashingsAndExits - default max 85.415 us/op 71.067 us/op 1.20
getSlashingsAndExits - 2k 345.45 us/op 305.19 us/op 1.13
isKnown best case - 1 super set check 224.00 ns/op 214.00 ns/op 1.05
isKnown normal case - 2 super set checks 240.00 ns/op 216.00 ns/op 1.11
isKnown worse case - 16 super set checks 227.00 ns/op 215.00 ns/op 1.06
validate api signedAggregateAndProof - struct 1.6661 ms/op 1.7209 ms/op 0.97
validate gossip signedAggregateAndProof - struct 1.7317 ms/op 1.7204 ms/op 1.01
batch validate gossip attestation - vc 640000 - chunk 32 137.09 us/op 146.52 us/op 0.94
batch validate gossip attestation - vc 640000 - chunk 64 117.73 us/op 103.91 us/op 1.13
batch validate gossip attestation - vc 640000 - chunk 128 108.04 us/op 95.899 us/op 1.13
batch validate gossip attestation - vc 640000 - chunk 256 101.45 us/op 91.729 us/op 1.11
bytes32 toHexString 384.00 ns/op 357.00 ns/op 1.08
bytes32 Buffer.toString(hex) 329.00 ns/op 293.00 ns/op 1.12
bytes32 Buffer.toString(hex) from Uint8Array 416.00 ns/op 389.00 ns/op 1.07
bytes32 Buffer.toString(hex) + 0x 281.00 ns/op 234.00 ns/op 1.20
Return object 10000 times 0.24890 ns/op 0.22730 ns/op 1.10
Throw Error 10000 times 4.7156 us/op 4.1523 us/op 1.14
toHex 146.93 ns/op 130.36 ns/op 1.13
Buffer.from 144.59 ns/op 131.33 ns/op 1.10
shared Buffer 87.432 ns/op 77.259 ns/op 1.13
fastMsgIdFn sha256 / 200 bytes 2.0870 us/op 1.8570 us/op 1.12
fastMsgIdFn h32 xxhash / 200 bytes 208.00 ns/op 257.00 ns/op 0.81
fastMsgIdFn h64 xxhash / 200 bytes 320.00 ns/op 341.00 ns/op 0.94
fastMsgIdFn sha256 / 1000 bytes 7.2110 us/op 5.8820 us/op 1.23
fastMsgIdFn h32 xxhash / 1000 bytes 314.00 ns/op 275.00 ns/op 1.14
fastMsgIdFn h64 xxhash / 1000 bytes 358.00 ns/op 319.00 ns/op 1.12
fastMsgIdFn sha256 / 10000 bytes 62.025 us/op 52.947 us/op 1.17
fastMsgIdFn h32 xxhash / 10000 bytes 1.6480 us/op 1.5220 us/op 1.08
fastMsgIdFn h64 xxhash / 10000 bytes 1.1310 us/op 1.0520 us/op 1.08
send data - 1000 256B messages 5.3801 ms/op 4.9341 ms/op 1.09
send data - 1000 512B messages 5.1601 ms/op 4.5773 ms/op 1.13
send data - 1000 1024B messages 6.3860 ms/op 5.5295 ms/op 1.15
send data - 1000 1200B messages 6.4987 ms/op 5.4201 ms/op 1.20
send data - 1000 2048B messages 7.3464 ms/op 5.7054 ms/op 1.29
send data - 1000 4096B messages 8.2224 ms/op 7.8407 ms/op 1.05
send data - 1000 16384B messages 45.036 ms/op 39.136 ms/op 1.15
send data - 1000 65536B messages 199.78 ms/op 82.732 ms/op 2.41
enrSubnets - fastDeserialize 64 bits 1.0740 us/op 863.00 ns/op 1.24
enrSubnets - ssz BitVector 64 bits 471.00 ns/op 507.00 ns/op 0.93
enrSubnets - fastDeserialize 4 bits 185.00 ns/op 130.00 ns/op 1.42
enrSubnets - ssz BitVector 4 bits 380.00 ns/op 338.00 ns/op 1.12
prioritizePeers score -10:0 att 32-0.1 sync 2-0 264.38 us/op 319.27 us/op 0.83
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 286.20 us/op 353.46 us/op 0.81
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 532.23 us/op 385.37 us/op 1.38
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 868.11 us/op 703.93 us/op 1.23
prioritizePeers score 0:0 att 64-1 sync 4-1 1.2193 ms/op 828.13 us/op 1.47
array of 16000 items push then shift 1.7661 us/op 1.5861 us/op 1.11
LinkedList of 16000 items push then shift 8.6160 ns/op 7.2720 ns/op 1.18
array of 16000 items push then pop 90.865 ns/op 73.780 ns/op 1.23
LinkedList of 16000 items push then pop 8.5540 ns/op 7.0880 ns/op 1.21
array of 24000 items push then shift 2.8641 us/op 2.3554 us/op 1.22
LinkedList of 24000 items push then shift 8.8050 ns/op 7.3580 ns/op 1.20
array of 24000 items push then pop 119.95 ns/op 105.45 ns/op 1.14
LinkedList of 24000 items push then pop 8.1990 ns/op 7.1220 ns/op 1.15
intersect bitArray bitLen 8 6.6670 ns/op 5.6920 ns/op 1.17
intersect array and set length 8 38.514 ns/op 33.091 ns/op 1.16
intersect bitArray bitLen 128 32.797 ns/op 28.458 ns/op 1.15
intersect array and set length 128 622.33 ns/op 545.73 ns/op 1.14
bitArray.getTrueBitIndexes() bitLen 128 1.3680 us/op 1.0250 us/op 1.33
bitArray.getTrueBitIndexes() bitLen 248 2.2560 us/op 1.7890 us/op 1.26
bitArray.getTrueBitIndexes() bitLen 512 4.4590 us/op 3.6530 us/op 1.22
Full columns - reconstruct all 6 blobs 216.36 us/op 247.44 us/op 0.87
Full columns - reconstruct half of the blobs out of 6 110.69 us/op 100.77 us/op 1.10
Full columns - reconstruct single blob out of 6 34.291 us/op 31.744 us/op 1.08
Half columns - reconstruct all 6 blobs 318.55 ms/op 263.38 ms/op 1.21
Half columns - reconstruct half of the blobs out of 6 163.10 ms/op 133.23 ms/op 1.22
Half columns - reconstruct single blob out of 6 60.870 ms/op 48.741 ms/op 1.25
Full columns - reconstruct all 10 blobs 341.97 us/op 376.33 us/op 0.91
Full columns - reconstruct half of the blobs out of 10 195.26 us/op 152.89 us/op 1.28
Full columns - reconstruct single blob out of 10 53.653 us/op 30.963 us/op 1.73
Half columns - reconstruct all 10 blobs 551.95 ms/op 437.37 ms/op 1.26
Half columns - reconstruct half of the blobs out of 10 280.43 ms/op 222.02 ms/op 1.26
Half columns - reconstruct single blob out of 10 61.651 ms/op 48.448 ms/op 1.27
Full columns - reconstruct all 20 blobs 712.91 us/op 1.1739 ms/op 0.61
Full columns - reconstruct half of the blobs out of 20 355.11 us/op 294.88 us/op 1.20
Full columns - reconstruct single blob out of 20 35.117 us/op 30.897 us/op 1.14
Half columns - reconstruct all 20 blobs 1.1112 s/op 870.47 ms/op 1.28
Half columns - reconstruct half of the blobs out of 20 556.44 ms/op 434.22 ms/op 1.28
Half columns - reconstruct single blob out of 20 62.901 ms/op 49.252 ms/op 1.28
Set add up to 64 items then delete first 3.6691 us/op 1.9979 us/op 1.84
OrderedSet add up to 64 items then delete first 4.8466 us/op 2.9573 us/op 1.64
Set add up to 64 items then delete last 3.5093 us/op 2.2440 us/op 1.56
OrderedSet add up to 64 items then delete last 4.9110 us/op 3.2475 us/op 1.51
Set add up to 64 items then delete middle 3.2444 us/op 2.2979 us/op 1.41
OrderedSet add up to 64 items then delete middle 6.7280 us/op 4.8678 us/op 1.38
Set add up to 128 items then delete first 6.6858 us/op 4.7563 us/op 1.41
OrderedSet add up to 128 items then delete first 10.079 us/op 7.1202 us/op 1.42
Set add up to 128 items then delete last 6.3753 us/op 4.6078 us/op 1.38
OrderedSet add up to 128 items then delete last 9.3608 us/op 6.6106 us/op 1.42
Set add up to 128 items then delete middle 6.2332 us/op 4.4843 us/op 1.39
OrderedSet add up to 128 items then delete middle 17.312 us/op 12.806 us/op 1.35
Set add up to 256 items then delete first 13.641 us/op 9.8468 us/op 1.39
OrderedSet add up to 256 items then delete first 19.976 us/op 14.971 us/op 1.33
Set add up to 256 items then delete last 11.875 us/op 9.3957 us/op 1.26
OrderedSet add up to 256 items then delete last 17.665 us/op 13.683 us/op 1.29
Set add up to 256 items then delete middle 11.777 us/op 9.3455 us/op 1.26
OrderedSet add up to 256 items then delete middle 52.189 us/op 39.809 us/op 1.31
pass gossip attestations to forkchoice per slot 630.57 us/op 492.34 us/op 1.28
computeDeltas 1400000 validators 0% inactive 16.377 ms/op 14.236 ms/op 1.15
computeDeltas 1400000 validators 10% inactive 16.857 ms/op 13.335 ms/op 1.26
computeDeltas 1400000 validators 20% inactive 14.876 ms/op 12.412 ms/op 1.20
computeDeltas 1400000 validators 50% inactive 11.662 ms/op 9.6370 ms/op 1.21
computeDeltas 2100000 validators 0% inactive 27.141 ms/op 21.377 ms/op 1.27
computeDeltas 2100000 validators 10% inactive 26.836 ms/op 21.561 ms/op 1.24
computeDeltas 2100000 validators 20% inactive 23.990 ms/op 18.609 ms/op 1.29
computeDeltas 2100000 validators 50% inactive 18.126 ms/op 14.470 ms/op 1.25
altair processAttestation - setStatus - 1/6 committees join 733.00 ns/op 536.00 ns/op 1.37
altair processAttestation - setStatus - 1/3 committees join 1.1300 us/op 882.00 ns/op 1.28
altair processAttestation - setStatus - 1/2 committees join 1.6290 us/op 1.2490 us/op 1.30
altair processAttestation - setStatus - 2/3 committees join 2.0380 us/op 1.4740 us/op 1.38
altair processAttestation - setStatus - 4/5 committees join 2.1610 us/op 1.7570 us/op 1.23
altair processAttestation - setStatus - 100% committees join 2.3600 us/op 2.0670 us/op 1.14
phase0 processBlock - 250000 vs - 7PWei normalcase 2.7649 ms/op 2.1023 ms/op 1.32
phase0 processBlock - 250000 vs - 7PWei worstcase 31.218 ms/op 29.022 ms/op 1.08
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 11.133 us/op 9.1750 us/op 1.21
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 63.338 us/op 51.503 us/op 1.23
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 31.193 us/op 16.289 us/op 1.91
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 12.456 us/op 8.2100 us/op 1.52
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 225.18 us/op 225.97 us/op 1.00
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 2.0043 ms/op 1.4534 ms/op 1.38
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 3.0561 ms/op 2.0065 ms/op 1.52
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 3.3529 ms/op 1.9749 ms/op 1.70
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 5.0742 ms/op 4.2150 ms/op 1.20
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 3.0580 ms/op 2.4527 ms/op 1.25
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 6.2100 ms/op 4.9194 ms/op 1.26
Tree 40 250000 create 476.10 ms/op 377.54 ms/op 1.26
Tree 40 250000 get(125000) 178.90 ns/op 129.64 ns/op 1.38
Tree 40 250000 set(125000) 1.8682 us/op 1.2646 us/op 1.48
Tree 40 250000 toArray() 22.813 ms/op 12.698 ms/op 1.80
Tree 40 250000 iterate all - toArray() + loop 20.697 ms/op 12.823 ms/op 1.61
Tree 40 250000 iterate all - get(i) 68.130 ms/op 43.772 ms/op 1.56
Array 250000 create 4.0182 ms/op 2.4901 ms/op 1.61
Array 250000 clone - spread 1.2878 ms/op 809.16 us/op 1.59
Array 250000 get(125000) 0.70500 ns/op 0.34000 ns/op 2.07
Array 250000 set(125000) 0.47600 ns/op 0.33700 ns/op 1.41
Array 250000 iterate all - loop 74.751 us/op 59.976 us/op 1.25
phase0 afterProcessEpoch - 250000 vs - 7PWei 54.396 ms/op 41.342 ms/op 1.32
Array.fill - length 1000000 3.6433 ms/op 2.9579 ms/op 1.23
Array push - length 1000000 11.436 ms/op 10.484 ms/op 1.09
Array.get 0.26339 ns/op 0.21194 ns/op 1.24
Uint8Array.get 0.28317 ns/op 0.22478 ns/op 1.26
phase0 beforeProcessEpoch - 250000 vs - 7PWei 18.595 ms/op 13.918 ms/op 1.34
altair processEpoch - mainnet_e81889 368.22 ms/op 330.96 ms/op 1.11
mainnet_e81889 - altair beforeProcessEpoch 24.826 ms/op 24.937 ms/op 1.00
mainnet_e81889 - altair processJustificationAndFinalization 7.4700 us/op 6.6240 us/op 1.13
mainnet_e81889 - altair processInactivityUpdates 8.0180 ms/op 3.6525 ms/op 2.20
mainnet_e81889 - altair processRewardsAndPenalties 36.503 ms/op 16.385 ms/op 2.23
mainnet_e81889 - altair processRegistryUpdates 1.3650 us/op 615.00 ns/op 2.22
mainnet_e81889 - altair processSlashings 347.00 ns/op 212.00 ns/op 1.64
mainnet_e81889 - altair processEth1DataReset 323.00 ns/op 163.00 ns/op 1.98
mainnet_e81889 - altair processEffectiveBalanceUpdates 5.8240 ms/op 1.6727 ms/op 3.48
mainnet_e81889 - altair processSlashingsReset 1.5430 us/op 837.00 ns/op 1.84
mainnet_e81889 - altair processRandaoMixesReset 2.0630 us/op 1.7510 us/op 1.18
mainnet_e81889 - altair processHistoricalRootsUpdate 314.00 ns/op 159.00 ns/op 1.97
mainnet_e81889 - altair processParticipationFlagUpdates 789.00 ns/op 490.00 ns/op 1.61
mainnet_e81889 - altair processSyncCommitteeUpdates 202.00 ns/op 125.00 ns/op 1.62
mainnet_e81889 - altair afterProcessEpoch 80.244 ms/op 43.995 ms/op 1.82
capella processEpoch - mainnet_e217614 1.3502 s/op 917.48 ms/op 1.47
mainnet_e217614 - capella beforeProcessEpoch 113.22 ms/op 55.485 ms/op 2.04
mainnet_e217614 - capella processJustificationAndFinalization 8.9240 us/op 7.3410 us/op 1.22
mainnet_e217614 - capella processInactivityUpdates 25.317 ms/op 15.614 ms/op 1.62
mainnet_e217614 - capella processRewardsAndPenalties 152.54 ms/op 113.52 ms/op 1.34
mainnet_e217614 - capella processRegistryUpdates 8.2280 us/op 5.6650 us/op 1.45
mainnet_e217614 - capella processSlashings 230.00 ns/op 163.00 ns/op 1.41
mainnet_e217614 - capella processEth1DataReset 229.00 ns/op 153.00 ns/op 1.50
mainnet_e217614 - capella processEffectiveBalanceUpdates 20.069 ms/op 10.911 ms/op 1.84
mainnet_e217614 - capella processSlashingsReset 1.4950 us/op 812.00 ns/op 1.84
mainnet_e217614 - capella processRandaoMixesReset 2.0080 us/op 1.1570 us/op 1.74
mainnet_e217614 - capella processHistoricalRootsUpdate 281.00 ns/op 160.00 ns/op 1.76
mainnet_e217614 - capella processParticipationFlagUpdates 777.00 ns/op 457.00 ns/op 1.70
mainnet_e217614 - capella afterProcessEpoch 166.30 ms/op 115.40 ms/op 1.44
phase0 processEpoch - mainnet_e58758 354.00 ms/op 252.49 ms/op 1.40
mainnet_e58758 - phase0 beforeProcessEpoch 80.064 ms/op 56.537 ms/op 1.42
mainnet_e58758 - phase0 processJustificationAndFinalization 9.1850 us/op 5.4360 us/op 1.69
mainnet_e58758 - phase0 processRewardsAndPenalties 26.049 ms/op 18.856 ms/op 1.38
mainnet_e58758 - phase0 processRegistryUpdates 3.8290 us/op 2.8020 us/op 1.37
mainnet_e58758 - phase0 processSlashings 324.00 ns/op 190.00 ns/op 1.71
mainnet_e58758 - phase0 processEth1DataReset 268.00 ns/op 156.00 ns/op 1.72
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 2.6728 ms/op 1.0990 ms/op 2.43
mainnet_e58758 - phase0 processSlashingsReset 1.4370 us/op 785.00 ns/op 1.83
mainnet_e58758 - phase0 processRandaoMixesReset 1.6720 us/op 1.1150 us/op 1.50
mainnet_e58758 - phase0 processHistoricalRootsUpdate 258.00 ns/op 189.00 ns/op 1.37
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.4190 us/op 803.00 ns/op 1.77
mainnet_e58758 - phase0 afterProcessEpoch 60.109 ms/op 35.237 ms/op 1.71
phase0 processEffectiveBalanceUpdates - 250000 normalcase 2.5988 ms/op 1.5966 ms/op 1.63
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 3.1142 ms/op 2.0156 ms/op 1.55
altair processInactivityUpdates - 250000 normalcase 185.83 us/op 85.904 us/op 2.16
altair processInactivityUpdates - 250000 worstcase 81.478 us/op 64.075 us/op 1.27
phase0 processRegistryUpdates - 250000 normalcase 7.5290 us/op 10.830 us/op 0.70
phase0 processRegistryUpdates - 250000 badcase_full_deposits 379.07 us/op 354.30 us/op 1.07
phase0 processRegistryUpdates - 250000 worstcase 0.5 130.83 ms/op 68.069 ms/op 1.92
altair processRewardsAndPenalties - 250000 normalcase 127.83 us/op 126.62 us/op 1.01
altair processRewardsAndPenalties - 250000 worstcase 100.93 us/op 122.43 us/op 0.82
phase0 getAttestationDeltas - 250000 normalcase 8.6274 ms/op 5.7927 ms/op 1.49
phase0 getAttestationDeltas - 250000 worstcase 9.3467 ms/op 5.7458 ms/op 1.63
phase0 processSlashings - 250000 worstcase 149.68 us/op 128.44 us/op 1.17
altair processSyncCommitteeUpdates - 250000 13.995 ms/op 8.5123 ms/op 1.64
BeaconState.hashTreeRoot - No change 355.00 ns/op 241.00 ns/op 1.47
BeaconState.hashTreeRoot - 1 full validator 111.75 us/op 103.16 us/op 1.08
BeaconState.hashTreeRoot - 32 full validator 1.1561 ms/op 1.0309 ms/op 1.12
BeaconState.hashTreeRoot - 512 full validator 11.609 ms/op 9.5256 ms/op 1.22
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 164.72 us/op 108.08 us/op 1.52
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.1405 ms/op 1.5591 ms/op 1.37
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 27.554 ms/op 16.688 ms/op 1.65
BeaconState.hashTreeRoot - 1 balances 124.36 us/op 63.993 us/op 1.94
BeaconState.hashTreeRoot - 32 balances 1.0189 ms/op 958.51 us/op 1.06
BeaconState.hashTreeRoot - 512 balances 7.5446 ms/op 6.3582 ms/op 1.19
BeaconState.hashTreeRoot - 250000 balances 197.01 ms/op 177.19 ms/op 1.11
aggregationBits - 2048 els - zipIndexesInBitList 32.255 us/op 20.090 us/op 1.61
regular array get 100000 times 40.869 us/op 23.585 us/op 1.73
wrappedArray get 100000 times 40.794 us/op 23.581 us/op 1.73
arrayWithProxy get 100000 times 28.348 ms/op 14.024 ms/op 2.02
ssz.Root.equals 39.710 ns/op 22.698 ns/op 1.75
byteArrayEquals 37.470 ns/op 22.405 ns/op 1.67
Buffer.compare 16.015 ns/op 10.273 ns/op 1.56
processSlot - 1 slots 14.675 us/op 12.729 us/op 1.15
processSlot - 32 slots 2.7997 ms/op 2.2073 ms/op 1.27
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.1710 ms/op 3.1438 ms/op 1.33
getCommitteeAssignments - req 1 vs - 250000 vc 2.6263 ms/op 1.8480 ms/op 1.42
getCommitteeAssignments - req 100 vs - 250000 vc 4.9669 ms/op 3.6033 ms/op 1.38
getCommitteeAssignments - req 1000 vs - 250000 vc 5.4107 ms/op 3.8810 ms/op 1.39
findModifiedValidators - 10000 modified validators 598.37 ms/op 487.03 ms/op 1.23
findModifiedValidators - 1000 modified validators 470.58 ms/op 432.80 ms/op 1.09
findModifiedValidators - 100 modified validators 262.53 ms/op 221.53 ms/op 1.19
findModifiedValidators - 10 modified validators 168.53 ms/op 137.90 ms/op 1.22
findModifiedValidators - 1 modified validators 171.03 ms/op 131.56 ms/op 1.30
findModifiedValidators - no difference 151.68 ms/op 154.48 ms/op 0.98
migrate state 1500000 validators, 3400 modified, 2000 new 440.27 ms/op 393.36 ms/op 1.12
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 6.3800 ns/op 4.1100 ns/op 1.55
state getBlockRootAtSlot - 250000 vs - 7PWei 632.18 ns/op 523.92 ns/op 1.21
computeProposerIndex 100000 validators 1.9721 ms/op 1.5232 ms/op 1.29
getNextSyncCommitteeIndices 1000 validators 4.2501 ms/op 3.3901 ms/op 1.25
getNextSyncCommitteeIndices 10000 validators 4.2200 ms/op 3.3898 ms/op 1.24
getNextSyncCommitteeIndices 100000 validators 4.2451 ms/op 3.3677 ms/op 1.26
computeProposers - vc 250000 769.03 us/op 621.57 us/op 1.24
computeEpochShuffling - vc 250000 59.124 ms/op 41.921 ms/op 1.41
getNextSyncCommittee - vc 250000 14.837 ms/op 10.354 ms/op 1.43
nodejs block root to RootHex using toHex 182.99 ns/op 134.00 ns/op 1.37
nodejs block root to RootHex using toRootHex 108.05 ns/op 84.245 ns/op 1.28
nodejs fromHex(blob) 482.29 us/op 300.68 us/op 1.60
nodejs fromHexInto(blob) 845.93 us/op 681.55 us/op 1.24
nodejs block root to RootHex using the deprecated toHexString 700.80 ns/op 552.80 ns/op 1.27
nodejs byteArrayEquals 32 bytes (block root) 33.829 ns/op 27.371 ns/op 1.24
nodejs byteArrayEquals 48 bytes (pubkey) 48.708 ns/op 39.141 ns/op 1.24
nodejs byteArrayEquals 96 bytes (signature) 47.155 ns/op 38.852 ns/op 1.21
nodejs byteArrayEquals 1024 bytes 54.622 ns/op 43.858 ns/op 1.25
nodejs byteArrayEquals 131072 bytes (blob) 2.2210 us/op 1.8069 us/op 1.23
browser block root to RootHex using toHex 333.60 ns/op 157.10 ns/op 2.12
browser block root to RootHex using toRootHex 185.87 ns/op 148.03 ns/op 1.26
browser fromHex(blob) 1.4087 ms/op 1.1418 ms/op 1.23
browser fromHexInto(blob) 870.60 us/op 708.88 us/op 1.23
browser block root to RootHex using the deprecated toHexString 725.14 ns/op 417.09 ns/op 1.74
browser byteArrayEquals 32 bytes (block root) 36.002 ns/op 31.496 ns/op 1.14
browser byteArrayEquals 48 bytes (pubkey) 48.952 ns/op 43.817 ns/op 1.12
browser byteArrayEquals 96 bytes (signature) 96.042 ns/op 85.790 ns/op 1.12
browser byteArrayEquals 1024 bytes 929.19 ns/op 806.72 ns/op 1.15
browser byteArrayEquals 131072 bytes (blob) 114.62 us/op 101.90 us/op 1.12

by benchmarkbot/action

@twoeths
twoeths marked this pull request as ready for review March 18, 2026 07:36
@twoeths
twoeths requested a review from a team as a code owner March 18, 2026 07:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a142e115e7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/beacon-node/src/network/processor/index.ts Outdated
Comment thread packages/beacon-node/src/network/processor/index.ts Outdated
name: "lodestar_awaiting_block_gossip_messages_wait_time_reject_seconds",
help: "Time to wait for unknown block before being rejected",
labelNames: ["reason"],
labelNames: ["reason", "topic"],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I suspect this is fine since it's a gauge, but flagging the 2 labels here

Comment thread packages/beacon-node/src/network/processor/index.ts

@ensi321 ensi321 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are stale comments in createExtractBlockSlotRootFns. Need to update that too.

/**
* Extract the slot and block root of a gossip message form serialized data.
* Only applicable for beacon_attestation and beacon_aggregate_and_proof topics.
*/

Comment thread packages/beacon-node/src/network/processor/index.ts Outdated
for (const [slot, roots] of this.unknownBlocksBySlot) {
if (slot > minSlot) continue;
for (const rootHex of roots) {
const gossipMessagesByRoot = this.awaitingBlockByRoot.get(rootHex);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

gossipMessagesByRoot is a set of gossip messages. The naming suggests it is a map but it is not. Consider gossipMessages or something similar

Comment thread packages/beacon-node/src/network/processor/index.ts Outdated
metrics.gossipValidationQueue.concurrency.set({topic}, this.gossipTopicConcurrency[topic]);
}
metrics.reprocessGossipAttestations.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);
metrics.awaitingBlockGossipMessages.countPerSlot.set(this.unknownBlockGossipsubMessagesCount);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Essentially this metric is just to track total number of messages sitting in awaitingBlockByRoot. I find having a variable unknownBlockGossipsubMessagesCount and we increment/decrement in several places is error prone.

Can we add a function and just track this instead?

  private get unknownBlockGossipsubMessagesCount(): number {
    let count = 0;                                                                                       
    for (const messages of this.awaitingBlockByRoot.values()) {                                        
      count += messages.size;                                                                            
    }
    return count;                                                                                        
  }    

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

agree 👍

Comment thread packages/beacon-node/src/network/processor/index.ts Outdated

@wemeetagain wemeetagain left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good

@ensi321
ensi321 merged commit 4118b5b into unstable Mar 23, 2026
25 of 26 checks passed
@ensi321
ensi321 deleted the te/refactor_network_processor branch March 23, 2026 22:59
@codecov

codecov Bot commented Mar 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.36%. Comparing base (1ff95ea) to head (305cc7a).
⚠️ Report is 22 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #9059      +/-   ##
============================================
+ Coverage     52.32%   52.36%   +0.04%     
============================================
  Files           848      848              
  Lines         62326    62234      -92     
  Branches       4572     4572              
============================================
- Hits          32612    32589      -23     
+ Misses        29649    29580      -69     
  Partials         65       65              
🚀 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.

lodekeeper added a commit to lodekeeper/lodestar that referenced this pull request Mar 23, 2026
Resolve 1 conflict in network/processor/index.ts:
- PR ChainSafe#9059 refactored awaiting-block mechanism for all gossip types
- Keep unstable's refactored structure, add back ePBS execution_payload bypass
@wemeetagain

Copy link
Copy Markdown
Member

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