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