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