mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix: never ban trusted peers (#11254)
Co-authored-by: Emilia Hane <elsaemiliaevahane@gmail.com>
This commit is contained in:
@ -288,6 +288,7 @@ impl PeersConfig {
|
||||
Self {
|
||||
refill_slots_interval: Duration::from_millis(100),
|
||||
backoff_durations: PeerBackoffDurations::test(),
|
||||
ban_duration: Duration::from_millis(200),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,21 +549,26 @@ impl PeersManager {
|
||||
trace!(target: "net::peers", ?remote_addr, ?peer_id, %err, "fatal connection error");
|
||||
// remove the peer to which we can't establish a connection due to protocol related
|
||||
// issues.
|
||||
if let Some((peer_id, peer)) = self.peers.remove_entry(peer_id) {
|
||||
self.connection_info.decr_state(peer.state);
|
||||
self.queued_actions.push_back(PeerAction::PeerRemoved(peer_id));
|
||||
if let Entry::Occupied(mut entry) = self.peers.entry(*peer_id) {
|
||||
self.connection_info.decr_state(entry.get().state);
|
||||
// only remove if the peer is not trusted
|
||||
if entry.get().is_trusted() {
|
||||
entry.get_mut().state = PeerConnectionState::Idle;
|
||||
} else {
|
||||
entry.remove();
|
||||
self.queued_actions.push_back(PeerAction::PeerRemoved(*peer_id));
|
||||
// If the error is caused by a peer that should be banned from discovery
|
||||
if err.merits_discovery_ban() {
|
||||
self.queued_actions.push_back(PeerAction::DiscoveryBanPeerId {
|
||||
peer_id: *peer_id,
|
||||
ip_addr: remote_addr.ip(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ban the peer
|
||||
self.ban_peer(*peer_id);
|
||||
|
||||
// If the error is caused by a peer that should be banned from discovery
|
||||
if err.merits_discovery_ban() {
|
||||
self.queued_actions.push_back(PeerAction::DiscoveryBanPeerId {
|
||||
peer_id: *peer_id,
|
||||
ip_addr: remote_addr.ip(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let mut backoff_until = None;
|
||||
let mut remove_peer = false;
|
||||
@ -1113,6 +1118,7 @@ mod tests {
|
||||
|
||||
use super::PeersManager;
|
||||
use crate::{
|
||||
error::SessionError,
|
||||
peers::{
|
||||
ConnectionInfo, InboundConnectionError, PeerAction, PeerAddr, PeerBackoffDurations,
|
||||
PeerConnectionState,
|
||||
@ -1896,6 +1902,64 @@ mod tests {
|
||||
assert!(!peers.peers.contains_key(&peer));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_fatal_outgoing_connection_error_trusted() {
|
||||
let peer = PeerId::random();
|
||||
let config = PeersConfig::test()
|
||||
.with_trusted_nodes(vec![TrustedPeer {
|
||||
host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
|
||||
tcp_port: 8008,
|
||||
udp_port: 8008,
|
||||
id: peer,
|
||||
}])
|
||||
.with_trusted_nodes_only(true);
|
||||
let mut peers = PeersManager::new(config);
|
||||
let socket_addr = peers.peers.get(&peer).unwrap().addr.tcp();
|
||||
|
||||
match event!(peers) {
|
||||
PeerAction::Connect { peer_id, remote_addr } => {
|
||||
assert_eq!(peer_id, peer);
|
||||
assert_eq!(remote_addr, socket_addr);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
let p = peers.peers.get(&peer).unwrap();
|
||||
assert_eq!(p.state, PeerConnectionState::PendingOut);
|
||||
|
||||
assert_eq!(peers.num_outbound_connections(), 0);
|
||||
|
||||
let err = PendingSessionHandshakeError::Eth(EthStreamError::EthHandshakeError(
|
||||
EthHandshakeError::NonStatusMessageInHandshake,
|
||||
));
|
||||
assert!(err.is_fatal_protocol_error());
|
||||
|
||||
peers.on_outgoing_pending_session_dropped(&socket_addr, &peer, &err);
|
||||
assert_eq!(peers.num_outbound_connections(), 0);
|
||||
|
||||
// try tmp ban peer
|
||||
match event!(peers) {
|
||||
PeerAction::BanPeer { peer_id } => {
|
||||
assert_eq!(peer_id, peer);
|
||||
}
|
||||
err => unreachable!("{err:?}"),
|
||||
}
|
||||
|
||||
// ensure we still have trusted peer
|
||||
assert!(peers.peers.contains_key(&peer));
|
||||
|
||||
// await for the ban to expire
|
||||
tokio::time::sleep(peers.backoff_durations.medium).await;
|
||||
|
||||
match event!(peers) {
|
||||
PeerAction::Connect { peer_id, remote_addr } => {
|
||||
assert_eq!(peer_id, peer);
|
||||
assert_eq!(remote_addr, socket_addr);
|
||||
}
|
||||
err => unreachable!("{err:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_outgoing_connection_error() {
|
||||
let peer = PeerId::random();
|
||||
|
||||
Reference in New Issue
Block a user