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 {
|
Self {
|
||||||
refill_slots_interval: Duration::from_millis(100),
|
refill_slots_interval: Duration::from_millis(100),
|
||||||
backoff_durations: PeerBackoffDurations::test(),
|
backoff_durations: PeerBackoffDurations::test(),
|
||||||
|
ban_duration: Duration::from_millis(200),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -549,21 +549,26 @@ impl PeersManager {
|
|||||||
trace!(target: "net::peers", ?remote_addr, ?peer_id, %err, "fatal connection error");
|
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
|
// remove the peer to which we can't establish a connection due to protocol related
|
||||||
// issues.
|
// issues.
|
||||||
if let Some((peer_id, peer)) = self.peers.remove_entry(peer_id) {
|
if let Entry::Occupied(mut entry) = self.peers.entry(*peer_id) {
|
||||||
self.connection_info.decr_state(peer.state);
|
self.connection_info.decr_state(entry.get().state);
|
||||||
self.queued_actions.push_back(PeerAction::PeerRemoved(peer_id));
|
// 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
|
// ban the peer
|
||||||
self.ban_peer(*peer_id);
|
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 {
|
} else {
|
||||||
let mut backoff_until = None;
|
let mut backoff_until = None;
|
||||||
let mut remove_peer = false;
|
let mut remove_peer = false;
|
||||||
@ -1113,6 +1118,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::PeersManager;
|
use super::PeersManager;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
error::SessionError,
|
||||||
peers::{
|
peers::{
|
||||||
ConnectionInfo, InboundConnectionError, PeerAction, PeerAddr, PeerBackoffDurations,
|
ConnectionInfo, InboundConnectionError, PeerAction, PeerAddr, PeerBackoffDurations,
|
||||||
PeerConnectionState,
|
PeerConnectionState,
|
||||||
@ -1896,6 +1902,64 @@ mod tests {
|
|||||||
assert!(!peers.peers.contains_key(&peer));
|
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]
|
#[tokio::test]
|
||||||
async fn test_outgoing_connection_error() {
|
async fn test_outgoing_connection_error() {
|
||||||
let peer = PeerId::random();
|
let peer = PeerId::random();
|
||||||
|
|||||||
Reference in New Issue
Block a user