use crate::service::message::*;
use crate::service::*;
#[derive(Debug, Default)]
#[allow(clippy::large_enum_variant)]
pub enum PeerState {
/// Initial peer state. For outgoing peers this
/// means we've attempted a connection. For incoming
/// peers, this means they've successfully connected
/// to us.
#[default]
Initial,
/// State after successful handshake.
Negotiated {
/// The peer's unique identifier.
id: NodeId,
since: LocalTime,
/// Addresses this peer is reachable on.
addrs: Vec
,
git: Url,
},
/// When a peer is disconnected.
Disconnected { since: LocalTime },
}
#[derive(thiserror::Error, Debug, Clone)]
pub enum PeerError {
#[error("wrong network constant in message: {0}")]
WrongMagic(u32),
#[error("wrong protocol version in message: {0}")]
WrongVersion(u32),
#[error("invalid inventory timestamp: {0}")]
InvalidTimestamp(u64),
#[error("peer misbehaved")]
Misbehavior,
}
#[derive(Debug)]
pub struct Peer {
/// Peer address.
pub addr: net::SocketAddr,
/// Connection direction.
pub link: Link,
/// Whether we should attempt to re-connect
/// to this peer upon disconnection.
pub persistent: bool,
/// Peer connection state.
pub state: PeerState,
/// Last known peer time.
pub timestamp: Timestamp,
/// Peer subscription.
pub subscribe: Option,
/// Connection attempts. For persistent peers, Tracks
/// how many times we've attempted to connect. We reset this to zero
/// upon successful connection.
attempts: usize,
}
impl Peer {
pub fn new(addr: net::SocketAddr, link: Link, persistent: bool) -> Self {
Self {
addr,
state: PeerState::default(),
link,
timestamp: Timestamp::default(),
subscribe: None,
persistent,
attempts: 0,
}
}
pub fn ip(&self) -> IpAddr {
self.addr.ip()
}
pub fn is_negotiated(&self) -> bool {
matches!(self.state, PeerState::Negotiated { .. })
}
pub fn attempts(&self) -> usize {
self.attempts
}
pub fn attempted(&mut self) {
self.attempts += 1;
}
pub fn connected(&mut self) {
self.attempts = 0;
}
pub fn received<'r, S, T, G>(
&mut self,
envelope: Envelope,
ctx: &mut Context,
) -> Result