amareleo_node/validator/
mod.rs1use amareleo_chain_account::Account;
17use amareleo_chain_tracing::{TracingHandler, TracingHandlerGuard};
18use amareleo_node_bft::{helpers::init_primary_channels, ledger_service::CoreLedgerService};
19use amareleo_node_consensus::Consensus;
20use amareleo_node_rest::Rest;
21
22use snarkvm::prelude::{Ledger, Network, block::Block, store::ConsensusStorage};
23
24use aleo_std::StorageMode;
25use anyhow::Result;
26use std::{
27 net::SocketAddr,
28 sync::{Arc, atomic::AtomicBool},
29};
30use tracing::subscriber::DefaultGuard;
31
32#[derive(Clone)]
34pub struct Validator<N: Network, C: ConsensusStorage<N>> {
35 ledger: Ledger<N, C>,
37 consensus: Consensus<N>,
39 rest: Option<Rest<N, C>>,
41 tracing: Option<TracingHandler>,
43 shutdown: Arc<AtomicBool>,
45}
46
47impl<N: Network, C: ConsensusStorage<N>> TracingHandlerGuard for Validator<N, C> {
48 fn get_tracing_guard(&self) -> Option<DefaultGuard> {
50 self.tracing.as_ref().and_then(|trace_handle| trace_handle.get_tracing_guard())
51 }
52}
53
54impl<N: Network, C: ConsensusStorage<N>> Validator<N, C> {
55 pub async fn new(
57 rest_ip: SocketAddr,
58 rest_rps: u32,
59 account: Account<N>,
60 genesis: Block<N>,
61 keep_state: bool,
62 storage_mode: StorageMode,
63 tracing: Option<TracingHandler>,
64 shutdown: Arc<AtomicBool>,
65 ) -> Result<Self> {
66 let ledger = Ledger::load(genesis, storage_mode.clone())?;
68 let tracing_: TracingHandler = tracing.clone().into();
69
70 guard_info!(tracing_, "Starting Consensus...");
72 let ledger_service = Arc::new(CoreLedgerService::new(ledger.clone(), tracing.clone(), shutdown.clone()));
73 let mut consensus =
74 Consensus::new(account.clone(), ledger_service.clone(), keep_state, storage_mode.clone(), tracing.clone())?;
75
76 let (primary_sender, primary_receiver) = init_primary_channels::<N>();
77 consensus.run(primary_sender, primary_receiver).await?;
78
79 guard_info!(tracing_, "Starting the REST server...");
81 let rest_srv = Rest::start(rest_ip, rest_rps, Some(consensus.clone()), ledger.clone(), tracing.clone()).await;
82 if let Err(err) = rest_srv {
83 guard_error!(tracing_, "Failed to start REST server: {:?}", err);
84 consensus.shut_down().await;
85 return Err(err);
86 }
87
88 Ok(Self { ledger, consensus, rest: Some(rest_srv.unwrap()), tracing, shutdown })
90 }
91
92 pub fn ledger(&self) -> &Ledger<N, C> {
94 &self.ledger
95 }
96
97 pub fn rest(&self) -> &Option<Rest<N, C>> {
99 &self.rest
100 }
101}
102
103impl<N: Network, C: ConsensusStorage<N>> Validator<N, C> {
104 pub async fn shut_down(&self) {
106 guard_info!(self, "Shutting down...");
109 self.shutdown.store(true, std::sync::atomic::Ordering::Release);
110
111 if let Some(rest) = &self.rest {
113 guard_trace!(self, "Shutting down the REST server...");
114 rest.shut_down().await;
115 }
116
117 guard_trace!(self, "Shutting down consensus...");
119 self.consensus.shut_down().await;
120
121 guard_info!(self, "Node has shut down.");
122 guard_info!(self, "");
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129 use amareleo_node_bft::DEVELOPMENT_MODE_RNG_SEED;
130
131 use snarkvm::prelude::{
132 MainnetV0,
133 VM,
134 store::{ConsensusStore, helpers::memory::ConsensusMemory},
135 };
136
137 use anyhow::bail;
138 use rand::SeedableRng;
139 use rand_chacha::ChaChaRng;
140 use std::str::FromStr;
141
142 type CurrentNetwork = MainnetV0;
143
144 #[ignore]
146 #[tokio::test]
147 async fn test_profiler() -> Result<()> {
148 let rest = SocketAddr::from_str("0.0.0.0:3030").unwrap();
150 let storage_mode = StorageMode::Development(0);
151
152 let mut rng = ChaChaRng::seed_from_u64(DEVELOPMENT_MODE_RNG_SEED);
154 let account = Account::<CurrentNetwork>::new(&mut rng).unwrap();
156 let vm = VM::from(ConsensusStore::<CurrentNetwork, ConsensusMemory<CurrentNetwork>>::open(
158 StorageMode::new_test(None),
159 )?)?;
160 let genesis = vm.genesis_beacon(account.private_key(), &mut rng)?;
162
163 println!("Initializing validator node...");
164
165 let validator = Validator::<CurrentNetwork, ConsensusMemory<CurrentNetwork>>::new(
166 rest,
167 10,
168 account,
169 genesis,
170 false,
171 storage_mode,
172 None,
173 Default::default(),
174 )
175 .await
176 .unwrap();
177
178 println!("Loaded validator node with {} blocks", validator.ledger.latest_height(),);
179
180 bail!("\n\nRemember to #[ignore] this test!\n\n")
181 }
182}