1#![recursion_limit = "256"]
13#![doc(
14 html_logo_url = "https://github.com/maidsafe/QA/raw/master/Images/maidsafe_logo.png",
15 html_favicon_url = "https://maidsafe.net/img/favicon.ico",
16 test(attr(deny(warnings)))
17)]
18#![warn(missing_docs, unreachable_pub, unused_results, clippy::unwrap_used)]
20#![allow(clippy::large_enum_variant)]
21#![allow(clippy::result_large_err)]
22
23#[macro_use]
24extern crate tracing;
25
26mod error;
27mod event;
28mod log_markers;
29#[cfg(feature = "open-metrics")]
30mod metrics;
31mod node;
32mod put_validation;
33#[cfg(feature = "extension-module")]
34mod python;
35mod quote;
36mod replication;
37#[allow(missing_docs)]
38pub mod spawn;
39#[allow(missing_docs)]
40pub mod utils;
41
42pub use self::{
43 error::{Error, PutValidationError},
44 event::{NodeEvent, NodeEventsChannel, NodeEventsReceiver},
45 log_markers::Marker,
46 node::{NodeBuilder, PERIODIC_REPLICATION_INTERVAL_MAX_S},
47};
48
49use crate::error::Result;
50use ant_evm::RewardsAddress;
51use ant_networking::{Network, SwarmLocalState};
52use ant_protocol::{get_port_from_multiaddr, NetworkAddress};
53use libp2p::{Multiaddr, PeerId};
54use std::{
55 collections::{BTreeMap, HashSet},
56 path::PathBuf,
57};
58use tokio::sync::watch;
59
60#[derive(Clone)]
63pub struct RunningNode {
64 shutdown_sender: watch::Sender<bool>,
65 network: Network,
66 node_events_channel: NodeEventsChannel,
67 root_dir_path: PathBuf,
68 rewards_address: RewardsAddress,
69}
70
71impl RunningNode {
72 pub fn peer_id(&self) -> PeerId {
74 self.network.peer_id()
75 }
76
77 #[expect(rustdoc::invalid_html_tags)]
85 pub fn root_dir_path(&self) -> PathBuf {
86 self.root_dir_path.clone()
87 }
88
89 pub async fn get_swarm_local_state(&self) -> Result<SwarmLocalState> {
91 let state = self.network.get_swarm_local_state().await?;
92 Ok(state)
93 }
94
95 pub async fn get_listen_addrs(&self) -> Result<Vec<Multiaddr>> {
97 let listeners = self.network.get_swarm_local_state().await?.listeners;
98 Ok(listeners)
99 }
100
101 pub async fn get_listen_addrs_with_peer_id(&self) -> Result<Vec<Multiaddr>> {
103 let listeners = self.get_listen_addrs().await?;
104
105 let multi_addrs: Vec<Multiaddr> = listeners
106 .into_iter()
107 .filter_map(|listen_addr| listen_addr.with_p2p(self.peer_id()).ok())
108 .collect();
109
110 Ok(multi_addrs)
111 }
112
113 pub async fn get_node_listening_port(&self) -> Result<u16> {
115 let listen_addrs = self.network.get_swarm_local_state().await?.listeners;
116 for addr in listen_addrs {
117 if let Some(port) = get_port_from_multiaddr(&addr) {
118 return Ok(port);
119 }
120 }
121 Err(Error::FailedToGetNodePort)
122 }
123
124 pub fn node_events_channel(&self) -> &NodeEventsChannel {
126 &self.node_events_channel
127 }
128
129 pub async fn get_all_record_addresses(&self) -> Result<HashSet<NetworkAddress>> {
131 #[allow(clippy::mutable_key_type)] let addresses: HashSet<_> = self
133 .network
134 .get_all_local_record_addresses()
135 .await?
136 .keys()
137 .cloned()
138 .collect();
139 Ok(addresses)
140 }
141
142 pub async fn get_kbuckets(&self) -> Result<BTreeMap<u32, Vec<PeerId>>> {
145 let kbuckets = self.network.get_kbuckets().await?;
146 Ok(kbuckets)
147 }
148
149 pub fn reward_address(&self) -> &RewardsAddress {
151 &self.rewards_address
152 }
153
154 pub fn shutdown(self) {
156 let _ = self.shutdown_sender.send(true);
158 }
159}