kaspa_p2p_lib/core/
peer.rs

1use kaspa_consensus_core::subnets::SubnetworkId;
2use kaspa_utils::networking::{IpAddress, PeerId};
3use std::{fmt::Display, net::SocketAddr, sync::Arc, time::Instant};
4
5#[derive(Debug, Clone, Default)]
6pub struct PeerProperties {
7    pub user_agent: String,
8    // TODO: add services
9    pub advertised_protocol_version: u32,
10    pub protocol_version: u32,
11    pub disable_relay_tx: bool,
12    pub subnetwork_id: Option<SubnetworkId>,
13    pub time_offset: i64,
14}
15
16#[derive(Debug)]
17pub struct Peer {
18    identity: PeerId,
19    net_address: SocketAddr,
20    is_outbound: bool,
21    connection_started: Instant,
22    properties: Arc<PeerProperties>,
23    last_ping_duration: u64,
24}
25
26impl Peer {
27    pub fn new(
28        identity: PeerId,
29        net_address: SocketAddr,
30        is_outbound: bool,
31        connection_started: Instant,
32        properties: Arc<PeerProperties>,
33        last_ping_duration: u64,
34    ) -> Self {
35        Self { identity, net_address, is_outbound, connection_started, properties, last_ping_duration }
36    }
37
38    /// Internal identity of this peer
39    pub fn identity(&self) -> PeerId {
40        self.identity
41    }
42
43    /// The socket address of this peer
44    pub fn net_address(&self) -> SocketAddr {
45        self.net_address
46    }
47
48    pub fn key(&self) -> PeerKey {
49        self.into()
50    }
51
52    /// Indicates whether this connection is an outbound connection
53    pub fn is_outbound(&self) -> bool {
54        self.is_outbound
55    }
56
57    pub fn time_connected(&self) -> u64 {
58        Instant::now().duration_since(self.connection_started).as_millis() as u64
59    }
60
61    pub fn properties(&self) -> Arc<PeerProperties> {
62        self.properties.clone()
63    }
64
65    pub fn last_ping_duration(&self) -> u64 {
66        self.last_ping_duration
67    }
68}
69
70#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
71pub struct PeerKey {
72    identity: PeerId,
73    ip: IpAddress,
74}
75
76impl PeerKey {
77    pub fn new(identity: PeerId, ip: IpAddress) -> Self {
78        Self { identity, ip }
79    }
80}
81
82impl From<&Peer> for PeerKey {
83    fn from(value: &Peer) -> Self {
84        Self::new(value.identity, value.net_address.ip().into())
85    }
86}
87
88impl Display for PeerKey {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        write!(f, "{}+{}", self.identity, self.ip)
91    }
92}