lib.rs
1 // Copyright (c) 2025 ALPHA/DELTA Network 2 3 //! # ADNet Runtime 4 //! 5 //! Orchestrates the ALPHA and DELTA chain runtimes within the unified binary. 6 //! 7 //! ## Architecture 8 //! 9 //! ```text 10 //! ┌─────────── adnet Process ──────────────┐ 11 //! │ │ 12 //! │ ┌─────────────────┐ ┌────────────┐ │ 13 //! │ │ ALPHA Runtime │◄─┼─ IPC ──────┤ │ 14 //! │ │ (thread) │ │ (channels)│ │ 15 //! │ └────────┬────────┘ └────────────┤ │ 16 //! │ │ │ │ │ 17 //! │ ┌────────▼──────────┐ │ │ │ 18 //! │ │ DELTA Runtime │◄────────┘ │ │ 19 //! │ │ (thread) │ │ │ 20 //! │ └────────┬──────────┘ │ │ 21 //! │ │ │ │ 22 //! │ ┌────────▼──────────────────────┐ │ │ 23 //! │ │ Shared State │ │ │ 24 //! │ │ - Peer list │ │ │ 25 //! │ │ - Block cache │ │ │ 26 //! │ │ - Attestations │ │ │ 27 //! │ └───────────────────────────────┘ │ │ 28 //! └────────────────────────────────────────┘ 29 //! ``` 30 31 use adnet_ipc::{AlphaIpcHandle, DeltaIpcHandle, RuntimeIpc}; 32 use std::sync::Arc; 33 use tokio::sync::RwLock; 34 use tracing::{info, warn}; 35 36 pub mod alpha; 37 pub mod delta; 38 pub mod config; 39 40 /// The unified ADNet runtime managing both chains. 41 pub struct AdnetRuntime { 42 /// ALPHA chain runtime. 43 pub alpha: Option<alpha::AlphaRuntime>, 44 /// DELTA chain runtime. 45 pub delta: Option<delta::DeltaRuntime>, 46 /// IPC channels for cross-chain communication. 47 pub ipc: RuntimeIpc, 48 /// Shared state between runtimes. 49 pub shared: Arc<SharedState>, 50 /// Runtime configuration. 51 pub config: config::RuntimeConfig, 52 } 53 54 /// Shared state accessible by both chain runtimes. 55 pub struct SharedState { 56 /// Shared peer list (combined from both networks). 57 pub peers: RwLock<Vec<PeerInfo>>, 58 /// Runtime metrics. 59 pub metrics: RwLock<RuntimeMetrics>, 60 /// Whether the node is shutting down. 61 pub shutting_down: RwLock<bool>, 62 } 63 64 /// Information about a connected peer. 65 #[derive(Debug, Clone)] 66 pub struct PeerInfo { 67 /// Peer address. 68 pub address: String, 69 /// Which chain(s) this peer supports. 70 pub chains: ChainSupport, 71 /// Latency to this peer in milliseconds. 72 pub latency_ms: u32, 73 } 74 75 /// Which chains a peer supports. 76 #[derive(Debug, Clone, Copy)] 77 pub enum ChainSupport { 78 AlphaOnly, 79 DeltaOnly, 80 Both, 81 } 82 83 /// Runtime metrics for monitoring. 84 #[derive(Debug, Default)] 85 pub struct RuntimeMetrics { 86 pub alpha_block_height: u64, 87 pub delta_block_height: u64, 88 pub alpha_peers: usize, 89 pub delta_peers: usize, 90 pub ipc_messages_sent: u64, 91 pub ipc_messages_received: u64, 92 } 93 94 impl AdnetRuntime { 95 /// Create a new unified runtime. 96 pub fn new(config: config::RuntimeConfig) -> Self { 97 let ipc = RuntimeIpc::new(); 98 99 Self { 100 alpha: None, 101 delta: None, 102 ipc, 103 shared: Arc::new(SharedState { 104 peers: RwLock::new(Vec::new()), 105 metrics: RwLock::new(RuntimeMetrics::default()), 106 shutting_down: RwLock::new(false), 107 }), 108 config, 109 } 110 } 111 112 /// Initialize the ALPHA runtime. 113 pub async fn init_alpha(&mut self) -> anyhow::Result<()> { 114 if !self.config.enable_alpha { 115 info!("ALPHA chain disabled by configuration"); 116 return Ok(()); 117 } 118 119 info!("Initializing ALPHA runtime..."); 120 let alpha_handle = self.ipc.alpha_handle(); 121 122 self.alpha = Some(alpha::AlphaRuntime::new( 123 alpha_handle, 124 self.shared.clone(), 125 self.config.alpha.clone(), 126 )?); 127 128 info!("ALPHA runtime initialized"); 129 Ok(()) 130 } 131 132 /// Initialize the DELTA runtime. 133 pub async fn init_delta(&mut self) -> anyhow::Result<()> { 134 if !self.config.enable_delta { 135 info!("DELTA chain disabled by configuration"); 136 return Ok(()); 137 } 138 139 info!("Initializing DELTA runtime..."); 140 let delta_handle = self.ipc.delta_handle(); 141 142 self.delta = Some(delta::DeltaRuntime::new( 143 delta_handle, 144 self.shared.clone(), 145 self.config.delta.clone(), 146 )?); 147 148 info!("DELTA runtime initialized"); 149 Ok(()) 150 } 151 152 /// Start both runtimes. 153 pub async fn start(&self) -> anyhow::Result<()> { 154 info!("Starting ADNet runtime..."); 155 156 if let Some(ref alpha) = self.alpha { 157 alpha.start().await?; 158 } 159 160 if let Some(ref delta) = self.delta { 161 delta.start().await?; 162 } 163 164 info!("ADNet runtime started"); 165 Ok(()) 166 } 167 168 /// Shutdown both runtimes gracefully. 169 pub async fn shutdown(&self) -> anyhow::Result<()> { 170 info!("Shutting down ADNet runtime..."); 171 172 *self.shared.shutting_down.write().await = true; 173 174 if let Some(ref delta) = self.delta { 175 delta.shutdown().await?; 176 } 177 178 if let Some(ref alpha) = self.alpha { 179 alpha.shutdown().await?; 180 } 181 182 info!("ADNet runtime shutdown complete"); 183 Ok(()) 184 } 185 186 /// Get current runtime metrics. 187 pub async fn metrics(&self) -> RuntimeMetrics { 188 let guard = self.shared.metrics.read().await; 189 RuntimeMetrics { 190 alpha_block_height: guard.alpha_block_height, 191 delta_block_height: guard.delta_block_height, 192 alpha_peers: guard.alpha_peers, 193 delta_peers: guard.delta_peers, 194 ipc_messages_sent: guard.ipc_messages_sent, 195 ipc_messages_received: guard.ipc_messages_received, 196 } 197 } 198 }