diff --git a/crates/net/network/src/error.rs b/crates/net/network/src/error.rs index da0bd0d87c..695387e2ee 100644 --- a/crates/net/network/src/error.rs +++ b/crates/net/network/src/error.rs @@ -91,9 +91,10 @@ impl SessionError for EthStreamError { fn should_backoff(&self) -> bool { matches!( self, - EthStreamError::P2PStreamError(P2PStreamError::HandshakeError( - P2PHandshakeError::NoResponse - )) + EthStreamError::HandshakeError(HandshakeError::NoResponse) | + EthStreamError::P2PStreamError(P2PStreamError::HandshakeError( + P2PHandshakeError::NoResponse + )) ) || self .as_disconnected() .map(|reason| { diff --git a/crates/net/network/src/peers/manager.rs b/crates/net/network/src/peers/manager.rs index 979827944f..4454b86c2e 100644 --- a/crates/net/network/src/peers/manager.rs +++ b/crates/net/network/src/peers/manager.rs @@ -871,7 +871,7 @@ mod test { PeersConfig, }; use reth_eth_wire::{ - error::{EthStreamError, P2PHandshakeError, P2PStreamError}, + error::{EthStreamError, HandshakeError, P2PHandshakeError, P2PStreamError}, DisconnectReason, }; use reth_net_common::ban_list::BanList; @@ -1010,6 +1010,69 @@ mod test { } } + #[tokio::test] + async fn test_backoff_on_no_response() { + let peer = PeerId::random(); + let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008); + + let backoff_duration = Duration::from_secs(3); + let config = PeersConfig { backoff_duration, ..Default::default() }; + let mut peers = PeersManager::new(config); + peers.add_discovered_node(peer, socket_addr); + + match event!(peers) { + PeerAction::PeerAdded(peer_id) => { + assert_eq!(peer_id, peer); + } + _ => unreachable!(), + } + match event!(peers) { + PeerAction::Connect { peer_id, .. } => { + assert_eq!(peer_id, peer); + } + _ => unreachable!(), + } + + poll_fn(|cx| { + assert!(peers.poll(cx).is_pending()); + Poll::Ready(()) + }) + .await; + + peers.on_pending_session_dropped( + &socket_addr, + &peer, + &PendingSessionHandshakeError::Eth(EthStreamError::HandshakeError( + HandshakeError::NoResponse, + )), + ); + + poll_fn(|cx| { + assert!(peers.poll(cx).is_pending()); + Poll::Ready(()) + }) + .await; + + assert!(peers.ban_list.is_banned_peer(&peer)); + assert!(peers.peers.get(&peer).is_some()); + + tokio::time::sleep(backoff_duration).await; + + match event!(peers) { + PeerAction::UnBanPeer { peer_id, .. } => { + assert_eq!(peer_id, peer); + } + _ => unreachable!(), + } + + match event!(peers) { + PeerAction::Connect { peer_id, .. } => { + assert_eq!(peer_id, peer); + } + _ => unreachable!(), + } + } + #[tokio::test] async fn test_ban_on_active_drop() { let peer = PeerId::random();