reth_network_types/peers/
mod.rspub mod addr;
pub mod config;
pub mod kind;
pub mod reputation;
pub mod state;
pub use config::{ConnectionsConfig, PeersConfig};
pub use reputation::{Reputation, ReputationChange, ReputationChangeKind, ReputationChangeWeights};
use reth_ethereum_forks::ForkId;
use tracing::trace;
use crate::{
is_banned_reputation, PeerAddr, PeerConnectionState, PeerKind, ReputationChangeOutcome,
DEFAULT_REPUTATION,
};
#[derive(Debug, Clone)]
pub struct Peer {
pub addr: PeerAddr,
pub reputation: i32,
pub state: PeerConnectionState,
pub fork_id: Option<ForkId>,
pub remove_after_disconnect: bool,
pub kind: PeerKind,
pub backed_off: bool,
pub severe_backoff_counter: u8,
}
impl Peer {
pub fn new(addr: PeerAddr) -> Self {
Self::with_state(addr, Default::default())
}
pub fn trusted(addr: PeerAddr) -> Self {
Self { kind: PeerKind::Trusted, ..Self::new(addr) }
}
pub const fn reputation(&self) -> i32 {
self.reputation
}
pub fn with_state(addr: PeerAddr, state: PeerConnectionState) -> Self {
Self {
addr,
state,
reputation: DEFAULT_REPUTATION,
fork_id: None,
remove_after_disconnect: false,
kind: Default::default(),
backed_off: false,
severe_backoff_counter: 0,
}
}
pub fn with_kind(addr: PeerAddr, kind: PeerKind) -> Self {
Self { kind, ..Self::new(addr) }
}
pub fn reset_reputation(&mut self) -> ReputationChangeOutcome {
self.reputation = DEFAULT_REPUTATION;
ReputationChangeOutcome::None
}
pub fn apply_reputation(&mut self, reputation: i32) -> ReputationChangeOutcome {
let previous = self.reputation;
self.reputation = previous.saturating_add(reputation);
trace!(target: "net::peers", reputation=%self.reputation, banned=%self.is_banned(), "applied reputation change");
if self.state.is_connected() && self.is_banned() {
self.state.disconnect();
return ReputationChangeOutcome::DisconnectAndBan
}
if self.is_banned() && !is_banned_reputation(previous) {
return ReputationChangeOutcome::Ban
}
if !self.is_banned() && is_banned_reputation(previous) {
return ReputationChangeOutcome::Unban
}
ReputationChangeOutcome::None
}
#[inline]
pub const fn is_banned(&self) -> bool {
is_banned_reputation(self.reputation)
}
#[inline]
pub const fn is_backed_off(&self) -> bool {
self.backed_off
}
#[inline]
pub fn unban(&mut self) {
self.reputation = DEFAULT_REPUTATION
}
#[inline]
pub const fn is_trusted(&self) -> bool {
matches!(self.kind, PeerKind::Trusted)
}
#[inline]
pub const fn is_static(&self) -> bool {
matches!(self.kind, PeerKind::Static)
}
}