Skip to content
2 changes: 1 addition & 1 deletion anchor/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ version = { workspace = true }
[dev-dependencies]
libp2p-swarm-test = "0.5.0"
message_receiver = { workspace = true }
tokio = { workspace = true, features = ["rt", "macros", "time"] }
tokio = { workspace = true, features = ["rt", "macros", "time", "test-util"] }
tracing-subscriber = { workspace = true }
7 changes: 6 additions & 1 deletion anchor/network/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,12 @@ impl AnchorBehaviour {
discovery
};

let peer_manager = PeerManager::new(network_config);
let peer_manager = {
let slots_per_epoch = E::slots_per_epoch();
let slot_duration = Duration::from_secs(spec.seconds_per_slot);
let one_epoch_duration = slot_duration * slots_per_epoch as u32;
PeerManager::new(network_config, one_epoch_duration)
};

let handshake = handshake::create_behaviour(local_keypair);

Expand Down
43 changes: 41 additions & 2 deletions anchor/network/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,13 @@ impl<R: MessageReceiver> Network<R> {
self.handle_handshake_result(result);
}
}
AnchorBehaviourEvent::PeerManager(peer_manager::Event::ConnectActions(actions)) => {
self.handle_connect_actions(actions);
AnchorBehaviourEvent::PeerManager(peer_manager::Event::Heartbeat(heartbeat)) => {
if let Some(actions) = heartbeat.connect_actions {
self.handle_connect_actions(actions);
}
if heartbeat.check_peer_scores {
self.check_and_block_peers_by_score();
}
}
_ => {
trace!(event = ?behaviour_event, "Unhandled behaviour event");
Expand Down Expand Up @@ -413,6 +418,40 @@ impl<R: MessageReceiver> Network<R> {
}
}
}

/// Get the list of currently blocked peers.
pub fn blocked_peers(&self) -> &std::collections::HashSet<PeerId> {
self.swarm.behaviour().peer_manager.blocked_peers()
}

/// Check gossipsub peer scores and block peers with scores below graylist threshold
pub fn check_and_block_peers_by_score(&mut self) {
use crate::scoring::peer_score_config::GRAYLIST_THRESHOLD;

let gossipsub = &self.swarm.behaviour().gossipsub;

// Get all peers with poor scores that should be blocked
let peers_to_block: Vec<PeerId> = self
.swarm
.connected_peers()
.filter_map(|peer_id| {
if let Some(score) = gossipsub.peer_score(peer_id) {
if score < GRAYLIST_THRESHOLD {
Some(*peer_id)
} else {
None
}
} else {
None
}
})
.collect();

// Block the peers (connections will be closed automatically)
for peer_id in peers_to_block {
self.swarm.behaviour_mut().peer_manager.block_peer(peer_id);
}
}
}

fn build_swarm(
Expand Down
Loading
Loading