1use crate::{BootstrapClient, Client, Prover, Validator, traits::NodeInterface};
17use snarkos_account::Account;
18use snarkos_node_router::{Outbound, Peer, PeerPoolHandling, messages::NodeType};
19use snarkvm::prelude::{
20 Address,
21 Header,
22 Ledger,
23 Network,
24 PrivateKey,
25 ViewKey,
26 block::Block,
27 store::helpers::{memory::ConsensusMemory, rocksdb::ConsensusDB},
28};
29
30use aleo_std::StorageMode;
31use anyhow::Result;
32#[cfg(feature = "locktick")]
33use locktick::parking_lot::RwLock;
34#[cfg(not(feature = "locktick"))]
35use parking_lot::RwLock;
36use std::{
37 collections::HashMap,
38 net::SocketAddr,
39 sync::{Arc, atomic::AtomicBool},
40};
41
42#[derive(Clone)]
43pub enum Node<N: Network> {
44 Validator(Arc<Validator<N, ConsensusDB<N>>>),
46 Prover(Arc<Prover<N, ConsensusMemory<N>>>),
48 Client(Arc<Client<N, ConsensusDB<N>>>),
50 BootstrapClient(BootstrapClient<N>),
52}
53
54impl<N: Network> Node<N> {
55 pub async fn new_validator(
57 node_ip: SocketAddr,
58 bft_ip: Option<SocketAddr>,
59 rest_ip: Option<SocketAddr>,
60 rest_rps: u32,
61 account: Account<N>,
62 trusted_peers: &[SocketAddr],
63 trusted_validators: &[SocketAddr],
64 genesis: Block<N>,
65 cdn: Option<http::Uri>,
66 storage_mode: StorageMode,
67 allow_external_peers: bool,
68 dev_txs: bool,
69 dev: Option<u16>,
70 shutdown: Arc<AtomicBool>,
71 ) -> Result<Self> {
72 Ok(Self::Validator(Arc::new(
73 Validator::new(
74 node_ip,
75 bft_ip,
76 rest_ip,
77 rest_rps,
78 account,
79 trusted_peers,
80 trusted_validators,
81 genesis,
82 cdn,
83 storage_mode,
84 allow_external_peers,
85 dev_txs,
86 dev,
87 shutdown,
88 )
89 .await?,
90 )))
91 }
92
93 pub async fn new_prover(
95 node_ip: SocketAddr,
96 account: Account<N>,
97 trusted_peers: &[SocketAddr],
98 genesis: Block<N>,
99 storage_mode: StorageMode,
100 dev: Option<u16>,
101 shutdown: Arc<AtomicBool>,
102 ) -> Result<Self> {
103 Ok(Self::Prover(Arc::new(
104 Prover::new(node_ip, account, trusted_peers, genesis, storage_mode, dev, shutdown).await?,
105 )))
106 }
107
108 pub async fn new_client(
110 node_ip: SocketAddr,
111 rest_ip: Option<SocketAddr>,
112 rest_rps: u32,
113 account: Account<N>,
114 trusted_peers: &[SocketAddr],
115 genesis: Block<N>,
116 cdn: Option<http::Uri>,
117 storage_mode: StorageMode,
118 rotate_external_peers: bool,
119 dev: Option<u16>,
120 shutdown: Arc<AtomicBool>,
121 ) -> Result<Self> {
122 Ok(Self::Client(Arc::new(
123 Client::new(
124 node_ip,
125 rest_ip,
126 rest_rps,
127 account,
128 trusted_peers,
129 genesis,
130 cdn,
131 storage_mode,
132 rotate_external_peers,
133 dev,
134 shutdown,
135 )
136 .await?,
137 )))
138 }
139
140 pub async fn new_bootstrap_client(
142 listener_addr: SocketAddr,
143 account: Account<N>,
144 genesis_header: Header<N>,
145 dev: Option<u16>,
146 ) -> Result<Self> {
147 Ok(Self::BootstrapClient(BootstrapClient::new(listener_addr, account, genesis_header, dev).await?))
148 }
149
150 pub fn node_type(&self) -> NodeType {
152 match self {
153 Self::Validator(validator) => validator.node_type(),
154 Self::Prover(prover) => prover.node_type(),
155 Self::Client(client) => client.node_type(),
156 Self::BootstrapClient(_) => NodeType::BootstrapClient,
157 }
158 }
159
160 pub fn private_key(&self) -> &PrivateKey<N> {
162 match self {
163 Self::Validator(node) => node.private_key(),
164 Self::Prover(node) => node.private_key(),
165 Self::Client(node) => node.private_key(),
166 Self::BootstrapClient(node) => node.private_key(),
167 }
168 }
169
170 pub fn view_key(&self) -> &ViewKey<N> {
172 match self {
173 Self::Validator(node) => node.view_key(),
174 Self::Prover(node) => node.view_key(),
175 Self::Client(node) => node.view_key(),
176 Self::BootstrapClient(node) => node.view_key(),
177 }
178 }
179
180 pub fn address(&self) -> Address<N> {
182 match self {
183 Self::Validator(node) => node.address(),
184 Self::Prover(node) => node.address(),
185 Self::Client(node) => node.address(),
186 Self::BootstrapClient(node) => node.address(),
187 }
188 }
189
190 pub fn is_dev(&self) -> bool {
192 match self {
193 Self::Validator(node) => node.is_dev(),
194 Self::Prover(node) => node.is_dev(),
195 Self::Client(node) => node.is_dev(),
196 Self::BootstrapClient(node) => node.is_dev(),
197 }
198 }
199
200 pub fn peer_pool(&self) -> &RwLock<HashMap<SocketAddr, Peer<N>>> {
202 match self {
203 Self::Validator(validator) => validator.router().peer_pool(),
204 Self::Prover(prover) => prover.router().peer_pool(),
205 Self::Client(client) => client.router().peer_pool(),
206 Self::BootstrapClient(client) => client.peer_pool(),
207 }
208 }
209
210 pub fn ledger(&self) -> Option<&Ledger<N, ConsensusDB<N>>> {
212 match self {
213 Self::Validator(node) => Some(node.ledger()),
214 Self::Prover(_) => None,
215 Self::Client(node) => Some(node.ledger()),
216 Self::BootstrapClient(_) => None,
217 }
218 }
219
220 pub fn is_block_synced(&self) -> bool {
222 match self {
223 Self::Validator(node) => node.is_block_synced(),
224 Self::Prover(node) => node.is_block_synced(),
225 Self::Client(node) => node.is_block_synced(),
226 Self::BootstrapClient(_) => true,
227 }
228 }
229
230 pub fn num_blocks_behind(&self) -> Option<u32> {
233 match self {
234 Self::Validator(node) => node.num_blocks_behind(),
235 Self::Prover(node) => node.num_blocks_behind(),
236 Self::Client(node) => node.num_blocks_behind(),
237 Self::BootstrapClient(_) => Some(0),
238 }
239 }
240
241 pub fn get_sync_speed(&self) -> f64 {
244 match self {
245 Self::Validator(node) => node.get_sync_speed(),
246 Self::Prover(node) => node.get_sync_speed(),
247 Self::Client(node) => node.get_sync_speed(),
248 Self::BootstrapClient(_) => 0.0,
249 }
250 }
251
252 pub async fn shut_down(&self) {
254 match self {
255 Self::Validator(node) => node.shut_down().await,
256 Self::Prover(node) => node.shut_down().await,
257 Self::Client(node) => node.shut_down().await,
258 Self::BootstrapClient(node) => node.shut_down().await,
259 }
260 }
261}