ant_node/spawn/
node_spawner.rs1use crate::utils::get_root_dir_and_keypair;
10use crate::{NodeBuilder, RunningNode};
11use ant_evm::{EvmNetwork, RewardsAddress};
12use libp2p::Multiaddr;
13use std::net::{IpAddr, Ipv4Addr, SocketAddr};
14use std::path::PathBuf;
15
16pub struct NodeSpawner {
17 socket_addr: SocketAddr,
19 evm_network: EvmNetwork,
21 rewards_address: RewardsAddress,
23 initial_peers: Vec<Multiaddr>,
25 local: bool,
27 no_upnp: bool,
29 root_dir: Option<PathBuf>,
31}
32
33impl NodeSpawner {
34 pub fn new() -> Self {
36 Self {
37 socket_addr: SocketAddr::new(IpAddr::from(Ipv4Addr::UNSPECIFIED), 0),
38 evm_network: Default::default(),
39 rewards_address: Default::default(),
40 initial_peers: vec![],
41 local: false,
42 no_upnp: false,
43 root_dir: None,
44 }
45 }
46
47 pub fn with_socket_addr(mut self, socket_addr: SocketAddr) -> Self {
53 self.socket_addr = socket_addr;
54 self
55 }
56
57 pub fn with_evm_network(mut self, evm_network: EvmNetwork) -> Self {
63 self.evm_network = evm_network;
64 self
65 }
66
67 pub fn with_rewards_address(mut self, rewards_address: RewardsAddress) -> Self {
73 self.rewards_address = rewards_address;
74 self
75 }
76
77 pub fn with_initial_peers(mut self, initial_peers: Vec<Multiaddr>) -> Self {
83 self.initial_peers = initial_peers;
84 self
85 }
86
87 pub fn with_local(mut self, local: bool) -> Self {
93 self.local = local;
94 self
95 }
96
97 pub fn with_no_upnp(mut self, no_upnp: bool) -> Self {
103 self.no_upnp = no_upnp;
104 self
105 }
106
107 pub fn with_root_dir(mut self, root_dir: Option<PathBuf>) -> Self {
113 self.root_dir = root_dir;
114 self
115 }
116
117 pub async fn spawn(self) -> eyre::Result<RunningNode> {
123 spawn_node(
124 self.socket_addr,
125 self.evm_network,
126 self.rewards_address,
127 self.initial_peers,
128 self.local,
129 self.no_upnp,
130 &self.root_dir,
131 )
132 .await
133 }
134}
135
136impl Default for NodeSpawner {
137 fn default() -> Self {
138 Self::new()
139 }
140}
141
142async fn spawn_node(
143 socket_addr: SocketAddr,
144 evm_network: EvmNetwork,
145 rewards_address: RewardsAddress,
146 initial_peers: Vec<Multiaddr>,
147 local: bool,
148 no_upnp: bool,
149 root_dir: &Option<PathBuf>,
150) -> eyre::Result<RunningNode> {
151 let (root_dir, keypair) = get_root_dir_and_keypair(root_dir)?;
152
153 let mut node_builder = NodeBuilder::new(
154 keypair,
155 initial_peers,
156 rewards_address,
157 evm_network,
158 socket_addr,
159 root_dir,
160 );
161 node_builder.local(local);
162 node_builder.no_upnp(no_upnp);
163
164 let running_node = node_builder.build_and_run()?;
165
166 let mut retries: u8 = 0;
168
169 let listen_addrs: Vec<Multiaddr> = loop {
170 if let Ok(listen_addrs) = running_node.get_listen_addrs().await {
172 if !listen_addrs.is_empty() {
173 break Ok(listen_addrs);
174 }
175 }
176
177 if retries >= 3 {
178 break Err(eyre::eyre!(
179 "Failed to get listen addresses after {} retries",
180 retries
181 ));
182 }
183
184 retries += 1;
185
186 tokio::time::sleep(tokio::time::Duration::from_secs(retries as u64)).await;
187 }?;
188
189 info!("Node listening on addresses: {:?}", listen_addrs);
190
191 Ok(running_node)
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197 use ant_evm::EvmNetwork;
198 use futures::StreamExt;
199 use libp2p::swarm::dummy;
200
201 #[tokio::test]
202 async fn test_launch_node() {
203 let evm_network = EvmNetwork::ArbitrumSepoliaTest;
204
205 let running_node = NodeSpawner::new()
206 .with_evm_network(evm_network)
207 .with_local(true)
208 .spawn()
209 .await
210 .unwrap();
211
212 let listen_addrs = running_node.get_listen_addrs().await.unwrap();
213
214 assert!(!listen_addrs.is_empty());
215
216 let mut swarm = libp2p::SwarmBuilder::with_new_identity()
217 .with_tokio()
218 .with_quic()
219 .with_behaviour(|_| dummy::Behaviour)
220 .unwrap()
221 .build();
222
223 let address = listen_addrs.first().unwrap().clone();
224
225 assert!(swarm.dial(address).is_ok());
226 assert!(matches!(
227 swarm.next().await,
228 Some(libp2p::swarm::SwarmEvent::ConnectionEstablished { .. })
229 ));
230
231 running_node.shutdown();
232 }
233}