reth_network_types/peers/
mod.rs1pub 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::debug;
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 const fn reset_reputation(&mut self) -> ReputationChangeOutcome {
80 self.reputation = DEFAULT_REPUTATION;
81
82 ReputationChangeOutcome::None
83 }
84
85 pub fn apply_reputation(
87 &mut self,
88 reputation: i32,
89 kind: ReputationChangeKind,
90 ) -> ReputationChangeOutcome {
91 let previous = self.reputation;
92 self.reputation = previous.saturating_add(reputation);
94
95 debug!(target: "net::peers", reputation=%self.reputation, banned=%self.is_banned(), ?kind, "applied reputation change");
96
97 if self.state.is_connected() && self.is_banned() {
98 self.state.disconnect();
99 return ReputationChangeOutcome::DisconnectAndBan
100 }
101
102 if self.is_banned() && !is_banned_reputation(previous) {
103 return ReputationChangeOutcome::Ban
104 }
105
106 if !self.is_banned() && is_banned_reputation(previous) {
107 return ReputationChangeOutcome::Unban
108 }
109
110 ReputationChangeOutcome::None
111 }
112
113 #[inline]
115 pub const fn is_banned(&self) -> bool {
116 is_banned_reputation(self.reputation)
117 }
118
119 #[inline]
121 pub const fn is_backed_off(&self) -> bool {
122 self.backed_off
123 }
124
125 #[inline]
127 pub const fn unban(&mut self) {
128 self.reputation = DEFAULT_REPUTATION
129 }
130
131 #[inline]
133 pub const fn is_trusted(&self) -> bool {
134 matches!(self.kind, PeerKind::Trusted)
135 }
136
137 #[inline]
139 pub const fn is_static(&self) -> bool {
140 matches!(self.kind, PeerKind::Static)
141 }
142}