/ node / src / node.rs
node.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaOS library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use crate::{
 17      BootstrapClient,
 18      Client,
 19      Prover,
 20      Validator,
 21      network::{NodeType, Peer, PeerPoolHandling},
 22      router::Outbound,
 23      traits::NodeInterface,
 24  };
 25  
 26  use alphaos_account::Account;
 27  use alphaos_utilities::SignalHandler;
 28  
 29  use alphavm::prelude::{
 30      Address,
 31      Header,
 32      Ledger,
 33      Network,
 34      PrivateKey,
 35      ViewKey,
 36      block::Block,
 37      store::helpers::{memory::ConsensusMemory, rocksdb::ConsensusDB},
 38  };
 39  
 40  use alpha_std::StorageMode;
 41  use anyhow::Result;
 42  
 43  #[cfg(feature = "locktick")]
 44  use locktick::parking_lot::RwLock;
 45  #[cfg(not(feature = "locktick"))]
 46  use parking_lot::RwLock;
 47  use std::{collections::HashMap, net::SocketAddr, sync::Arc};
 48  
 49  #[derive(Clone)]
 50  pub enum Node<N: Network> {
 51      /// A validator is a full node, capable of validating blocks.
 52      Validator(Arc<Validator<N, ConsensusDB<N>>>),
 53      /// A prover is a light node, capable of producing proofs for consensus.
 54      Prover(Arc<Prover<N, ConsensusMemory<N>>>),
 55      /// A client node is a full node, capable of querying with the network.
 56      Client(Arc<Client<N, ConsensusDB<N>>>),
 57      /// A bootstrap client node is a light node dedicated to serving lists of peers.
 58      BootstrapClient(BootstrapClient<N>),
 59  }
 60  
 61  impl<N: Network> Node<N> {
 62      /// Initializes a new validator node.
 63      pub async fn new_validator(
 64          node_ip: SocketAddr,
 65          bft_ip: Option<SocketAddr>,
 66          rest_ip: Option<SocketAddr>,
 67          rest_rps: u32,
 68          account: Account<N>,
 69          trusted_peers: &[SocketAddr],
 70          trusted_validators: &[SocketAddr],
 71          genesis: Block<N>,
 72          cdn: Option<http::Uri>,
 73          storage_mode: StorageMode,
 74          trusted_peers_only: bool,
 75          dev_txs: bool,
 76          dev: Option<u16>,
 77          signal_handler: Arc<SignalHandler>,
 78      ) -> Result<Self> {
 79          Ok(Self::Validator(Arc::new(
 80              Validator::new(
 81                  node_ip,
 82                  bft_ip,
 83                  rest_ip,
 84                  rest_rps,
 85                  account,
 86                  trusted_peers,
 87                  trusted_validators,
 88                  genesis,
 89                  cdn,
 90                  storage_mode,
 91                  trusted_peers_only,
 92                  dev_txs,
 93                  dev,
 94                  signal_handler,
 95              )
 96              .await?,
 97          )))
 98      }
 99  
100      /// Initializes a new prover node.
101      pub async fn new_prover(
102          node_ip: SocketAddr,
103          account: Account<N>,
104          trusted_peers: &[SocketAddr],
105          genesis: Block<N>,
106          storage_mode: StorageMode,
107          trusted_peers_only: bool,
108          dev: Option<u16>,
109          signal_handler: Arc<SignalHandler>,
110      ) -> Result<Self> {
111          Ok(Self::Prover(Arc::new(
112              Prover::new(
113                  node_ip,
114                  account,
115                  trusted_peers,
116                  genesis,
117                  storage_mode,
118                  trusted_peers_only,
119                  dev,
120                  signal_handler,
121              )
122              .await?,
123          )))
124      }
125  
126      /// Initializes a new client node.
127      pub async fn new_client(
128          node_ip: SocketAddr,
129          rest_ip: Option<SocketAddr>,
130          rest_rps: u32,
131          account: Account<N>,
132          trusted_peers: &[SocketAddr],
133          genesis: Block<N>,
134          cdn: Option<http::Uri>,
135          storage_mode: StorageMode,
136          trusted_peers_only: bool,
137          dev: Option<u16>,
138          signal_handler: Arc<SignalHandler>,
139      ) -> Result<Self> {
140          Ok(Self::Client(Arc::new(
141              Client::new(
142                  node_ip,
143                  rest_ip,
144                  rest_rps,
145                  account,
146                  trusted_peers,
147                  genesis,
148                  cdn,
149                  storage_mode,
150                  trusted_peers_only,
151                  dev,
152                  signal_handler,
153              )
154              .await?,
155          )))
156      }
157  
158      /// Initializes a new bootstrap client node.
159      pub async fn new_bootstrap_client(
160          listener_addr: SocketAddr,
161          account: Account<N>,
162          genesis_header: Header<N>,
163          dev: Option<u16>,
164      ) -> Result<Self> {
165          Ok(Self::BootstrapClient(BootstrapClient::new(listener_addr, account, genesis_header, dev).await?))
166      }
167  
168      /// Returns the node type.
169      pub fn node_type(&self) -> NodeType {
170          match self {
171              Self::Validator(validator) => validator.node_type(),
172              Self::Prover(prover) => prover.node_type(),
173              Self::Client(client) => client.node_type(),
174              Self::BootstrapClient(_) => NodeType::BootstrapClient,
175          }
176      }
177  
178      /// Returns the account private key of the node.
179      pub fn private_key(&self) -> &PrivateKey<N> {
180          match self {
181              Self::Validator(node) => node.private_key(),
182              Self::Prover(node) => node.private_key(),
183              Self::Client(node) => node.private_key(),
184              Self::BootstrapClient(node) => node.private_key(),
185          }
186      }
187  
188      /// Returns the account view key of the node.
189      pub fn view_key(&self) -> &ViewKey<N> {
190          match self {
191              Self::Validator(node) => node.view_key(),
192              Self::Prover(node) => node.view_key(),
193              Self::Client(node) => node.view_key(),
194              Self::BootstrapClient(node) => node.view_key(),
195          }
196      }
197  
198      /// Returns the account address of the node.
199      pub fn address(&self) -> Address<N> {
200          match self {
201              Self::Validator(node) => node.address(),
202              Self::Prover(node) => node.address(),
203              Self::Client(node) => node.address(),
204              Self::BootstrapClient(node) => node.address(),
205          }
206      }
207  
208      /// Returns `true` if the node is in development mode.
209      pub fn is_dev(&self) -> bool {
210          match self {
211              Self::Validator(node) => node.is_dev(),
212              Self::Prover(node) => node.is_dev(),
213              Self::Client(node) => node.is_dev(),
214              Self::BootstrapClient(node) => node.is_dev(),
215          }
216      }
217  
218      /// Returns a reference to the underlying peer pool.
219      pub fn peer_pool(&self) -> &RwLock<HashMap<SocketAddr, Peer<N>>> {
220          match self {
221              Self::Validator(validator) => validator.router().peer_pool(),
222              Self::Prover(prover) => prover.router().peer_pool(),
223              Self::Client(client) => client.router().peer_pool(),
224              Self::BootstrapClient(client) => client.peer_pool(),
225          }
226      }
227  
228      /// Get the underlying ledger (if any).
229      pub fn ledger(&self) -> Option<&Ledger<N, ConsensusDB<N>>> {
230          match self {
231              Self::Validator(node) => Some(node.ledger()),
232              Self::Prover(_) => None,
233              Self::Client(node) => Some(node.ledger()),
234              Self::BootstrapClient(_) => None,
235          }
236      }
237  
238      /// Returns `true` if the node is synced up to the latest block (within the given tolerance).
239      pub fn is_block_synced(&self) -> bool {
240          match self {
241              Self::Validator(node) => node.is_block_synced(),
242              Self::Prover(node) => node.is_block_synced(),
243              Self::Client(node) => node.is_block_synced(),
244              Self::BootstrapClient(_) => true,
245          }
246      }
247  
248      /// Returns the number of blocks this node is behind the greatest peer height,
249      /// or `None` if not connected to peers yet.
250      pub fn num_blocks_behind(&self) -> Option<u32> {
251          match self {
252              Self::Validator(node) => node.num_blocks_behind(),
253              Self::Prover(node) => node.num_blocks_behind(),
254              Self::Client(node) => node.num_blocks_behind(),
255              Self::BootstrapClient(_) => Some(0),
256          }
257      }
258  
259      /// Calculates the current sync speed in blocks per second.
260      /// Returns None if sync speed cannot be calculated (e.g., not syncing or insufficient data).
261      pub fn get_sync_speed(&self) -> f64 {
262          match self {
263              Self::Validator(node) => node.get_sync_speed(),
264              Self::Prover(node) => node.get_sync_speed(),
265              Self::Client(node) => node.get_sync_speed(),
266              Self::BootstrapClient(_) => 0.0,
267          }
268      }
269  
270      /// Shuts down the node.
271      pub async fn shut_down(&self) {
272          match self {
273              Self::Validator(node) => node.shut_down().await,
274              Self::Prover(node) => node.shut_down().await,
275              Self::Client(node) => node.shut_down().await,
276              Self::BootstrapClient(node) => node.shut_down().await,
277          }
278      }
279  
280      /// Waits until the node receives a signal.
281      pub async fn wait_for_signals(&self, signal_handler: &SignalHandler) {
282          match self {
283              Self::Validator(node) => node.wait_for_signals(signal_handler).await,
284              Self::Prover(node) => node.wait_for_signals(signal_handler).await,
285              Self::Client(node) => node.wait_for_signals(signal_handler).await,
286              Self::BootstrapClient(node) => node.wait_for_signals(signal_handler).await,
287          }
288      }
289  }