feat(beacon): score gossipsub peers with lighthouse's parameters - #656
Draft
MegaRedHand wants to merge 2 commits into
Draft
MegaRedHand wants to merge 2 commits into
MegaRedHand wants to merge 2 commits into
Conversation
The beacon wire had no way to push out peers that send invalid messages, break IWANT promises or cannot keep up: gossipsub kept exchanging with all of them, and the connection cap was the only bound on bad peers. The parameters are lighthouse's, ported formula for formula. Teku, Lodestar and Grandine run the same ones, so a score means here what it means on most of mainnet. Two deviations: - Mesh-delivery scoring (P3) is off while the head lags the wall clock by more than four slots, and back on only after an epoch within that. Lighthouse joins these topics only once synced. This node subscribes at startup and, while catching up, ignores every aggregate voting for a block it has not imported; a mesh peer credited with no aggregates scores below the graylist, so a restart would graylist the whole aggregate mesh for our own lag. SyncStatus cannot be the gate: its network-stall rule reported synced through a 98-slot catch-up on the mainnet follower. - Peers below the graylist are disconnected every 10 s. Gossipsub alone only ignores them, and they keep a connection slot. Columns, sync committee contributions and BLS changes stay unscored. This node ignores every contribution and change for lack of a consumer, so P3 there would penalize the mesh for a gap that is ours.
MegaRedHand
added a commit
that referenced
this pull request
Oct 2, 2026
…-636-638-gloas-live The scoring refresh names the dynamic topics for the digest current at each slot, so on this branch's runtime fork schedule they follow a switch within a slot; the docs say what does not follow (exit and slashing parameters, old-digest weights).
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The beacon wire had no gossipsub peer scoring (
// TODO: set peer scoring params). Gossipsub kept exchanging with every peer, including ones that send invalid messages, break IWANT promises or cannot keep up, and the connection cap was the only bound on bad peers.Slow peers are the visible case on the followers. The mainnet follower logged 96k gossipsub
Send Queue fullwarnings in 22 h, from only 8 peers (one of them 60k). The Hoodi follower currently logs about 5000 a minute, almost all from 2 peers. Without scoring, nothing penalizes or drops those peers.Changes
p2p/src/beacon/scoring.rs(new)gossipsub_scoring_parameters.rs, ported formula for formula: thresholds, peer score parameters, and per-topic parameters forbeacon_block,beacon_aggregate_and_proof, all 64beacon_attestation_{n}subnets, exits and slashings.MeshDeliveryGate(the P3 sync gate below). Unit tests for the derived parameters against lighthouse's values.p2p/src/lib.rsRefreshPeerScoring, first run at startup) from the head's current-epoch shuffling and sends them to the swarm.p2p/src/swarm_adapter.rsSwarmCommand::SetTopicScoreParams. On the existing 10 s tick, peers below the graylist are disconnected and peers are counted by score band.storage/src/committee_cache.rs,types/beacon/committees.rsCommitteeCache::head_current_committeesreads the pinned head's current-epoch shuffling (never builds one), andEpochCommittees::active_validator_counttakes the count from its length, so the refresh needs no registry scan.lean_gossipsub_peers_by_score{band},lean_gossipsub_score_disconnects_total,lean_gossipsub_mesh_delivery_scoring.beacon_wire.md"Peer scoring" section;metrics.md.Design decisions
mesh_nis ours (8), not lighthouse's 5. It only enters the first-message-delivery cap.SyncStatus. On the mainnet followerSyncStatusreportedsyncedthrough a 10-minute catch-up up to 98 slots behind: its network-stall rule reads a lagging freshest-imported block as a stalled network.retain_score(100 epochs) after it leaves, so one that reconnects comes back graylisted and is dropped again on the next pass.Ignores every contribution and change (no consumer), and a delivery is only credited once accepted, so P3 there would penalize the mesh for a gap that is ours. Only Prysm scores columns.Not in this PR
remove_topic_weight_except).SyncStatusduring beacon catch-up.Testing
Run on the branch after merging
beacon-chain-integration(125dce1).cargo clippy --workspace --all-targets --profile release-fast -- -D warningscargo fmt --all --checkcargo test --profile release-fast -p ethlambda-p2p --libcargo test --profile release-fast -p ethlambda-storage --libThe beacon spec suites were not run: the only state-transition change makes
committee_count_per_slotpublic, and fork choice is untouched.