Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ actual_slot = finalized_slot + 1 + relative_index
- `fork_digest` is a 4-byte hex string (no `0x` prefix); currently the dummy `12345678` agreed across clients
- Mesh size: 8 (6-12 bounds), heartbeat: 700ms
- Beacon wire: `validate_messages()` is on, so every beacon message waits for a verdict (~4.2s before gossipsub's cache evicts it). Rules in `state_transition::beacon::gossip` (cheap half inline, stateful half on a bounded `spawn_blocking` task); plumbing in `p2p/src/beacon/verdict.rs`. Lean gossip still auto-forwards
- Beacon peer scoring: lighthouse's parameters ported in `p2p/src/beacon/scoring.rs` (block, aggregate, 64 attestation subnets, exits, slashings; columns and sync contributions unscored), refreshed every slot from the head's active validator count. Mesh-delivery scoring (P3) is gated off while the head lags more than 4 slots and for an epoch after, because a catching-up node `Ignore`s every aggregate and would otherwise graylist its own mesh. The swarm disconnects peers below the graylist (-16000) every 10 s. Lean runs unscored. See [`docs/beacon_wire.md`](docs/beacon_wire.md#peer-scoring)
- Data columns: every check runs in p2p. A column gossip did not accept (`Queue`/`Overloaded`), every fetched column, and parked columns replayed after their parent imports go through `column::chain_checks` in `p2p/src/beacon/column_checks.rs`. The chain actor stores what it gets unchecked; only debug builds re-run `chain_checks` there
- Beacon subscribes seven global topics plus two node-id-derived subnet families: custody
columns and backbone attestation subnets. `beacon_aggregate_and_proof` and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,10 @@ pub fn get_seed(state: &BeaconState, epoch: Epoch, domain_type: DomainType) -> B
/// split out so [`build_epoch_committees`] can share one
/// [`get_active_validator_indices`] scan between this and its own committee
/// derivation, rather than [`get_committee_count_per_slot`] repeating the scan
/// the caller already did to get `active_count` in the first place.
fn committee_count_per_slot(active_count: u64) -> u64 {
/// the caller already did to get `active_count` in the first place. Public
/// for p2p's gossipsub scoring, which sizes expected aggregate traffic from
/// a validator count rather than from a state.
pub fn committee_count_per_slot(active_count: u64) -> u64 {
let ideal = active_count / preset::SLOTS_PER_EPOCH / preset::TARGET_COMMITTEE_SIZE;
ideal.clamp(1, preset::MAX_COMMITTEES_PER_SLOT as u64)
}
Expand Down
7 changes: 7 additions & 0 deletions crates/common/types/src/beacon/committees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ impl EpochCommittees {
self.committees_per_slot
}

/// How many validators are active in this epoch: the shuffle is a
/// permutation of exactly that set, so its length is the count without
/// another registry scan.
pub fn active_validator_count(&self) -> u64 {
self.shuffled.len() as u64
}

/// The committee at `slot` with `index`.
///
/// The same members `ethlambda-state-transition`'s `get_beacon_committee`
Expand Down
1 change: 1 addition & 0 deletions crates/net/p2p/src/beacon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod encoding;
pub mod handler;
pub mod messages;
pub mod protocols;
pub mod scoring;
pub mod subnets;
pub mod swarm;
pub mod topics;
Expand Down
Loading
Loading