reth_network_types/peers/
mod.rs
1pub mod addr;
2pub mod config;
3pub mod kind;
4pub mod reputation;
5pub mod state;
6
7pub use config::{ConnectionsConfig, PeersConfig};
8pub use reputation::{Reputation, ReputationChange, ReputationChangeKind, ReputationChangeWeights};
9
10use alloy_eip2124::ForkId;
11use tracing::trace;
12
13use crate::{
14 is_banned_reputation, PeerAddr, PeerConnectionState, PeerKind, ReputationChangeOutcome,
15 DEFAULT_REPUTATION,
16};
17
18#[derive(Debug, Clone)]
20pub struct Peer {
21 pub addr: PeerAddr,
23 pub reputation: i32,
25 pub state: PeerConnectionState,
27 pub fork_id: Option<ForkId>,
29 pub remove_after_disconnect: bool,
31 pub kind: PeerKind,
33 pub backed_off: bool,
35 pub severe_backoff_counter: u8,
38}
39
40impl Peer {
43 pub fn new(addr: PeerAddr) -> Self {
45 Self::with_state(addr, Default::default())
46 }
47
48 pub fn trusted(addr: PeerAddr) -> Self {
50 Self { kind: PeerKind::Trusted, ..Self::new(addr) }
51 }
52
53 pub const fn reputation(&self) -> i32 {
55 self.reputation
56 }
57
58 pub fn with_state(addr: PeerAddr, state: PeerConnectionState) -> Self {
60 Self {
61 addr,
62 state,
63 reputation: DEFAULT_REPUTATION,
64 fork_id: None,
65 remove_after_disconnect: false,
66 kind: Default::default(),
67 backed_off: false,
68 severe_backoff_counter: 0,
69 }
70 }
71
72 pub fn with_kind(addr: PeerAddr, kind: PeerKind) -> Self {
74 Self { kind, ..Self::new(addr) }
75 }
76
77 pub fn reset_reputation(&mut self) -> ReputationChangeOutcome {
80 self.reputation = DEFAULT_REPUTATION;
81
82 ReputationChangeOutcome::None
83 }
84
85 pub fn apply_reputation(&mut self, reputation: i32) -> ReputationChangeOutcome {
87 let previous = self.reputation;
88 self.reputation = previous.saturating_add(reputation);
90
91 trace!(target: "net::peers", reputation=%self.reputation, banned=%self.is_banned(), "applied reputation change");
92
93 if self.state.is_connected() && self.is_banned() {
94 self.state.disconnect();
95 return ReputationChangeOutcome::DisconnectAndBan
96 }
97
98 if self.is_banned() && !is_banned_reputation(previous) {
99 return ReputationChangeOutcome::Ban
100 }
101
102 if !self.is_banned() && is_banned_reputation(previous) {
103 return ReputationChangeOutcome::Unban
104 }
105
106 ReputationChangeOutcome::None
107 }
108
109 #[inline]
111 pub const fn is_banned(&self) -> bool {
112 is_banned_reputation(self.reputation)
113 }
114
115 #[inline]
117 pub const fn is_backed_off(&self) -> bool {
118 self.backed_off
119 }
120
121 #[inline]
123 pub fn unban(&mut self) {
124 self.reputation = DEFAULT_REPUTATION
125 }
126
127 #[inline]
129 pub const fn is_trusted(&self) -> bool {
130 matches!(self.kind, PeerKind::Trusted)
131 }
132
133 #[inline]
135 pub const fn is_static(&self) -> bool {
136 matches!(self.kind, PeerKind::Static)
137 }
138}