snarkos_node_network/
peer.rs1use crate::NodeType;
17use snarkvm::prelude::{Address, Network};
18use tracing::*;
19
20use std::{net::SocketAddr, time::Instant};
21
22#[derive(Clone, Debug)]
24pub enum Peer<N: Network> {
25 Candidate(CandidatePeer),
27 Connecting(ConnectingPeer),
29 Connected(ConnectedPeer<N>),
31}
32
33#[derive(Clone, Debug)]
35pub struct ConnectingPeer {
36 pub listener_addr: SocketAddr,
38 pub trusted: bool,
40}
41
42#[derive(Clone, Debug)]
44pub struct CandidatePeer {
45 pub listener_addr: SocketAddr,
47 pub trusted: bool,
49 pub last_height_seen: Option<u32>,
51}
52
53#[derive(Clone, Debug)]
55pub struct ConnectedPeer<N: Network> {
56 pub listener_addr: SocketAddr,
58 pub connected_addr: SocketAddr,
60 pub connection_mode: ConnectionMode,
62 pub trusted: bool,
64 pub aleo_addr: Address<N>,
66 pub node_type: NodeType,
68 pub version: u32,
70 pub last_height_seen: Option<u32>,
72 pub first_seen: Instant,
74 pub last_seen: Instant,
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum ConnectionMode {
81 Gateway,
82 Router,
83}
84
85impl<N: Network> Peer<N> {
86 pub const fn new_candidate(listener_addr: SocketAddr, trusted: bool) -> Self {
88 Self::Candidate(CandidatePeer { listener_addr, trusted, last_height_seen: None })
89 }
90
91 pub const fn new_connecting(listener_addr: SocketAddr, trusted: bool) -> Self {
93 Self::Connecting(ConnectingPeer { listener_addr, trusted })
94 }
95
96 pub fn upgrade_to_connected(
98 &mut self,
99 connected_addr: SocketAddr,
100 listener_port: u16,
101 aleo_address: Address<N>,
102 node_type: NodeType,
103 node_version: u32,
104 connection_mode: ConnectionMode,
105 ) {
106 let timestamp = Instant::now();
107 let listener_addr = SocketAddr::from((connected_addr.ip(), listener_port));
108
109 if !matches!(self, Self::Connecting(_)) {
112 warn!("Peer '{listener_addr}' is being upgraded to Connected, but isn't Connecting");
113 }
114
115 *self = Self::Connected(ConnectedPeer {
116 listener_addr,
117 connected_addr,
118 connection_mode,
119 aleo_addr: aleo_address,
120 node_type,
121 trusted: self.is_trusted(),
122 version: node_version,
123 last_height_seen: None,
124 first_seen: timestamp,
125 last_seen: timestamp,
126 });
127 }
128
129 pub fn downgrade_to_candidate(&mut self, listener_addr: SocketAddr) {
131 *self = Self::Candidate(CandidatePeer {
132 listener_addr,
133 trusted: self.is_trusted(),
134 last_height_seen: self.last_height_seen(),
135 });
136 }
137
138 pub fn node_type(&self) -> Option<NodeType> {
140 match self {
141 Self::Candidate(_) => None,
142 Self::Connecting(_) => None,
143 Self::Connected(peer) => Some(peer.node_type),
144 }
145 }
146
147 pub fn listener_addr(&self) -> SocketAddr {
149 match self {
150 Self::Candidate(p) => p.listener_addr,
151 Self::Connecting(p) => p.listener_addr,
152 Self::Connected(p) => p.listener_addr,
153 }
154 }
155
156 pub fn last_height_seen(&self) -> Option<u32> {
158 match self {
159 Self::Candidate(_) => None,
160 Self::Connecting(_) => None,
161 Self::Connected(peer) => peer.last_height_seen,
162 }
163 }
164
165 pub fn is_candidate(&self) -> bool {
167 matches!(self, Peer::Candidate(_))
168 }
169
170 pub fn is_connecting(&self) -> bool {
172 matches!(self, Peer::Connecting(_))
173 }
174
175 pub fn is_connected(&self) -> bool {
177 matches!(self, Peer::Connected(_))
178 }
179
180 pub fn is_trusted(&self) -> bool {
182 match self {
183 Self::Candidate(peer) => peer.trusted,
184 Self::Connecting(peer) => peer.trusted,
185 Self::Connected(peer) => peer.trusted,
186 }
187 }
188
189 pub fn update_last_seen(&mut self) {
191 if let Self::Connected(ConnectedPeer { last_seen, .. }) = self {
192 *last_seen = Instant::now();
193 }
194 }
195}