Skip to content

feat(peer-manager): place newly incoming validators in Secondary peer group #3583

@decofe

Description

@decofe

Summary

New validators joining the network should be placed in the Secondary peer group instead of immediately being tracked as primary peers.

Motivation

Commonware's p2p layer supports TrackedPeers with distinct primary and secondary sets (p2p/src/lib.rs#L234-L258). Secondary peers:

  • Are accepted for inbound connections
  • Receive Recipients::All broadcast traffic on established connections
  • Are visible in PeerSetUpdate notifications
  • Are not dialed outbound (saving connection overhead)

The reshare example demonstrates the intended pattern:

// Primary = dealers (drive the DKG round/running consensus)
// Secondary = current players + next-epoch players (give time to sync)
//
// Overlapping keys are deduplicated as primary
self.manager
    .track(
        epoch.get(),
        TrackedPeers::new(
            dealers.clone(),
            Set::from_iter_dedup(players.iter().chain(next_players.iter()).cloned()),
        ),
    )
    .await;

Currently, Tempo's PeerManager (crates/commonware-node/src/peer_manager/actor.rs) tracks all validators — including next-epoch players read from the DKG outcome — as a flat ordered::Map<PublicKey, Address> passed to oracle.track(), which places them all as primary peers. This means we eagerly dial validators that may not yet be participating in consensus.

Changes

  1. peer_manager/actor.rs: Change track_or_overwrite and refresh_peers to distinguish between:

    • Primary: current epoch's active players/dealers (those currently participating in consensus)
    • Secondary: next-epoch players (onchain_outcome.next_players()) and any newly registered validators not yet in the active set

    Use TrackedPeers::new(primary, secondary) when calling oracle.track() instead of the current flat peer map.

  2. validators.rs: May need to return richer data (e.g., which validators are current vs next-epoch) so the peer manager can split them. Currently read_active_and_known_peers_at_block_hash merges everything into one map.

  3. read_peer_set_if_boundary: Currently unions players() and next_players() into one flat Set. Should pass them separately so the caller can assign primary/secondary.

Benefits

  • Avoids unnecessary outbound dials to validators that haven't started participating yet
  • Gives new validators time to sync and establish inbound connections before being relied upon
  • Aligns with commonware's recommended peer group pattern
  • Reduces connection churn during validator set transitions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions