/ crates / adnet-runtime / src / lib.rs
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  }