snarkos_node_router/helpers/
peer.rs1use crate::NodeType;
17use snarkvm::prelude::{Address, Network};
18
19use std::{net::SocketAddr, time::Instant};
20
21#[derive(Clone)]
23pub enum Peer<N: Network> {
24 Candidate(CandidatePeer),
26 Connecting(ConnectingPeer),
28 Connected(ConnectedPeer<N>),
30}
31
32#[derive(Clone)]
34pub struct ConnectingPeer {
35 pub listener_addr: SocketAddr,
37 pub trusted: bool,
39}
40
41#[derive(Clone)]
43pub struct CandidatePeer {
44 pub listener_addr: SocketAddr,
46 pub trusted: bool,
48 pub last_height_seen: Option<u32>,
50}
51
52#[derive(Clone)]
54pub struct ConnectedPeer<N: Network> {
55 pub listener_addr: SocketAddr,
57 pub connected_addr: SocketAddr,
59 pub trusted: bool,
61 pub aleo_addr: Address<N>,
63 pub node_type: NodeType,
65 pub version: u32,
67 pub last_height_seen: Option<u32>,
69 pub first_seen: Instant,
71 pub last_seen: Instant,
73}
74
75impl<N: Network> Peer<N> {
76 pub const fn new_candidate(listener_addr: SocketAddr, trusted: bool) -> Self {
78 Self::Candidate(CandidatePeer { listener_addr, trusted, last_height_seen: None })
79 }
80
81 pub const fn new_connecting(listener_addr: SocketAddr, trusted: bool) -> Self {
83 Self::Connecting(ConnectingPeer { listener_addr, trusted })
84 }
85
86 pub fn upgrade_to_connected(
88 &mut self,
89 connected_addr: SocketAddr,
90 listener_port: u16,
91 aleo_address: Address<N>,
92 node_type: NodeType,
93 node_version: u32,
94 ) {
95 let timestamp = Instant::now();
96 let listener_addr = SocketAddr::from((connected_addr.ip(), listener_port));
97
98 if !matches!(self, Self::Connecting(_)) {
101 warn!("Peer '{listener_addr}' is being upgraded to Connected, but isn't Connecting");
102 }
103
104 *self = Self::Connected(ConnectedPeer {
105 listener_addr,
106 connected_addr,
107 aleo_addr: aleo_address,
108 node_type,
109 trusted: self.is_trusted(),
110 version: node_version,
111 last_height_seen: None,
112 first_seen: timestamp,
113 last_seen: timestamp,
114 });
115 }
116
117 pub fn downgrade_to_candidate(&mut self, listener_addr: SocketAddr) {
119 *self = Self::Candidate(CandidatePeer {
120 listener_addr,
121 trusted: self.is_trusted(),
122 last_height_seen: self.last_height_seen(),
123 });
124 }
125
126 pub fn node_type(&self) -> Option<NodeType> {
128 match self {
129 Self::Candidate(_) => None,
130 Self::Connecting(_) => None,
131 Self::Connected(peer) => Some(peer.node_type),
132 }
133 }
134
135 pub fn listener_addr(&self) -> SocketAddr {
137 match self {
138 Self::Candidate(p) => p.listener_addr,
139 Self::Connecting(p) => p.listener_addr,
140 Self::Connected(p) => p.listener_addr,
141 }
142 }
143
144 pub fn last_height_seen(&self) -> Option<u32> {
146 match self {
147 Self::Candidate(_) => None,
148 Self::Connecting(_) => None,
149 Self::Connected(peer) => peer.last_height_seen,
150 }
151 }
152
153 pub fn is_candidate(&self) -> bool {
155 matches!(self, Peer::Candidate(_))
156 }
157
158 pub fn is_connecting(&self) -> bool {
160 matches!(self, Peer::Connecting(_))
161 }
162
163 pub fn is_connected(&self) -> bool {
165 matches!(self, Peer::Connected(_))
166 }
167
168 pub fn is_trusted(&self) -> bool {
170 match self {
171 Self::Candidate(peer) => peer.trusted,
172 Self::Connecting(peer) => peer.trusted,
173 Self::Connected(peer) => peer.trusted,
174 }
175 }
176
177 pub fn update_last_seen(&mut self) {
179 if let Self::Connected(ConnectedPeer { last_seen, .. }) = self {
180 *last_seen = Instant::now();
181 }
182 }
183}