1use crate::{
4 cache::LruMap,
5 error::SessionError,
6 session::{Direction, PendingSessionHandshakeError},
7 swarm::NetworkConnectionState,
8 trusted_peers_resolver::TrustedPeersResolver,
9};
10use alloy_primitives::map::{hash_map::Entry, FbBuildHasher, HashMap, HashSet};
11use futures::StreamExt;
12
13use rand::Rng;
14use reth_eth_wire::{
15 errors::{EthStreamError, P2PHandshakeError, P2PStreamError},
16 DisconnectReason,
17};
18use reth_ethereum_forks::ForkId;
19use reth_net_banlist::{is_global, BanList};
20use reth_network_api::test_utils::{PeerCommand, PeersHandle};
21use reth_network_peers::{NodeRecord, PeerId, TrustedPeer};
22use reth_network_types::{
23 is_connection_failed_reputation,
24 peers::{
25 config::{PeerBackoffDurations, PEER_ROTATION_MIN_UPTIME},
26 reputation::{DEFAULT_REPUTATION, MAX_TRUSTED_PEER_REPUTATION_CHANGE},
27 },
28 BackoffKind, ConnectionsConfig, Peer, PeerAddr, PeerConnectionState, PeerKind, PeersConfig,
29 PersistedPeerInfo, ReputationChangeKind, ReputationChangeOutcome, ReputationChangeWeights,
30};
31use std::{
32 collections::VecDeque,
33 fmt::Display,
34 io,
35 net::{IpAddr, SocketAddr},
36 pin::Pin,
37 task::{Context, Poll},
38 time::Duration,
39};
40use thiserror::Error;
41use tokio::{
42 sync::mpsc,
43 time::{Instant, Interval, Sleep},
44};
45use tokio_stream::wrappers::UnboundedReceiverStream;
46use tracing::{trace, warn};
47
48const MAX_INCOMING_IP_THROTTLE_ENTRIES: u32 = 16_384;
50
51#[derive(Debug)]
58pub struct PeersManager {
59 peers: HashMap<PeerId, Peer, FbBuildHasher<64>>,
61 trusted_peer_ids: HashSet<PeerId, FbBuildHasher<64>>,
66 trusted_peers_resolver: TrustedPeersResolver,
69 manager_tx: mpsc::UnboundedSender<PeerCommand>,
71 handle_rx: UnboundedReceiverStream<PeerCommand>,
73 queued_actions: VecDeque<PeerAction>,
75 refill_slots_interval: Interval,
77 reputation_weights: ReputationChangeWeights,
79 connection_info: ConnectionInfo,
81 ban_list: BanList,
83 incoming_ip_throttle: LruMap<IpAddr, std::time::Instant>,
85 backed_off_peers: HashMap<PeerId, std::time::Instant, FbBuildHasher<64>>,
87 release_interval: Interval,
89 ban_duration: Duration,
91 backoff_durations: PeerBackoffDurations,
94 trusted_nodes_only: bool,
97 last_tick: Instant,
99 max_backoff_count: u8,
101 net_connection_state: NetworkConnectionState,
103 incoming_ip_throttle_duration: Duration,
105 ip_filter: reth_net_banlist::IpFilter,
107 enforce_enr_fork_id: bool,
110 peer_rotation_sleep: Option<Pin<Box<Sleep>>>,
113 peer_rotation_mean: Option<Duration>,
115}
116
117impl PeersManager {
118 pub fn new(config: PeersConfig) -> Self {
120 let PeersConfig {
121 refill_slots_interval,
122 connection_info,
123 reputation_weights,
124 ban_list,
125 ban_duration,
126 backoff_durations,
127 trusted_nodes,
128 trusted_nodes_only,
129 trusted_nodes_resolution_interval,
130 basic_nodes,
131 persisted_peers,
132 max_backoff_count,
133 incoming_ip_throttle_duration,
134 ip_filter,
135 enforce_enr_fork_id,
136 peer_rotation_interval,
137 } = config;
138 let (manager_tx, handle_rx) = mpsc::unbounded_channel();
139 let now = Instant::now();
140
141 let unban_interval = ban_duration.min(backoff_durations.low) / 2;
143
144 let mut peers: HashMap<PeerId, Peer, FbBuildHasher<64>> = HashMap::with_capacity_and_hasher(
145 trusted_nodes.len() + basic_nodes.len() + persisted_peers.len(),
146 Default::default(),
147 );
148 let mut trusted_peer_ids: HashSet<PeerId, FbBuildHasher<64>> =
149 HashSet::with_capacity_and_hasher(trusted_nodes.len(), Default::default());
150
151 for trusted_peer in &trusted_nodes {
152 match trusted_peer.resolve_blocking() {
153 Ok(NodeRecord { address, tcp_port, udp_port, id }) => {
154 trusted_peer_ids.insert(id);
155 peers.entry(id).or_insert_with(|| {
156 Peer::trusted(PeerAddr::new_with_ports(address, tcp_port, Some(udp_port)))
157 });
158 }
159 Err(err) => {
160 warn!(target: "net::peers", ?err, "Failed to resolve trusted peer");
161 }
162 }
163 }
164
165 for PersistedPeerInfo { record, kind, fork_id, reputation } in persisted_peers {
166 if enforce_enr_fork_id && fork_id.is_none() {
170 continue
171 }
172 let NodeRecord { address, tcp_port, udp_port, id } = record;
173 peers.entry(id).or_insert_with(|| {
174 if kind.is_trusted() {
175 trusted_peer_ids.insert(id);
176 }
177 let mut peer = Peer::with_kind(
178 PeerAddr::new_with_ports(address, tcp_port, Some(udp_port)),
179 kind,
180 );
181 peer.fork_id = fork_id.map(Box::new);
182 peer.reputation = reputation;
183 peer
184 });
185 }
186
187 for NodeRecord { address, tcp_port, udp_port, id } in basic_nodes {
188 peers.entry(id).or_insert_with(|| {
189 Peer::new(PeerAddr::new_with_ports(address, tcp_port, Some(udp_port)))
190 });
191 }
192
193 trace!(target: "net::peers", trusted_peers=?trusted_peer_ids, "Initialized peers manager");
194
195 Self {
196 peers,
197 trusted_peer_ids,
198 trusted_peers_resolver: TrustedPeersResolver::new(
199 trusted_nodes,
200 tokio::time::interval(trusted_nodes_resolution_interval), ),
202 manager_tx,
203 handle_rx: UnboundedReceiverStream::new(handle_rx),
204 queued_actions: Default::default(),
205 reputation_weights,
206 refill_slots_interval: tokio::time::interval(refill_slots_interval),
207 release_interval: tokio::time::interval_at(now + unban_interval, unban_interval),
208 connection_info: ConnectionInfo::new(connection_info),
209 ban_list,
210 incoming_ip_throttle: LruMap::new(MAX_INCOMING_IP_THROTTLE_ENTRIES),
211 backed_off_peers: Default::default(),
212 ban_duration,
213 backoff_durations,
214 trusted_nodes_only,
215 last_tick: Instant::now(),
216 max_backoff_count,
217 net_connection_state: NetworkConnectionState::default(),
218 incoming_ip_throttle_duration,
219 ip_filter,
220 enforce_enr_fork_id,
221 peer_rotation_sleep: peer_rotation_interval
222 .map(|mean| Box::pin(tokio::time::sleep(jitter_rotation_interval(mean)))),
223 peer_rotation_mean: peer_rotation_interval,
224 }
225 }
226
227 pub(crate) fn handle(&self) -> PeersHandle {
229 PeersHandle::new(self.manager_tx.clone())
230 }
231
232 pub(crate) const fn enforce_enr_fork_id(&self) -> bool {
234 self.enforce_enr_fork_id
235 }
236
237 #[inline]
239 pub(crate) fn num_known_peers(&self) -> usize {
240 self.peers.len()
241 }
242
243 pub(crate) fn iter_peers(&self) -> impl Iterator<Item = NodeRecord> + '_ {
245 self.peers.iter().map(|(peer_id, v)| {
246 NodeRecord::new_with_ports(
247 v.addr.tcp().ip(),
248 v.addr.tcp().port(),
249 v.addr.udp().map(|addr| addr.port()),
250 *peer_id,
251 )
252 })
253 }
254
255 pub(crate) fn persistable_peers(&self) -> impl Iterator<Item = PersistedPeerInfo> + '_ {
260 self.peers.iter().filter(|(_, peer)| !peer.is_backed_off() && !peer.is_banned()).map(
261 |(peer_id, peer)| PersistedPeerInfo {
262 record: NodeRecord::new_with_ports(
263 peer.addr.tcp().ip(),
264 peer.addr.tcp().port(),
265 peer.addr.udp().map(|addr| addr.port()),
266 *peer_id,
267 ),
268 kind: peer.kind,
269 fork_id: peer.fork_id.as_deref().copied(),
270 reputation: peer.reputation,
271 },
272 )
273 }
274
275 pub(crate) fn peer_by_id(&self, peer_id: PeerId) -> Option<(NodeRecord, PeerKind)> {
277 self.peers.get(&peer_id).map(|v| {
278 (
279 NodeRecord::new_with_ports(
280 v.addr.tcp().ip(),
281 v.addr.tcp().port(),
282 v.addr.udp().map(|addr| addr.port()),
283 peer_id,
284 ),
285 v.kind,
286 )
287 })
288 }
289
290 pub(crate) fn is_inbound_peer(&self, peer_id: &PeerId) -> bool {
292 self.peers.get(peer_id).is_some_and(|p| {
293 matches!(p.state, PeerConnectionState::In | PeerConnectionState::DisconnectingIn)
294 })
295 }
296
297 pub(crate) fn peers_by_kind(&self, kind: PeerKind) -> impl Iterator<Item = PeerId> + '_ {
299 self.peers.iter().filter_map(move |(peer_id, peer)| (peer.kind == kind).then_some(*peer_id))
300 }
301
302 #[inline]
304 pub(crate) const fn num_inbound_connections(&self) -> usize {
305 self.connection_info.num_inbound
306 }
307
308 #[inline]
310 pub(crate) const fn num_outbound_connections(&self) -> usize {
311 self.connection_info.num_outbound
312 }
313
314 #[inline]
316 pub(crate) const fn num_pending_outbound_connections(&self) -> usize {
317 self.connection_info.num_pending_out
318 }
319
320 #[inline]
322 pub(crate) fn num_backed_off_peers(&self) -> usize {
323 self.backed_off_peers.len()
324 }
325
326 fn num_idle_trusted_peers(&self) -> usize {
328 self.peers.iter().filter(|(_, peer)| peer.kind.is_trusted() && peer.state.is_idle()).count()
329 }
330
331 pub(crate) fn on_incoming_pending_session(
335 &mut self,
336 addr: IpAddr,
337 ) -> Result<(), InboundConnectionError> {
338 if !self.ip_filter.is_allowed(&addr) {
340 trace!(target: "net", ?addr, "Rejecting connection from IP not in allowed ranges");
341 return Err(InboundConnectionError::IpBanned)
342 }
343
344 if self.ban_list.is_banned_ip(&addr) ||
345 self.incoming_ip_throttle
346 .get(&addr)
347 .is_some_and(|until| *until > std::time::Instant::now())
348 {
349 return Err(InboundConnectionError::IpBanned)
350 }
351
352 if !self.connection_info.has_in_capacity() {
354 if self.trusted_peer_ids.is_empty() {
355 return Err(InboundConnectionError::ExceedsCapacity)
358 }
359
360 let num_idle_trusted_peers = self.num_idle_trusted_peers();
364 if num_idle_trusted_peers <= self.trusted_peer_ids.len() {
365 let max_inbound =
367 self.trusted_peer_ids.len().max(self.connection_info.config.max_inbound);
368 if self.connection_info.num_pending_in < max_inbound {
369 self.throttle_incoming_ip(addr);
372 self.connection_info.inc_pending_in();
373 return Ok(())
374 }
375 }
376
377 return Err(InboundConnectionError::ExceedsCapacity)
379 }
380
381 if !self.connection_info.has_in_pending_capacity() {
383 return Err(InboundConnectionError::ExceedsCapacity)
384 }
385
386 self.throttle_incoming_ip(addr);
388
389 self.connection_info.inc_pending_in();
390 Ok(())
391 }
392
393 pub(crate) const fn on_incoming_pending_session_rejected_internally(&mut self) {
396 self.connection_info.decr_pending_in();
397 }
398
399 pub(crate) const fn on_incoming_pending_session_gracefully_closed(&mut self) {
401 self.connection_info.decr_pending_in()
402 }
403
404 pub(crate) fn on_incoming_pending_session_dropped(
406 &mut self,
407 remote_addr: SocketAddr,
408 err: &PendingSessionHandshakeError,
409 ) {
410 if err.is_fatal_protocol_error() {
411 self.ban_ip(remote_addr.ip());
412
413 if err.merits_discovery_ban() {
414 self.queued_actions
415 .push_back(PeerAction::DiscoveryBanIp { ip_addr: remote_addr.ip() })
416 }
417 }
418
419 self.connection_info.decr_pending_in();
420 }
421
422 pub(crate) fn on_incoming_session_established(&mut self, peer_id: PeerId, addr: SocketAddr) {
429 self.connection_info.decr_pending_in();
430
431 if self.ban_list.is_banned_peer(&peer_id) {
434 self.queued_actions.push_back(PeerAction::DisconnectBannedIncoming { peer_id });
435 return
436 }
437
438 let is_trusted = self.trusted_peer_ids.contains(&peer_id);
440 if self.trusted_nodes_only && !is_trusted {
441 self.queued_actions.push_back(PeerAction::DisconnectUntrustedIncoming { peer_id });
442 return
443 }
444
445 self.tick();
447
448 match self.peers.entry(peer_id) {
449 Entry::Occupied(mut entry) => {
450 let peer = entry.get_mut();
451 if peer.is_banned() {
452 self.queued_actions.push_back(PeerAction::DisconnectBannedIncoming { peer_id });
453 return
454 }
455 if peer.state.is_pending_out() {
458 self.connection_info.decr_state(peer.state);
459 }
460
461 peer.state = PeerConnectionState::In;
462 peer.mark_connected();
463 }
464 Entry::Vacant(entry) => {
465 let mut peer = Peer::with_state(PeerAddr::from_tcp(addr), PeerConnectionState::In);
468 peer.mark_connected();
469 peer.remove_after_disconnect = true;
470 entry.insert(peer);
471 self.queued_actions.push_back(PeerAction::PeerAdded(peer_id));
472 }
473 }
474
475 let has_in_capacity = self.has_inbound_capacity(peer_id);
476 self.connection_info.inc_in();
478
479 if !has_in_capacity {
481 self.queued_actions.push_back(PeerAction::Disconnect {
482 peer_id,
483 reason: Some(DisconnectReason::TooManyPeers),
484 });
485 }
486 }
487
488 pub(crate) fn has_inbound_capacity(&self, peer_id: PeerId) -> bool {
490 self.connection_info.has_in_capacity() ||
491 self.trusted_peer_ids.contains(&peer_id) ||
492 self.peers.get(&peer_id).is_some_and(|peer| peer.is_trusted())
493 }
494
495 fn ban_peer(&mut self, peer_id: PeerId) {
497 let ban_duration = if let Some(peer) = self.peers.get(&peer_id) &&
498 (peer.is_trusted() || peer.is_static())
499 {
500 self.backoff_durations.low / 2
503 } else {
504 self.ban_duration
505 };
506
507 self.ban_list.ban_peer_until(peer_id, std::time::Instant::now() + ban_duration);
508 self.queued_actions.push_back(PeerAction::BanPeer { peer_id });
509 }
510
511 fn ban_ip(&mut self, ip: IpAddr) {
513 self.ban_list.ban_ip_until(ip, std::time::Instant::now() + self.ban_duration);
514 }
515
516 fn throttle_incoming_ip(&mut self, ip: IpAddr) {
518 if is_global(&ip) {
519 self.incoming_ip_throttle
522 .insert(ip, std::time::Instant::now() + self.incoming_ip_throttle_duration);
523 }
524 }
525
526 fn backoff_peer_until(&mut self, peer_id: PeerId, until: std::time::Instant) {
528 trace!(target: "net::peers", ?peer_id, "backing off");
529
530 if let Some(peer) = self.peers.get_mut(&peer_id) {
531 peer.backed_off = true;
532 self.backed_off_peers.insert(peer_id, until);
533 }
534 }
535
536 fn unban_peer(&mut self, peer_id: PeerId) {
538 self.ban_list.unban_peer(&peer_id);
539 self.queued_actions.push_back(PeerAction::UnBanPeer { peer_id });
540 }
541
542 fn tick(&mut self) {
547 let now = Instant::now();
548 let secs_since_last_tick =
552 if self.last_tick > now { 0 } else { (now - self.last_tick).as_secs() as i32 };
553 self.last_tick = now;
554
555 for peer in self.peers.iter_mut().filter(|(_, peer)| peer.state.is_connected()) {
557 if peer.1.reputation < DEFAULT_REPUTATION {
560 peer.1.reputation += secs_since_last_tick;
561 }
562 }
563 }
564
565 pub(crate) fn get_reputation(&self, peer_id: &PeerId) -> Option<i32> {
567 self.peers.get(peer_id).map(|peer| peer.reputation)
568 }
569
570 pub(crate) fn apply_reputation_change(&mut self, peer_id: &PeerId, rep: ReputationChangeKind) {
576 trace!(target: "net::peers", ?peer_id, reputation=?rep, "applying reputation change");
577
578 let reputation_change = if rep.is_reset() {
579 None
580 } else {
581 let reputation_change = self.reputation_weights.change(rep).as_i32();
582 if reputation_change == 0 {
583 return
584 }
585 Some(reputation_change)
586 };
587
588 let outcome = if let Some(peer) = self.peers.get_mut(peer_id) {
589 if let Some(mut reputation_change) = reputation_change {
590 if peer.is_trusted() || peer.is_static() {
591 if matches!(
593 rep,
594 ReputationChangeKind::Dropped |
595 ReputationChangeKind::BadAnnouncement |
596 ReputationChangeKind::Timeout |
597 ReputationChangeKind::AlreadySeenTransaction
598 ) {
599 return
600 }
601
602 if reputation_change < MAX_TRUSTED_PEER_REPUTATION_CHANGE {
604 reputation_change = MAX_TRUSTED_PEER_REPUTATION_CHANGE;
606 }
607 }
608 peer.apply_reputation(reputation_change, rep)
609 } else {
610 peer.reset_reputation()
611 }
612 } else {
613 return
614 };
615
616 match outcome {
617 ReputationChangeOutcome::None => {}
618 ReputationChangeOutcome::Ban => {
619 self.ban_peer(*peer_id);
620 }
621 ReputationChangeOutcome::Unban => self.unban_peer(*peer_id),
622 ReputationChangeOutcome::DisconnectAndBan => {
623 self.queued_actions.push_back(PeerAction::Disconnect {
624 peer_id: *peer_id,
625 reason: Some(DisconnectReason::DisconnectRequested),
626 });
627 self.ban_peer(*peer_id);
628 }
629 }
630 }
631
632 pub(crate) fn on_outgoing_pending_session_gracefully_closed(&mut self, peer_id: &PeerId) {
634 if let Some(peer) = self.peers.get_mut(peer_id) &&
635 peer.state.is_pending_out()
636 {
637 self.connection_info.decr_state(peer.state);
638 peer.state = PeerConnectionState::Idle;
639 peer.mark_disconnected();
640 }
641 }
642
643 pub(crate) fn on_outgoing_pending_session_dropped(
646 &mut self,
647 remote_addr: &SocketAddr,
648 peer_id: &PeerId,
649 err: &PendingSessionHandshakeError,
650 ) {
651 if matches!(
652 err,
653 PendingSessionHandshakeError::Ecies(_) | PendingSessionHandshakeError::Timeout
654 ) || matches!(
655 err,
656 PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
657 P2PStreamError::HandshakeError(
658 P2PHandshakeError::Timeout | P2PHandshakeError::NoResponse
659 )
660 ))
661 ) || matches!(err, PendingSessionHandshakeError::Eth(error) if error.as_io().is_some())
662 {
663 if self.peers.get(peer_id).is_some_and(|peer| peer.state.is_pending_out()) {
667 self.on_outgoing_pending_session_gracefully_closed(peer_id);
668 self.backoff_peer_until(
669 *peer_id,
670 self.backoff_durations.backoff_until(BackoffKind::Low, 0),
671 );
672 self.fill_outbound_slots();
673 }
674 return
675 }
676 self.on_connection_failure(remote_addr, peer_id, err, ReputationChangeKind::FailedToConnect)
677 }
678
679 pub(crate) fn on_active_session_gracefully_closed(&mut self, peer_id: PeerId) {
681 match self.peers.entry(peer_id) {
682 Entry::Occupied(mut entry) => {
683 trace!(target: "net::peers", ?peer_id, direction=?entry.get().state, "active session gracefully closed");
684 self.connection_info.decr_state(entry.get().state);
685
686 if entry.get().remove_after_disconnect && !entry.get().is_trusted() {
687 entry.remove();
689 self.queued_actions.push_back(PeerAction::PeerRemoved(peer_id));
690 } else {
691 let peer = entry.get_mut();
692 peer.severe_backoff_counter = 0;
696 peer.state = PeerConnectionState::Idle;
697 peer.mark_disconnected();
698
699 peer.backed_off = true;
704 self.backed_off_peers.insert(
705 peer_id,
706 std::time::Instant::now() + self.incoming_ip_throttle_duration,
707 );
708 trace!(target: "net::peers", ?peer_id, kind=?peer.kind, duration=?self.incoming_ip_throttle_duration, "backing off on gracefully closed session");
709 }
710 }
711 Entry::Vacant(_) => return,
712 }
713
714 self.fill_outbound_slots();
715 }
716
717 pub(crate) fn on_active_outgoing_established(&mut self, peer_id: PeerId) {
719 let at_capacity = self.connection_info.is_outbound_at_capacity();
720 if let Some(peer) = self.peers.get_mut(&peer_id) {
721 trace!(target: "net::peers", ?peer_id, "established active outgoing connection");
722 self.connection_info.decr_state(peer.state);
723 self.connection_info.inc_out();
724 peer.state = PeerConnectionState::Out;
725 peer.mark_connected();
726 if at_capacity &&
727 !peer.is_trusted() &&
728 !peer.is_static() &&
729 !self.trusted_peer_ids.contains(&peer_id)
730 {
731 self.queued_actions.push_back(PeerAction::Disconnect {
732 peer_id,
733 reason: Some(DisconnectReason::TooManyPeers),
734 });
735 }
736 }
737 }
738
739 pub(crate) fn on_active_session_dropped(
744 &mut self,
745 remote_addr: &SocketAddr,
746 peer_id: &PeerId,
747 err: &EthStreamError,
748 ) {
749 self.on_connection_failure(remote_addr, peer_id, err, ReputationChangeKind::Dropped)
750 }
751
752 pub(crate) fn on_outgoing_connection_failure(
755 &mut self,
756 remote_addr: &SocketAddr,
757 peer_id: &PeerId,
758 err: &io::Error,
759 ) {
760 if let Some(peer) = self.peers.get(peer_id) {
764 if peer.state.is_incoming() {
765 return
767 }
768
769 if peer.is_trusted() && is_connection_failed_reputation(peer.reputation) {
770 self.trusted_peers_resolver.interval.reset_immediately();
773 }
774 }
775
776 self.on_connection_failure(remote_addr, peer_id, err, ReputationChangeKind::FailedToConnect)
777 }
778
779 fn on_connection_failure(
780 &mut self,
781 remote_addr: &SocketAddr,
782 peer_id: &PeerId,
783 err: impl SessionError,
784 reputation_change: ReputationChangeKind,
785 ) {
786 trace!(target: "net::peers", ?remote_addr, ?peer_id, %err, "handling failed connection");
787
788 if err.is_fatal_protocol_error() {
789 trace!(target: "net::peers", ?remote_addr, ?peer_id, %err, "fatal connection error");
790 if let Entry::Occupied(mut entry) = self.peers.entry(*peer_id) {
793 self.connection_info.decr_state(entry.get().state);
794 if entry.get().is_trusted() {
796 let peer = entry.get_mut();
797 peer.state = PeerConnectionState::Idle;
798 peer.mark_disconnected();
799 } else {
800 entry.remove();
801 self.queued_actions.push_back(PeerAction::PeerRemoved(*peer_id));
802 if err.merits_discovery_ban() {
804 self.queued_actions.push_back(PeerAction::DiscoveryBanPeerId {
805 peer_id: *peer_id,
806 ip_addr: remote_addr.ip(),
807 })
808 }
809 }
810 }
811
812 self.ban_peer(*peer_id);
814 } else {
815 let mut backoff_until = None;
816 let mut remove_peer = false;
817
818 if let Some(peer) = self.peers.get_mut(peer_id) {
819 if let Some(kind) = err.should_backoff() {
820 if peer.is_trusted() || peer.is_static() {
821 let backoff = self.backoff_durations.low;
827 backoff_until = Some(std::time::Instant::now() + backoff);
828 trace!(target: "net::peers", ?peer_id, ?backoff, "backing off trusted peer");
829 } else {
830 if kind.is_severe() {
832 peer.severe_backoff_counter =
833 peer.severe_backoff_counter.saturating_add(1);
834 }
835 trace!(target: "net::peers", ?peer_id, ?kind, severe_backoff_counter=peer.severe_backoff_counter, "backing off basic peer");
836
837 let backoff_time =
838 self.backoff_durations.backoff_until(kind, peer.severe_backoff_counter);
839
840 backoff_until = Some(backoff_time);
844 }
845 } else {
846 let reputation_change = self.reputation_weights.change(reputation_change);
848 peer.reputation = peer.reputation.saturating_add(reputation_change.as_i32());
849 };
850
851 self.connection_info.decr_state(peer.state);
852 peer.state = PeerConnectionState::Idle;
853 peer.mark_disconnected();
854
855 if peer.severe_backoff_counter > self.max_backoff_count &&
856 !peer.is_trusted() &&
857 !peer.is_static()
858 {
859 remove_peer = true;
862 }
863 }
864
865 if remove_peer {
867 trace!(target: "net", ?peer_id, "removed peer after exceeding backoff counter");
868 let (peer_id, _) = self.peers.remove_entry(peer_id).expect("peer must exist");
869 self.queued_actions.push_back(PeerAction::PeerRemoved(peer_id));
870 } else if let Some(backoff_until) = backoff_until {
871 self.backoff_peer_until(*peer_id, backoff_until);
873 }
874 }
875
876 self.fill_outbound_slots();
877 }
878
879 pub(crate) const fn on_already_connected(&mut self, direction: Direction) {
885 match direction {
886 Direction::Incoming => {
887 self.connection_info.decr_pending_in();
889 }
890 Direction::Outgoing(_) => {
891 }
894 }
895 }
896
897 pub(crate) fn add_peer(&mut self, peer_id: PeerId, addr: PeerAddr, fork_id: Option<ForkId>) {
901 self.add_peer_kind(peer_id, None, addr, fork_id)
902 }
903
904 pub(crate) fn add_trusted_peer_id(&mut self, peer_id: PeerId) {
906 self.trusted_peer_ids.insert(peer_id);
907 if let Some(peer) = self.peers.get_mut(&peer_id) {
908 peer.kind = PeerKind::Trusted;
909 }
910 }
911
912 #[cfg_attr(not(test), expect(dead_code))]
916 pub(crate) fn add_trusted_peer(&mut self, peer_id: PeerId, addr: PeerAddr) {
917 self.add_peer_kind(peer_id, Some(PeerKind::Trusted), addr, None)
918 }
919
920 pub(crate) fn add_trusted_peer_node(&mut self, trusted: TrustedPeer) {
922 let peer_id = trusted.id;
923 self.trusted_peer_ids.insert(peer_id);
924 self.trusted_peers_resolver.remove(peer_id);
925 self.trusted_peers_resolver.trusted_peers.push(trusted);
926 self.trusted_peers_resolver.interval.reset_immediately();
927 }
928
929 pub(crate) fn add_peer_kind(
934 &mut self,
935 peer_id: PeerId,
936 kind: Option<PeerKind>,
937 addr: PeerAddr,
938 fork_id: Option<ForkId>,
939 ) {
940 let ip_addr = addr.tcp().ip();
941
942 if !self.ip_filter.is_allowed(&ip_addr) {
944 trace!(target: "net", ?peer_id, ?ip_addr, "Skipping peer from IP not in allowed ranges");
945 return
946 }
947
948 if self.ban_list.is_banned(&peer_id, &ip_addr) {
949 return
950 }
951
952 match self.peers.entry(peer_id) {
953 Entry::Occupied(mut entry) => {
954 let peer = entry.get_mut();
955 peer.fork_id = fork_id.map(Box::new);
956 peer.addr = addr;
957
958 if let Some(kind) = kind {
959 peer.kind = kind;
960 }
961
962 if peer.state.is_incoming() {
963 peer.remove_after_disconnect = false;
967 }
968 }
969 Entry::Vacant(entry) => {
970 trace!(target: "net::peers", ?peer_id, addr=?addr.tcp(), "discovered new node");
971 let mut peer = Peer::with_kind(addr, kind.unwrap_or(PeerKind::Basic));
972 peer.fork_id = fork_id.map(Box::new);
973 entry.insert(peer);
974 self.queued_actions.push_back(PeerAction::PeerAdded(peer_id));
975 }
976 }
977
978 if kind.is_some_and(|kind| kind.is_trusted()) {
979 self.trusted_peer_ids.insert(peer_id);
981 }
982 }
983
984 pub(crate) fn add_requested_peer(
989 &mut self,
990 peer_id: PeerId,
991 kind: Option<PeerKind>,
992 addr: PeerAddr,
993 ) {
994 self.add_peer_kind(peer_id, kind, addr, None);
995 self.fill_outbound_slots();
996 }
997
998 pub(crate) fn remove_peer(&mut self, peer_id: PeerId) {
1000 let Entry::Occupied(entry) = self.peers.entry(peer_id) else { return };
1001 if entry.get().is_trusted() {
1002 return
1003 }
1004 let mut peer = entry.remove();
1005
1006 trace!(target: "net::peers", ?peer_id, "remove discovered node");
1007 self.queued_actions.push_back(PeerAction::PeerRemoved(peer_id));
1008
1009 if peer.state.is_connected() {
1010 trace!(target: "net::peers", ?peer_id, "disconnecting on remove from discovery");
1011 peer.remove_after_disconnect = true;
1016 peer.state.disconnect();
1017 self.peers.insert(peer_id, peer);
1018 self.queued_actions.push_back(PeerAction::Disconnect {
1019 peer_id,
1020 reason: Some(DisconnectReason::DisconnectRequested),
1021 })
1022 }
1023 }
1024
1025 pub(crate) fn ban_peer_by_admin(&mut self, peer_id: PeerId) {
1030 if self.trusted_peer_ids.contains(&peer_id) ||
1031 self.peers.get(&peer_id).is_some_and(Peer::is_trusted)
1032 {
1033 return
1034 }
1035
1036 self.remove_peer(peer_id);
1037 self.ban_list.ban_peer(peer_id);
1038 }
1039
1040 pub(crate) fn unban_peer_by_admin(&mut self, peer_id: PeerId) {
1042 self.ban_list.unban_peer(&peer_id);
1043 if let Some(peer) = self.peers.get_mut(&peer_id) &&
1044 peer.is_banned()
1045 {
1046 peer.unban();
1047 self.queued_actions.push_back(PeerAction::UnBanPeer { peer_id });
1048 }
1049 }
1050
1051 #[cfg_attr(not(test), expect(dead_code))]
1054 pub(crate) fn add_and_connect(
1055 &mut self,
1056 peer_id: PeerId,
1057 addr: PeerAddr,
1058 fork_id: Option<ForkId>,
1059 ) {
1060 self.add_and_connect_kind(peer_id, PeerKind::Basic, addr, fork_id)
1061 }
1062
1063 pub(crate) fn add_and_connect_kind(
1067 &mut self,
1068 peer_id: PeerId,
1069 kind: PeerKind,
1070 addr: PeerAddr,
1071 fork_id: Option<ForkId>,
1072 ) {
1073 let ip_addr = addr.tcp().ip();
1074
1075 if !self.ip_filter.is_allowed(&ip_addr) {
1077 trace!(target: "net", ?peer_id, ?ip_addr, "Skipping outbound connection to IP not in allowed ranges");
1078 return
1079 }
1080
1081 if self.ban_list.is_banned(&peer_id, &ip_addr) {
1082 return
1083 }
1084
1085 match self.peers.entry(peer_id) {
1086 Entry::Occupied(mut entry) => {
1087 let peer = entry.get_mut();
1088 peer.kind = kind;
1089 peer.fork_id = fork_id.map(Box::new);
1090 peer.addr = addr;
1091
1092 if peer.state.is_idle() {
1093 peer.state = PeerConnectionState::PendingOut;
1095 self.connection_info.inc_pending_out();
1096 self.queued_actions
1097 .push_back(PeerAction::Connect { peer_id, remote_addr: addr.tcp() });
1098 }
1099 }
1100 Entry::Vacant(entry) => {
1101 trace!(target: "net::peers", ?peer_id, addr=?addr.tcp(), "connects new node");
1102 let mut peer = Peer::with_kind(addr, kind);
1103 peer.state = PeerConnectionState::PendingOut;
1104 peer.fork_id = fork_id.map(Box::new);
1105 entry.insert(peer);
1106 self.connection_info.inc_pending_out();
1107 self.queued_actions
1108 .push_back(PeerAction::Connect { peer_id, remote_addr: addr.tcp() });
1109 }
1110 }
1111
1112 if kind.is_trusted() {
1113 self.trusted_peer_ids.insert(peer_id);
1114 }
1115 }
1116
1117 pub(crate) fn remove_peer_from_trusted_set(&mut self, peer_id: PeerId) {
1119 self.trusted_peers_resolver.remove(peer_id);
1120 self.trusted_peer_ids.remove(&peer_id);
1121 if let Some(peer) = self.peers.get_mut(&peer_id) &&
1122 peer.is_trusted()
1123 {
1124 peer.kind = PeerKind::Basic;
1125 }
1126 }
1127
1128 fn best_unconnected(&mut self, trusted_only: bool) -> Option<(PeerId, &mut Peer)> {
1142 let mut unconnected = self.peers.iter_mut().filter(|(peer_id, peer)| {
1143 !peer.is_backed_off() &&
1144 !peer.is_banned() &&
1145 peer.state.is_unconnected() &&
1146 (!(self.trusted_nodes_only || trusted_only) ||
1147 peer.is_trusted() ||
1148 self.trusted_peer_ids.contains(*peer_id))
1149 });
1150
1151 let mut best_peer = unconnected.next()?;
1153
1154 if best_peer.1.is_trusted() ||
1155 best_peer.1.is_static() ||
1156 self.trusted_peer_ids.contains(best_peer.0)
1157 {
1158 return Some((*best_peer.0, best_peer.1))
1159 }
1160
1161 for maybe_better in unconnected {
1162 if maybe_better.1.is_trusted() ||
1164 maybe_better.1.is_static() ||
1165 self.trusted_peer_ids.contains(maybe_better.0)
1166 {
1167 return Some((*maybe_better.0, maybe_better.1))
1168 }
1169
1170 match maybe_better.1.reputation.cmp(&best_peer.1.reputation) {
1172 std::cmp::Ordering::Greater => best_peer = maybe_better,
1173 std::cmp::Ordering::Equal
1174 if maybe_better.1.fork_id.is_some() && best_peer.1.fork_id.is_none() =>
1175 {
1176 best_peer = maybe_better
1177 }
1178 _ => {}
1179 }
1180 }
1181 Some((*best_peer.0, best_peer.1))
1182 }
1183
1184 fn try_rotate_peer(&mut self) {
1191 let outbound_at_capacity = self.connection_info.is_outbound_at_capacity();
1192 let inbound_at_capacity = self.connection_info.is_inbound_at_capacity();
1193
1194 if !outbound_at_capacity && !inbound_at_capacity {
1195 return
1196 }
1197
1198 let now = std::time::Instant::now();
1199
1200 let candidates = self
1201 .peers
1202 .iter()
1203 .filter_map(|(peer_id, peer)| {
1204 let eligible = match peer.state {
1205 PeerConnectionState::Out => outbound_at_capacity,
1206 PeerConnectionState::In => inbound_at_capacity,
1207 _ => false,
1208 };
1209 (eligible &&
1210 !peer.is_trusted() &&
1211 !peer.is_static() &&
1212 !self.trusted_peer_ids.contains(peer_id) &&
1213 peer.connected_for_at_least(now, PEER_ROTATION_MIN_UPTIME))
1214 .then_some(*peer_id)
1215 })
1216 .collect::<Vec<_>>();
1217
1218 if candidates.is_empty() {
1219 return
1220 }
1221 let peer_id = candidates[rand::rng().random_range(0..candidates.len())];
1222
1223 trace!(target: "net::peers", ?peer_id, "rotating peer to open slot for new nodes");
1224
1225 self.queued_actions.push_back(PeerAction::Disconnect {
1226 peer_id,
1227 reason: Some(DisconnectReason::UselessPeer),
1228 });
1229 }
1230
1231 fn fill_outbound_slots(&mut self) {
1237 self.tick();
1238
1239 if !self.net_connection_state.is_active() {
1240 return
1242 }
1243
1244 while self.connection_info.has_out_dial_capacity() {
1246 let has_out_capacity = self.connection_info.has_out_capacity();
1249 let action = {
1250 let Some((peer_id, peer)) = self.best_unconnected(!has_out_capacity) else { break };
1251
1252 trace!(target: "net::peers", ?peer_id, addr=?peer.addr, "schedule outbound connection");
1253
1254 peer.state = PeerConnectionState::PendingOut;
1255 PeerAction::Connect { peer_id, remote_addr: peer.addr.tcp() }
1256 };
1257
1258 self.connection_info.inc_pending_out();
1259
1260 self.queued_actions.push_back(action);
1261 }
1262 }
1263
1264 fn on_resolved_peer(&mut self, peer_id: PeerId, new_record: NodeRecord) {
1265 if !self.trusted_peer_ids.contains(&peer_id) {
1266 trace!(target: "net::peers", ?peer_id, "Ignoring resolved trusted peer after removal");
1267 return
1268 }
1269
1270 let new_addr = PeerAddr::new_with_ports(
1271 new_record.address,
1272 new_record.tcp_port,
1273 Some(new_record.udp_port),
1274 );
1275
1276 if let Some(peer) = self.peers.get_mut(&peer_id) {
1277 if peer.addr != new_addr {
1278 peer.addr = new_addr;
1279 trace!(target: "net::peers", ?peer_id, addr=?peer.addr, "Updated resolved trusted peer address");
1280 }
1281 } else {
1282 trace!(target: "net::peers", ?peer_id, ?new_addr, "Adding trusted peer after first successful resolution");
1283 self.add_peer_kind(peer_id, Some(PeerKind::Trusted), new_addr, None);
1284 }
1285 }
1286
1287 pub const fn on_network_state_change(&mut self, state: NetworkConnectionState) {
1289 self.net_connection_state = state;
1290 }
1291
1292 pub const fn connection_state(&self) -> &NetworkConnectionState {
1294 &self.net_connection_state
1295 }
1296
1297 pub const fn on_shutdown(&mut self) {
1299 self.net_connection_state = NetworkConnectionState::ShuttingDown;
1300 }
1301
1302 pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll<PeerAction> {
1307 loop {
1308 if let Some(action) = self.queued_actions.pop_front() {
1310 return Poll::Ready(action)
1311 }
1312
1313 while let Poll::Ready(Some(cmd)) = self.handle_rx.poll_next_unpin(cx) {
1314 match cmd {
1315 PeerCommand::Add(peer_id, addr) => {
1316 self.add_requested_peer(peer_id, None, PeerAddr::from_tcp(addr));
1317 }
1318 PeerCommand::Remove(peer) => self.remove_peer(peer),
1319 PeerCommand::ReputationChange(peer_id, rep) => {
1320 self.apply_reputation_change(&peer_id, rep)
1321 }
1322 PeerCommand::GetPeer(peer, tx) => {
1323 let _ = tx.send(self.peers.get(&peer).cloned());
1324 }
1325 PeerCommand::GetPeers(tx) => {
1326 let _ = tx.send(self.iter_peers().collect());
1327 }
1328 }
1329 }
1330
1331 if self.release_interval.poll_tick(cx).is_ready() {
1332 let now = std::time::Instant::now();
1333 let (_, unbanned_peers) = self.ban_list.evict(now);
1334
1335 for peer_id in unbanned_peers {
1336 if let Some(peer) = self.peers.get_mut(&peer_id) {
1337 peer.unban();
1338 self.queued_actions.push_back(PeerAction::UnBanPeer { peer_id });
1339 }
1340 }
1341
1342 self.backed_off_peers.retain(|peer_id, until| {
1345 if now > *until {
1346 if let Some(peer) = self.peers.get_mut(peer_id) {
1347 peer.backed_off = false;
1348 }
1349 return false
1350 }
1351 true
1352 })
1353 }
1354
1355 while self.refill_slots_interval.poll_tick(cx).is_ready() {
1356 self.fill_outbound_slots();
1357 }
1358
1359 if let Poll::Ready((peer_id, new_record)) = self.trusted_peers_resolver.poll(cx) {
1360 self.on_resolved_peer(peer_id, new_record);
1361 }
1362
1363 let rotation_ready = self
1365 .peer_rotation_sleep
1366 .as_mut()
1367 .is_some_and(|sleep| sleep.as_mut().poll(cx).is_ready());
1368 if rotation_ready {
1369 self.try_rotate_peer();
1370 if let Some((mean, sleep)) =
1371 self.peer_rotation_mean.zip(self.peer_rotation_sleep.as_mut())
1372 {
1373 sleep
1374 .as_mut()
1375 .reset(tokio::time::Instant::now() + jitter_rotation_interval(mean));
1376 }
1377 }
1378
1379 if self.queued_actions.is_empty() {
1380 return Poll::Pending
1381 }
1382 }
1383 }
1384}
1385
1386impl Default for PeersManager {
1387 fn default() -> Self {
1388 Self::new(Default::default())
1389 }
1390}
1391
1392#[derive(Debug, Clone, PartialEq, Eq, Default)]
1394pub struct ConnectionInfo {
1395 num_outbound: usize,
1397 num_pending_out: usize,
1399 num_inbound: usize,
1401 num_pending_in: usize,
1403 config: ConnectionsConfig,
1405}
1406
1407impl ConnectionInfo {
1410 const fn new(config: ConnectionsConfig) -> Self {
1412 Self { config, num_outbound: 0, num_pending_out: 0, num_inbound: 0, num_pending_in: 0 }
1413 }
1414
1415 const fn has_out_capacity(&self) -> bool {
1417 self.has_out_dial_capacity() &&
1418 self.num_pending_out < self.config.max_outbound.saturating_sub(self.num_outbound)
1419 }
1420
1421 const fn is_outbound_at_capacity(&self) -> bool {
1423 self.num_outbound >= self.config.max_outbound
1424 }
1425
1426 const fn is_inbound_at_capacity(&self) -> bool {
1428 self.num_inbound >= self.config.max_inbound
1429 }
1430
1431 const fn has_in_capacity(&self) -> bool {
1433 self.num_inbound < self.config.max_inbound
1434 }
1435
1436 const fn has_in_pending_capacity(&self) -> bool {
1438 self.num_pending_in < self.config.max_inbound
1439 }
1440
1441 const fn has_out_dial_capacity(&self) -> bool {
1444 self.num_pending_out < self.config.max_concurrent_outbound_dials
1445 }
1446
1447 const fn decr_state(&mut self, state: PeerConnectionState) {
1448 match state {
1449 PeerConnectionState::Idle => {}
1450 PeerConnectionState::DisconnectingIn | PeerConnectionState::In => self.decr_in(),
1451 PeerConnectionState::DisconnectingOut | PeerConnectionState::Out => self.decr_out(),
1452 PeerConnectionState::PendingOut => self.decr_pending_out(),
1453 }
1454 }
1455
1456 const fn decr_out(&mut self) {
1457 self.num_outbound -= 1;
1458 }
1459
1460 const fn inc_out(&mut self) {
1461 self.num_outbound += 1;
1462 }
1463
1464 const fn inc_pending_out(&mut self) {
1465 self.num_pending_out += 1;
1466 }
1467
1468 const fn inc_in(&mut self) {
1469 self.num_inbound += 1;
1470 }
1471
1472 const fn inc_pending_in(&mut self) {
1473 self.num_pending_in += 1;
1474 }
1475
1476 const fn decr_in(&mut self) {
1477 self.num_inbound -= 1;
1478 }
1479
1480 const fn decr_pending_out(&mut self) {
1481 self.num_pending_out -= 1;
1482 }
1483
1484 const fn decr_pending_in(&mut self) {
1485 self.num_pending_in -= 1;
1486 }
1487}
1488
1489#[derive(Debug)]
1491pub enum PeerAction {
1492 Connect {
1494 peer_id: PeerId,
1496 remote_addr: SocketAddr,
1498 },
1499 Disconnect {
1501 peer_id: PeerId,
1503 reason: Option<DisconnectReason>,
1505 },
1506 DisconnectBannedIncoming {
1509 peer_id: PeerId,
1511 },
1512 DisconnectUntrustedIncoming {
1514 peer_id: PeerId,
1516 },
1517 DiscoveryBanPeerId {
1519 peer_id: PeerId,
1521 ip_addr: IpAddr,
1523 },
1524 DiscoveryBanIp {
1526 ip_addr: IpAddr,
1528 },
1529 BanPeer {
1531 peer_id: PeerId,
1533 },
1534 UnBanPeer {
1536 peer_id: PeerId,
1538 },
1539 PeerAdded(PeerId),
1541 PeerRemoved(PeerId),
1543}
1544
1545#[derive(Debug, Error, PartialEq, Eq)]
1547pub enum InboundConnectionError {
1548 IpBanned,
1550 ExceedsCapacity,
1552}
1553
1554impl Display for InboundConnectionError {
1555 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1556 write!(f, "{self:?}")
1557 }
1558}
1559
1560#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1562pub enum BackoffReason {
1563 TooManyPeers,
1565 GracefulClose,
1567 ConnectionError,
1569}
1570
1571impl BackoffReason {
1572 pub const fn from_disconnect(reason: Option<DisconnectReason>) -> Self {
1574 match reason {
1575 Some(DisconnectReason::TooManyPeers) => Self::TooManyPeers,
1576 _ => Self::ConnectionError,
1577 }
1578 }
1579}
1580
1581fn jitter_rotation_interval(mean: Duration) -> Duration {
1586 let min_nanos = (mean * 3 / 5).as_nanos() as u64;
1587 let max_nanos = (mean * 7 / 5).as_nanos() as u64;
1588 Duration::from_nanos(rand::rng().random_range(min_nanos..=max_nanos))
1589}
1590
1591#[cfg(test)]
1592mod tests {
1593 use super::*;
1594 use alloy_primitives::B512;
1595 use reth_ecies::ECIESErrorImpl;
1596 use reth_eth_wire::{
1597 errors::{EthHandshakeError, EthStreamError, P2PHandshakeError, P2PStreamError},
1598 DisconnectReason,
1599 };
1600 use reth_ethereum_forks::{ForkHash, ForkId};
1601 use reth_net_banlist::BanList;
1602 use reth_network_api::Direction;
1603 use reth_network_peers::{NodeRecord, PeerId, TrustedPeer};
1604 use reth_network_types::{
1605 peers::reputation::DEFAULT_REPUTATION, BackoffKind, Peer, PeerKind, ReputationChangeKind,
1606 };
1607 use std::{
1608 future::{poll_fn, Future},
1609 io,
1610 net::{IpAddr, Ipv4Addr, SocketAddr},
1611 pin::Pin,
1612 task::{Context, Poll, Waker},
1613 time::Duration,
1614 };
1615 use url::Host;
1616
1617 use crate::{
1618 error::SessionError,
1619 peers::{
1620 ConnectionInfo, InboundConnectionError, PeerAction, PeerAddr, PeerBackoffDurations,
1621 PeerConnectionState, MAX_INCOMING_IP_THROTTLE_ENTRIES,
1622 },
1623 session::PendingSessionHandshakeError,
1624 PeersConfig,
1625 };
1626
1627 struct PeerActionFuture<'a> {
1628 peers: &'a mut PeersManager,
1629 }
1630
1631 impl Future for PeerActionFuture<'_> {
1632 type Output = PeerAction;
1633
1634 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1635 self.get_mut().peers.poll(cx)
1636 }
1637 }
1638
1639 macro_rules! event {
1640 ($peers:expr) => {
1641 PeerActionFuture { peers: &mut $peers }.await
1642 };
1643 }
1644
1645 fn set_connected_at(
1646 peers: &mut PeersManager,
1647 peer_id: PeerId,
1648 connected_at: std::time::Instant,
1649 ) {
1650 peers.peers.get_mut(&peer_id).expect("peer exists").connected_at = Some(connected_at);
1651 }
1652
1653 fn poll_now(peers: &mut PeersManager) -> Poll<PeerAction> {
1655 peers.poll(&mut Context::from_waker(Waker::noop()))
1656 }
1657
1658 #[tokio::test]
1659 async fn test_insert() {
1660 let peer = PeerId::random();
1661 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1662 let mut peers = PeersManager::default();
1663 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1664
1665 match event!(peers) {
1666 PeerAction::PeerAdded(peer_id) => {
1667 assert_eq!(peer_id, peer);
1668 }
1669 _ => unreachable!(),
1670 }
1671 match event!(peers) {
1672 PeerAction::Connect { peer_id, remote_addr } => {
1673 assert_eq!(peer_id, peer);
1674 assert_eq!(remote_addr, socket_addr);
1675 }
1676 _ => unreachable!(),
1677 }
1678
1679 let (record, _) = peers.peer_by_id(peer).unwrap();
1680 assert_eq!(record.tcp_addr(), socket_addr);
1681 assert_eq!(record.udp_addr(), socket_addr);
1682 }
1683
1684 #[tokio::test]
1685 async fn test_insert_udp() {
1686 let peer = PeerId::random();
1687 let tcp_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1688 let udp_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
1689 let mut peers = PeersManager::default();
1690 peers.add_peer(peer, PeerAddr::new(tcp_addr, Some(udp_addr)), None);
1691
1692 match event!(peers) {
1693 PeerAction::PeerAdded(peer_id) => {
1694 assert_eq!(peer_id, peer);
1695 }
1696 _ => unreachable!(),
1697 }
1698 match event!(peers) {
1699 PeerAction::Connect { peer_id, remote_addr } => {
1700 assert_eq!(peer_id, peer);
1701 assert_eq!(remote_addr, tcp_addr);
1702 }
1703 _ => unreachable!(),
1704 }
1705
1706 let (record, _) = peers.peer_by_id(peer).unwrap();
1707 assert_eq!(record.tcp_addr(), tcp_addr);
1708 assert_eq!(record.udp_addr(), udp_addr);
1709 }
1710
1711 #[tokio::test]
1712 async fn test_ban() {
1713 let peer = PeerId::random();
1714 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1715 let mut peers = PeersManager::default();
1716 peers.ban_peer(peer);
1717 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1718
1719 match event!(peers) {
1720 PeerAction::BanPeer { peer_id } => {
1721 assert_eq!(peer_id, peer);
1722 }
1723 _ => unreachable!(),
1724 }
1725
1726 poll_fn(|cx| {
1727 assert!(peers.poll(cx).is_pending());
1728 Poll::Ready(())
1729 })
1730 .await;
1731 }
1732
1733 #[tokio::test]
1734 async fn test_unban() {
1735 let peer = PeerId::random();
1736 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1737 let mut peers = PeersManager::default();
1738 peers.ban_peer(peer);
1739 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1740
1741 match event!(peers) {
1742 PeerAction::BanPeer { peer_id } => {
1743 assert_eq!(peer_id, peer);
1744 }
1745 _ => unreachable!(),
1746 }
1747
1748 poll_fn(|cx| {
1749 assert!(peers.poll(cx).is_pending());
1750 Poll::Ready(())
1751 })
1752 .await;
1753
1754 peers.unban_peer(peer);
1755
1756 match event!(peers) {
1757 PeerAction::UnBanPeer { peer_id } => {
1758 assert_eq!(peer_id, peer);
1759 }
1760 _ => unreachable!(),
1761 }
1762
1763 poll_fn(|cx| {
1764 assert!(peers.poll(cx).is_pending());
1765 Poll::Ready(())
1766 })
1767 .await;
1768 }
1769
1770 #[tokio::test]
1771 async fn test_admin_ban_removes_peer_and_bans_indefinitely() {
1772 let peer = PeerId::random();
1773 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1774 let mut peers = PeersManager::default();
1775 peers.peers.insert(peer, Peer::new(PeerAddr::from_tcp(socket_addr)));
1776
1777 peers.ban_peer_by_admin(peer);
1778
1779 assert!(peers.ban_list.is_banned_peer(&peer));
1780 assert!(peers.peer_by_id(peer).is_none());
1781
1782 match peers.queued_actions.pop_front() {
1783 Some(PeerAction::PeerRemoved(peer_id)) => assert_eq!(peer_id, peer),
1784 other => panic!("unexpected action: {other:?}"),
1785 }
1786
1787 let (_, unbanned_peers) =
1788 peers.ban_list.evict(std::time::Instant::now() + Duration::from_secs(1));
1789 assert!(unbanned_peers.is_empty());
1790 }
1791
1792 #[tokio::test]
1793 async fn test_admin_ban_does_not_override_trusted_peer() {
1794 let peer = PeerId::random();
1795 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1796 let mut peers = PeersManager::default();
1797 peers.peers.insert(peer, Peer::trusted(PeerAddr::from_tcp(socket_addr)));
1798
1799 peers.ban_peer_by_admin(peer);
1800
1801 assert!(!peers.ban_list.is_banned_peer(&peer));
1802 assert!(peers.peer_by_id(peer).is_some());
1803 assert!(peers.queued_actions.is_empty());
1804 }
1805
1806 #[tokio::test]
1807 async fn test_admin_unban_resets_reputation() {
1808 let peer = PeerId::random();
1809 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1810 let mut peers = PeersManager::default();
1811 let mut peer_info = Peer::new(PeerAddr::from_tcp(socket_addr));
1812 peer_info.reputation = i32::MIN;
1813 peers.peers.insert(peer, peer_info);
1814 peers.ban_list.ban_peer(peer);
1815 assert!(peers.peers.get(&peer).is_some_and(Peer::is_banned));
1816
1817 peers.unban_peer_by_admin(peer);
1818
1819 assert!(!peers.ban_list.is_banned_peer(&peer));
1820 assert!(!peers.peers.get(&peer).is_some_and(Peer::is_banned));
1821 assert!(matches!(
1822 peers.queued_actions.pop_front(),
1823 Some(PeerAction::UnBanPeer { peer_id }) if peer_id == peer
1824 ));
1825 }
1826
1827 #[tokio::test]
1828 async fn test_backoff_on_busy() {
1829 let peer = PeerId::random();
1830 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1831
1832 let mut peers = PeersManager::new(PeersConfig::test());
1833 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1834
1835 match event!(peers) {
1836 PeerAction::PeerAdded(peer_id) => {
1837 assert_eq!(peer_id, peer);
1838 }
1839 _ => unreachable!(),
1840 }
1841 match event!(peers) {
1842 PeerAction::Connect { peer_id, .. } => {
1843 assert_eq!(peer_id, peer);
1844 }
1845 _ => unreachable!(),
1846 }
1847
1848 poll_fn(|cx| {
1849 assert!(peers.poll(cx).is_pending());
1850 Poll::Ready(())
1851 })
1852 .await;
1853
1854 peers.on_active_session_dropped(
1855 &socket_addr,
1856 &peer,
1857 &EthStreamError::P2PStreamError(P2PStreamError::Disconnected(
1858 DisconnectReason::TooManyPeers,
1859 )),
1860 );
1861
1862 poll_fn(|cx| {
1863 assert!(peers.poll(cx).is_pending());
1864 Poll::Ready(())
1865 })
1866 .await;
1867
1868 assert!(peers.backed_off_peers.contains_key(&peer));
1869 assert!(peers.peers.get(&peer).unwrap().is_backed_off());
1870
1871 tokio::time::sleep(peers.backoff_durations.low).await;
1872
1873 match event!(peers) {
1874 PeerAction::Connect { peer_id, .. } => {
1875 assert_eq!(peer_id, peer);
1876 }
1877 _ => unreachable!(),
1878 }
1879
1880 assert!(!peers.backed_off_peers.contains_key(&peer));
1881 assert!(!peers.peers.get(&peer).unwrap().is_backed_off());
1882 }
1883
1884 #[tokio::test]
1885 async fn test_backoff_on_no_response() {
1886 let peer = PeerId::random();
1887 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1888
1889 let backoff_durations = PeerBackoffDurations::test();
1890 let config = PeersConfig { backoff_durations, ..PeersConfig::test() };
1891 let mut peers = PeersManager::new(config);
1892 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1893
1894 match event!(peers) {
1895 PeerAction::PeerAdded(peer_id) => {
1896 assert_eq!(peer_id, peer);
1897 }
1898 _ => unreachable!(),
1899 }
1900 match event!(peers) {
1901 PeerAction::Connect { peer_id, .. } => {
1902 assert_eq!(peer_id, peer);
1903 }
1904 _ => unreachable!(),
1905 }
1906
1907 poll_fn(|cx| {
1908 assert!(peers.poll(cx).is_pending());
1909 Poll::Ready(())
1910 })
1911 .await;
1912
1913 peers.on_outgoing_pending_session_dropped(
1914 &socket_addr,
1915 &peer,
1916 &PendingSessionHandshakeError::Eth(EthStreamError::EthHandshakeError(
1917 EthHandshakeError::NoResponse,
1918 )),
1919 );
1920
1921 poll_fn(|cx| {
1922 assert!(peers.poll(cx).is_pending());
1923 Poll::Ready(())
1924 })
1925 .await;
1926
1927 assert!(peers.backed_off_peers.contains_key(&peer));
1928 assert!(peers.peers.get(&peer).unwrap().is_backed_off());
1929
1930 tokio::time::sleep(backoff_durations.high).await;
1931
1932 match event!(peers) {
1933 PeerAction::Connect { peer_id, .. } => {
1934 assert_eq!(peer_id, peer);
1935 }
1936 _ => unreachable!(),
1937 }
1938
1939 assert!(!peers.backed_off_peers.contains_key(&peer));
1940 assert!(!peers.peers.get(&peer).unwrap().is_backed_off());
1941 }
1942
1943 #[tokio::test]
1944 async fn test_low_backoff() {
1945 let peer = PeerId::random();
1946 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1947 let config = PeersConfig::test();
1948 let mut peers = PeersManager::new(config);
1949 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1950 let peer_struct = peers.peers.get_mut(&peer).unwrap();
1951
1952 let backoff_timestamp = peers
1953 .backoff_durations
1954 .backoff_until(BackoffKind::Low, peer_struct.severe_backoff_counter);
1955
1956 let expected = std::time::Instant::now() + peers.backoff_durations.low;
1957 assert!(backoff_timestamp <= expected);
1958 }
1959
1960 #[tokio::test]
1961 async fn test_multiple_backoff_calculations() {
1962 let peer = PeerId::random();
1963 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1964 let config = PeersConfig::default();
1965 let mut peers = PeersManager::new(config);
1966 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1967 let peer_struct = peers.peers.get_mut(&peer).unwrap();
1968
1969 peer_struct.severe_backoff_counter = 1;
1971
1972 let now = std::time::Instant::now();
1973
1974 peer_struct.severe_backoff_counter += 1;
1976 let backoff_time = peers
1978 .backoff_durations
1979 .backoff_until(BackoffKind::High, peer_struct.severe_backoff_counter);
1980
1981 let backoff_duration = std::time::Duration::new(30 * 60, 0);
1983
1984 assert!(backoff_time.duration_since(now) > backoff_duration);
1987 }
1988
1989 #[tokio::test]
1990 async fn test_ban_on_active_drop() {
1991 let peer = PeerId::random();
1992 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
1993 let mut peers = PeersManager::default();
1994 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
1995
1996 match event!(peers) {
1997 PeerAction::PeerAdded(peer_id) => {
1998 assert_eq!(peer_id, peer);
1999 }
2000 _ => unreachable!(),
2001 }
2002 match event!(peers) {
2003 PeerAction::Connect { peer_id, .. } => {
2004 assert_eq!(peer_id, peer);
2005 }
2006 _ => unreachable!(),
2007 }
2008
2009 poll_fn(|cx| {
2010 assert!(peers.poll(cx).is_pending());
2011 Poll::Ready(())
2012 })
2013 .await;
2014
2015 peers.on_active_session_dropped(
2016 &socket_addr,
2017 &peer,
2018 &EthStreamError::P2PStreamError(P2PStreamError::Disconnected(
2019 DisconnectReason::UselessPeer,
2020 )),
2021 );
2022
2023 match event!(peers) {
2024 PeerAction::PeerRemoved(peer_id) => {
2025 assert_eq!(peer_id, peer);
2026 }
2027 _ => unreachable!(),
2028 }
2029 match event!(peers) {
2030 PeerAction::BanPeer { peer_id } => {
2031 assert_eq!(peer_id, peer);
2032 }
2033 _ => unreachable!(),
2034 }
2035
2036 poll_fn(|cx| {
2037 assert!(peers.poll(cx).is_pending());
2038 Poll::Ready(())
2039 })
2040 .await;
2041
2042 assert!(!peers.peers.contains_key(&peer));
2043 }
2044
2045 #[tokio::test]
2046 async fn test_remove_on_max_backoff_count() {
2047 let peer = PeerId::random();
2048 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2049 let config = PeersConfig::test();
2050 let mut peers = PeersManager::new(config.clone());
2051 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2052 let peer_struct = peers.peers.get_mut(&peer).unwrap();
2053
2054 peer_struct.severe_backoff_counter = config.max_backoff_count;
2056
2057 match event!(peers) {
2058 PeerAction::PeerAdded(peer_id) => {
2059 assert_eq!(peer_id, peer);
2060 }
2061 _ => unreachable!(),
2062 }
2063 match event!(peers) {
2064 PeerAction::Connect { peer_id, .. } => {
2065 assert_eq!(peer_id, peer);
2066 }
2067 _ => unreachable!(),
2068 }
2069
2070 poll_fn(|cx| {
2071 assert!(peers.poll(cx).is_pending());
2072 Poll::Ready(())
2073 })
2074 .await;
2075
2076 peers.on_outgoing_connection_failure(
2077 &socket_addr,
2078 &peer,
2079 &io::Error::new(io::ErrorKind::ConnectionRefused, "peer unreachable"),
2080 );
2081
2082 match event!(peers) {
2083 PeerAction::PeerRemoved(peer_id) => {
2084 assert_eq!(peer_id, peer);
2085 }
2086 _ => unreachable!(),
2087 }
2088
2089 poll_fn(|cx| {
2090 assert!(peers.poll(cx).is_pending());
2091 Poll::Ready(())
2092 })
2093 .await;
2094
2095 assert!(!peers.peers.contains_key(&peer));
2096 }
2097
2098 #[tokio::test]
2099 async fn test_ban_on_pending_drop() {
2100 let peer = PeerId::random();
2101 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2102 let mut peers = PeersManager::default();
2103 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2104
2105 match event!(peers) {
2106 PeerAction::PeerAdded(peer_id) => {
2107 assert_eq!(peer_id, peer);
2108 }
2109 _ => unreachable!(),
2110 }
2111 match event!(peers) {
2112 PeerAction::Connect { peer_id, .. } => {
2113 assert_eq!(peer_id, peer);
2114 }
2115 _ => unreachable!(),
2116 }
2117
2118 poll_fn(|cx| {
2119 assert!(peers.poll(cx).is_pending());
2120 Poll::Ready(())
2121 })
2122 .await;
2123
2124 peers.on_outgoing_pending_session_dropped(
2125 &socket_addr,
2126 &peer,
2127 &PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
2128 P2PStreamError::Disconnected(DisconnectReason::UselessPeer),
2129 )),
2130 );
2131
2132 match event!(peers) {
2133 PeerAction::PeerRemoved(peer_id) => {
2134 assert_eq!(peer_id, peer);
2135 }
2136 _ => unreachable!(),
2137 }
2138 match event!(peers) {
2139 PeerAction::BanPeer { peer_id } => {
2140 assert_eq!(peer_id, peer);
2141 }
2142 _ => unreachable!(),
2143 }
2144
2145 poll_fn(|cx| {
2146 assert!(peers.poll(cx).is_pending());
2147 Poll::Ready(())
2148 })
2149 .await;
2150
2151 assert!(!peers.peers.contains_key(&peer));
2152 }
2153
2154 #[tokio::test]
2155 async fn test_internally_closed_incoming() {
2156 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2157 let mut peers = PeersManager::default();
2158
2159 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2160 assert_eq!(peers.connection_info.num_pending_in, 1);
2161 peers.on_incoming_pending_session_rejected_internally();
2162 assert_eq!(peers.connection_info.num_pending_in, 0);
2163 }
2164
2165 #[tokio::test]
2166 async fn test_reject_incoming_at_pending_capacity() {
2167 let mut peers = PeersManager::default();
2168
2169 for count in 1..=peers.connection_info.config.max_inbound {
2170 let socket_addr =
2171 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, count as u8)), 8008);
2172 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2173 assert_eq!(peers.connection_info.num_pending_in, count);
2174 }
2175 assert!(peers.connection_info.has_in_capacity());
2176 assert!(!peers.connection_info.has_in_pending_capacity());
2177
2178 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 100)), 8008);
2179 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_err());
2180 }
2181
2182 #[tokio::test]
2183 async fn test_reject_incoming_at_pending_capacity_trusted_peers() {
2184 let mut peers = PeersManager::new(PeersConfig::test().with_max_inbound(2));
2185 let trusted = PeerId::random();
2186 peers.add_trusted_peer_id(trusted);
2187
2188 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 0)), 8008);
2190 assert!(peers.on_incoming_pending_session(addr.ip()).is_ok());
2191 peers.on_incoming_session_established(trusted, addr);
2192
2193 match event!(peers) {
2194 PeerAction::PeerAdded(id) => {
2195 assert_eq!(id, trusted);
2196 }
2197 _ => unreachable!(),
2198 }
2199
2200 let mut connected_untrusted_peer_ids = Vec::new();
2202 for i in 0..(peers.connection_info.config.max_inbound - 1) {
2203 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, (i + 1) as u8)), 8008);
2204 assert!(peers.on_incoming_pending_session(addr.ip()).is_ok());
2205 let peer_id = PeerId::random();
2206 peers.on_incoming_session_established(peer_id, addr);
2207 connected_untrusted_peer_ids.push(peer_id);
2208
2209 match event!(peers) {
2210 PeerAction::PeerAdded(id) => {
2211 assert_eq!(id, peer_id);
2212 }
2213 _ => unreachable!(),
2214 }
2215 }
2216
2217 let mut pending_addrs = Vec::new();
2218
2219 for i in 0..2 {
2221 let socket_addr =
2222 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, (i + 10) as u8)), 8008);
2223 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2224
2225 pending_addrs.push(socket_addr);
2226 }
2227
2228 assert_eq!(peers.connection_info.num_pending_in, 2);
2229
2230 for i in 0..2 {
2232 let socket_addr =
2233 SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, (i + 20) as u8)), 8008);
2234 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_err());
2235 }
2236
2237 let err = PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
2238 P2PStreamError::HandshakeError(P2PHandshakeError::Disconnected(
2239 DisconnectReason::UselessPeer,
2240 )),
2241 ));
2242
2243 for pending_addr in pending_addrs {
2245 peers.on_incoming_pending_session_dropped(pending_addr, &err);
2246 }
2247
2248 println!("num_pending_in: {}", peers.connection_info.num_pending_in);
2249
2250 println!(
2251 "num_inbound: {}, has_in_capacity: {}",
2252 peers.connection_info.num_inbound,
2253 peers.connection_info.has_in_capacity()
2254 );
2255
2256 peers.on_active_session_gracefully_closed(connected_untrusted_peer_ids[0]);
2258
2259 println!(
2260 "num_inbound: {}, has_in_capacity: {}",
2261 peers.connection_info.num_inbound,
2262 peers.connection_info.has_in_capacity()
2263 );
2264
2265 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 99)), 8008);
2266 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2267 }
2268
2269 #[tokio::test]
2270 async fn test_closed_incoming() {
2271 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2272 let mut peers = PeersManager::default();
2273
2274 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2275 assert_eq!(peers.connection_info.num_pending_in, 1);
2276 peers.on_incoming_pending_session_gracefully_closed();
2277 assert_eq!(peers.connection_info.num_pending_in, 0);
2278 }
2279
2280 #[tokio::test]
2281 async fn test_dropped_incoming() {
2282 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 0, 1, 2)), 8008);
2283 let ban_duration = Duration::from_millis(500);
2284 let config = PeersConfig {
2285 ban_duration,
2286 incoming_ip_throttle_duration: ban_duration,
2287 ..PeersConfig::test()
2288 };
2289 let mut peers = PeersManager::new(config);
2290
2291 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2292 assert_eq!(peers.connection_info.num_pending_in, 1);
2293 let err = PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
2294 P2PStreamError::HandshakeError(P2PHandshakeError::Disconnected(
2295 DisconnectReason::UselessPeer,
2296 )),
2297 ));
2298
2299 peers.on_incoming_pending_session_dropped(socket_addr, &err);
2300 assert_eq!(peers.connection_info.num_pending_in, 0);
2301 assert!(peers.ban_list.is_banned_ip(&socket_addr.ip()));
2302
2303 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_err());
2304
2305 tokio::time::sleep(ban_duration).await;
2307
2308 poll_fn(|cx| {
2309 let _ = peers.poll(cx);
2310 Poll::Ready(())
2311 })
2312 .await;
2313
2314 assert!(!peers.ban_list.is_banned_ip(&socket_addr.ip()));
2315 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2316 }
2317
2318 #[tokio::test]
2319 async fn test_reputation_change_connected() {
2320 let peer = PeerId::random();
2321 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2322 let mut peers = PeersManager::default();
2323 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2324
2325 match event!(peers) {
2326 PeerAction::PeerAdded(peer_id) => {
2327 assert_eq!(peer_id, peer);
2328 }
2329 _ => unreachable!(),
2330 }
2331 match event!(peers) {
2332 PeerAction::Connect { peer_id, remote_addr } => {
2333 assert_eq!(peer_id, peer);
2334 assert_eq!(remote_addr, socket_addr);
2335 }
2336 _ => unreachable!(),
2337 }
2338
2339 let p = peers.peers.get_mut(&peer).unwrap();
2340 assert_eq!(p.state, PeerConnectionState::PendingOut);
2341
2342 peers.apply_reputation_change(&peer, ReputationChangeKind::BadProtocol);
2343
2344 let p = peers.peers.get(&peer).unwrap();
2345 assert_eq!(p.state, PeerConnectionState::PendingOut);
2346 assert!(p.is_banned());
2347
2348 peers.on_active_session_gracefully_closed(peer);
2349
2350 let p = peers.peers.get(&peer).unwrap();
2351 assert_eq!(p.state, PeerConnectionState::Idle);
2352 assert!(p.is_banned());
2353
2354 match event!(peers) {
2355 PeerAction::Disconnect { peer_id, .. } => {
2356 assert_eq!(peer_id, peer);
2357 }
2358 _ => unreachable!(),
2359 }
2360 }
2361
2362 #[tokio::test]
2363 async fn retain_trusted_status() {
2364 let _socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 99)), 8008);
2365 let trusted = PeerId::random();
2366 let mut peers =
2367 PeersManager::new(PeersConfig::test().with_trusted_nodes(vec![TrustedPeer {
2368 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2369 tcp_port: 8008,
2370 udp_port: 8008,
2371 id: trusted,
2372 }]));
2373 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2374 peers.add_peer(trusted, PeerAddr::from_tcp(socket_addr), None);
2375 assert!(peers.peers.get(&trusted).unwrap().is_trusted());
2376 }
2377
2378 #[tokio::test]
2379 async fn accept_incoming_trusted_unknown_peer_address() {
2380 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 99)), 8008);
2381 let mut peers = PeersManager::new(PeersConfig::test().with_max_inbound(2));
2382 let trusted = PeerId::random();
2384 peers.add_trusted_peer_id(trusted);
2385
2386 for i in 0..peers.connection_info.config.max_inbound {
2388 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, i as u8)), 8008);
2389 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2390 let peer_id = PeerId::random();
2391 peers.on_incoming_session_established(peer_id, addr);
2392
2393 match event!(peers) {
2394 PeerAction::PeerAdded(id) => {
2395 assert_eq!(id, peer_id);
2396 }
2397 _ => unreachable!(),
2398 }
2399 }
2400
2401 let untrusted = PeerId::random();
2403 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 99)), 8008);
2404 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2405 peers.on_incoming_session_established(untrusted, socket_addr);
2406
2407 match event!(peers) {
2408 PeerAction::PeerAdded(id) => {
2409 assert_eq!(id, untrusted);
2410 }
2411 _ => unreachable!(),
2412 }
2413
2414 match event!(peers) {
2415 PeerAction::Disconnect { peer_id, reason } => {
2416 assert_eq!(peer_id, untrusted);
2417 assert_eq!(reason, Some(DisconnectReason::TooManyPeers));
2418 }
2419 _ => unreachable!(),
2420 }
2421
2422 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 100)), 8008);
2423 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2424 peers.on_incoming_session_established(trusted, socket_addr);
2425
2426 match event!(peers) {
2427 PeerAction::PeerAdded(id) => {
2428 assert_eq!(id, trusted);
2429 }
2430 _ => unreachable!(),
2431 }
2432
2433 poll_fn(|cx| {
2434 assert!(peers.poll(cx).is_pending());
2435 Poll::Ready(())
2436 })
2437 .await;
2438
2439 let peer = peers.peers.get(&trusted).unwrap();
2440 assert_eq!(peer.state, PeerConnectionState::In);
2441 }
2442
2443 #[tokio::test]
2444 async fn test_already_connected() {
2445 let peer = PeerId::random();
2446 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2447 let mut peers = PeersManager::default();
2448
2449 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2451 assert_eq!(peers.connection_info.num_pending_in, 1);
2452
2453 peers.on_incoming_session_established(peer, socket_addr);
2456 let p = peers.peers.get_mut(&peer).expect("peer not found");
2457 assert_eq!(p.addr.tcp(), socket_addr);
2458 assert_eq!(peers.connection_info.num_pending_in, 0);
2459 assert_eq!(peers.connection_info.num_inbound, 1);
2460
2461 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
2464 assert_eq!(peers.connection_info.num_pending_in, 1);
2465
2466 peers.on_already_connected(Direction::Incoming);
2470
2471 let p = peers.peers.get_mut(&peer).expect("peer not found");
2472 assert_eq!(p.addr.tcp(), socket_addr);
2473 assert_eq!(peers.connection_info.num_pending_in, 0);
2474 assert_eq!(peers.connection_info.num_inbound, 1);
2475 }
2476
2477 #[tokio::test]
2478 async fn test_reputation_change_trusted_peer() {
2479 let peer = PeerId::random();
2480 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2481 let mut peers = PeersManager::default();
2482 peers.add_trusted_peer(peer, PeerAddr::from_tcp(socket_addr));
2483
2484 match event!(peers) {
2485 PeerAction::PeerAdded(peer_id) => {
2486 assert_eq!(peer_id, peer);
2487 }
2488 _ => unreachable!(),
2489 }
2490 match event!(peers) {
2491 PeerAction::Connect { peer_id, remote_addr } => {
2492 assert_eq!(peer_id, peer);
2493 assert_eq!(remote_addr, socket_addr);
2494 }
2495 _ => unreachable!(),
2496 }
2497
2498 assert_eq!(peers.peers.get_mut(&peer).unwrap().state, PeerConnectionState::PendingOut);
2499 peers.on_active_outgoing_established(peer);
2500 assert_eq!(peers.peers.get_mut(&peer).unwrap().state, PeerConnectionState::Out);
2501
2502 peers.apply_reputation_change(&peer, ReputationChangeKind::BadMessage);
2503
2504 {
2505 let p = peers.peers.get(&peer).unwrap();
2506 assert_eq!(p.state, PeerConnectionState::Out);
2507 assert!(!p.is_banned());
2509 }
2510
2511 loop {
2513 peers.apply_reputation_change(&peer, ReputationChangeKind::BadMessage);
2514
2515 let p = peers.peers.get(&peer).unwrap();
2516 if p.is_banned() {
2517 break
2518 }
2519 }
2520
2521 match event!(peers) {
2522 PeerAction::Disconnect { peer_id, .. } => {
2523 assert_eq!(peer_id, peer);
2524 }
2525 _ => unreachable!(),
2526 }
2527 }
2528
2529 #[tokio::test]
2530 async fn test_reputation_management() {
2531 let peer = PeerId::random();
2532 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2533 let mut peers = PeersManager::default();
2534 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2535 assert_eq!(peers.get_reputation(&peer), Some(0));
2536
2537 peers.apply_reputation_change(&peer, ReputationChangeKind::Other(1024));
2538 assert_eq!(peers.get_reputation(&peer), Some(1024));
2539
2540 peers.apply_reputation_change(&peer, ReputationChangeKind::Reset);
2541 assert_eq!(peers.get_reputation(&peer), Some(0));
2542 }
2543
2544 #[tokio::test]
2545 async fn test_remove_discovered_active() {
2546 let peer = PeerId::random();
2547 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2548 let mut peers = PeersManager::default();
2549 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2550
2551 match event!(peers) {
2552 PeerAction::PeerAdded(peer_id) => {
2553 assert_eq!(peer_id, peer);
2554 }
2555 _ => unreachable!(),
2556 }
2557 match event!(peers) {
2558 PeerAction::Connect { peer_id, remote_addr } => {
2559 assert_eq!(peer_id, peer);
2560 assert_eq!(remote_addr, socket_addr);
2561 }
2562 _ => unreachable!(),
2563 }
2564
2565 let p = peers.peers.get(&peer).unwrap();
2566 assert_eq!(p.state, PeerConnectionState::PendingOut);
2567
2568 peers.remove_peer(peer);
2569
2570 match event!(peers) {
2571 PeerAction::PeerRemoved(peer_id) => {
2572 assert_eq!(peer_id, peer);
2573 }
2574 _ => unreachable!(),
2575 }
2576 match event!(peers) {
2577 PeerAction::Disconnect { peer_id, .. } => {
2578 assert_eq!(peer_id, peer);
2579 }
2580 _ => unreachable!(),
2581 }
2582
2583 let p = peers.peers.get(&peer).unwrap();
2584 assert_eq!(p.state, PeerConnectionState::PendingOut);
2585
2586 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2587 let p = peers.peers.get(&peer).unwrap();
2588 assert_eq!(p.state, PeerConnectionState::PendingOut);
2589
2590 peers.on_active_session_gracefully_closed(peer);
2591 assert!(!peers.peers.contains_key(&peer));
2592 }
2593
2594 #[tokio::test]
2595 async fn test_fatal_outgoing_connection_error_trusted() {
2596 let peer = PeerId::random();
2597 let config = PeersConfig::test()
2598 .with_trusted_nodes(vec![TrustedPeer {
2599 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2600 tcp_port: 8008,
2601 udp_port: 8008,
2602 id: peer,
2603 }])
2604 .with_trusted_nodes_only(true);
2605 let mut peers = PeersManager::new(config);
2606 let socket_addr = peers.peers.get(&peer).unwrap().addr.tcp();
2607
2608 match event!(peers) {
2609 PeerAction::Connect { peer_id, remote_addr } => {
2610 assert_eq!(peer_id, peer);
2611 assert_eq!(remote_addr, socket_addr);
2612 }
2613 _ => unreachable!(),
2614 }
2615
2616 let p = peers.peers.get(&peer).unwrap();
2617 assert_eq!(p.state, PeerConnectionState::PendingOut);
2618
2619 assert_eq!(peers.num_outbound_connections(), 0);
2620
2621 let err = PendingSessionHandshakeError::Eth(EthStreamError::EthHandshakeError(
2622 EthHandshakeError::NonStatusMessageInHandshake,
2623 ));
2624 assert!(err.is_fatal_protocol_error());
2625
2626 peers.on_outgoing_pending_session_dropped(&socket_addr, &peer, &err);
2627 assert_eq!(peers.num_outbound_connections(), 0);
2628
2629 match event!(peers) {
2631 PeerAction::BanPeer { peer_id } => {
2632 assert_eq!(peer_id, peer);
2633 }
2634 err => unreachable!("{err:?}"),
2635 }
2636
2637 assert!(peers.peers.contains_key(&peer));
2639
2640 tokio::time::sleep(peers.backoff_durations.medium).await;
2642
2643 match event!(peers) {
2644 PeerAction::Connect { peer_id, remote_addr } => {
2645 assert_eq!(peer_id, peer);
2646 assert_eq!(remote_addr, socket_addr);
2647 }
2648 err => unreachable!("{err:?}"),
2649 }
2650 }
2651
2652 #[tokio::test]
2653 async fn test_outgoing_connection_error() {
2654 let peer = PeerId::random();
2655 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2656 let mut peers = PeersManager::default();
2657 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2658
2659 match event!(peers) {
2660 PeerAction::PeerAdded(peer_id) => {
2661 assert_eq!(peer_id, peer);
2662 }
2663 _ => unreachable!(),
2664 }
2665 match event!(peers) {
2666 PeerAction::Connect { peer_id, remote_addr } => {
2667 assert_eq!(peer_id, peer);
2668 assert_eq!(remote_addr, socket_addr);
2669 }
2670 _ => unreachable!(),
2671 }
2672
2673 let p = peers.peers.get(&peer).unwrap();
2674 assert_eq!(p.state, PeerConnectionState::PendingOut);
2675
2676 assert_eq!(peers.num_outbound_connections(), 0);
2677
2678 peers.on_outgoing_connection_failure(
2679 &socket_addr,
2680 &peer,
2681 &io::Error::new(io::ErrorKind::ConnectionRefused, ""),
2682 );
2683
2684 assert_eq!(peers.num_outbound_connections(), 0);
2685 }
2686
2687 #[tokio::test]
2688 async fn test_outgoing_connection_gracefully_closed() {
2689 let peer = PeerId::random();
2690 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2691 let mut peers = PeersManager::default();
2692 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
2693
2694 match event!(peers) {
2695 PeerAction::PeerAdded(peer_id) => {
2696 assert_eq!(peer_id, peer);
2697 }
2698 _ => unreachable!(),
2699 }
2700 match event!(peers) {
2701 PeerAction::Connect { peer_id, remote_addr } => {
2702 assert_eq!(peer_id, peer);
2703 assert_eq!(remote_addr, socket_addr);
2704 }
2705 _ => unreachable!(),
2706 }
2707
2708 let p = peers.peers.get(&peer).unwrap();
2709 assert_eq!(p.state, PeerConnectionState::PendingOut);
2710
2711 assert_eq!(peers.num_outbound_connections(), 0);
2712
2713 peers.on_outgoing_pending_session_gracefully_closed(&peer);
2714
2715 assert_eq!(peers.num_outbound_connections(), 0);
2716 assert_eq!(peers.connection_info.num_pending_out, 0);
2717 }
2718
2719 #[tokio::test]
2720 async fn test_discovery_ban_list() {
2721 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
2722 let socket_addr = SocketAddr::new(ip, 8008);
2723 let ban_list = BanList::new(vec![], vec![ip]);
2724 let config = PeersConfig::default().with_ban_list(ban_list);
2725 let mut peer_manager = PeersManager::new(config);
2726 peer_manager.add_peer(B512::default(), PeerAddr::from_tcp(socket_addr), None);
2727
2728 assert!(peer_manager.peers.is_empty());
2729 }
2730
2731 #[tokio::test]
2732 async fn test_on_pending_ban_list() {
2733 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
2734 let socket_addr = SocketAddr::new(ip, 8008);
2735 let ban_list = BanList::new(vec![], vec![ip]);
2736 let config = PeersConfig::test().with_ban_list(ban_list);
2737 let mut peer_manager = PeersManager::new(config);
2738 let a = peer_manager.on_incoming_pending_session(socket_addr.ip());
2739 match a {
2741 Ok(_) => panic!(),
2742 Err(err) => match err {
2743 InboundConnectionError::IpBanned => {
2744 assert_eq!(peer_manager.connection_info.num_pending_in, 0)
2745 }
2746 _ => unreachable!(),
2747 },
2748 }
2749 }
2750
2751 #[tokio::test]
2752 async fn test_on_active_inbound_ban_list() {
2753 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
2754 let socket_addr = SocketAddr::new(ip, 8008);
2755 let given_peer_id = PeerId::random();
2756 let ban_list = BanList::new(vec![given_peer_id], vec![]);
2757 let config = PeersConfig::test().with_ban_list(ban_list);
2758 let mut peer_manager = PeersManager::new(config);
2759 assert!(peer_manager.on_incoming_pending_session(socket_addr.ip()).is_ok());
2760 assert_eq!(peer_manager.connection_info.num_pending_in, 1);
2762 peer_manager.on_incoming_session_established(given_peer_id, socket_addr);
2763 assert_eq!(peer_manager.connection_info.num_pending_in, 0);
2766 assert_eq!(peer_manager.connection_info.num_inbound, 0);
2767
2768 let Some(PeerAction::DisconnectBannedIncoming { peer_id }) =
2769 peer_manager.queued_actions.pop_front()
2770 else {
2771 panic!()
2772 };
2773
2774 assert_eq!(peer_id, given_peer_id)
2775 }
2776
2777 #[test]
2778 fn test_connection_limits() {
2779 let mut info = ConnectionInfo::default();
2780 info.inc_in();
2781 assert_eq!(info.num_inbound, 1);
2782 assert_eq!(info.num_outbound, 0);
2783 assert!(info.has_in_capacity());
2784
2785 info.decr_in();
2786 assert_eq!(info.num_inbound, 0);
2787 assert_eq!(info.num_outbound, 0);
2788
2789 info.inc_out();
2790 assert_eq!(info.num_inbound, 0);
2791 assert_eq!(info.num_outbound, 1);
2792 assert!(info.has_out_capacity());
2793
2794 info.decr_out();
2795 assert_eq!(info.num_inbound, 0);
2796 assert_eq!(info.num_outbound, 0);
2797 }
2798
2799 #[test]
2800 fn test_connection_peer_state() {
2801 let mut info = ConnectionInfo::default();
2802 info.inc_in();
2803
2804 info.decr_state(PeerConnectionState::In);
2805 assert_eq!(info.num_inbound, 0);
2806 assert_eq!(info.num_outbound, 0);
2807
2808 info.inc_out();
2809
2810 info.decr_state(PeerConnectionState::Out);
2811 assert_eq!(info.num_inbound, 0);
2812 assert_eq!(info.num_outbound, 0);
2813 }
2814
2815 #[tokio::test]
2816 async fn test_trusted_peers_are_prioritized() {
2817 let trusted_peer = PeerId::random();
2818 let trusted_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2819 let config = PeersConfig::test().with_trusted_nodes(vec![TrustedPeer {
2820 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2821 tcp_port: 8008,
2822 udp_port: 8008,
2823 id: trusted_peer,
2824 }]);
2825 let mut peers = PeersManager::new(config);
2826
2827 let basic_peer = PeerId::random();
2828 let basic_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
2829 peers.add_peer(basic_peer, PeerAddr::from_tcp(basic_sock), None);
2830
2831 match event!(peers) {
2832 PeerAction::PeerAdded(peer_id) => {
2833 assert_eq!(peer_id, basic_peer);
2834 }
2835 _ => unreachable!(),
2836 }
2837 match event!(peers) {
2838 PeerAction::Connect { peer_id, remote_addr } => {
2839 assert_eq!(peer_id, trusted_peer);
2840 assert_eq!(remote_addr, trusted_sock);
2841 }
2842 _ => unreachable!(),
2843 }
2844 match event!(peers) {
2845 PeerAction::Connect { peer_id, remote_addr } => {
2846 assert_eq!(peer_id, basic_peer);
2847 assert_eq!(remote_addr, basic_sock);
2848 }
2849 _ => unreachable!(),
2850 }
2851 }
2852
2853 #[tokio::test]
2854 async fn test_trusted_peers_bypass_outbound_capacity() {
2855 let mut peers = PeersManager::new(PeersConfig::test().with_max_outbound(1));
2856
2857 let basic_peer = PeerId::random();
2859 let basic_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2860 peers.add_peer(basic_peer, PeerAddr::from_tcp(basic_sock), None);
2861 peers.fill_outbound_slots();
2862 peers.on_active_outgoing_established(basic_peer);
2863 assert!(!peers.connection_info.has_out_capacity());
2864 peers.queued_actions.clear();
2865
2866 let static_peer = PeerId::random();
2867 peers.add_peer_kind(
2868 static_peer,
2869 Some(PeerKind::Static),
2870 PeerAddr::from_tcp(basic_sock),
2871 None,
2872 );
2873 assert!(peers.best_unconnected(true).is_none());
2874 peers.queued_actions.clear();
2875
2876 let trusted_peer = PeerId::random();
2878 let trusted_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 3)), 8008);
2879 peers.add_trusted_peer(trusted_peer, PeerAddr::from_tcp(trusted_sock));
2880 peers.queued_actions.clear();
2881 peers.fill_outbound_slots();
2882 match peers.queued_actions.pop_front() {
2883 Some(PeerAction::Connect { peer_id, remote_addr }) => {
2884 assert_eq!(peer_id, trusted_peer);
2885 assert_eq!(remote_addr, trusted_sock);
2886 }
2887 action => panic!("expected the trusted peer to be dialed, got {action:?}"),
2888 }
2889 assert!(peers.queued_actions.is_empty());
2890 peers.on_active_outgoing_established(trusted_peer);
2891
2892 let other_peer = PeerId::random();
2894 let other_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 4)), 8008);
2895 peers.add_peer(other_peer, PeerAddr::from_tcp(other_sock), None);
2896 peers.queued_actions.clear();
2897 peers.fill_outbound_slots();
2898 assert!(peers.queued_actions.is_empty());
2899 assert!(peers.peers[&other_peer].state.is_idle());
2900 }
2901
2902 #[tokio::test]
2903 async fn test_connect_trusted_nodes_only() {
2904 let trusted_peer = PeerId::random();
2905 let trusted_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
2906 let config = PeersConfig::test()
2907 .with_trusted_nodes(vec![TrustedPeer {
2908 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2909 tcp_port: 8008,
2910 udp_port: 8008,
2911 id: trusted_peer,
2912 }])
2913 .with_trusted_nodes_only(true);
2914 let mut peers = PeersManager::new(config);
2915
2916 let basic_peer = PeerId::random();
2917 let basic_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
2918 peers.add_peer(basic_peer, PeerAddr::from_tcp(basic_sock), None);
2919
2920 match event!(peers) {
2921 PeerAction::PeerAdded(peer_id) => {
2922 assert_eq!(peer_id, basic_peer);
2923 }
2924 _ => unreachable!(),
2925 }
2926 match event!(peers) {
2927 PeerAction::Connect { peer_id, remote_addr } => {
2928 assert_eq!(peer_id, trusted_peer);
2929 assert_eq!(remote_addr, trusted_sock);
2930 }
2931 _ => unreachable!(),
2932 }
2933 poll_fn(|cx| {
2934 assert!(peers.poll(cx).is_pending());
2935 Poll::Ready(())
2936 })
2937 .await;
2938 }
2939
2940 #[tokio::test]
2941 async fn test_incoming_with_trusted_nodes_only() {
2942 let trusted_peer = PeerId::random();
2943 let config = PeersConfig::test()
2944 .with_trusted_nodes(vec![TrustedPeer {
2945 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2946 tcp_port: 8008,
2947 udp_port: 8008,
2948 id: trusted_peer,
2949 }])
2950 .with_trusted_nodes_only(true);
2951 let mut peers = PeersManager::new(config);
2952
2953 let basic_peer = PeerId::random();
2954 let basic_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
2955 assert!(peers.on_incoming_pending_session(basic_sock.ip()).is_ok());
2956 assert_eq!(peers.connection_info.num_pending_in, 1);
2958 peers.on_incoming_session_established(basic_peer, basic_sock);
2959 assert_eq!(peers.connection_info.num_pending_in, 0);
2962 assert_eq!(peers.connection_info.num_inbound, 0);
2963
2964 let Some(PeerAction::DisconnectUntrustedIncoming { peer_id }) =
2965 peers.queued_actions.pop_front()
2966 else {
2967 panic!()
2968 };
2969 assert_eq!(basic_peer, peer_id);
2970 assert!(!peers.peers.contains_key(&basic_peer));
2971 }
2972
2973 #[tokio::test]
2974 async fn test_incoming_without_trusted_nodes_only() {
2975 let trusted_peer = PeerId::random();
2976 let config = PeersConfig::test()
2977 .with_trusted_nodes(vec![TrustedPeer {
2978 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 2)),
2979 tcp_port: 8008,
2980 udp_port: 8008,
2981 id: trusted_peer,
2982 }])
2983 .with_trusted_nodes_only(false);
2984 let mut peers = PeersManager::new(config);
2985
2986 let basic_peer = PeerId::random();
2987 let basic_sock = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
2988 assert!(peers.on_incoming_pending_session(basic_sock.ip()).is_ok());
2989
2990 assert_eq!(peers.connection_info.num_pending_in, 1);
2992 peers.on_incoming_session_established(basic_peer, basic_sock);
2993 assert_eq!(peers.connection_info.num_pending_in, 0);
2996 assert_eq!(peers.connection_info.num_inbound, 1);
2997 assert!(peers.peers.contains_key(&basic_peer));
2998 }
2999
3000 #[tokio::test]
3001 async fn test_incoming_at_capacity() {
3002 let mut config = PeersConfig::test();
3003 config.connection_info.max_inbound = 1;
3004 let mut peers = PeersManager::new(config);
3005
3006 let peer = PeerId::random();
3007 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3008 assert!(peers.on_incoming_pending_session(addr.ip()).is_ok());
3009
3010 peers.on_incoming_session_established(peer, addr);
3011
3012 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3013 assert_eq!(
3014 peers.on_incoming_pending_session(addr.ip()).unwrap_err(),
3015 InboundConnectionError::ExceedsCapacity
3016 );
3017 }
3018
3019 #[tokio::test]
3020 async fn test_incoming_rate_limit() {
3021 for max_inbound in [0, 1] {
3022 let config = PeersConfig {
3023 incoming_ip_throttle_duration: Duration::from_millis(100),
3024 ..PeersConfig::test().with_max_inbound(max_inbound)
3025 };
3026 let mut peers = PeersManager::new(config);
3027 peers.add_trusted_peer_id(PeerId::random());
3028
3029 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(168, 0, 1, 2)), 8009);
3030 peers.on_incoming_pending_session(addr.ip()).unwrap();
3031 peers.on_incoming_pending_session_gracefully_closed();
3032 assert_eq!(
3033 peers.on_incoming_pending_session(addr.ip()).unwrap_err(),
3034 InboundConnectionError::IpBanned
3035 );
3036
3037 peers.release_interval.reset_immediately();
3038 tokio::time::sleep(peers.incoming_ip_throttle_duration).await;
3039
3040 poll_fn(|cx| loop {
3042 if peers.poll(cx).is_pending() {
3043 return Poll::Ready(());
3044 }
3045 })
3046 .await;
3047
3048 peers.on_incoming_pending_session(addr.ip()).unwrap();
3049 peers.on_incoming_pending_session_gracefully_closed();
3050 assert_eq!(
3051 peers.on_incoming_pending_session(addr.ip()).unwrap_err(),
3052 InboundConnectionError::IpBanned
3053 );
3054 }
3055 }
3056
3057 #[tokio::test]
3058 async fn test_incoming_throttle_capacity() {
3059 for max_inbound in [0, 1] {
3060 let mut peers = PeersManager::new(PeersConfig::test().with_max_inbound(max_inbound));
3061 peers.add_trusted_peer_id(PeerId::random());
3062 peers.ban_list = BanList::new(
3063 [],
3064 (0..MAX_INCOMING_IP_THROTTLE_ENTRIES)
3065 .map(|i| IpAddr::V4(Ipv4Addr::from(0x0800_0000 + i))),
3066 );
3067 for i in 0..MAX_INCOMING_IP_THROTTLE_ENTRIES {
3068 peers.throttle_incoming_ip(IpAddr::V4(Ipv4Addr::from(0x0900_0000 + i)));
3069 }
3070 let ip = IpAddr::from([1, 1, 1, 1]);
3071 assert!(peers.on_incoming_pending_session(ip).is_ok());
3072 assert_eq!(peers.connection_info.num_pending_in, 1);
3073 assert_eq!(
3074 peers.incoming_ip_throttle.len(),
3075 usize::try_from(MAX_INCOMING_IP_THROTTLE_ENTRIES).unwrap()
3076 );
3077 peers.on_incoming_pending_session_gracefully_closed();
3078 assert_eq!(peers.connection_info.num_pending_in, 0);
3079 assert_eq!(
3080 peers.on_incoming_pending_session(ip),
3081 Err(InboundConnectionError::IpBanned)
3082 );
3083
3084 assert_eq!(
3086 peers.on_incoming_pending_session(IpAddr::from([8, 0, 0, 1])),
3087 Err(InboundConnectionError::IpBanned)
3088 );
3089 }
3090 }
3091
3092 #[tokio::test]
3093 async fn test_tick() {
3094 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
3095 let socket_addr = SocketAddr::new(ip, 8008);
3096 let config = PeersConfig::test();
3097 let mut peer_manager = PeersManager::new(config);
3098 let peer_id = PeerId::random();
3099 peer_manager.add_peer(peer_id, PeerAddr::from_tcp(socket_addr), None);
3100
3101 peer_manager.last_tick -= Duration::from_secs(1);
3103 peer_manager.tick();
3104
3105 assert_eq!(peer_manager.peers.get_mut(&peer_id).unwrap().reputation, DEFAULT_REPUTATION);
3107
3108 peer_manager.peers.get_mut(&peer_id).unwrap().state = PeerConnectionState::Out;
3110
3111 peer_manager.last_tick -= Duration::from_secs(1);
3112 peer_manager.tick();
3113
3114 assert_eq!(peer_manager.peers.get_mut(&peer_id).unwrap().reputation, DEFAULT_REPUTATION);
3116
3117 peer_manager.peers.get_mut(&peer_id).unwrap().reputation -= 1;
3118
3119 peer_manager.last_tick -= Duration::from_secs(1);
3120 peer_manager.tick();
3121
3122 assert!(peer_manager.peers.get_mut(&peer_id).unwrap().reputation >= DEFAULT_REPUTATION);
3124 }
3125
3126 #[tokio::test]
3127 async fn test_remove_incoming_after_disconnect() {
3128 let peer_id = PeerId::random();
3129 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3130 let mut peers = PeersManager::default();
3131
3132 peers.on_incoming_pending_session(addr.ip()).unwrap();
3133 peers.on_incoming_session_established(peer_id, addr);
3134 let peer = peers.peers.get(&peer_id).unwrap();
3135 assert_eq!(peer.state, PeerConnectionState::In);
3136 assert!(peer.remove_after_disconnect);
3137
3138 peers.on_active_session_gracefully_closed(peer_id);
3139 assert!(!peers.peers.contains_key(&peer_id))
3140 }
3141
3142 #[tokio::test]
3143 async fn test_keep_incoming_after_disconnect_if_discovered() {
3144 let peer_id = PeerId::random();
3145 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3146 let mut peers = PeersManager::default();
3147
3148 peers.on_incoming_pending_session(addr.ip()).unwrap();
3149 peers.on_incoming_session_established(peer_id, addr);
3150 let peer = peers.peers.get(&peer_id).unwrap();
3151 assert_eq!(peer.state, PeerConnectionState::In);
3152 assert!(peer.remove_after_disconnect);
3153
3154 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
3156
3157 peers.on_active_session_gracefully_closed(peer_id);
3158
3159 let peer = peers.peers.get(&peer_id).unwrap();
3160 assert_eq!(peer.state, PeerConnectionState::Idle);
3161 assert!(!peer.remove_after_disconnect);
3162 }
3163
3164 #[tokio::test]
3165 async fn test_peer_reconnect_after_graceful_close_respects_throttle() {
3166 let throttle_duration = Duration::from_millis(100);
3167 let config =
3168 PeersConfig { incoming_ip_throttle_duration: throttle_duration, ..PeersConfig::test() };
3169 let mut peers = PeersManager::new(config);
3170
3171 let peer_id = PeerId::random();
3172 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3173
3174 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
3176
3177 match event!(peers) {
3178 PeerAction::PeerAdded(id) => assert_eq!(id, peer_id),
3179 _ => unreachable!(),
3180 }
3181
3182 match event!(peers) {
3183 PeerAction::Connect { .. } => {}
3184 _ => unreachable!(),
3185 }
3186
3187 peers.on_active_outgoing_established(peer_id);
3189 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::Out);
3190
3191 peers.on_active_session_gracefully_closed(peer_id);
3193
3194 let peer = peers.peers.get(&peer_id).unwrap();
3195 assert_eq!(peer.state, PeerConnectionState::Idle);
3196 assert!(peer.backed_off);
3197
3198 assert!(peers.backed_off_peers.contains_key(&peer_id));
3200
3201 poll_fn(|cx| {
3203 assert!(peers.poll(cx).is_pending());
3204 Poll::Ready(())
3205 })
3206 .await;
3207
3208 assert!(peers.backed_off_peers.contains_key(&peer_id));
3210 assert!(peers.peers.get(&peer_id).unwrap().backed_off);
3211
3212 tokio::time::sleep(throttle_duration).await;
3214
3215 match event!(peers) {
3217 PeerAction::Connect { peer_id: id, .. } => assert_eq!(id, peer_id),
3218 _ => unreachable!(),
3219 }
3220
3221 assert!(!peers.backed_off_peers.contains_key(&peer_id));
3223 assert!(!peers.peers.get(&peer_id).unwrap().backed_off);
3224 }
3225
3226 #[tokio::test]
3227 async fn test_backed_off_peer_can_accept_incoming_connection() {
3228 let throttle_duration = Duration::from_millis(100);
3229 let config =
3230 PeersConfig { incoming_ip_throttle_duration: throttle_duration, ..PeersConfig::test() };
3231 let mut peers = PeersManager::new(config);
3232
3233 let peer_id = PeerId::random();
3234 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3235
3236 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
3238
3239 match event!(peers) {
3240 PeerAction::PeerAdded(id) => assert_eq!(id, peer_id),
3241 _ => unreachable!(),
3242 }
3243
3244 match event!(peers) {
3245 PeerAction::Connect { .. } => {}
3246 _ => unreachable!(),
3247 }
3248
3249 peers.on_active_outgoing_established(peer_id);
3251 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::Out);
3252
3253 peers.on_active_session_gracefully_closed(peer_id);
3255
3256 let peer = peers.peers.get(&peer_id).unwrap();
3257 assert_eq!(peer.state, PeerConnectionState::Idle);
3258 assert!(peer.backed_off);
3259 assert!(peers.backed_off_peers.contains_key(&peer_id));
3260
3261 assert!(peers.on_incoming_pending_session(addr.ip()).is_ok());
3264 assert_eq!(peers.connection_info.num_pending_in, 1);
3265
3266 peers.on_incoming_session_established(peer_id, addr);
3268
3269 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::In);
3271 assert_eq!(peers.connection_info.num_inbound, 1);
3272
3273 assert!(peers.backed_off_peers.contains_key(&peer_id));
3275 assert!(peers.peers.get(&peer_id).unwrap().backed_off);
3276
3277 poll_fn(|cx| {
3279 assert!(peers.poll(cx).is_pending());
3280 Poll::Ready(())
3281 })
3282 .await;
3283
3284 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::In);
3286
3287 tokio::time::sleep(throttle_duration).await;
3289
3290 poll_fn(|cx| {
3291 let _ = peers.poll(cx);
3292 Poll::Ready(())
3293 })
3294 .await;
3295
3296 assert!(!peers.backed_off_peers.contains_key(&peer_id));
3298 assert!(!peers.peers.get(&peer_id).unwrap().backed_off);
3299
3300 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::In);
3302 }
3303
3304 #[tokio::test]
3305 async fn test_incoming_outgoing_already_connected() {
3306 let peer_id = PeerId::random();
3307 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3308 let mut peers = PeersManager::default();
3309
3310 peers.on_incoming_pending_session(addr.ip()).unwrap();
3311 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
3312
3313 match event!(peers) {
3314 PeerAction::PeerAdded(_) => {}
3315 _ => unreachable!(),
3316 }
3317
3318 match event!(peers) {
3319 PeerAction::Connect { .. } => {}
3320 _ => unreachable!(),
3321 }
3322
3323 peers.on_incoming_session_established(peer_id, addr);
3324 peers.on_already_connected(Direction::Outgoing(peer_id));
3325 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::In);
3326 assert_eq!(peers.connection_info.num_inbound, 1);
3327 assert_eq!(peers.connection_info.num_pending_out, 0);
3328 assert_eq!(peers.connection_info.num_pending_in, 0);
3329 assert_eq!(peers.connection_info.num_outbound, 0);
3330 }
3331
3332 #[tokio::test]
3333 async fn test_already_connected_incoming_outgoing_connection_error() {
3334 let peer_id = PeerId::random();
3335 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8009);
3336 let mut peers = PeersManager::default();
3337
3338 peers.on_incoming_pending_session(addr.ip()).unwrap();
3339 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
3340
3341 match event!(peers) {
3342 PeerAction::PeerAdded(_) => {}
3343 _ => unreachable!(),
3344 }
3345
3346 match event!(peers) {
3347 PeerAction::Connect { .. } => {}
3348 _ => unreachable!(),
3349 }
3350
3351 peers.on_incoming_session_established(peer_id, addr);
3352
3353 peers.on_outgoing_connection_failure(
3354 &addr,
3355 &peer_id,
3356 &io::Error::new(io::ErrorKind::ConnectionRefused, ""),
3357 );
3358 assert_eq!(peers.peers.get(&peer_id).unwrap().state, PeerConnectionState::In);
3359 assert_eq!(peers.connection_info.num_inbound, 1);
3360 assert_eq!(peers.connection_info.num_pending_out, 0);
3361 assert_eq!(peers.connection_info.num_pending_in, 0);
3362 assert_eq!(peers.connection_info.num_outbound, 0);
3363 }
3364
3365 #[tokio::test]
3366 async fn test_max_concurrent_dials() {
3367 let config = PeersConfig::default();
3368 let mut peer_manager = PeersManager::new(config);
3369 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
3370 let peer_addr = PeerAddr::from_tcp(SocketAddr::new(ip, 8008));
3371 for _ in 0..peer_manager.connection_info.config.max_concurrent_outbound_dials * 2 {
3372 peer_manager.add_peer(PeerId::random(), peer_addr, None);
3373 }
3374
3375 peer_manager.fill_outbound_slots();
3376 let dials = peer_manager
3377 .queued_actions
3378 .iter()
3379 .filter(|ev| matches!(ev, PeerAction::Connect { .. }))
3380 .count();
3381 assert_eq!(dials, peer_manager.connection_info.config.max_concurrent_outbound_dials);
3382 }
3383
3384 #[tokio::test]
3385 async fn test_max_num_of_pending_dials() {
3386 let config = PeersConfig::default();
3387 let mut peer_manager = PeersManager::new(config);
3388 let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2));
3389 let peer_addr = PeerAddr::from_tcp(SocketAddr::new(ip, 8008));
3390
3391 for _ in 0..peer_manager.connection_info.config.max_concurrent_outbound_dials * 2 {
3393 peer_manager.add_peer(PeerId::random(), peer_addr, None);
3394 }
3395
3396 for _ in 0..peer_manager.connection_info.config.max_concurrent_outbound_dials * 2 {
3397 match event!(peer_manager) {
3398 PeerAction::PeerAdded(_) => {}
3399 _ => unreachable!(),
3400 }
3401 }
3402
3403 for _ in 0..peer_manager.connection_info.config.max_concurrent_outbound_dials {
3404 match event!(peer_manager) {
3405 PeerAction::Connect { .. } => {}
3406 _ => unreachable!(),
3407 }
3408 }
3409
3410 peer_manager.fill_outbound_slots();
3412
3413 let dials = peer_manager.connection_info.num_pending_out;
3415 assert_eq!(dials, peer_manager.connection_info.config.max_concurrent_outbound_dials);
3416
3417 let num_pendingout_states = peer_manager
3418 .peers
3419 .iter()
3420 .filter(|(_, peer)| peer.state.is_pending_out())
3421 .map(|(peer_id, _)| *peer_id)
3422 .collect::<Vec<PeerId>>();
3423 assert_eq!(
3424 num_pendingout_states.len(),
3425 peer_manager.connection_info.config.max_concurrent_outbound_dials
3426 );
3427
3428 for peer_id in &num_pendingout_states {
3430 peer_manager.on_active_outgoing_established(*peer_id);
3431 }
3432
3433 for peer_id in &num_pendingout_states {
3435 assert_eq!(peer_manager.peers.get(peer_id).unwrap().state, PeerConnectionState::Out);
3436 }
3437
3438 assert_eq!(peer_manager.connection_info.num_pending_out, 0);
3440 }
3441
3442 #[tokio::test]
3443 async fn test_connect() {
3444 let peer = PeerId::random();
3445 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
3446 let mut peers = PeersManager::default();
3447 peers.add_and_connect(peer, PeerAddr::from_tcp(socket_addr), None);
3448 assert_eq!(peers.peers.get(&peer).unwrap().state, PeerConnectionState::PendingOut);
3449
3450 match event!(peers) {
3451 PeerAction::Connect { peer_id, remote_addr } => {
3452 assert_eq!(peer_id, peer);
3453 assert_eq!(remote_addr, socket_addr);
3454 }
3455 _ => unreachable!(),
3456 }
3457
3458 let (record, _) = peers.peer_by_id(peer).unwrap();
3459 assert_eq!(record.tcp_addr(), socket_addr);
3460 assert_eq!(record.udp_addr(), socket_addr);
3461
3462 peers.add_and_connect(peer, PeerAddr::from_tcp(socket_addr), None);
3464
3465 let (record, _) = peers.peer_by_id(peer).unwrap();
3466 assert_eq!(record.tcp_addr(), socket_addr);
3467 assert_eq!(record.udp_addr(), socket_addr);
3468 }
3469
3470 #[tokio::test]
3471 async fn test_incoming_connection_from_banned() {
3472 let peer = PeerId::random();
3473 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
3474 let config = PeersConfig::test().with_max_inbound(3);
3475 let mut peers = PeersManager::new(config);
3476 peers.add_peer(peer, PeerAddr::from_tcp(socket_addr), None);
3477
3478 match event!(peers) {
3479 PeerAction::PeerAdded(peer_id) => {
3480 assert_eq!(peer_id, peer);
3481 }
3482 _ => unreachable!(),
3483 }
3484 match event!(peers) {
3485 PeerAction::Connect { peer_id, .. } => {
3486 assert_eq!(peer_id, peer);
3487 }
3488 _ => unreachable!(),
3489 }
3490
3491 poll_fn(|cx| {
3492 assert!(peers.poll(cx).is_pending());
3493 Poll::Ready(())
3494 })
3495 .await;
3496
3497 loop {
3499 peers.on_active_session_dropped(
3500 &socket_addr,
3501 &peer,
3502 &EthStreamError::InvalidMessage(reth_eth_wire::message::MessageError::Invalid(
3503 reth_eth_wire::EthVersion::Eth68,
3504 reth_eth_wire::EthMessageID::Status,
3505 )),
3506 );
3507
3508 if peers.peers.get(&peer).unwrap().is_banned() {
3509 break;
3510 }
3511
3512 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
3513 peers.on_incoming_session_established(peer, socket_addr);
3514
3515 match event!(peers) {
3516 PeerAction::Connect { peer_id, .. } => {
3517 assert_eq!(peer_id, peer);
3518 }
3519 _ => unreachable!(),
3520 }
3521 }
3522
3523 assert!(peers.peers.get(&peer).unwrap().is_banned());
3524
3525 for _ in 0..peers.connection_info.config.max_inbound {
3527 assert!(peers.on_incoming_pending_session(socket_addr.ip()).is_ok());
3528 peers.on_incoming_session_established(peer, socket_addr);
3529
3530 match event!(peers) {
3531 PeerAction::DisconnectBannedIncoming { peer_id } => {
3532 assert_eq!(peer_id, peer);
3533 }
3534 _ => unreachable!(),
3535 }
3536 }
3537
3538 poll_fn(|cx| {
3539 assert!(peers.poll(cx).is_pending());
3540 Poll::Ready(())
3541 })
3542 .await;
3543
3544 assert_eq!(peers.connection_info.num_inbound, 0);
3545
3546 let new_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 3)), 8008);
3547
3548 assert!(peers.on_incoming_pending_session(new_addr.ip()).is_ok());
3550 assert_eq!(peers.connection_info.num_pending_in, 1);
3551
3552 peers.on_active_session_gracefully_closed(peer);
3556 assert_eq!(peers.connection_info.num_inbound, 0);
3557 }
3558
3559 #[tokio::test]
3560 async fn test_add_pending_connect() {
3561 let peer = PeerId::random();
3562 let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
3563 let mut peers = PeersManager::default();
3564 peers.add_and_connect(peer, PeerAddr::from_tcp(socket_addr), None);
3565 assert_eq!(peers.peers.get(&peer).unwrap().state, PeerConnectionState::PendingOut);
3566 assert_eq!(peers.connection_info.num_pending_out, 1);
3567 }
3568
3569 #[tokio::test]
3570 async fn test_dns_updates_peer_address() {
3571 let peer_id = PeerId::random();
3572 let initial_socket = SocketAddr::new("1.1.1.1".parse::<IpAddr>().unwrap(), 8008);
3573 let updated_ip = "2.2.2.2".parse::<IpAddr>().unwrap();
3574
3575 let trusted = TrustedPeer {
3576 host: url::Host::Ipv4("2.2.2.2".parse().unwrap()),
3577 tcp_port: 8008,
3578 udp_port: 8008,
3579 id: peer_id,
3580 };
3581
3582 let config = PeersConfig::test().with_trusted_nodes(vec![trusted.clone()]);
3583 let mut manager = PeersManager::new(config);
3584 manager
3585 .trusted_peers_resolver
3586 .set_interval(tokio::time::interval(Duration::from_millis(1)));
3587
3588 manager.peers.insert(
3589 peer_id,
3590 Peer::trusted(PeerAddr::new_with_ports(initial_socket.ip(), 8008, Some(8008))),
3591 );
3592
3593 for _ in 0..100 {
3594 let _ = event!(manager);
3595 if manager.peers.get(&peer_id).unwrap().addr.tcp().ip() == updated_ip {
3596 break;
3597 }
3598 tokio::time::sleep(Duration::from_millis(10)).await;
3599 }
3600
3601 let updated_peer = manager.peers.get(&peer_id).unwrap();
3602 assert_eq!(updated_peer.addr.tcp().ip(), updated_ip);
3603 }
3604
3605 #[tokio::test]
3606 async fn test_ip_filter_blocks_inbound_connection() {
3607 use reth_net_banlist::IpFilter;
3608 use std::net::IpAddr;
3609
3610 let ip_filter = IpFilter::from_cidr_string("192.168.0.0/16").unwrap();
3612 let config = PeersConfig::test().with_ip_filter(ip_filter);
3613 let mut peers = PeersManager::new(config);
3614
3615 let allowed_ip: IpAddr = "192.168.1.100".parse().unwrap();
3617 assert!(peers.on_incoming_pending_session(allowed_ip).is_ok());
3618
3619 let disallowed_ip: IpAddr = "10.0.0.1".parse().unwrap();
3621 assert!(peers.on_incoming_pending_session(disallowed_ip).is_err());
3622 }
3623
3624 #[tokio::test]
3625 async fn test_ip_filter_blocks_outbound_connection() {
3626 use reth_net_banlist::IpFilter;
3627 use std::net::SocketAddr;
3628
3629 let ip_filter = IpFilter::from_cidr_string("192.168.0.0/16").unwrap();
3631 let config = PeersConfig::test().with_ip_filter(ip_filter);
3632 let mut peers = PeersManager::new(config);
3633
3634 let peer_id = PeerId::repeat_byte(1);
3635
3636 let allowed_addr: SocketAddr = "192.168.1.100:30303".parse().unwrap();
3638 peers.add_peer(peer_id, PeerAddr::from_tcp(allowed_addr), None);
3639 assert!(peers.peers.contains_key(&peer_id));
3640
3641 let peer_id2 = PeerId::repeat_byte(2);
3643 let disallowed_addr: SocketAddr = "10.0.0.1:30303".parse().unwrap();
3644 peers.add_peer(peer_id2, PeerAddr::from_tcp(disallowed_addr), None);
3645 assert!(!peers.peers.contains_key(&peer_id2));
3646 }
3647
3648 #[tokio::test]
3649 async fn test_ip_filter_ipv6() {
3650 use reth_net_banlist::IpFilter;
3651 use std::net::IpAddr;
3652
3653 let ip_filter = IpFilter::from_cidr_string("2001:db8::/32").unwrap();
3655 let config = PeersConfig::test().with_ip_filter(ip_filter);
3656 let mut peers = PeersManager::new(config);
3657
3658 let allowed_ip: IpAddr = "2001:db8::1".parse().unwrap();
3660 assert!(peers.on_incoming_pending_session(allowed_ip).is_ok());
3661
3662 let disallowed_ip: IpAddr = "2001:db9::1".parse().unwrap();
3664 assert!(peers.on_incoming_pending_session(disallowed_ip).is_err());
3665 }
3666
3667 #[tokio::test]
3668 async fn test_ip_filter_multiple_ranges() {
3669 use reth_net_banlist::IpFilter;
3670 use std::net::IpAddr;
3671
3672 let ip_filter = IpFilter::from_cidr_string("192.168.0.0/16,10.0.0.0/8").unwrap();
3674 let config = PeersConfig::test().with_ip_filter(ip_filter);
3675 let mut peers = PeersManager::new(config);
3676
3677 let ip1: IpAddr = "192.168.1.1".parse().unwrap();
3679 let ip2: IpAddr = "10.5.10.20".parse().unwrap();
3680 assert!(peers.on_incoming_pending_session(ip1).is_ok());
3681 assert!(peers.on_incoming_pending_session(ip2).is_ok());
3682
3683 let disallowed_ip: IpAddr = "172.16.0.1".parse().unwrap();
3685 assert!(peers.on_incoming_pending_session(disallowed_ip).is_err());
3686 }
3687
3688 #[tokio::test]
3689 async fn test_ip_filter_no_restriction() {
3690 use reth_net_banlist::IpFilter;
3691 use std::net::IpAddr;
3692
3693 let ip_filter = IpFilter::allow_all();
3695 let config = PeersConfig::test().with_ip_filter(ip_filter);
3696 let mut peers = PeersManager::new(config);
3697
3698 let ip1: IpAddr = "192.168.1.1".parse().unwrap();
3700 let ip2: IpAddr = "10.0.0.1".parse().unwrap();
3701 let ip3: IpAddr = "8.8.8.8".parse().unwrap();
3702 assert!(peers.on_incoming_pending_session(ip1).is_ok());
3703 assert!(peers.on_incoming_pending_session(ip2).is_ok());
3704 assert!(peers.on_incoming_pending_session(ip3).is_ok());
3705 }
3706
3707 #[tokio::test]
3708 async fn test_best_unconnected_prefers_fork_id_as_tiebreaker() {
3709 let mut peers = PeersManager::default();
3710 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8008);
3711
3712 let fork_id = ForkId { hash: ForkHash([0xaa, 0xbb, 0xcc, 0xdd]), next: 0 };
3713
3714 let no_fork = PeerId::random();
3716 peers.add_peer(no_fork, PeerAddr::from_tcp(addr), None);
3717
3718 let with_fork = PeerId::random();
3719 peers.add_peer(with_fork, PeerAddr::from_tcp(addr), None);
3720 peers.peers.get_mut(&with_fork).unwrap().fork_id = Some(Box::new(fork_id));
3721
3722 let (best_id, _) = peers.best_unconnected(false).unwrap();
3723 assert_eq!(best_id, with_fork, "fork_id should break tie when reputation is equal");
3724 }
3725
3726 #[tokio::test]
3727 async fn test_add_trusted_peer_node_resolves_absent_peer() {
3728 let peer_id = PeerId::random();
3729 let trusted = TrustedPeer {
3730 host: url::Host::Domain("example.invalid".to_string()),
3731 tcp_port: 30303,
3732 udp_port: 30303,
3733 id: peer_id,
3734 };
3735
3736 let mut manager = PeersManager::default();
3737 manager.add_trusted_peer_node(trusted);
3738
3739 assert!(manager.trusted_peer_ids.contains(&peer_id));
3740 assert_eq!(manager.trusted_peers_resolver.trusted_peers.len(), 1);
3741 assert!(!manager.peers.contains_key(&peer_id));
3742
3743 let resolved = NodeRecord {
3744 address: "10.0.0.1".parse::<IpAddr>().unwrap(),
3745 tcp_port: 30303,
3746 udp_port: 30303,
3747 id: peer_id,
3748 };
3749 manager.on_resolved_peer(peer_id, resolved);
3750
3751 let peer = manager.peers.get(&peer_id).expect("peer should be added after resolution");
3752 assert!(peer.kind.is_trusted());
3753 assert_eq!(peer.addr.tcp().ip(), "10.0.0.1".parse::<IpAddr>().unwrap());
3754 }
3755
3756 #[tokio::test]
3757 async fn test_removed_trusted_peer_ignores_late_resolution() {
3758 let peer_id = PeerId::random();
3759 let trusted = TrustedPeer {
3760 host: url::Host::Domain("example.invalid".to_string()),
3761 tcp_port: 30303,
3762 udp_port: 30303,
3763 id: peer_id,
3764 };
3765
3766 let mut manager = PeersManager::default();
3767 manager.add_trusted_peer_node(trusted);
3768 manager.remove_peer_from_trusted_set(peer_id);
3769
3770 let resolved = NodeRecord {
3771 address: "10.0.0.1".parse::<IpAddr>().unwrap(),
3772 tcp_port: 30303,
3773 udp_port: 30303,
3774 id: peer_id,
3775 };
3776 manager.on_resolved_peer(peer_id, resolved);
3777
3778 assert!(!manager.peers.contains_key(&peer_id));
3779 assert!(!manager.trusted_peer_ids.contains(&peer_id));
3780 }
3781
3782 #[tokio::test]
3783 async fn test_rotation_disconnects_eligible_peer() {
3784 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
3785 let peer = PeerId::random();
3786 let mut peers = PeersManager::new(
3787 PeersConfig::test()
3788 .with_max_outbound(1)
3789 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3790 );
3791
3792 peers.add_peer(peer, PeerAddr::from_tcp(addr), None);
3793 match event!(peers) {
3794 PeerAction::PeerAdded(_) => {}
3795 _ => unreachable!(),
3796 }
3797 match event!(peers) {
3798 PeerAction::Connect { .. } => {}
3799 _ => unreachable!(),
3800 }
3801 peers.on_active_outgoing_established(peer);
3802
3803 set_connected_at(
3804 &mut peers,
3805 peer,
3806 std::time::Instant::now() - Duration::from_secs(11 * 60),
3807 );
3808
3809 tokio::time::sleep(Duration::from_millis(100)).await;
3810
3811 match event!(peers) {
3812 PeerAction::Disconnect { peer_id, reason } => {
3813 assert_eq!(peer_id, peer);
3814 assert_eq!(reason, Some(DisconnectReason::UselessPeer));
3815 }
3816 _ => unreachable!(),
3817 }
3818 }
3819
3820 #[tokio::test]
3821 async fn test_rotation_then_remove_uses_active_session_removal() {
3822 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 7)), 8008);
3823 let peer = PeerId::random();
3824 let mut peers = PeersManager::new(
3825 PeersConfig::test()
3826 .with_max_outbound(1)
3827 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3828 );
3829
3830 peers.add_peer(peer, PeerAddr::from_tcp(addr), None);
3831 match event!(peers) {
3832 PeerAction::PeerAdded(_) => {}
3833 _ => unreachable!(),
3834 }
3835 match event!(peers) {
3836 PeerAction::Connect { .. } => {}
3837 _ => unreachable!(),
3838 }
3839 peers.on_active_outgoing_established(peer);
3840 set_connected_at(
3841 &mut peers,
3842 peer,
3843 std::time::Instant::now() - Duration::from_secs(11 * 60),
3844 );
3845
3846 tokio::time::sleep(Duration::from_millis(100)).await;
3847
3848 match event!(peers) {
3849 PeerAction::Disconnect { peer_id, reason } => {
3850 assert_eq!(peer_id, peer);
3851 assert_eq!(reason, Some(DisconnectReason::UselessPeer));
3852 }
3853 _ => unreachable!(),
3854 }
3855 assert_eq!(peers.peers.get(&peer).unwrap().state, PeerConnectionState::Out);
3856 assert_eq!(peers.connection_info.num_outbound, 1);
3857
3858 peers.remove_peer(peer);
3859 match event!(peers) {
3860 PeerAction::PeerRemoved(peer_id) => assert_eq!(peer_id, peer),
3861 _ => unreachable!(),
3862 }
3863 match event!(peers) {
3864 PeerAction::Disconnect { peer_id, reason } => {
3865 assert_eq!(peer_id, peer);
3866 assert_eq!(reason, Some(DisconnectReason::DisconnectRequested));
3867 }
3868 _ => unreachable!(),
3869 }
3870
3871 let p = peers.peers.get(&peer).unwrap();
3872 assert_eq!(p.state, PeerConnectionState::DisconnectingOut);
3873 assert!(p.remove_after_disconnect);
3874 assert_eq!(peers.connection_info.num_outbound, 1);
3875
3876 peers.on_active_session_gracefully_closed(peer);
3877 assert_eq!(peers.connection_info.num_outbound, 0);
3878 assert!(!peers.peers.contains_key(&peer));
3879 }
3880
3881 #[tokio::test]
3882 async fn test_rotation_skips_trusted_peers() {
3883 let _addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 3)), 8008);
3884 let peer = PeerId::random();
3885 let trusted = TrustedPeer {
3886 host: Host::Ipv4(Ipv4Addr::new(127, 0, 1, 3)),
3887 tcp_port: 8008,
3888 udp_port: 8008,
3889 id: peer,
3890 };
3891 let mut peers = PeersManager::new(
3892 PeersConfig::test()
3893 .with_max_outbound(1)
3894 .with_trusted_nodes(vec![trusted])
3895 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3896 );
3897
3898 match event!(peers) {
3899 PeerAction::Connect { .. } => {}
3900 _ => unreachable!(),
3901 }
3902 peers.on_active_outgoing_established(peer);
3903 set_connected_at(
3904 &mut peers,
3905 peer,
3906 std::time::Instant::now() - Duration::from_secs(11 * 60),
3907 );
3908
3909 tokio::time::sleep(Duration::from_millis(100)).await;
3910
3911 poll_fn(|cx| {
3912 assert!(peers.poll(cx).is_pending(), "trusted peer must not be rotated");
3913 Poll::Ready(())
3914 })
3915 .await;
3916 }
3917
3918 #[tokio::test]
3919 async fn test_rotation_skips_recently_connected_peers() {
3920 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 4)), 8008);
3921 let peer = PeerId::random();
3922 let mut peers = PeersManager::new(
3923 PeersConfig::test()
3924 .with_max_outbound(1)
3925 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3926 );
3927
3928 peers.add_peer(peer, PeerAddr::from_tcp(addr), None);
3929 match event!(peers) {
3930 PeerAction::PeerAdded(_) => {}
3931 _ => unreachable!(),
3932 }
3933 match event!(peers) {
3934 PeerAction::Connect { .. } => {}
3935 _ => unreachable!(),
3936 }
3937 peers.on_active_outgoing_established(peer);
3938
3939 tokio::time::sleep(Duration::from_millis(100)).await;
3940
3941 poll_fn(|cx| {
3942 assert!(peers.poll(cx).is_pending(), "recently connected peer must not be rotated");
3943 Poll::Ready(())
3944 })
3945 .await;
3946 }
3947
3948 #[tokio::test]
3949 async fn test_rotation_skips_when_slots_available() {
3950 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 5)), 8008);
3951 let peer = PeerId::random();
3952 let mut peers = PeersManager::new(
3953 PeersConfig::test()
3954 .with_max_outbound(2)
3955 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3956 );
3957
3958 peers.add_peer(peer, PeerAddr::from_tcp(addr), None);
3959 match event!(peers) {
3960 PeerAction::PeerAdded(_) => {}
3961 _ => unreachable!(),
3962 }
3963 match event!(peers) {
3964 PeerAction::Connect { .. } => {}
3965 _ => unreachable!(),
3966 }
3967 peers.on_active_outgoing_established(peer);
3968 set_connected_at(
3969 &mut peers,
3970 peer,
3971 std::time::Instant::now() - Duration::from_secs(11 * 60),
3972 );
3973
3974 tokio::time::sleep(Duration::from_millis(100)).await;
3975
3976 poll_fn(|cx| {
3977 assert!(
3978 peers.poll(cx).is_pending(),
3979 "rotation must not fire when outbound slots are available"
3980 );
3981 Poll::Ready(())
3982 })
3983 .await;
3984 }
3985
3986 #[tokio::test]
3987 async fn test_rotation_disconnects_inbound_peer() {
3988 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 6)), 8008);
3989 let peer = PeerId::random();
3990 let mut peers = PeersManager::new(
3991 PeersConfig::test()
3992 .with_max_inbound(1)
3993 .with_peer_rotation_interval(Some(Duration::from_millis(50))),
3994 );
3995
3996 assert!(peers.on_incoming_pending_session(addr.ip()).is_ok());
3997 peers.on_incoming_session_established(peer, addr);
3998
3999 match event!(peers) {
4000 PeerAction::PeerAdded(_) => {}
4001 _ => unreachable!(),
4002 }
4003
4004 set_connected_at(
4005 &mut peers,
4006 peer,
4007 std::time::Instant::now() - Duration::from_secs(11 * 60),
4008 );
4009
4010 tokio::time::sleep(Duration::from_millis(100)).await;
4011
4012 match event!(peers) {
4013 PeerAction::Disconnect { peer_id, reason } => {
4014 assert_eq!(peer_id, peer);
4015 assert_eq!(reason, Some(DisconnectReason::UselessPeer));
4016 }
4017 _ => unreachable!(),
4018 }
4019 }
4020
4021 #[tokio::test]
4024 async fn test_requested_peer_is_dialed_before_refill_tick() {
4025 let mut peers = PeersManager::new(PeersConfig {
4026 refill_slots_interval: Duration::from_secs(60),
4027 ..PeersConfig::test()
4028 });
4029 assert!(poll_now(&mut peers).is_pending());
4031
4032 let discovered = PeerId::random();
4033 let discovered_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 1)), 8008);
4034 peers.add_peer(discovered, PeerAddr::from_tcp(discovered_addr), None);
4035 assert!(
4036 matches!(poll_now(&mut peers), Poll::Ready(PeerAction::PeerAdded(id)) if id == discovered)
4037 );
4038 assert!(poll_now(&mut peers).is_pending());
4039
4040 let requested = PeerId::random();
4041 let requested_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 2)), 8008);
4042 peers.handle().add_peer(requested, requested_addr);
4043 assert!(
4044 matches!(poll_now(&mut peers), Poll::Ready(PeerAction::PeerAdded(id)) if id == requested)
4045 );
4046
4047 let mut dialed = Vec::new();
4049 while let Poll::Ready(PeerAction::Connect { peer_id, .. }) = poll_now(&mut peers) {
4050 dialed.push(peer_id);
4051 }
4052 dialed.sort();
4053 let mut expected = vec![discovered, requested];
4054 expected.sort();
4055 assert_eq!(dialed, expected);
4056 }
4057
4058 #[tokio::test]
4059 async fn test_revoke_trust_independent_of_peer_kind() {
4060 for kind in [None, Some(PeerKind::Basic), Some(PeerKind::Static), Some(PeerKind::Trusted)] {
4061 let mut peers = PeersManager::new(PeersConfig::test());
4062 let peer_id = PeerId::random();
4063 peers.add_trusted_peer_id(peer_id);
4064 if let Some(kind) = kind {
4065 peers.add_peer_kind(
4066 peer_id,
4067 Some(kind),
4068 PeerAddr::from_tcp("127.0.0.1:8008".parse().unwrap()),
4069 None,
4070 );
4071 }
4072 peers.remove_peer_from_trusted_set(peer_id);
4073 assert!(!peers.trusted_peer_ids.contains(&peer_id));
4074 assert_eq!(
4075 peers.peers.get(&peer_id).map(|peer| peer.kind),
4076 kind.map(|kind| if kind == PeerKind::Trusted { PeerKind::Basic } else { kind })
4077 );
4078 peers.ban_peer_by_admin(peer_id);
4080 assert!(peers.ban_list.is_banned_peer(&peer_id));
4081 }
4082 }
4083
4084 #[tokio::test]
4085 async fn test_persisted_trust_controls_inbound_admission() {
4086 for kind in [PeerKind::Basic, PeerKind::Static, PeerKind::Trusted] {
4087 for trusted_only in [false, true] {
4088 let peer_id = PeerId::random();
4089 let addr = "127.0.0.1:8008".parse::<SocketAddr>().unwrap();
4090 let mut config = PeersConfig::test().with_trusted_nodes_only(trusted_only);
4091 config.connection_info.max_inbound = 0;
4092 config.persisted_peers.push(PersistedPeerInfo {
4093 record: NodeRecord::new(addr, peer_id),
4094 kind,
4095 fork_id: None,
4096 reputation: 0,
4097 });
4098 let mut peers = PeersManager::new(config);
4099 assert_eq!(peers.trusted_peer_ids.contains(&peer_id), kind.is_trusted());
4100 peers.connection_info.inc_pending_in();
4101 peers.on_incoming_session_established(peer_id, addr);
4102 if kind.is_trusted() {
4103 assert!(peers.queued_actions.is_empty());
4104 assert_eq!(peers.connection_info.num_inbound, 1);
4105 } else if trusted_only {
4106 assert!(matches!(peers.queued_actions.pop_front(),
4107 Some(PeerAction::DisconnectUntrustedIncoming { peer_id: id }) if id == peer_id));
4108 } else {
4109 assert!(matches!(peers.queued_actions.pop_front(),
4110 Some(PeerAction::Disconnect { peer_id: id, reason: Some(DisconnectReason::TooManyPeers) }) if id == peer_id));
4111 }
4112 }
4113 }
4114 }
4115
4116 #[tokio::test]
4117 async fn test_filtered_persisted_peer_does_not_restore_trust() {
4118 let peer_id = PeerId::random();
4119 let mut config = PeersConfig::test();
4120 config.enforce_enr_fork_id = true;
4121 config.persisted_peers.push(PersistedPeerInfo {
4122 record: NodeRecord::new("127.0.0.1:8008".parse().unwrap(), peer_id),
4123 kind: PeerKind::Trusted,
4124 fork_id: None,
4125 reputation: 0,
4126 });
4127 let peers = PeersManager::new(config);
4128 assert!(!peers.trusted_peer_ids.contains(&peer_id));
4129 assert!(!peers.peers.contains_key(&peer_id));
4130 }
4131 #[tokio::test]
4132 async fn test_pending_dials_reserve_outbound_capacity() {
4133 for max_outbound in [0, 1, 3] {
4134 let mut peers = PeersManager::new(PeersConfig::test().with_max_outbound(max_outbound));
4135 let addr = PeerAddr::from_tcp("127.0.0.1:8008".parse().unwrap());
4136 for _ in 0..30 {
4137 peers.add_peer(PeerId::random(), addr, None);
4138 }
4139 peers.fill_outbound_slots();
4140 let dialed = peers
4141 .queued_actions
4142 .iter()
4143 .filter_map(|action| match action {
4144 PeerAction::Connect { peer_id, .. } => Some(*peer_id),
4145 _ => None,
4146 })
4147 .collect::<Vec<_>>();
4148 assert_eq!(dialed.len(), max_outbound);
4149 peers.queued_actions.clear();
4150 for peer in dialed {
4151 peers.on_active_outgoing_established(peer);
4152 peers.fill_outbound_slots();
4153 assert!(peers.queued_actions.is_empty());
4154 }
4155 assert_eq!(peers.connection_info.num_outbound, max_outbound);
4156 assert_eq!(peers.connection_info.num_pending_out, 0);
4157 }
4158 }
4159
4160 #[tokio::test]
4161 async fn test_surplus_outbound_completion() {
4162 for kind in [PeerKind::Basic, PeerKind::Trusted, PeerKind::Static] {
4163 let mut peers = PeersManager::new(PeersConfig::test().with_max_outbound(0));
4164 let peer = PeerId::random();
4165 let addr = PeerAddr::from_tcp("127.0.0.1:8008".parse().unwrap());
4166 peers.add_and_connect_kind(peer, kind, addr, None);
4167 peers.queued_actions.clear();
4168 peers.on_active_outgoing_established(peer);
4169 if kind == PeerKind::Basic {
4170 assert!(matches!(
4171 peers.queued_actions.pop_front(),
4172 Some(PeerAction::Disconnect {
4173 peer_id,
4174 reason: Some(DisconnectReason::TooManyPeers),
4175 }) if peer_id == peer
4176 ));
4177 } else {
4178 assert!(peers.queued_actions.is_empty());
4179 }
4180 peers.on_active_session_gracefully_closed(peer);
4182 assert_eq!(peers.connection_info.num_outbound, 0);
4183 assert_eq!(peers.connection_info.num_pending_out, 0);
4184 }
4185 }
4186
4187 #[tokio::test]
4188 async fn test_surplus_outbound_preserves_id_trusted_peers() {
4189 for hostname in [false, true] {
4190 let mut peers = PeersManager::new(PeersConfig::test().with_max_outbound(0));
4191 let peer_id = PeerId::random();
4192 let addr = PeerAddr::from_tcp("127.0.0.1:8008".parse().unwrap());
4193 if hostname {
4194 peers.add_peer(peer_id, addr, None);
4195 peers.add_trusted_peer_node(TrustedPeer {
4196 host: Host::Domain("example.invalid".to_string()),
4197 tcp_port: 8008,
4198 udp_port: 8008,
4199 id: peer_id,
4200 });
4201 } else {
4202 peers.add_trusted_peer_id(peer_id);
4203 }
4204 peers.add_and_connect_kind(peer_id, PeerKind::Basic, addr, None);
4205 assert_eq!(peers.peers[&peer_id].kind, PeerKind::Basic);
4206 peers.queued_actions.clear();
4207
4208 peers.on_active_outgoing_established(peer_id);
4209
4210 assert!(peers.queued_actions.is_empty());
4211 assert_eq!(peers.num_outbound_connections(), 1);
4212 peers.on_active_session_gracefully_closed(peer_id);
4213 assert_eq!(peers.num_outbound_connections(), 0);
4214 assert_eq!(peers.num_pending_outbound_connections(), 0);
4215 }
4216 }
4217
4218 #[tokio::test]
4219 async fn test_pending_outbound_cleanup_preserves_incoming_session() {
4220 let mut peers = PeersManager::new(PeersConfig::test());
4221 let peer_id = PeerId::random();
4222 let addr = "127.0.0.1:8008".parse::<SocketAddr>().unwrap();
4223 peers.add_and_connect_kind(peer_id, PeerKind::Basic, PeerAddr::from_tcp(addr), None);
4224 peers.on_incoming_pending_session(addr.ip()).unwrap();
4225 peers.on_incoming_session_established(peer_id, addr);
4226 let connected_at = peers.peers[&peer_id].connected_at;
4227
4228 peers.on_outgoing_pending_session_gracefully_closed(&peer_id);
4229
4230 assert_eq!(peers.peers[&peer_id].state, PeerConnectionState::In);
4231 assert_eq!(peers.peers[&peer_id].connected_at, connected_at);
4232 assert_eq!(peers.connection_info.num_inbound, 1);
4233 assert_eq!(peers.num_pending_outbound_connections(), 0);
4234 }
4235
4236 #[tokio::test]
4237 async fn test_inbound_capacity_preserves_pending_outbound_and_trusted_exemption() {
4238 for trusted in [false, true] {
4239 let mut peers = PeersManager::new(PeersConfig::test().with_max_inbound(0));
4240 let peer_id = PeerId::random();
4241 let addr = "127.0.0.1:8008".parse().unwrap();
4242 peers.add_and_connect_kind(peer_id, PeerKind::Basic, PeerAddr::from_tcp(addr), None);
4243 if trusted {
4244 peers.add_trusted_peer_id(peer_id);
4245 }
4246 assert_eq!(peers.has_inbound_capacity(peer_id), trusted);
4247 assert_eq!(peers.peers[&peer_id].state, PeerConnectionState::PendingOut);
4248 assert_eq!(peers.connection_info.num_pending_out, 1);
4249 }
4250 }
4251
4252 #[tokio::test]
4253 async fn test_unauthenticated_outbound_errors_do_not_ban_identity() {
4254 for error in [
4255 PendingSessionHandshakeError::Timeout,
4256 PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
4257 P2PStreamError::HandshakeError(P2PHandshakeError::Timeout),
4258 )),
4259 PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(
4260 P2PStreamError::HandshakeError(P2PHandshakeError::NoResponse),
4261 )),
4262 PendingSessionHandshakeError::Ecies(ECIESErrorImpl::InvalidAckData.into()),
4263 PendingSessionHandshakeError::Ecies(ECIESErrorImpl::TagCheckDecryptFailed.into()),
4264 PendingSessionHandshakeError::Eth(EthStreamError::P2PStreamError(P2PStreamError::Io(
4265 io::Error::other("invalid frame MAC"),
4266 ))),
4267 ] {
4268 let mut peers = PeersManager::new(PeersConfig::test());
4269 let peer_id = PeerId::random();
4270 let addr = "8.8.8.8:30303".parse::<SocketAddr>().unwrap();
4271 peers.add_and_connect_kind(peer_id, PeerKind::Basic, PeerAddr::from_tcp(addr), None);
4272 peers.queued_actions.clear();
4273 let reputation = peers.peers[&peer_id].reputation;
4274 for _ in 0..=peers.max_backoff_count + 1 {
4275 peers.add_and_connect_kind(
4276 peer_id,
4277 PeerKind::Basic,
4278 PeerAddr::from_tcp(addr),
4279 None,
4280 );
4281 peers.queued_actions.clear();
4282 peers.on_outgoing_pending_session_dropped(&addr, &peer_id, &error);
4283 assert_eq!(peers.peers[&peer_id].reputation, reputation);
4284 }
4285 let peer = &peers.peers[&peer_id];
4286 assert_eq!(peer.state, PeerConnectionState::Idle);
4287 assert_eq!(peer.reputation, reputation);
4288 assert_eq!(peer.severe_backoff_counter, 0);
4289 assert!(peer.backed_off);
4290 assert!(!peers.ban_list.is_banned_peer(&peer_id));
4291 assert!(peers.queued_actions.is_empty());
4292 assert_eq!(peers.connection_info.num_pending_out, 0);
4293
4294 if matches!(&error, PendingSessionHandshakeError::Ecies(_)) {
4296 peers.connection_info.inc_pending_in();
4297 peers.on_incoming_pending_session_dropped(addr, &error);
4298 assert!(peers.ban_list.is_banned_ip(&addr.ip()));
4299 }
4300 }
4301 }
4302
4303 #[tokio::test]
4304 async fn test_unattributable_backoff_respects_maximum() {
4305 let mut config = PeersConfig::test();
4306 config.backoff_durations.low = Duration::from_secs(60);
4307 config.backoff_durations.max = Duration::from_secs(1);
4308 let mut peers = PeersManager::new(config);
4309 let peer_id = PeerId::random();
4310 let addr = "8.8.8.8:30303".parse::<SocketAddr>().unwrap();
4311 peers.add_and_connect_kind(peer_id, PeerKind::Basic, PeerAddr::from_tcp(addr), None);
4312 peers.peers.get_mut(&peer_id).unwrap().severe_backoff_counter = 3;
4313 let before = std::time::Instant::now();
4314 peers.on_outgoing_pending_session_dropped(
4315 &addr,
4316 &peer_id,
4317 &PendingSessionHandshakeError::Timeout,
4318 );
4319 let after = std::time::Instant::now();
4320 let until = peers.backed_off_peers[&peer_id];
4321 assert!(until >= before + Duration::from_secs(1));
4322 assert!(until <= after + Duration::from_secs(1));
4323 assert_eq!(peers.peers[&peer_id].severe_backoff_counter, 3);
4324 }
4325
4326 #[tokio::test]
4327 async fn test_dns_trusted_ids_bypass_outbound_capacity() {
4328 for register_first in [false, true] {
4329 let mut peers = PeersManager::new(PeersConfig::test().with_max_outbound(0));
4330 let peer_id = PeerId::random();
4331 let addr = "127.0.0.1:30303".parse::<SocketAddr>().unwrap();
4332 let trusted =
4333 TrustedPeer::new(Host::Domain("trusted.invalid".into()), addr.port(), peer_id);
4334 if register_first {
4335 peers.add_trusted_peer_node(trusted.clone());
4336 }
4337 peers.add_peer(peer_id, PeerAddr::from_tcp(addr), None);
4338 if !register_first {
4339 peers.add_trusted_peer_node(trusted);
4340 }
4341 assert_eq!(peers.peers[&peer_id].kind, PeerKind::Basic);
4342 peers.queued_actions.clear();
4343 peers.fill_outbound_slots();
4344 assert!(
4345 matches!(peers.queued_actions.pop_front(), Some(PeerAction::Connect { peer_id: id, remote_addr }) if id == peer_id && remote_addr == addr)
4346 );
4347 assert!(peers.queued_actions.is_empty());
4348 }
4349 }
4350
4351 #[tokio::test]
4352 async fn test_trusted_bypass_respects_shared_dial_limit() {
4353 let mut peers = PeersManager::new(
4354 PeersConfig::test().with_max_outbound(1).with_max_concurrent_dials(1),
4355 );
4356 let addr = "127.0.0.1:30303".parse().unwrap();
4357 let basic = PeerId::random();
4358 peers.add_peer(basic, PeerAddr::from_tcp(addr), None);
4359 peers.fill_outbound_slots();
4360 assert_eq!(peers.connection_info.num_pending_out, 1);
4361 for _ in 0..2 {
4362 peers.add_trusted_peer(PeerId::random(), PeerAddr::from_tcp(addr));
4363 }
4364 peers.queued_actions.clear();
4365 peers.fill_outbound_slots();
4366 assert!(peers.queued_actions.is_empty());
4367 peers.on_active_outgoing_established(basic);
4368 peers.fill_outbound_slots();
4369 assert!(
4370 matches!(peers.queued_actions.pop_front(), Some(PeerAction::Connect { peer_id, .. }) if peers.peers[&peer_id].is_trusted())
4371 );
4372 assert!(peers.queued_actions.is_empty());
4373 assert_eq!(peers.connection_info.num_pending_out, 1);
4374 assert_eq!(peers.connection_info.num_outbound, 1);
4375 }
4376}