diff --git a/Cargo.lock b/Cargo.lock index 999850c2d5..e6d3183c8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1091,6 +1091,7 @@ dependencies = [ name = "ant-service-management" version = "0.4.3" dependencies = [ + "ant-bootstrap", "ant-evm", "ant-logging", "ant-protocol", diff --git a/ant-bootstrap/src/cache_store.rs b/ant-bootstrap/src/cache_store.rs index c435fbec23..eabffd6164 100644 --- a/ant-bootstrap/src/cache_store.rs +++ b/ant-bootstrap/src/cache_store.rs @@ -181,15 +181,21 @@ impl BootstrapCacheStore { /// Create a empty CacheStore from the given peers argument. /// This also modifies the cfg if provided based on the PeersArgs. /// And also performs some actions based on the PeersArgs. + /// + /// `PeersArgs::bootstrap_cache_dir` will take precedence over the path provided inside `config`. pub fn new_from_peers_args( peers_arg: &PeersArgs, - cfg: Option, + config: Option, ) -> Result { - let config = if let Some(cfg) = cfg { + let mut config = if let Some(cfg) = config { cfg } else { BootstrapCacheConfig::default_config()? }; + if let Some(bootstrap_cache_path) = peers_arg.get_bootstrap_cache_path()? { + config.cache_file_path = bootstrap_cache_path; + } + let mut store = Self::new(config)?; // If it is the first node, clear the cache. diff --git a/ant-bootstrap/src/config.rs b/ant-bootstrap/src/config.rs index 52d85b7dee..131d857694 100644 --- a/ant-bootstrap/src/config.rs +++ b/ant-bootstrap/src/config.rs @@ -118,8 +118,13 @@ fn default_cache_path() -> Result { std::fs::create_dir_all(&dir)?; - let network_id = format!("{}_{}", get_key_version_str(), get_truncate_version_str()); - let path = dir.join(format!("bootstrap_cache_{}.json", network_id)); + let path = dir.join(cache_file_name()); Ok(path) } + +/// Returns the name of the cache file +pub fn cache_file_name() -> String { + let network_id = format!("{}_{}", get_key_version_str(), get_truncate_version_str()); + format!("bootstrap_cache_{network_id}.json") +} diff --git a/ant-bootstrap/src/contacts.rs b/ant-bootstrap/src/contacts.rs index 83262fbc1a..24d9ac9bcf 100644 --- a/ant-bootstrap/src/contacts.rs +++ b/ant-bootstrap/src/contacts.rs @@ -95,7 +95,6 @@ impl ContactsFetcher { self.endpoints ); let mut bootstrap_addresses = Vec::new(); - let mut last_error = None; let mut fetches = stream::iter(self.endpoints.clone()) .map(|endpoint| async move { @@ -131,37 +130,16 @@ impl ContactsFetcher { } Err(e) => { warn!("Failed to fetch bootstrap addrs from {}: {}", endpoint, e); - last_error = Some(e); } } } - if bootstrap_addresses.is_empty() { - last_error.map_or_else( - || { - warn!("No bootstrap addrs found from any endpoint and no errors reported"); - Err(Error::NoBootstrapAddressesFound( - "No valid peers found from any endpoint".to_string(), - )) - }, - |e| { - warn!( - "No bootstrap addrs found from any endpoint. Last error: {}", - e - ); - Err(Error::NoBootstrapAddressesFound(format!( - "No valid bootstrap addrs found from any endpoint: {e}", - ))) - }, - ) - } else { - info!( - "Successfully discovered {} total addresses. First few: {:?}", - bootstrap_addresses.len(), - bootstrap_addresses.iter().take(3).collect::>() - ); - Ok(bootstrap_addresses) - } + info!( + "Successfully discovered {} total addresses. First few: {:?}", + bootstrap_addresses.len(), + bootstrap_addresses.iter().take(3).collect::>() + ); + Ok(bootstrap_addresses) } /// Fetch the list of multiaddrs from a single endpoint @@ -244,20 +222,13 @@ impl ContactsFetcher { }) .collect::>(); - if bootstrap_addresses.is_empty() { - warn!("No valid peers found in JSON response"); - Err(Error::NoBootstrapAddressesFound( - "No valid peers found in JSON response".to_string(), - )) - } else { - info!( - "Successfully parsed {} valid peers from JSON", - bootstrap_addresses.len() - ); - Ok(bootstrap_addresses) - } + info!( + "Successfully parsed {} valid peers from JSON", + bootstrap_addresses.len() + ); + Ok(bootstrap_addresses) } - Err(e) => { + Err(_err) => { info!("Attempting to parse response as plain text"); // Try parsing as plain text with one multiaddr per line // example of contacts file exists in resources/network-contacts-examples @@ -266,20 +237,11 @@ impl ContactsFetcher { .filter_map(|str| craft_valid_multiaddr_from_str(str, ignore_peer_id)) .collect::>(); - if bootstrap_addresses.is_empty() { - warn!( - "No valid bootstrap addrs found in plain text response. Previous Json error: {e:?}" - ); - Err(Error::NoBootstrapAddressesFound( - "No valid bootstrap addrs found in plain text response".to_string(), - )) - } else { - info!( - "Successfully parsed {} valid bootstrap addrs from plain text", - bootstrap_addresses.len() - ); - Ok(bootstrap_addresses) - } + info!( + "Successfully parsed {} valid bootstrap addrs from plain text", + bootstrap_addresses.len() + ); + Ok(bootstrap_addresses) } } } @@ -387,24 +349,6 @@ mod tests { assert_eq!(addrs[0].addr, valid_addr); } - #[tokio::test] - async fn test_empty_response() { - let mock_server = MockServer::start().await; - - Mock::given(method("GET")) - .and(path("/")) - .respond_with(ResponseTemplate::new(200).set_body_string("")) - .mount(&mock_server) - .await; - - let mut fetcher = ContactsFetcher::new().unwrap(); - fetcher.endpoints = vec![mock_server.uri().parse().unwrap()]; - - let result = fetcher.fetch_bootstrap_addresses().await; - - assert!(matches!(result, Err(Error::NoBootstrapAddressesFound(_)))); - } - #[tokio::test] async fn test_whitespace_and_empty_lines() { let mock_server = MockServer::start().await; diff --git a/ant-bootstrap/src/error.rs b/ant-bootstrap/src/error.rs index 77002702e5..a2eedfeee5 100644 --- a/ant-bootstrap/src/error.rs +++ b/ant-bootstrap/src/error.rs @@ -16,10 +16,12 @@ pub enum Error { FailedToParseCacheData, #[error("Could not obtain data directory")] CouldNotObtainDataDir, + #[error("Invalid bootstrap cache directory")] + InvalidBootstrapCacheDir, #[error("Could not obtain bootstrap addresses from {0} after {1} retries")] FailedToObtainAddrsFromUrl(String, usize), - #[error("No Bootstrap Addresses found: {0}")] - NoBootstrapAddressesFound(String), + #[error("Failed to parse Url")] + FailedToParseUrl, #[error("IO error: {0}")] Io(#[from] std::io::Error), #[error("JSON error: {0}")] diff --git a/ant-bootstrap/src/initial_peers.rs b/ant-bootstrap/src/initial_peers.rs index 07d0cd3b24..afa983b0de 100644 --- a/ant-bootstrap/src/initial_peers.rs +++ b/ant-bootstrap/src/initial_peers.rs @@ -7,19 +7,22 @@ // permissions and limitations relating to use of the SAFE Network Software. use crate::{ + config::cache_file_name, craft_valid_multiaddr, craft_valid_multiaddr_from_str, error::{Error, Result}, BootstrapAddr, BootstrapCacheConfig, BootstrapCacheStore, ContactsFetcher, }; use clap::Args; use libp2p::Multiaddr; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; use url::Url; /// The name of the environment variable that can be used to pass peers to the node. pub const ANT_PEERS_ENV: &str = "ANT_PEERS"; /// Command line arguments for peer configuration -#[derive(Args, Debug, Clone, Default)] +#[derive(Args, Debug, Clone, Default, PartialEq, Serialize, Deserialize)] pub struct PeersArgs { /// Set to indicate this is the first node in a new network /// @@ -41,16 +44,15 @@ pub struct PeersArgs { long = "peer", value_name = "multiaddr", value_delimiter = ',', - conflicts_with = "first", - value_parser = parse_multiaddr_str + conflicts_with = "first" )] pub addrs: Vec, /// Specify the URL to fetch the network contacts from. /// /// The URL can point to a text file containing Multiaddresses separated by newline character, or /// a bootstrap cache JSON file. - #[clap(long, conflicts_with = "first")] - pub network_contacts_url: Option, + #[clap(long, conflicts_with = "first", value_delimiter = ',')] + pub network_contacts_url: Vec, /// Set to indicate this is a local network. You could also set the `local` feature flag to set this to true. /// /// This would use mDNS for peer discovery. @@ -59,38 +61,55 @@ pub struct PeersArgs { /// Set to indicate this is a testnet. /// /// This disables fetching peers from the mainnet network contacts. - #[clap(name = "testnet", long, conflicts_with = "network_contacts_url")] + #[clap(name = "testnet", long)] pub disable_mainnet_contacts: bool, - /// Set to not load the bootstrap addresses from the local cache. #[clap(long, default_value = "false")] pub ignore_cache: bool, + /// The directory to load and store the bootstrap cache. If not provided, the default path will be used. + /// + /// The JSON filename will be derived automatically from the network ID + /// + /// The default location is platform specific: + /// - Linux: $HOME/.local/share/autonomi/bootstrap_cache/bootstrap_cache_.json + /// - macOS: $HOME/Library/Application Support/autonomi/bootstrap_cache/bootstrap_cache_.json + /// - Windows: C:\Users\\AppData\Roaming\autonomi\bootstrap_cache\bootstrap_cache_.json + #[clap(long)] + pub bootstrap_cache_dir: Option, } + impl PeersArgs { - /// Get bootstrap peers + /// Get bootstrap peers sorted by the failure rate. The peer with the lowest failure rate will be + /// the first in the list. /// Order of precedence: /// 1. Addresses from arguments /// 2. Addresses from environment variable SAFE_PEERS - /// 3. Addresses from cache + /// 3. Addresses from cache. `Self::bootstrap_cache_dir` will take precedence over the path provided inside `config` /// 4. Addresses from network contacts URL - pub async fn get_addrs(&self, config: Option) -> Result> { + pub async fn get_addrs( + &self, + config: Option, + count: Option, + ) -> Result> { Ok(self - .get_bootstrap_addr(config) + .get_bootstrap_addr(config, count) .await? .into_iter() .map(|addr| addr.addr) .collect()) } - /// Get bootstrap peers + /// Get bootstrap peers sorted by the failure rate. The peer with the lowest failure rate will be + /// the first in the list. /// Order of precedence: /// 1. Addresses from arguments /// 2. Addresses from environment variable SAFE_PEERS - /// 3. Addresses from cache + /// 3. Addresses from cache. `Self::bootstrap_cache_dir` will take precedence over the path provided inside `config` /// 4. Addresses from network contacts URL pub async fn get_bootstrap_addr( &self, config: Option, + count: Option, ) -> Result> { // If this is the first node, return an empty list if self.first { @@ -115,33 +134,25 @@ impl PeersArgs { warn!("Invalid multiaddress format from arguments: {addr}"); } } - // Read from ANT_PEERS environment variable if present - if let Ok(addrs) = std::env::var(ANT_PEERS_ENV) { - for addr_str in addrs.split(',') { - if let Some(addr) = craft_valid_multiaddr_from_str(addr_str, false) { - info!("Adding addr from environment variable: {addr}"); - bootstrap_addresses.push(BootstrapAddr::new(addr)); - } else { - warn!("Invalid multiaddress format from environment variable: {addr_str}"); - } - } - } + bootstrap_addresses.extend(Self::read_bootstrap_addr_from_env()); // If we have a network contacts URL, fetch addrs from there. - if let Some(url) = self.network_contacts_url.clone() { - info!("Fetching bootstrap address from network contacts URL: {url}",); - let contacts_fetcher = ContactsFetcher::with_endpoints(vec![url])?; + if !self.network_contacts_url.is_empty() { + info!( + "Fetching bootstrap address from network contacts URLs: {:?}", + self.network_contacts_url + ); + let addrs = self + .network_contacts_url + .iter() + .map(|url| url.parse::().map_err(|_| Error::FailedToParseUrl)) + .collect::>>()?; + let contacts_fetcher = ContactsFetcher::with_endpoints(addrs)?; let addrs = contacts_fetcher.fetch_bootstrap_addresses().await?; bootstrap_addresses.extend(addrs); } - // Return here if we fetched peers from the args - if !bootstrap_addresses.is_empty() { - bootstrap_addresses.sort_by_key(|addr| addr.failure_rate() as u64); - return Ok(bootstrap_addresses); - } - // load from cache if present if !self.ignore_cache { let cfg = if let Some(config) = config { @@ -149,7 +160,10 @@ impl PeersArgs { } else { BootstrapCacheConfig::default_config().ok() }; - if let Some(cfg) = cfg { + if let Some(mut cfg) = cfg { + if let Some(file_path) = self.get_bootstrap_cache_path()? { + cfg.cache_file_path = file_path; + } info!("Loading bootstrap addresses from cache"); if let Ok(data) = BootstrapCacheStore::load_cache_data(&cfg) { bootstrap_addresses = data @@ -166,11 +180,6 @@ impl PeersArgs { } } - if !bootstrap_addresses.is_empty() { - bootstrap_addresses.sort_by_key(|addr| addr.failure_rate() as u64); - return Ok(bootstrap_addresses); - } - if !self.disable_mainnet_contacts { let contacts_fetcher = ContactsFetcher::with_mainnet_endpoints()?; let addrs = contacts_fetcher.fetch_bootstrap_addresses().await?; @@ -179,14 +188,54 @@ impl PeersArgs { if !bootstrap_addresses.is_empty() { bootstrap_addresses.sort_by_key(|addr| addr.failure_rate() as u64); + if let Some(count) = count { + bootstrap_addresses.truncate(count); + } Ok(bootstrap_addresses) } else { error!("No initial bootstrap peers found through any means"); Err(Error::NoBootstrapPeersFound) } } -} -pub fn parse_multiaddr_str(addr: &str) -> std::result::Result { - addr.parse::() + pub fn read_addr_from_env() -> Vec { + Self::read_bootstrap_addr_from_env() + .into_iter() + .map(|addr| addr.addr) + .collect() + } + + pub fn read_bootstrap_addr_from_env() -> Vec { + let mut bootstrap_addresses = Vec::new(); + // Read from ANT_PEERS environment variable if present + if let Ok(addrs) = std::env::var(ANT_PEERS_ENV) { + for addr_str in addrs.split(',') { + if let Some(addr) = craft_valid_multiaddr_from_str(addr_str, false) { + info!("Adding addr from environment variable: {addr}"); + bootstrap_addresses.push(BootstrapAddr::new(addr)); + } else { + warn!("Invalid multiaddress format from environment variable: {addr_str}"); + } + } + } + bootstrap_addresses + } + + /// Get the path to the bootstrap cache JSON file if `Self::bootstrap_cache_dir` is set + pub fn get_bootstrap_cache_path(&self) -> Result> { + if let Some(dir) = &self.bootstrap_cache_dir { + if dir.is_file() { + return Err(Error::InvalidBootstrapCacheDir); + } + + if !dir.exists() { + std::fs::create_dir_all(dir)?; + } + + let path = dir.join(cache_file_name()); + Ok(Some(path)) + } else { + Ok(None) + } + } } diff --git a/ant-bootstrap/tests/address_format_tests.rs b/ant-bootstrap/tests/address_format_tests.rs index 55d9246b8b..88369f4cd8 100644 --- a/ant-bootstrap/tests/address_format_tests.rs +++ b/ant-bootstrap/tests/address_format_tests.rs @@ -45,13 +45,14 @@ async fn test_multiaddr_format_parsing() -> Result<(), Box Result<(), Box let args = PeersArgs { first: false, addrs: vec![], - network_contacts_url: Some(format!("{}/peers", mock_server.uri()).parse()?), + network_contacts_url: vec![format!("{}/peers", mock_server.uri()).parse()?], local: false, - disable_mainnet_contacts: false, - ignore_cache: false, + disable_mainnet_contacts: true, + ignore_cache: true, + bootstrap_cache_dir: None, }; - let addrs = args.get_bootstrap_addr(None).await?; + let addrs = args.get_bootstrap_addr(None, None).await?; assert_eq!( addrs.len(), 2, diff --git a/ant-bootstrap/tests/cli_integration_tests.rs b/ant-bootstrap/tests/cli_integration_tests.rs index 1afee9176e..98341ae452 100644 --- a/ant-bootstrap/tests/cli_integration_tests.rs +++ b/ant-bootstrap/tests/cli_integration_tests.rs @@ -31,13 +31,14 @@ async fn test_first_flag() -> Result<(), Box> { let args = PeersArgs { first: true, addrs: vec![], - network_contacts_url: None, + network_contacts_url: vec![], local: false, disable_mainnet_contacts: false, ignore_cache: false, + bootstrap_cache_dir: None, }; - let addrs = args.get_addrs(Some(config)).await?; + let addrs = args.get_addrs(Some(config), None).await?; assert!(addrs.is_empty(), "First node should have no addrs"); @@ -56,13 +57,14 @@ async fn test_peer_argument() -> Result<(), Box> { let args = PeersArgs { first: false, addrs: vec![peer_addr.clone()], - network_contacts_url: None, + network_contacts_url: vec![], local: false, disable_mainnet_contacts: true, ignore_cache: false, + bootstrap_cache_dir: None, }; - let addrs = args.get_addrs(None).await?; + let addrs = args.get_addrs(None, None).await?; assert_eq!(addrs.len(), 1, "Should have one addr"); assert_eq!(addrs[0], peer_addr, "Should have the correct address"); @@ -90,13 +92,14 @@ async fn test_network_contacts_fallback() -> Result<(), Box Result<(), Box> { let args = PeersArgs { first: false, addrs: vec![], - network_contacts_url: None, + network_contacts_url: vec![], local: true, disable_mainnet_contacts: false, ignore_cache: false, + bootstrap_cache_dir: None, }; - let addrs = args.get_addrs(Some(config)).await?; + let addrs = args.get_addrs(Some(config), None).await?; assert!(addrs.is_empty(), "Local mode should have no peers"); @@ -155,13 +159,14 @@ async fn test_test_network_peers() -> Result<(), Box> { let args = PeersArgs { first: false, addrs: vec![peer_addr.clone()], - network_contacts_url: None, + network_contacts_url: vec![], local: false, disable_mainnet_contacts: true, ignore_cache: false, + bootstrap_cache_dir: None, }; - let addrs = args.get_addrs(Some(config)).await?; + let addrs = args.get_addrs(Some(config), None).await?; assert_eq!(addrs.len(), 1, "Should have exactly one test network peer"); assert_eq!( diff --git a/ant-cli/src/access/network.rs b/ant-cli/src/access/network.rs index acf7acfae6..8c428e06d3 100644 --- a/ant-cli/src/access/network.rs +++ b/ant-cli/src/access/network.rs @@ -13,7 +13,7 @@ use color_eyre::Result; use color_eyre::Section; pub async fn get_peers(peers: PeersArgs) -> Result> { - peers.get_addrs(None).await + peers.get_addrs(None, Some(100)).await .wrap_err("Please provide valid Network peers to connect to") .with_suggestion(|| format!("make sure you've provided network peers using the --peers option or the {ANT_PEERS_ENV} env var")) .with_suggestion(|| "a peer address looks like this: /ip4/42.42.42.42/udp/4242/quic-v1/p2p/B64nodePeerIDvdjb3FAJF4ks3moreBase64CharsHere") diff --git a/ant-node-manager/src/add_services/config.rs b/ant-node-manager/src/add_services/config.rs index 046b29d79b..40eea8ff86 100644 --- a/ant-node-manager/src/add_services/config.rs +++ b/ant-node-manager/src/add_services/config.rs @@ -6,10 +6,11 @@ // KIND, either express or implied. Please review the Licences for the specific language governing // permissions and limitations relating to use of the SAFE Network Software. +use ant_bootstrap::PeersArgs; use ant_evm::{EvmNetwork, RewardsAddress}; use ant_logging::LogFormat; +use ant_service_management::node::push_arguments_from_peers_args; use color_eyre::{eyre::eyre, Result}; -use libp2p::Multiaddr; use service_manager::{ServiceInstallCtx, ServiceLabel}; use std::{ ffi::OsString, @@ -71,13 +72,10 @@ impl PortRange { pub struct InstallNodeServiceCtxBuilder { pub antnode_path: PathBuf, pub autostart: bool, - pub bootstrap_peers: Vec, pub data_dir_path: PathBuf, pub env_variables: Option>, pub evm_network: EvmNetwork, - pub genesis: bool, pub home_network: bool, - pub local: bool, pub log_dir_path: PathBuf, pub log_format: Option, pub name: String, @@ -87,6 +85,7 @@ pub struct InstallNodeServiceCtxBuilder { pub node_ip: Option, pub node_port: Option, pub owner: Option, + pub peers_args: PeersArgs, pub rewards_address: RewardsAddress, pub rpc_socket_addr: SocketAddr, pub service_user: Option, @@ -105,15 +104,10 @@ impl InstallNodeServiceCtxBuilder { OsString::from(self.log_dir_path.to_string_lossy().to_string()), ]; - if self.genesis { - args.push(OsString::from("--first")); - } + push_arguments_from_peers_args(&self.peers_args, &mut args); if self.home_network { args.push(OsString::from("--home-network")); } - if self.local { - args.push(OsString::from("--local")); - } if let Some(log_format) = self.log_format { args.push(OsString::from("--log-format")); args.push(OsString::from(log_format.as_str())); @@ -146,17 +140,6 @@ impl InstallNodeServiceCtxBuilder { args.push(OsString::from(log_files.to_string())); } - if !self.bootstrap_peers.is_empty() { - let peers_str = self - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } - args.push(OsString::from("--rewards-address")); args.push(OsString::from(self.rewards_address.to_string())); @@ -192,15 +175,12 @@ pub struct AddNodeServiceOptions { pub antnode_src_path: PathBuf, pub auto_restart: bool, pub auto_set_nat_flags: bool, - pub bootstrap_peers: Vec, pub count: Option, pub delete_antnode_src: bool, pub enable_metrics_server: bool, pub env_variables: Option>, pub evm_network: EvmNetwork, - pub genesis: bool, pub home_network: bool, - pub local: bool, pub log_format: Option, pub max_archived_log_files: Option, pub max_log_files: Option, @@ -208,6 +188,7 @@ pub struct AddNodeServiceOptions { pub node_ip: Option, pub node_port: Option, pub owner: Option, + pub peers_args: PeersArgs, pub rewards_address: RewardsAddress, pub rpc_address: Option, pub rpc_port: Option, @@ -223,7 +204,6 @@ pub struct AddNodeServiceOptions { pub struct InstallAuditorServiceCtxBuilder { pub auditor_path: PathBuf, pub beta_encryption_key: Option, - pub bootstrap_peers: Vec, pub env_variables: Option>, pub log_dir_path: PathBuf, pub name: String, @@ -237,16 +217,6 @@ impl InstallAuditorServiceCtxBuilder { OsString::from(self.log_dir_path.to_string_lossy().to_string()), ]; - if !self.bootstrap_peers.is_empty() { - let peers_str = self - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } if let Some(beta_encryption_key) = self.beta_encryption_key { args.push(OsString::from("--beta-encryption-key")); args.push(OsString::from(beta_encryption_key)); @@ -267,7 +237,6 @@ impl InstallAuditorServiceCtxBuilder { #[derive(Debug, PartialEq)] pub struct InstallFaucetServiceCtxBuilder { - pub bootstrap_peers: Vec, pub env_variables: Option>, pub faucet_path: PathBuf, pub local: bool, @@ -283,17 +252,6 @@ impl InstallFaucetServiceCtxBuilder { OsString::from(self.log_dir_path.to_string_lossy().to_string()), ]; - if !self.bootstrap_peers.is_empty() { - let peers_str = self - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } - args.push(OsString::from("server")); Ok(ServiceInstallCtx { @@ -313,7 +271,6 @@ pub struct AddAuditorServiceOptions { pub auditor_install_bin_path: PathBuf, pub auditor_src_bin_path: PathBuf, pub beta_encryption_key: Option, - pub bootstrap_peers: Vec, pub env_variables: Option>, pub service_log_dir_path: PathBuf, pub user: String, @@ -321,7 +278,6 @@ pub struct AddAuditorServiceOptions { } pub struct AddFaucetServiceOptions { - pub bootstrap_peers: Vec, pub env_variables: Option>, pub faucet_install_bin_path: PathBuf, pub faucet_src_bin_path: PathBuf, @@ -352,13 +308,10 @@ mod tests { InstallNodeServiceCtxBuilder { antnode_path: PathBuf::from("/bin/antnode"), autostart: true, - bootstrap_peers: vec![], data_dir_path: PathBuf::from("/data"), env_variables: None, evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, - local: false, log_dir_path: PathBuf::from("/logs"), log_format: None, name: "test-node".to_string(), @@ -368,6 +321,7 @@ mod tests { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124") .unwrap(), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), @@ -379,7 +333,6 @@ mod tests { fn create_custom_evm_network_builder() -> InstallNodeServiceCtxBuilder { InstallNodeServiceCtxBuilder { autostart: true, - bootstrap_peers: vec![], data_dir_path: PathBuf::from("/data"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -393,9 +346,7 @@ mod tests { ) .unwrap(), }), - genesis: false, home_network: false, - local: false, log_dir_path: PathBuf::from("/logs"), log_format: None, name: "test-node".to_string(), @@ -405,6 +356,7 @@ mod tests { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124") .unwrap(), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), @@ -417,7 +369,6 @@ mod tests { fn create_builder_with_all_options_enabled() -> InstallNodeServiceCtxBuilder { InstallNodeServiceCtxBuilder { autostart: true, - bootstrap_peers: vec![], data_dir_path: PathBuf::from("/data"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -431,9 +382,7 @@ mod tests { ) .unwrap(), }), - genesis: false, home_network: false, - local: false, log_dir_path: PathBuf::from("/logs"), log_format: None, name: "test-node".to_string(), @@ -443,6 +392,7 @@ mod tests { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124") .unwrap(), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080), @@ -525,19 +475,22 @@ mod tests { #[test] fn build_should_assign_expected_values_when_all_options_are_enabled() { let mut builder = create_builder_with_all_options_enabled(); - builder.genesis = true; builder.home_network = true; - builder.local = true; builder.log_format = Some(LogFormat::Json); builder.upnp = true; builder.node_ip = Some(Ipv4Addr::new(192, 168, 1, 1)); builder.node_port = Some(12345); builder.metrics_port = Some(9090); builder.owner = Some("test-owner".to_string()); - builder.bootstrap_peers = vec![ + builder.peers_args.addrs = vec![ "/ip4/127.0.0.1/tcp/8080".parse().unwrap(), "/ip4/192.168.1.1/tcp/8081".parse().unwrap(), ]; + builder.peers_args.first = true; + builder.peers_args.local = true; + builder.peers_args.network_contacts_url = vec!["http://localhost:8080".parse().unwrap()]; + builder.peers_args.ignore_cache = true; + builder.peers_args.disable_mainnet_contacts = true; builder.service_user = Some("antnode-user".to_string()); let result = builder.build().unwrap(); @@ -550,8 +503,14 @@ mod tests { "--log-output-dest", "/logs", "--first", - "--home-network", "--local", + "--peer", + "/ip4/127.0.0.1/tcp/8080,/ip4/192.168.1.1/tcp/8081", + "--network-contacts-url", + "http://localhost:8080", + "--testnet", + "--ignore-cache", + "--home-network", "--log-format", "json", "--upnp", @@ -567,8 +526,6 @@ mod tests { "10", "--max-log-files", "10", - "--peer", - "/ip4/127.0.0.1/tcp/8080,/ip4/192.168.1.1/tcp/8081", "--rewards-address", "0x03B770D9cD32077cC0bF330c13C114a87643B124", "evm-custom", diff --git a/ant-node-manager/src/add_services/mod.rs b/ant-node-manager/src/add_services/mod.rs index f3b77d4649..a871f73179 100644 --- a/ant-node-manager/src/add_services/mod.rs +++ b/ant-node-manager/src/add_services/mod.rs @@ -48,7 +48,7 @@ pub async fn add_node( service_control: &dyn ServiceControl, verbosity: VerbosityLevel, ) -> Result> { - if options.genesis { + if options.peers_args.first { if let Some(count) = options.count { if count > 1 { error!("A genesis node can only be added as a single node"); @@ -56,7 +56,7 @@ pub async fn add_node( } } - let genesis_node = node_registry.nodes.iter().find(|n| n.genesis); + let genesis_node = node_registry.nodes.iter().find(|n| n.peers_args.first); if genesis_node.is_some() { error!("A genesis node already exists"); return Err(eyre!("A genesis node already exists")); @@ -98,30 +98,11 @@ pub async fn add_node( .to_string_lossy() .to_string(); - { - let mut should_save = false; - let new_bootstrap_peers: Vec<_> = options - .bootstrap_peers - .iter() - .filter(|peer| !node_registry.bootstrap_peers.contains(peer)) - .collect(); - if !new_bootstrap_peers.is_empty() { - node_registry - .bootstrap_peers - .extend(new_bootstrap_peers.into_iter().cloned()); - should_save = true; - } - - if options.env_variables.is_some() { - node_registry - .environment_variables - .clone_from(&options.env_variables); - should_save = true; - } - - if should_save { - node_registry.save()?; - } + if options.env_variables.is_some() { + node_registry + .environment_variables + .clone_from(&options.env_variables); + node_registry.save()?; } let mut added_service_data = vec![]; @@ -219,13 +200,10 @@ pub async fn add_node( let install_ctx = InstallNodeServiceCtxBuilder { autostart: options.auto_restart, - bootstrap_peers: options.bootstrap_peers.clone(), data_dir_path: service_data_dir_path.clone(), env_variables: options.env_variables.clone(), evm_network: options.evm_network.clone(), - genesis: options.genesis, home_network: options.home_network, - local: options.local, log_dir_path: service_log_dir_path.clone(), log_format: options.log_format, max_archived_log_files: options.max_archived_log_files, @@ -235,6 +213,7 @@ pub async fn add_node( node_ip: options.node_ip, node_port, owner: owner.clone(), + peers_args: options.peers_args.clone(), rewards_address: options.rewards_address, rpc_socket_addr, antnode_path: service_antnode_path.clone(), @@ -260,10 +239,8 @@ pub async fn add_node( connected_peers: None, data_dir_path: service_data_dir_path.clone(), evm_network: options.evm_network.clone(), - genesis: options.genesis, home_network: options.home_network, listen_addr: None, - local: options.local, log_dir_path: service_log_dir_path.clone(), log_format: options.log_format, max_archived_log_files: options.max_archived_log_files, @@ -277,6 +254,7 @@ pub async fn add_node( rpc_socket_addr, owner: owner.clone(), peer_id: None, + peers_args: options.peers_args.clone(), pid: None, service_name, status: ServiceStatus::Added, @@ -381,7 +359,6 @@ pub fn add_auditor( let install_ctx = InstallAuditorServiceCtxBuilder { auditor_path: install_options.auditor_install_bin_path.clone(), beta_encryption_key: install_options.beta_encryption_key.clone(), - bootstrap_peers: install_options.bootstrap_peers.clone(), env_variables: install_options.env_variables.clone(), log_dir_path: install_options.service_log_dir_path.clone(), name: "auditor".to_string(), @@ -525,7 +502,6 @@ pub fn add_faucet( )?; let install_ctx = InstallFaucetServiceCtxBuilder { - bootstrap_peers: install_options.bootstrap_peers.clone(), env_variables: install_options.env_variables.clone(), faucet_path: install_options.faucet_install_bin_path.clone(), local: install_options.local, diff --git a/ant-node-manager/src/add_services/tests.rs b/ant-node-manager/src/add_services/tests.rs index 8a413a331e..ee19f167b0 100644 --- a/ant-node-manager/src/add_services/tests.rs +++ b/ant-node-manager/src/add_services/tests.rs @@ -16,6 +16,7 @@ use crate::{ }, VerbosityLevel, }; +use ant_bootstrap::PeersArgs; use ant_evm::{AttoTokens, CustomNetwork, EvmNetwork, RewardsAddress}; use ant_service_management::{auditor::AuditorServiceData, control::ServiceControl}; use ant_service_management::{error::Result as ServiceControlResult, NatDetectionStatus}; @@ -25,7 +26,6 @@ use ant_service_management::{ use assert_fs::prelude::*; use assert_matches::assert_matches; use color_eyre::Result; -use libp2p::Multiaddr; use mockall::{mock, predicate::*, Sequence}; use predicates::prelude::*; use service_manager::ServiceInstallCtx; @@ -97,7 +97,6 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -110,9 +109,18 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res .returning(|| Ok(8081)) .in_sequence(&mut seq); + let peers_args = PeersArgs { + first: true, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -124,9 +132,7 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: true, home_network: false, - local: true, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -136,6 +142,7 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res node_ip: None, node_port: None, owner: None, + peers_args: peers_args.clone(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir @@ -157,21 +164,19 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: true, home_network: false, - local: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args, rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -207,7 +212,7 @@ async fn add_genesis_node_should_use_latest_version_and_add_one_service() -> Res node_reg_path.assert(predicates::path::is_file()); assert_eq!(node_registry.nodes.len(), 1); - assert!(node_registry.nodes[0].genesis); + assert!(node_registry.nodes[0].peers_args.first); assert_eq!(node_registry.nodes[0].version, latest_version); assert_eq!(node_registry.nodes[0].service_name, "antnode1"); assert_eq!(node_registry.nodes[0].user, Some(get_username())); @@ -254,6 +259,16 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n let mock_service_control = MockServiceControl::new(); let latest_version = "0.96.4"; + + let peers_args = PeersArgs { + first: true, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; let mut node_registry = NodeRegistry { auditor: None, faucet: None, @@ -272,10 +287,8 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: true, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -284,9 +297,10 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n node_ip: None, node_port: None, number: 1, - pid: None, - peer_id: None, owner: None, + peer_id: None, + peers_args: peers_args.clone(), + pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", )?, @@ -300,7 +314,6 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n user_mode: false, version: latest_version.to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -319,21 +332,19 @@ async fn add_genesis_node_should_return_an_error_if_there_is_already_a_genesis_n AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: true, home_network: false, - local: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args, rpc_address: Some(custom_rpc_address), rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -384,10 +395,18 @@ async fn add_genesis_node_should_return_an_error_if_count_is_greater_than_1() -> save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; + let peers_args = PeersArgs { + first: true, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; let latest_version = "0.96.4"; let temp_dir = assert_fs::TempDir::new()?; @@ -402,21 +421,19 @@ async fn add_genesis_node_should_return_an_error_if_count_is_greater_than_1() -> AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: true, home_network: false, - local: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args, rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -467,7 +484,6 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -492,7 +508,6 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -504,9 +519,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -516,6 +529,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir .to_path_buf() @@ -542,7 +556,6 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( .in_sequence(&mut seq); let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode2"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -554,9 +567,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode2"), log_format: None, max_archived_log_files: None, @@ -566,6 +577,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8083), antnode_path: node_data_dir @@ -593,7 +605,6 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, data_dir_path: node_data_dir.to_path_buf().join("antnode3"), - bootstrap_peers: vec![], env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { rpc_url_http: "http://localhost:8545".parse()?, @@ -604,9 +615,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_format: None, log_dir_path: node_logs_dir.to_path_buf().join("antnode3"), max_archived_log_files: None, @@ -616,6 +625,7 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8085), antnode_path: node_data_dir @@ -638,21 +648,19 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -739,14 +747,16 @@ async fn add_node_should_use_latest_version_and_add_three_services() -> Result<( } #[tokio::test] -async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Result<()> { +async fn add_node_should_update_the_environment_variables_inside_node_registry() -> Result<()> { let tmp_data_dir = assert_fs::TempDir::new()?; let node_reg_path = tmp_data_dir.child("node_reg.json"); let mut mock_service_control = MockServiceControl::new(); - let mut old_peers = vec![Multiaddr::from_str("/ip4/64.227.35.186/udp/33188/quic-v1/p2p/12D3KooWDrx4zfUuJgz7jSusC28AZRDRbj7eo3WKZigPsw9tVKs3")?]; - let new_peers = vec![Multiaddr::from_str("/ip4/178.62.78.116/udp/45442/quic-v1/p2p/12D3KooWLH4E68xFqoSKuF2JPQQhzaAg7GNvN1vpxoLMgJq6Zqz8")?]; + let env_variables = Some(vec![ + ("ANT_LOG".to_owned(), "all".to_owned()), + ("RUST_LOG".to_owned(), "libp2p=debug".to_owned()), + ]); let mut node_registry = NodeRegistry { auditor: None, @@ -754,7 +764,6 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: old_peers.clone(), environment_variables: None, daemon: None, }; @@ -774,12 +783,10 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re .times(1) .returning(|| Ok(12001)) .in_sequence(&mut seq); - let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: new_peers.clone(), data_dir_path: node_data_dir.to_path_buf().join("antnode1"), - env_variables: None, + env_variables: env_variables.clone(), evm_network: EvmNetwork::Custom(CustomNetwork { rpc_url_http: "http://localhost:8545".parse()?, payment_token_address: RewardsAddress::from_str( @@ -789,9 +796,7 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -801,6 +806,7 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), antnode_path: node_data_dir @@ -811,7 +817,6 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re upnp: false, } .build()?; - mock_service_control .expect_install() .times(1) @@ -823,25 +828,23 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: new_peers.clone(), count: None, delete_antnode_src: true, enable_metrics_server: false, - env_variables: None, - local: false, - genesis: false, + env_variables: env_variables.clone(), home_network: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, - antnode_src_path: antnode_download_path.to_path_buf(), antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), service_data_dir_path: node_data_dir.to_path_buf(), service_log_dir_path: node_logs_dir.to_path_buf(), upnp: false, @@ -871,8 +874,7 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re node_data_dir.assert(predicate::path::is_dir()); node_logs_dir.assert(predicate::path::is_dir()); - old_peers.extend(new_peers); - assert_eq!(node_registry.bootstrap_peers, old_peers); + assert_eq!(node_registry.environment_variables, env_variables); assert_eq!(node_registry.nodes.len(), 1); assert_eq!(node_registry.nodes[0].version, latest_version); @@ -897,30 +899,63 @@ async fn add_node_should_update_the_bootstrap_peers_inside_node_registry() -> Re } #[tokio::test] -async fn add_node_should_update_the_environment_variables_inside_node_registry() -> Result<()> { +async fn add_new_node_should_add_another_service() -> Result<()> { let tmp_data_dir = assert_fs::TempDir::new()?; let node_reg_path = tmp_data_dir.child("node_reg.json"); let mut mock_service_control = MockServiceControl::new(); - let env_variables = Some(vec![ - ("ANT_LOG".to_owned(), "all".to_owned()), - ("RUST_LOG".to_owned(), "libp2p=debug".to_owned()), - ]); - + let latest_version = "0.96.4"; let mut node_registry = NodeRegistry { auditor: None, faucet: None, save_path: node_reg_path.to_path_buf(), nat_status: None, - nodes: vec![], - bootstrap_peers: vec![], + nodes: vec![NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: None, + peers_args: PeersArgs::default(), + pid: None, + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: PathBuf::from("/var/antctl/services/antnode1/antnode"), + service_name: "antnode1".to_string(), + status: ServiceStatus::Added, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: latest_version.to_string(), + }], environment_variables: None, daemon: None, }; - let latest_version = "0.96.4"; let temp_dir = assert_fs::TempDir::new()?; - let node_data_dir = temp_dir.child("data"); + let node_data_dir = temp_dir.child("antnode1"); node_data_dir.create_dir_all()?; let node_logs_dir = temp_dir.child("logs"); node_logs_dir.create_dir_all()?; @@ -928,17 +963,15 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() antnode_download_path.write_binary(b"fake antnode bin")?; let mut seq = Sequence::new(); - mock_service_control .expect_get_available_port() .times(1) - .returning(|| Ok(12001)) + .returning(|| Ok(8083)) .in_sequence(&mut seq); let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], - data_dir_path: node_data_dir.to_path_buf().join("antnode1"), - env_variables: env_variables.clone(), + data_dir_path: node_data_dir.to_path_buf().join("antnode2"), + env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { rpc_url_http: "http://localhost:8545".parse()?, payment_token_address: RewardsAddress::from_str( @@ -948,28 +981,28 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, - log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), + log_dir_path: node_logs_dir.to_path_buf().join("antnode2"), log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - name: "antnode1".to_string(), + name: "antnode2".to_string(), node_ip: None, node_port: None, - owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, - rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8083), + owner: None, antnode_path: node_data_dir .to_path_buf() - .join("antnode1") + .join("antnode2") .join(ANTNODE_FILE_NAME), service_user: Some(get_username()), upnp: false, } .build()?; + mock_service_control .expect_install() .times(1) @@ -981,25 +1014,23 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, - env_variables: env_variables.clone(), - genesis: false, + env_variables: None, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, - antnode_dir_path: temp_dir.to_path_buf(), antnode_src_path: antnode_download_path.to_path_buf(), + antnode_dir_path: temp_dir.to_path_buf(), service_data_dir_path: node_data_dir.to_path_buf(), service_log_dir_path: node_logs_dir.to_path_buf(), upnp: false, @@ -1025,147 +1056,1039 @@ async fn add_node_should_update_the_environment_variables_inside_node_registry() ) .await?; - antnode_download_path.assert(predicate::path::missing()); - node_data_dir.assert(predicate::path::is_dir()); - node_logs_dir.assert(predicate::path::is_dir()); - - assert_eq!(node_registry.environment_variables, env_variables); - - assert_eq!(node_registry.nodes.len(), 1); - assert_eq!(node_registry.nodes[0].version, latest_version); - assert_eq!(node_registry.nodes[0].service_name, "antnode1"); - assert_eq!(node_registry.nodes[0].user, Some(get_username())); - assert_eq!(node_registry.nodes[0].number, 1); + assert_eq!(node_registry.nodes.len(), 2); + assert_eq!(node_registry.nodes[1].version, latest_version); + assert_eq!(node_registry.nodes[1].service_name, "antnode2"); + assert_eq!(node_registry.nodes[1].user, Some(get_username())); + assert_eq!(node_registry.nodes[1].number, 2); assert_eq!( - node_registry.nodes[0].rpc_socket_addr, - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001) + node_registry.nodes[1].rpc_socket_addr, + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8083) ); assert_eq!( - node_registry.nodes[0].log_dir_path, - node_logs_dir.to_path_buf().join("antnode1") + node_registry.nodes[1].log_dir_path, + node_logs_dir.to_path_buf().join("antnode2") ); assert_eq!( - node_registry.nodes[0].data_dir_path, - node_data_dir.to_path_buf().join("antnode1") + node_registry.nodes[1].data_dir_path, + node_data_dir.to_path_buf().join("antnode2") ); assert_matches!(node_registry.nodes[0].status, ServiceStatus::Added); + assert!(!node_registry.nodes[0].auto_restart); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_first_arg() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: true, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--first"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert!(node_registry.nodes[0].peers_args.first); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_peers_args() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: false, + addrs: vec![ + "/ip4/127.0.0.1/tcp/8080/p2p/12D3KooWRBhwfeP2Y4TCx1SM6s9rUoHhR5STiGwxBhgFRcw3UERE" + .parse()?, + ], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--peer"), + OsString::from( + "/ip4/127.0.0.1/tcp/8080/p2p/12D3KooWRBhwfeP2Y4TCx1SM6s9rUoHhR5STiGwxBhgFRcw3UERE"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert_eq!(node_registry.nodes[0].peers_args.addrs.len(), 1); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_local_arg() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: true, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--local"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert!(node_registry.nodes[0].peers_args.local); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_network_contacts_url_arg() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![ + "http://localhost:8080/contacts".to_string(), + "http://localhost:8081/contacts".to_string(), + ], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--network-contacts-url"), + OsString::from("http://localhost:8080/contacts,http://localhost:8081/contacts"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert_eq!( + node_registry.nodes[0].peers_args.network_contacts_url.len(), + 2 + ); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_testnet_arg() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: true, + ignore_cache: false, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--testnet"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert!(node_registry.nodes[0].peers_args.disable_mainnet_contacts); + + Ok(()) +} + +#[tokio::test] +async fn add_node_should_create_service_file_with_ignore_cache_arg() -> Result<()> { + let tmp_data_dir = assert_fs::TempDir::new()?; + let node_reg_path = tmp_data_dir.child("node_reg.json"); + + let mut mock_service_control = MockServiceControl::new(); + + let mut node_registry = NodeRegistry { + auditor: None, + faucet: None, + save_path: node_reg_path.to_path_buf(), + nat_status: None, + nodes: vec![], + environment_variables: None, + daemon: None, + }; + let latest_version = "0.96.4"; + let temp_dir = assert_fs::TempDir::new()?; + let node_data_dir = temp_dir.child("data"); + node_data_dir.create_dir_all()?; + let node_logs_dir = temp_dir.child("logs"); + node_logs_dir.create_dir_all()?; + let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); + antnode_download_path.write_binary(b"fake antnode bin")?; + + let peers_args = PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: true, + bootstrap_cache_dir: None, + }; + + let mut seq = Sequence::new(); + + mock_service_control + .expect_get_available_port() + .times(1) + .returning(|| Ok(12001)) + .in_sequence(&mut seq); + + mock_service_control + .expect_install() + .times(1) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--ignore-cache"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) + .returning(|_, _| Ok(())) + .in_sequence(&mut seq); + + add_node( + AddNodeServiceOptions { + auto_restart: false, + auto_set_nat_flags: false, + count: None, + delete_antnode_src: true, + enable_metrics_server: false, + env_variables: None, + home_network: false, + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + owner: None, + peers_args: peers_args.clone(), + rpc_address: None, + rpc_port: None, + antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), + service_data_dir_path: node_data_dir.to_path_buf(), + service_log_dir_path: node_logs_dir.to_path_buf(), + upnp: false, + user: Some(get_username()), + user_mode: false, + version: latest_version.to_string(), + evm_network: EvmNetwork::Custom(CustomNetwork { + rpc_url_http: "http://localhost:8545".parse()?, + payment_token_address: RewardsAddress::from_str( + "0x5FbDB2315678afecb367f032d93F642f64180aa3", + )?, + data_payments_address: RewardsAddress::from_str( + "0x8464135c8F25Da09e49BC8782676a84730C318bC", + )?, + }), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + }, + &mut node_registry, + &mock_service_control, + VerbosityLevel::Normal, + ) + .await?; + + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); + assert!(node_registry.nodes[0].peers_args.ignore_cache); Ok(()) } #[tokio::test] -async fn add_new_node_should_add_another_service() -> Result<()> { +async fn add_node_should_create_service_file_with_custom_bootstrap_cache_path() -> Result<()> { let tmp_data_dir = assert_fs::TempDir::new()?; let node_reg_path = tmp_data_dir.child("node_reg.json"); let mut mock_service_control = MockServiceControl::new(); - let latest_version = "0.96.4"; let mut node_registry = NodeRegistry { auditor: None, faucet: None, save_path: node_reg_path.to_path_buf(), nat_status: None, - nodes: vec![NodeServiceData { - auto_restart: false, - connected_peers: None, - data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), - evm_network: EvmNetwork::Custom(CustomNetwork { - rpc_url_http: "http://localhost:8545".parse()?, - payment_token_address: RewardsAddress::from_str( - "0x5FbDB2315678afecb367f032d93F642f64180aa3", - )?, - data_payments_address: RewardsAddress::from_str( - "0x8464135c8F25Da09e49BC8782676a84730C318bC", - )?, - }), - genesis: true, - home_network: false, - listen_addr: None, - local: false, - log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), - log_format: None, - max_archived_log_files: None, - max_log_files: None, - metrics_port: None, - node_ip: None, - node_port: None, - number: 1, - owner: None, - peer_id: None, - pid: None, - rewards_address: RewardsAddress::from_str( - "0x03B770D9cD32077cC0bF330c13C114a87643B124", - )?, - reward_balance: Some(AttoTokens::zero()), - rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), - antnode_path: PathBuf::from("/var/antctl/services/antnode1/antnode"), - service_name: "antnode1".to_string(), - status: ServiceStatus::Added, - upnp: false, - user: Some("ant".to_string()), - user_mode: false, - version: latest_version.to_string(), - }], - bootstrap_peers: vec![], + nodes: vec![], environment_variables: None, daemon: None, }; + let latest_version = "0.96.4"; let temp_dir = assert_fs::TempDir::new()?; - let node_data_dir = temp_dir.child("antnode1"); + let node_data_dir = temp_dir.child("data"); node_data_dir.create_dir_all()?; let node_logs_dir = temp_dir.child("logs"); node_logs_dir.create_dir_all()?; let antnode_download_path = temp_dir.child(ANTNODE_FILE_NAME); antnode_download_path.write_binary(b"fake antnode bin")?; + let peers_args = PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: Some(PathBuf::from("/path/to/bootstrap/cache")), + }; + let mut seq = Sequence::new(); + mock_service_control .expect_get_available_port() .times(1) - .returning(|| Ok(8083)) + .returning(|| Ok(12001)) .in_sequence(&mut seq); - let install_ctx = InstallNodeServiceCtxBuilder { - autostart: false, - bootstrap_peers: vec![], - data_dir_path: node_data_dir.to_path_buf().join("antnode2"), - env_variables: None, - evm_network: EvmNetwork::Custom(CustomNetwork { - rpc_url_http: "http://localhost:8545".parse()?, - payment_token_address: RewardsAddress::from_str( - "0x5FbDB2315678afecb367f032d93F642f64180aa3", - )?, - data_payments_address: RewardsAddress::from_str( - "0x8464135c8F25Da09e49BC8782676a84730C318bC", - )?, - }), - genesis: false, - home_network: false, - local: false, - log_dir_path: node_logs_dir.to_path_buf().join("antnode2"), - log_format: None, - max_archived_log_files: None, - max_log_files: None, - metrics_port: None, - name: "antnode2".to_string(), - node_ip: None, - node_port: None, - rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, - rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8083), - owner: None, - antnode_path: node_data_dir - .to_path_buf() - .join("antnode2") - .join(ANTNODE_FILE_NAME), - service_user: Some(get_username()), - upnp: false, - } - .build()?; mock_service_control .expect_install() .times(1) - .with(eq(install_ctx), eq(false)) + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:12001"), + OsString::from("--root-dir"), + OsString::from( + node_data_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--log-output-dest"), + OsString::from( + node_logs_dir + .to_path_buf() + .join("antnode1") + .to_string_lossy() + .to_string(), + ), + OsString::from("--bootstrap-cache-dir"), + OsString::from("/path/to/bootstrap/cache"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-custom"), + OsString::from("--rpc-url"), + OsString::from("http://localhost:8545/"), + OsString::from("--payment-token-address"), + OsString::from("0x5FbDB2315678afecb367f032d93F642f64180aa3"), + OsString::from("--data-payments-address"), + OsString::from("0x8464135c8F25Da09e49BC8782676a84730C318bC"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: node_data_dir + .to_path_buf() + .join("antnode1") + .join(ANTNODE_FILE_NAME), + username: Some(get_username()), + working_directory: None, + }), + eq(false), + ) .returning(|_, _| Ok(())) .in_sequence(&mut seq); @@ -1173,25 +2096,23 @@ async fn add_new_node_should_add_another_service() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: peers_args.clone(), rpc_address: None, rpc_port: None, - antnode_src_path: antnode_download_path.to_path_buf(), antnode_dir_path: temp_dir.to_path_buf(), + antnode_src_path: antnode_download_path.to_path_buf(), service_data_dir_path: node_data_dir.to_path_buf(), service_log_dir_path: node_logs_dir.to_path_buf(), upnp: false, @@ -1217,25 +2138,16 @@ async fn add_new_node_should_add_another_service() -> Result<()> { ) .await?; - assert_eq!(node_registry.nodes.len(), 2); - assert_eq!(node_registry.nodes[1].version, latest_version); - assert_eq!(node_registry.nodes[1].service_name, "antnode2"); - assert_eq!(node_registry.nodes[1].user, Some(get_username())); - assert_eq!(node_registry.nodes[1].number, 2); - assert_eq!( - node_registry.nodes[1].rpc_socket_addr, - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8083) - ); - assert_eq!( - node_registry.nodes[1].log_dir_path, - node_logs_dir.to_path_buf().join("antnode2") - ); + antnode_download_path.assert(predicate::path::missing()); + node_data_dir.assert(predicate::path::is_dir()); + node_logs_dir.assert(predicate::path::is_dir()); + assert_eq!(node_registry.nodes.len(), 1); + assert_eq!(node_registry.nodes[0].version, latest_version); + assert_eq!(node_registry.nodes[0].peers_args, peers_args); assert_eq!( - node_registry.nodes[1].data_dir_path, - node_data_dir.to_path_buf().join("antnode2") + node_registry.nodes[0].peers_args.bootstrap_cache_dir, + Some(PathBuf::from("/path/to/bootstrap/cache")) ); - assert_matches!(node_registry.nodes[0].status, ServiceStatus::Added); - assert!(!node_registry.nodes[0].auto_restart); Ok(()) } @@ -1253,7 +2165,6 @@ async fn add_node_should_use_custom_ip() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -1332,21 +2243,19 @@ async fn add_node_should_use_custom_ip() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: Some(custom_ip), node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -1399,7 +2308,6 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -1423,7 +2331,6 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { .in_sequence(&mut seq); let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -1435,9 +2342,7 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -1447,6 +2352,7 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { node_ip: None, node_port: Some(custom_port), owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), antnode_path: node_data_dir @@ -1469,21 +2375,19 @@ async fn add_node_should_use_custom_ports_for_one_service() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Single(custom_port)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -1536,7 +2440,6 @@ async fn add_node_should_use_a_custom_port_range() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -1729,21 +2632,19 @@ async fn add_node_should_use_a_custom_port_range() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Range(12000, 12002)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -1807,10 +2708,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_format: None, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), max_archived_log_files: None, @@ -1821,6 +2720,7 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1835,7 +2735,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -1852,21 +2751,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_is_used() -> R AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Single(12000)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -1928,10 +2825,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_format: None, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), max_archived_log_files: None, @@ -1939,8 +2834,9 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us metrics_port: None, node_ip: None, node_port: Some(12000), - number: 1, owner: None, + peers_args: PeersArgs::default(), + number: 1, peer_id: None, pid: None, rewards_address: RewardsAddress::from_str( @@ -1956,7 +2852,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -1973,21 +2868,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_port_in_range_is_us AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Range(12000, 12002)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2037,7 +2930,6 @@ async fn add_node_should_return_an_error_if_port_and_node_count_do_not_match() - save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2054,21 +2946,19 @@ async fn add_node_should_return_an_error_if_port_and_node_count_do_not_match() - AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(2), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Range(12000, 12002)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_src_path: antnode_download_path.to_path_buf(), @@ -2123,7 +3013,6 @@ async fn add_node_should_return_an_error_if_multiple_services_are_specified_with save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2140,21 +3029,19 @@ async fn add_node_should_return_an_error_if_multiple_services_are_specified_with AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(2), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: Some(PortRange::Single(12000)), + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2210,7 +3097,6 @@ async fn add_node_should_set_random_ports_if_enable_metrics_server_is_true() -> save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2288,21 +3174,19 @@ async fn add_node_should_set_random_ports_if_enable_metrics_server_is_true() -> AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: true, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2349,7 +3233,6 @@ async fn add_node_should_set_max_archived_log_files() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2428,21 +3311,19 @@ async fn add_node_should_set_max_archived_log_files() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: Some(20), max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2490,7 +3371,6 @@ async fn add_node_should_set_max_log_files() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2569,21 +3449,19 @@ async fn add_node_should_set_max_log_files() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: Some(20), metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2631,7 +3509,6 @@ async fn add_node_should_use_a_custom_port_range_for_metrics_server() -> Result< save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2824,21 +3701,19 @@ async fn add_node_should_use_a_custom_port_range_for_metrics_server() -> Result< AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: Some(PortRange::Range(12000, 12002)), - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -2899,10 +3774,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2913,6 +3786,7 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2927,7 +3801,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -2944,21 +3817,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_is_use AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: Some(PortRange::Single(12000)), - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -3021,10 +3892,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3035,6 +3904,7 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3049,7 +3919,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3066,21 +3935,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_metrics_port_in_ran AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: Some(PortRange::Range(12000, 12002)), - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -3132,7 +3999,6 @@ async fn add_node_should_use_a_custom_port_range_for_the_rpc_server() -> Result< save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3304,21 +4170,19 @@ async fn add_node_should_use_a_custom_port_range_for_the_rpc_server() -> Result< AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(3), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: Some(PortRange::Range(20000, 20002)), antnode_dir_path: temp_dir.to_path_buf(), @@ -3390,10 +4254,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3404,6 +4266,7 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3418,7 +4281,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3435,21 +4297,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_is_used() AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: Some(PortRange::Single(8081)), antnode_dir_path: temp_dir.to_path_buf(), @@ -3512,10 +4372,8 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3526,6 +4384,7 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3540,7 +4399,6 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i user_mode: false, version: "0.98.1".to_string(), }], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3557,21 +4415,19 @@ async fn add_node_should_return_an_error_if_duplicate_custom_rpc_port_in_range_i AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(2), delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: Some(PortRange::Range(8081, 8082)), antnode_dir_path: temp_dir.to_path_buf(), @@ -3623,7 +4479,6 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() save_path: node_reg_path.to_path_buf(), nat_status: Some(NatDetectionStatus::Public), nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3646,7 +4501,6 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -3658,9 +4512,7 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -3670,6 +4522,7 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), antnode_path: node_data_dir @@ -3691,21 +4544,19 @@ async fn add_node_should_disable_upnp_and_home_network_if_nat_status_is_public() AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: true, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - local: false, - genesis: false, home_network: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -3754,7 +4605,6 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: Some(NatDetectionStatus::UPnP), nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3777,7 +4627,6 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -3789,9 +4638,7 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -3801,6 +4648,7 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), antnode_path: node_data_dir @@ -3822,21 +4670,19 @@ async fn add_node_should_enable_upnp_if_nat_status_is_upnp() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: true, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - local: false, - genesis: false, home_network: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -3885,7 +4731,6 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul save_path: node_reg_path.to_path_buf(), nat_status: Some(NatDetectionStatus::Private), nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -3908,7 +4753,6 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -3920,9 +4764,7 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: true, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -3932,6 +4774,7 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 12001), antnode_path: node_data_dir @@ -3953,21 +4796,19 @@ async fn add_node_should_enable_home_network_if_nat_status_is_private() -> Resul AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: true, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - local: false, - genesis: false, home_network: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -4017,7 +4858,6 @@ async fn add_node_should_return_an_error_if_nat_status_is_none_but_auto_set_nat_ save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -4042,21 +4882,19 @@ async fn add_node_should_return_an_error_if_nat_status_is_none_but_auto_set_nat_ AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: true, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - local: false, - genesis: false, home_network: true, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -4115,7 +4953,6 @@ async fn add_auditor_should_add_an_auditor_service() -> Result<()> { auditor_download_path.write_binary(b"fake auditor bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: None, faucet: None, @@ -4150,7 +4987,6 @@ async fn add_auditor_should_add_an_auditor_service() -> Result<()> { add_auditor( AddAuditorServiceOptions { - bootstrap_peers: vec![], beta_encryption_key: None, env_variables: Some(vec![("ANT_LOG".to_string(), "all".to_string())]), auditor_src_bin_path: auditor_download_path.to_path_buf(), @@ -4202,7 +5038,6 @@ async fn add_auditor_should_return_an_error_if_a_auditor_service_was_already_cre auditor_download_path.write_binary(b"fake auditor bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: Some(AuditorServiceData { auditor_path: auditor_download_path.to_path_buf(), @@ -4222,7 +5057,6 @@ async fn add_auditor_should_return_an_error_if_a_auditor_service_was_already_cre let result = add_auditor( AddAuditorServiceOptions { - bootstrap_peers: vec![], beta_encryption_key: None, env_variables: Some(vec![("ANT_LOG".to_string(), "all".to_string())]), auditor_src_bin_path: auditor_download_path.to_path_buf(), @@ -4265,7 +5099,6 @@ async fn add_auditor_should_include_beta_encryption_key_if_specified() -> Result auditor_download_path.write_binary(b"fake auditor bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: None, faucet: None, @@ -4302,7 +5135,6 @@ async fn add_auditor_should_include_beta_encryption_key_if_specified() -> Result add_auditor( AddAuditorServiceOptions { - bootstrap_peers: vec![], beta_encryption_key: Some("test".to_string()), env_variables: Some(vec![("ANT_LOG".to_string(), "all".to_string())]), auditor_src_bin_path: auditor_download_path.to_path_buf(), @@ -4355,7 +5187,6 @@ async fn add_faucet_should_add_a_faucet_service() -> Result<()> { faucet_download_path.write_binary(b"fake faucet bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: None, faucet: None, @@ -4391,7 +5222,6 @@ async fn add_faucet_should_add_a_faucet_service() -> Result<()> { add_faucet( AddFaucetServiceOptions { - bootstrap_peers: vec![], env_variables: Some(vec![("ANT_LOG".to_string(), "all".to_string())]), faucet_src_bin_path: faucet_download_path.to_path_buf(), faucet_install_bin_path: faucet_install_path.to_path_buf(), @@ -4443,7 +5273,6 @@ async fn add_faucet_should_return_an_error_if_a_faucet_service_was_already_creat faucet_download_path.write_binary(b"fake faucet bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: None, faucet: Some(FaucetServiceData { @@ -4464,7 +5293,6 @@ async fn add_faucet_should_return_an_error_if_a_faucet_service_was_already_creat let result = add_faucet( AddFaucetServiceOptions { - bootstrap_peers: vec![], env_variables: Some(vec![("ANT_LOG".to_string(), "all".to_string())]), faucet_src_bin_path: faucet_download_path.to_path_buf(), faucet_install_bin_path: faucet_install_path.to_path_buf(), @@ -4506,7 +5334,6 @@ async fn add_daemon_should_add_a_daemon_service() -> Result<()> { daemon_download_path.write_binary(b"fake daemon bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: None, auditor: None, faucet: None, @@ -4584,7 +5411,6 @@ async fn add_daemon_should_return_an_error_if_a_daemon_service_was_already_creat daemon_download_path.write_binary(b"fake daemon bin")?; let mut node_registry = NodeRegistry { - bootstrap_peers: vec![], daemon: Some(DaemonServiceData { daemon_path: PathBuf::from("/usr/local/bin/antctld"), endpoint: Some(SocketAddr::new( @@ -4644,7 +5470,6 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -4669,7 +5494,6 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -4681,9 +5505,7 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -4693,6 +5515,7 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir @@ -4715,21 +5538,19 @@ async fn add_node_should_not_delete_the_source_binary_if_path_arg_is_used() -> R AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -4777,7 +5598,6 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -4802,12 +5622,9 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, - genesis: false, home_network: true, - local: false, evm_network: EvmNetwork::Custom(CustomNetwork { rpc_url_http: "http://localhost:8545".parse()?, payment_token_address: RewardsAddress::from_str( @@ -4826,6 +5643,7 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir @@ -4848,21 +5666,19 @@ async fn add_node_should_apply_the_home_network_flag_if_it_is_used() -> Result<( AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: true, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -4910,7 +5726,6 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -4935,7 +5750,6 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -4947,9 +5761,7 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: true, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -4959,6 +5771,7 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir @@ -4981,21 +5794,19 @@ async fn add_node_should_add_the_node_in_user_mode() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: true, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -5041,7 +5852,6 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { save_path: node_reg_path.to_path_buf(), nat_status: None, nodes: vec![], - bootstrap_peers: vec![], environment_variables: None, daemon: None, }; @@ -5065,7 +5875,6 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { let install_ctx = InstallNodeServiceCtxBuilder { autostart: false, - bootstrap_peers: vec![], data_dir_path: node_data_dir.to_path_buf().join("antnode1"), env_variables: None, evm_network: EvmNetwork::Custom(CustomNetwork { @@ -5077,9 +5886,7 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: true, - local: false, log_dir_path: node_logs_dir.to_path_buf().join("antnode1"), log_format: None, max_archived_log_files: None, @@ -5089,6 +5896,7 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { node_ip: None, node_port: None, owner: None, + peers_args: PeersArgs::default(), rewards_address: RewardsAddress::from_str("0x03B770D9cD32077cC0bF330c13C114a87643B124")?, rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), antnode_path: node_data_dir @@ -5111,21 +5919,19 @@ async fn add_node_should_add_the_node_with_upnp_enabled() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: Some(1), delete_antnode_src: false, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: true, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: None, node_ip: None, node_port: None, + owner: None, + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -5177,7 +5983,6 @@ async fn add_node_should_assign_an_owner_in_lowercase() -> Result<()> { let mut node_registry = NodeRegistry { auditor: None, - bootstrap_peers: vec![], daemon: None, environment_variables: None, faucet: None, @@ -5250,21 +6055,19 @@ async fn add_node_should_assign_an_owner_in_lowercase() -> Result<()> { AddNodeServiceOptions { auto_restart: false, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: Some("Discord_Username".to_string()), node_ip: None, node_port: None, + owner: Some("Discord_Username".to_string()), + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), @@ -5318,7 +6121,6 @@ async fn add_node_should_auto_restart() -> Result<()> { let mut node_registry = NodeRegistry { auditor: None, - bootstrap_peers: vec![], daemon: None, environment_variables: None, faucet: None, @@ -5391,21 +6193,19 @@ async fn add_node_should_auto_restart() -> Result<()> { AddNodeServiceOptions { auto_restart: true, auto_set_nat_flags: false, - bootstrap_peers: vec![], count: None, delete_antnode_src: true, enable_metrics_server: false, env_variables: None, - genesis: false, home_network: false, - local: false, log_format: None, max_archived_log_files: None, max_log_files: None, metrics_port: None, - owner: Some("discord_username".to_string()), node_ip: None, node_port: None, + owner: Some("discord_username".to_string()), + peers_args: PeersArgs::default(), rpc_address: None, rpc_port: None, antnode_dir_path: temp_dir.to_path_buf(), diff --git a/ant-node-manager/src/bin/cli/main.rs b/ant-node-manager/src/bin/cli/main.rs index 14b84e55f7..5e6afa325c 100644 --- a/ant-node-manager/src/bin/cli/main.rs +++ b/ant-node-manager/src/bin/cli/main.rs @@ -1097,7 +1097,6 @@ async fn main() -> Result<()> { env_variables, Some(evm_network.try_into()?), home_network, - peers.local, log_dir_path, log_format, max_archived_log_files, diff --git a/ant-node-manager/src/cmd/local.rs b/ant-node-manager/src/cmd/local.rs index cdf0bd375c..2f0b3b465b 100644 --- a/ant-node-manager/src/cmd/local.rs +++ b/ant-node-manager/src/cmd/local.rs @@ -36,7 +36,7 @@ pub async fn join( log_format: Option, owner: Option, owner_prefix: Option, - peers_args: PeersArgs, + _peers_args: PeersArgs, rpc_port: Option, rewards_address: RewardsAddress, evm_network: Option, @@ -70,21 +70,6 @@ pub async fn join( ) .await?; - // If no peers are obtained we will attempt to join the existing local network, if one - // is running. - let peers = match peers_args.get_addrs(None).await { - Ok(peers) => Some(peers), - Err(err) => match err { - ant_bootstrap::error::Error::NoBootstrapPeersFound => { - warn!("PeersNotObtained, peers is set to None"); - None - } - _ => { - error!("Failed to obtain peers: {err:?}"); - return Err(err.into()); - } - }, - }; let options = LocalNetworkOptions { antnode_bin_path, enable_metrics_server, @@ -95,7 +80,7 @@ pub async fn join( node_port, owner, owner_prefix, - peers, + peers: None, rpc_port, skip_validation, log_format, diff --git a/ant-node-manager/src/cmd/node.rs b/ant-node-manager/src/cmd/node.rs index d21de2b45e..fd4b938bbc 100644 --- a/ant-node-manager/src/cmd/node.rs +++ b/ant-node-manager/src/cmd/node.rs @@ -44,7 +44,6 @@ pub async fn add( env_variables: Option>, evm_network: Option, home_network: bool, - local: bool, log_dir_path: Option, log_format: Option, max_archived_log_files: Option, @@ -53,7 +52,7 @@ pub async fn add( node_ip: Option, node_port: Option, owner: Option, - peers_args: PeersArgs, + mut peers_args: PeersArgs, rewards_address: RewardsAddress, rpc_address: Option, rpc_port: Option, @@ -84,6 +83,11 @@ pub async fn add( config::get_service_data_dir_path(data_dir_path, service_user.clone())?; let service_log_dir_path = config::get_service_log_dir_path(ReleaseType::AntNode, log_dir_path, service_user.clone())?; + let bootstrap_cache_dir = if let Some(user) = &service_user { + Some(config::get_bootstrap_cache_owner_path(user)?) + } else { + None + }; let mut node_registry = NodeRegistry::load(&config::get_node_registry_path()?)?; let release_repo = ::default_config(); @@ -105,47 +109,18 @@ pub async fn add( debug!("Parsing peers from PeersArgs"); - // Handle the `PeersNotObtained` error to make the `--peer` argument optional for the node - // manager. - // - // Since any application making use of the node manager can enable the `network-contacts` feature on - // ant_peers_acquisition, we might end up getting having a huge peer list, and that's problematic for - // service definition files. - // Thus make use of get_peers_exclude_network_contacts() instead of get_peers() to make sure we only - // parse the --peers and ANT_PEERS env var. - - // If the `antnode` binary we're using has `network-contacts` enabled (which is the case for released binaries), - // it's fine if the service definition doesn't call `antnode` with a `--peer` argument. - let is_first = peers_args.first; - let bootstrap_peers = match peers_args.get_addrs(None).await { - Ok(peers) => { - info!("Obtained peers of length {}", peers.len()); - peers.into_iter().take(10).collect::>() - } - Err(err) => match err { - ant_bootstrap::error::Error::NoBootstrapPeersFound => { - info!("No bootstrap peers obtained, setting empty vec."); - Vec::new() - } - _ => { - error!("Error obtaining peers: {err:?}"); - return Err(err.into()); - } - }, - }; + peers_args.addrs.extend(PeersArgs::read_addr_from_env()); + peers_args.bootstrap_cache_dir = bootstrap_cache_dir; let options = AddNodeServiceOptions { auto_restart, auto_set_nat_flags, - bootstrap_peers, count, delete_antnode_src: src_path.is_none(), enable_metrics_server, evm_network: evm_network.unwrap_or(EvmNetwork::ArbitrumOne), env_variables, - genesis: is_first, home_network, - local, log_format, max_archived_log_files, max_log_files, @@ -153,6 +128,7 @@ pub async fn add( node_ip, node_port, owner, + peers_args, rewards_address, rpc_address, rpc_port, @@ -535,7 +511,6 @@ pub async fn upgrade( }; let options = UpgradeOptions { auto_restart: false, - bootstrap_peers: node_registry.bootstrap_peers.clone(), env_variables: env_variables.clone(), force: use_force, start_service: !do_not_start, @@ -613,7 +588,6 @@ pub async fn maintain_n_running_nodes( env_variables: Option>, evm_network: Option, home_network: bool, - local: bool, log_dir_path: Option, log_format: Option, max_archived_log_files: Option, @@ -622,7 +596,7 @@ pub async fn maintain_n_running_nodes( node_ip: Option, node_port: Option, owner: Option, - peers: PeersArgs, + peers_args: PeersArgs, rewards_address: RewardsAddress, rpc_address: Option, rpc_port: Option, @@ -718,7 +692,6 @@ pub async fn maintain_n_running_nodes( env_variables.clone(), evm_network.clone(), home_network, - local, log_dir_path.clone(), log_format, max_archived_log_files, @@ -727,7 +700,7 @@ pub async fn maintain_n_running_nodes( node_ip, Some(PortRange::Single(port)), owner.clone(), - peers.clone(), + peers_args.clone(), rewards_address, rpc_address, rpc_port.clone(), diff --git a/ant-node-manager/src/config.rs b/ant-node-manager/src/config.rs index f0c47f7ab2..946afdf5ab 100644 --- a/ant-node-manager/src/config.rs +++ b/ant-node-manager/src/config.rs @@ -159,6 +159,22 @@ pub fn get_service_data_dir_path( Ok(path) } +/// Get the bootstrap cache owner path +#[cfg(unix)] +pub fn get_bootstrap_cache_owner_path(owner: &str) -> Result { + let path = PathBuf::from("/var/antctl/bootstrap_cache"); + + create_owned_dir(path.clone(), owner)?; + Ok(path) +} + +#[cfg(windows)] +pub fn get_bootstrap_cache_owner_path(_owner: &str) -> Result { + let path = PathBuf::from("C:\\ProgramData\\antctl\\bootstrap_cache"); + std::fs::create_dir_all(&path)?; + Ok(path) +} + /// Get the logging directory for the service. /// /// It's a little counter-intuitive, but the owner will be `None` in the case of a user-mode diff --git a/ant-node-manager/src/lib.rs b/ant-node-manager/src/lib.rs index 696eb93463..2b4c6a8921 100644 --- a/ant-node-manager/src/lib.rs +++ b/ant-node-manager/src/lib.rs @@ -649,6 +649,7 @@ fn format_status_without_colour(status: &ServiceStatus) -> String { #[cfg(test)] mod tests { use super::*; + use ant_bootstrap::PeersArgs; use ant_evm::{AttoTokens, CustomNetwork, EvmNetwork, RewardsAddress}; use ant_logging::LogFormat; use ant_service_management::{ @@ -759,10 +760,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -773,6 +772,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -873,10 +873,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -889,6 +887,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -952,10 +951,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -968,6 +965,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1071,10 +1069,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1087,6 +1083,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1163,10 +1160,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1177,6 +1172,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1265,10 +1261,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1279,6 +1273,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1366,10 +1361,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1380,6 +1373,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1437,10 +1431,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1453,6 +1445,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1500,10 +1493,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1514,6 +1505,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1561,10 +1553,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1577,6 +1567,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1625,10 +1616,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1639,6 +1628,7 @@ mod tests { number: 1, owner: None, peer_id: None, + peers_args: PeersArgs::default(), pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1700,10 +1690,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1716,6 +1704,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1840,10 +1829,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1856,6 +1843,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1880,7 +1868,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -1942,10 +1929,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -1958,6 +1943,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -1983,7 +1969,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -2089,10 +2074,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2105,6 +2088,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2130,7 +2114,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: true, start_service: true, @@ -2248,10 +2231,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2264,6 +2245,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2289,7 +2271,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: false, @@ -2402,10 +2383,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2418,6 +2397,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2442,7 +2422,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -2557,10 +2536,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2573,6 +2550,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2598,7 +2576,6 @@ mod tests { let upgrade_result = service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -2630,6 +2607,1223 @@ mod tests { Ok(()) } + #[tokio::test] + async fn upgrade_should_retain_the_first_flag() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--first"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: true, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert!(service_manager.service.service_data.peers_args.first); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_peers_arg() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--peer"), + OsString::from( + "/ip4/127.0.0.1/tcp/8080/p2p/12D3KooWRBhwfeP2Y4TCx1SM6s9rUoHhR5STiGwxBhgFRcw3UERE" + ), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![ + "/ip4/127.0.0.1/tcp/8080/p2p/12D3KooWRBhwfeP2Y4TCx1SM6s9rUoHhR5STiGwxBhgFRcw3UERE" + .parse()?, + ], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert!(!service_manager + .service + .service_data + .peers_args + .addrs + .is_empty()); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_local_flag() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--local"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: true, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert!(service_manager.service.service_data.peers_args.local); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_network_contacts_url_arg() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--network-contacts-url"), + OsString::from("http://localhost:8080/contacts.json,http://localhost:8081/contacts.json"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![ + "http://localhost:8080/contacts.json".to_string(), + "http://localhost:8081/contacts.json".to_string(), + ], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert_eq!( + service_manager + .service + .service_data + .peers_args + .network_contacts_url + .len(), + 2 + ); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_testnet_flag() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--testnet"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: true, + ignore_cache: false, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert!( + service_manager + .service + .service_data + .peers_args + .disable_mainnet_contacts + ); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_ignore_cache_flag() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--ignore-cache"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: true, + bootstrap_cache_dir: None, + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert!(service_manager.service.service_data.peers_args.ignore_cache); + + Ok(()) + } + + #[tokio::test] + async fn upgrade_should_retain_the_custom_bootstrap_cache_path() -> Result<()> { + let current_version = "0.1.0"; + let target_version = "0.2.0"; + + let tmp_data_dir = assert_fs::TempDir::new()?; + let current_install_dir = tmp_data_dir.child("antnode_install"); + current_install_dir.create_dir_all()?; + + let current_node_bin = current_install_dir.child("antnode"); + current_node_bin.write_binary(b"fake antnode binary")?; + let target_node_bin = tmp_data_dir.child("antnode"); + target_node_bin.write_binary(b"fake antnode binary")?; + + let mut mock_service_control = MockServiceControl::new(); + let mut mock_rpc_client = MockRpcClient::new(); + + // before binary upgrade + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(1000)); + mock_service_control + .expect_stop() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + + // after binary upgrade + mock_service_control + .expect_uninstall() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_install() + .with( + eq(ServiceInstallCtx { + args: vec![ + OsString::from("--rpc"), + OsString::from("127.0.0.1:8081"), + OsString::from("--root-dir"), + OsString::from("/var/antctl/services/antnode1"), + OsString::from("--log-output-dest"), + OsString::from("/var/log/antnode/antnode1"), + OsString::from("--bootstrap-cache-dir"), + OsString::from("/var/antctl/services/antnode1/bootstrap_cache"), + OsString::from("--rewards-address"), + OsString::from("0x03B770D9cD32077cC0bF330c13C114a87643B124"), + OsString::from("evm-arbitrum-one"), + ], + autostart: false, + contents: None, + environment: None, + label: "antnode1".parse()?, + program: current_node_bin.to_path_buf(), + username: Some("ant".to_string()), + working_directory: None, + }), + eq(false), + ) + .times(1) + .returning(|_, _| Ok(())); + + // after service restart + mock_service_control + .expect_start() + .with(eq("antnode1"), eq(false)) + .times(1) + .returning(|_, _| Ok(())); + mock_service_control + .expect_wait() + .with(eq(3000)) + .times(1) + .returning(|_| ()); + mock_service_control + .expect_get_process_pid() + .with(eq(current_node_bin.to_path_buf().clone())) + .times(1) + .returning(|_| Ok(100)); + + mock_rpc_client.expect_node_info().times(1).returning(|| { + Ok(NodeInfo { + pid: 2000, + peer_id: PeerId::from_str("12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR")?, + data_path: PathBuf::from("/var/antctl/services/antnode1"), + log_path: PathBuf::from("/var/log/antnode/antnode1"), + version: target_version.to_string(), + uptime: std::time::Duration::from_secs(1), // the service was just started + wallet_balance: 0, + }) + }); + mock_rpc_client + .expect_network_info() + .times(1) + .returning(|| { + Ok(NetworkInfo { + connected_peers: Vec::new(), + listeners: Vec::new(), + }) + }); + + let mut service_data = NodeServiceData { + auto_restart: false, + connected_peers: None, + data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), + evm_network: EvmNetwork::ArbitrumOne, + home_network: false, + listen_addr: None, + log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), + log_format: None, + max_archived_log_files: None, + max_log_files: None, + metrics_port: None, + node_ip: None, + node_port: None, + number: 1, + owner: None, + peer_id: Some(PeerId::from_str( + "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", + )?), + peers_args: PeersArgs { + first: false, + addrs: vec![], + network_contacts_url: vec![], + local: false, + disable_mainnet_contacts: false, + ignore_cache: false, + bootstrap_cache_dir: Some(PathBuf::from( + "/var/antctl/services/antnode1/bootstrap_cache", + )), + }, + pid: Some(1000), + rewards_address: RewardsAddress::from_str( + "0x03B770D9cD32077cC0bF330c13C114a87643B124", + )?, + reward_balance: Some(AttoTokens::zero()), + rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), + antnode_path: current_node_bin.to_path_buf(), + service_name: "antnode1".to_string(), + status: ServiceStatus::Running, + upnp: false, + user: Some("ant".to_string()), + user_mode: false, + version: current_version.to_string(), + }; + let service = NodeService::new(&mut service_data, Box::new(mock_rpc_client)); + + let mut service_manager = ServiceManager::new( + service, + Box::new(mock_service_control), + VerbosityLevel::Normal, + ); + + service_manager + .upgrade(UpgradeOptions { + auto_restart: false, + env_variables: None, + force: false, + start_service: true, + target_bin_path: target_node_bin.to_path_buf(), + target_version: Version::parse(target_version).unwrap(), + }) + .await?; + + assert_eq!( + service_manager + .service + .service_data + .peers_args + .bootstrap_cache_dir, + Some(PathBuf::from( + "/var/antctl/services/antnode1/bootstrap_cache" + )) + ); + + Ok(()) + } + #[tokio::test] async fn upgrade_should_retain_the_upnp_flag() -> Result<()> { let current_version = "0.1.0"; @@ -2737,10 +3931,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -2753,6 +3945,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2778,7 +3971,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -2900,10 +4092,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: Some(LogFormat::Json), max_archived_log_files: None, @@ -2916,6 +4106,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -2941,7 +4132,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3066,10 +4256,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: true, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3082,6 +4270,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3107,7 +4296,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3229,10 +4417,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3245,6 +4431,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3270,7 +4457,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3395,10 +4581,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3411,6 +4595,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3436,7 +4621,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3557,10 +4741,8 @@ mod tests { auto_restart: false, connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: Some(20), @@ -3573,6 +4755,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), reward_balance: Some(AttoTokens::zero()), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), @@ -3599,7 +4782,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3723,10 +4905,8 @@ mod tests { auto_restart: false, connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3739,6 +4919,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), reward_balance: Some(AttoTokens::zero()), rpc_socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081), @@ -3765,7 +4946,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3887,10 +5067,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -3903,6 +5081,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -3928,7 +5107,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4053,10 +5231,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4069,6 +5245,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4094,7 +5271,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4219,10 +5395,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4235,6 +5409,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4260,7 +5435,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4385,10 +5559,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4401,6 +5573,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4426,7 +5599,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4562,10 +5734,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4578,6 +5748,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4604,7 +5775,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4740,10 +5910,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4756,6 +5924,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4782,7 +5951,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4906,10 +6074,8 @@ mod tests { connected_peers: None, data_dir_path: PathBuf::from("/var/antctl/services/antnode1"), evm_network: EvmNetwork::ArbitrumOne, - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -4922,6 +6088,7 @@ mod tests { peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", )?), + peers_args: PeersArgs::default(), pid: Some(1000), rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -4950,7 +6117,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4992,10 +6158,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, max_archived_log_files: None, @@ -5005,8 +6169,9 @@ mod tests { node_port: None, number: 1, owner: None, - pid: None, + peers_args: PeersArgs::default(), peer_id: None, + pid: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", )?, @@ -5061,10 +6226,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -5074,6 +6237,7 @@ mod tests { node_port: None, number: 1, owner: None, + peers_args: PeersArgs::default(), pid: Some(1000), peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", @@ -5145,10 +6309,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: PathBuf::from("/var/log/antnode/antnode1"), log_format: None, max_archived_log_files: None, @@ -5158,6 +6320,7 @@ mod tests { node_port: None, number: 1, owner: None, + peers_args: PeersArgs::default(), pid: Some(1000), peer_id: Some(PeerId::from_str( "12D3KooWS2tpXGGTmg2AHFiDh57yPQnat49YHnyqoggzXZWpqkCR", @@ -5224,10 +6387,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, max_archived_log_files: None, @@ -5238,6 +6399,7 @@ mod tests { number: 1, owner: None, pid: None, + peers_args: PeersArgs::default(), peer_id: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -5301,10 +6463,8 @@ mod tests { "0x8464135c8F25Da09e49BC8782676a84730C318bC", )?, }), - genesis: false, home_network: false, listen_addr: None, - local: false, log_dir_path: log_dir.to_path_buf(), log_format: None, max_archived_log_files: None, @@ -5315,6 +6475,7 @@ mod tests { number: 1, owner: None, pid: None, + peers_args: PeersArgs::default(), peer_id: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", diff --git a/ant-node-manager/src/local.rs b/ant-node-manager/src/local.rs index e1fa3d4290..9bfc06eee9 100644 --- a/ant-node-manager/src/local.rs +++ b/ant-node-manager/src/local.rs @@ -11,6 +11,7 @@ use crate::helpers::{ check_port_availability, get_bin_version, get_start_port_if_applicable, increment_port_option, }; +use ant_bootstrap::PeersArgs; use ant_evm::{EvmNetwork, RewardsAddress}; use ant_logging::LogFormat; use ant_service_management::{ @@ -38,7 +39,7 @@ pub trait Launcher { #[allow(clippy::too_many_arguments)] fn launch_node( &self, - bootstrap_peers: Vec, + first: bool, log_format: Option, metrics_port: Option, node_port: Option, @@ -62,7 +63,7 @@ impl Launcher for LocalSafeLauncher { fn launch_node( &self, - bootstrap_peers: Vec, + first: bool, log_format: Option, metrics_port: Option, node_port: Option, @@ -78,13 +79,8 @@ impl Launcher for LocalSafeLauncher { args.push(owner); } - if bootstrap_peers.is_empty() { + if first { args.push("--first".to_string()) - } else { - for peer in bootstrap_peers { - args.push("--peer".to_string()); - args.push(peer.to_string()); - } } if let Some(log_format) = log_format { @@ -296,8 +292,7 @@ pub async fn run_network( let owner = get_node_owner(&options.owner_prefix, &options.owner, &number); let node = run_node( RunNodeOptions { - bootstrap_peers: vec![], - genesis: true, + first: true, metrics_port: metrics_free_port, node_port, interval: options.interval, @@ -345,8 +340,7 @@ pub async fn run_network( let owner = get_node_owner(&options.owner_prefix, &options.owner, &number); let node = run_node( RunNodeOptions { - bootstrap_peers: bootstrap_peers.clone(), - genesis: false, + first: false, metrics_port: metrics_free_port, node_port, interval: options.interval, @@ -386,8 +380,7 @@ pub async fn run_network( } pub struct RunNodeOptions { - pub bootstrap_peers: Vec, - pub genesis: bool, + pub first: bool, pub interval: u64, pub log_format: Option, pub metrics_port: Option, @@ -408,7 +401,7 @@ pub async fn run_node( info!("Launching node {}...", run_options.number); println!("Launching node {}...", run_options.number); launcher.launch_node( - run_options.bootstrap_peers.clone(), + run_options.first, run_options.log_format, run_options.metrics_port, run_options.node_port, @@ -435,10 +428,8 @@ pub async fn run_node( connected_peers, data_dir_path: node_info.data_path, evm_network: run_options.evm_network.unwrap_or(EvmNetwork::ArbitrumOne), - genesis: run_options.genesis, home_network: false, listen_addr: Some(listen_addrs), - local: true, log_dir_path: node_info.log_path, log_format: run_options.log_format, max_archived_log_files: None, @@ -449,6 +440,15 @@ pub async fn run_node( number: run_options.number, owner: run_options.owner, peer_id: Some(peer_id), + peers_args: PeersArgs { + first: run_options.first, + addrs: vec![], + network_contacts_url: vec![], + local: true, + disable_mainnet_contacts: true, + ignore_cache: true, + bootstrap_cache_dir: None, + }, pid: Some(node_info.pid), rewards_address: run_options.rewards_address, reward_balance: None, @@ -564,7 +564,7 @@ mod tests { mock_launcher .expect_launch_node() .with( - eq(vec![]), + eq(true), eq(None), eq(None), eq(None), @@ -611,8 +611,7 @@ mod tests { let node = run_node( RunNodeOptions { - bootstrap_peers: vec![], - genesis: true, + first: true, interval: 100, log_format: None, metrics_port: None, @@ -629,7 +628,7 @@ mod tests { ) .await?; - assert!(node.genesis); + assert!(node.peers_args.first); assert_eq!(node.version, "0.100.12"); assert_eq!(node.service_name, "antnode-local1"); assert_eq!( diff --git a/ant-node-manager/src/rpc.rs b/ant-node-manager/src/rpc.rs index 5cc357c2e8..a06d0ef338 100644 --- a/ant-node-manager/src/rpc.rs +++ b/ant-node-manager/src/rpc.rs @@ -64,22 +64,20 @@ pub async fn restart_node_service( let install_ctx = InstallNodeServiceCtxBuilder { antnode_path: current_node_clone.antnode_path.clone(), autostart: current_node_clone.auto_restart, - bootstrap_peers: node_registry.bootstrap_peers.clone(), data_dir_path: current_node_clone.data_dir_path.clone(), env_variables: node_registry.environment_variables.clone(), evm_network: current_node_clone.evm_network.clone(), - genesis: current_node_clone.genesis, home_network: current_node_clone.home_network, - local: current_node_clone.local, log_dir_path: current_node_clone.log_dir_path.clone(), log_format: current_node_clone.log_format, max_archived_log_files: current_node_clone.max_archived_log_files, max_log_files: current_node_clone.max_log_files, metrics_port: None, - owner: current_node_clone.owner.clone(), name: current_node_clone.service_name.clone(), node_ip: current_node_clone.node_ip, node_port: current_node_clone.get_antnode_port(), + owner: current_node_clone.owner.clone(), + peers_args: current_node_clone.peers_args.clone(), rewards_address: current_node_clone.rewards_address, rpc_socket_addr: current_node_clone.rpc_socket_addr, service_user: current_node_clone.user.clone(), @@ -181,13 +179,10 @@ pub async fn restart_node_service( let install_ctx = InstallNodeServiceCtxBuilder { autostart: current_node_clone.auto_restart, - bootstrap_peers: node_registry.bootstrap_peers.clone(), data_dir_path: data_dir_path.clone(), env_variables: node_registry.environment_variables.clone(), evm_network: current_node_clone.evm_network.clone(), - genesis: current_node_clone.genesis, home_network: current_node_clone.home_network, - local: current_node_clone.local, log_dir_path: log_dir_path.clone(), log_format: current_node_clone.log_format, name: new_service_name.clone(), @@ -197,6 +192,7 @@ pub async fn restart_node_service( node_ip: current_node_clone.node_ip, node_port: None, owner: None, + peers_args: current_node_clone.peers_args.clone(), rewards_address: current_node_clone.rewards_address, rpc_socket_addr: current_node_clone.rpc_socket_addr, antnode_path: antnode_path.clone(), @@ -214,10 +210,8 @@ pub async fn restart_node_service( connected_peers: None, data_dir_path, evm_network: current_node_clone.evm_network, - genesis: current_node_clone.genesis, home_network: current_node_clone.home_network, listen_addr: None, - local: current_node_clone.local, log_dir_path, log_format: current_node_clone.log_format, max_archived_log_files: current_node_clone.max_archived_log_files, @@ -228,6 +222,7 @@ pub async fn restart_node_service( number: new_node_number as u16, owner: None, peer_id: None, + peers_args: current_node_clone.peers_args.clone(), pid: None, rewards_address: current_node_clone.rewards_address, reward_balance: current_node_clone.reward_balance, diff --git a/ant-node/src/bin/antnode/main.rs b/ant-node/src/bin/antnode/main.rs index 6246206211..ec8d759f7b 100644 --- a/ant-node/src/bin/antnode/main.rs +++ b/ant-node/src/bin/antnode/main.rs @@ -295,7 +295,7 @@ fn main() -> Result<()> { // another process with these args. #[cfg(feature = "metrics")] rt.spawn(init_metrics(std::process::id())); - let initial_peres = rt.block_on(opt.peers.get_addrs(None))?; + let initial_peres = rt.block_on(opt.peers.get_addrs(None, Some(100)))?; debug!("Node's owner set to: {:?}", opt.owner); let restart_options = rt.block_on(async move { let mut node_builder = NodeBuilder::new( diff --git a/ant-service-management/Cargo.toml b/ant-service-management/Cargo.toml index bd65f25575..53e2e27b38 100644 --- a/ant-service-management/Cargo.toml +++ b/ant-service-management/Cargo.toml @@ -10,6 +10,7 @@ repository = "https://github.com/maidsafe/autonomi" version = "0.4.3" [dependencies] +ant-bootstrap = { path = "../ant-bootstrap", version = "0.1.0" } ant-evm = { path = "../ant-evm", version = "0.1.4" } ant-logging = { path = "../ant-logging", version = "0.2.40" } ant-protocol = { path = "../ant-protocol", version = "0.17.15", features = ["rpc"] } diff --git a/ant-service-management/src/auditor.rs b/ant-service-management/src/auditor.rs index 7df0bcb46c..cea9273395 100644 --- a/ant-service-management/src/auditor.rs +++ b/ant-service-management/src/auditor.rs @@ -54,17 +54,6 @@ impl ServiceStateActions for AuditorService<'_> { OsString::from(self.service_data.log_dir_path.to_string_lossy().to_string()), ]; - if !options.bootstrap_peers.is_empty() { - let peers_str = options - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } - args.push(OsString::from("server")); Ok(ServiceInstallCtx { diff --git a/ant-service-management/src/faucet.rs b/ant-service-management/src/faucet.rs index 097db24f6a..7aa0d15b30 100644 --- a/ant-service-management/src/faucet.rs +++ b/ant-service-management/src/faucet.rs @@ -55,17 +55,6 @@ impl ServiceStateActions for FaucetService<'_> { OsString::from(self.service_data.log_dir_path.to_string_lossy().to_string()), ]; - if !options.bootstrap_peers.is_empty() { - let peers_str = options - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } - args.push(OsString::from("server")); Ok(ServiceInstallCtx { diff --git a/ant-service-management/src/lib.rs b/ant-service-management/src/lib.rs index 406f608631..1e4c970808 100644 --- a/ant-service-management/src/lib.rs +++ b/ant-service-management/src/lib.rs @@ -23,7 +23,6 @@ pub mod antctl_proto { use async_trait::async_trait; use auditor::AuditorServiceData; -use libp2p::Multiaddr; use semver::Version; use serde::{Deserialize, Serialize}; use service_manager::ServiceInstallCtx; @@ -68,7 +67,6 @@ pub enum UpgradeResult { #[derive(Clone, Debug, Eq, PartialEq)] pub struct UpgradeOptions { pub auto_restart: bool, - pub bootstrap_peers: Vec, pub env_variables: Option>, pub force: bool, pub start_service: bool, @@ -103,7 +101,6 @@ pub struct StatusSummary { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NodeRegistry { pub auditor: Option, - pub bootstrap_peers: Vec, pub daemon: Option, pub environment_variables: Option>, pub faucet: Option, @@ -139,7 +136,6 @@ impl NodeRegistry { debug!("Loading default node registry as {path:?} does not exist"); return Ok(NodeRegistry { auditor: None, - bootstrap_peers: vec![], daemon: None, environment_variables: None, faucet: None, @@ -162,7 +158,6 @@ impl NodeRegistry { if contents.is_empty() { return Ok(NodeRegistry { auditor: None, - bootstrap_peers: vec![], daemon: None, environment_variables: None, faucet: None, diff --git a/ant-service-management/src/node.rs b/ant-service-management/src/node.rs index e268976226..d9a91eeb12 100644 --- a/ant-service-management/src/node.rs +++ b/ant-service-management/src/node.rs @@ -7,6 +7,7 @@ // permissions and limitations relating to use of the SAFE Network Software. use crate::{error::Result, rpc::RpcActions, ServiceStateActions, ServiceStatus, UpgradeOptions}; +use ant_bootstrap::PeersArgs; use ant_evm::{AttoTokens, EvmNetwork, RewardsAddress}; use ant_logging::LogFormat; use ant_protocol::get_port_from_multiaddr; @@ -71,12 +72,7 @@ impl ServiceStateActions for NodeService<'_> { OsString::from(self.service_data.log_dir_path.to_string_lossy().to_string()), ]; - if self.service_data.genesis { - args.push(OsString::from("--first")); - } - if self.service_data.local { - args.push(OsString::from("--local")); - } + push_arguments_from_peers_args(&self.service_data.peers_args, &mut args); if let Some(log_fmt) = self.service_data.log_format { args.push(OsString::from("--log-format")); args.push(OsString::from(log_fmt.as_str())); @@ -115,17 +111,6 @@ impl ServiceStateActions for NodeService<'_> { args.push(OsString::from(owner)); } - if !options.bootstrap_peers.is_empty() { - let peers_str = options - .bootstrap_peers - .iter() - .map(|peer| peer.to_string()) - .collect::>() - .join(","); - args.push(OsString::from("--peer")); - args.push(OsString::from(peers_str)); - } - args.push(OsString::from("--rewards-address")); args.push(OsString::from( self.service_data.rewards_address.to_string(), @@ -291,10 +276,8 @@ pub struct NodeServiceData { pub data_dir_path: PathBuf, #[serde(default)] pub evm_network: EvmNetwork, - pub genesis: bool, pub home_network: bool, pub listen_addr: Option>, - pub local: bool, pub log_dir_path: PathBuf, pub log_format: Option, pub max_archived_log_files: Option, @@ -313,6 +296,7 @@ pub struct NodeServiceData { deserialize_with = "deserialize_peer_id" )] pub peer_id: Option, + pub peers_args: PeersArgs, pub pid: Option, #[serde(default)] pub rewards_address: RewardsAddress, @@ -404,3 +388,44 @@ impl NodeServiceData { None } } + +/// Pushes arguments from the `PeersArgs` struct to the provided `args` vector. +pub fn push_arguments_from_peers_args(peers_args: &PeersArgs, args: &mut Vec) { + if peers_args.first { + args.push(OsString::from("--first")); + } + if peers_args.local { + args.push(OsString::from("--local")); + } + if !peers_args.addrs.is_empty() { + let peers_str = peers_args + .addrs + .iter() + .map(|peer| peer.to_string()) + .collect::>() + .join(","); + args.push(OsString::from("--peer")); + args.push(OsString::from(peers_str)); + } + if !peers_args.network_contacts_url.is_empty() { + args.push(OsString::from("--network-contacts-url")); + args.push(OsString::from( + peers_args + .network_contacts_url + .iter() + .map(|url| url.to_string()) + .collect::>() + .join(","), + )); + } + if peers_args.disable_mainnet_contacts { + args.push(OsString::from("--testnet")); + } + if peers_args.ignore_cache { + args.push(OsString::from("--ignore-cache")); + } + if let Some(path) = &peers_args.bootstrap_cache_dir { + args.push(OsString::from("--bootstrap-cache-dir")); + args.push(OsString::from(path.to_string_lossy().to_string())); + } +} diff --git a/node-launchpad/src/node_mgmt.rs b/node-launchpad/src/node_mgmt.rs index 49fd1c1b32..daad00123f 100644 --- a/node-launchpad/src/node_mgmt.rs +++ b/node-launchpad/src/node_mgmt.rs @@ -418,7 +418,6 @@ async fn scale_down_nodes(config: &NodeConfig, count: u16) { None, Some(EvmNetwork::ArbitrumSepolia), config.home_network, - false, None, None, None, @@ -492,7 +491,6 @@ async fn add_nodes( None, Some(EvmNetwork::ArbitrumSepolia), config.home_network, - false, None, None, None,