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 }