diff --git a/Cargo.lock b/Cargo.lock index 34ae07c699..0c3c1f5bc6 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/error.rs b/ant-bootstrap/src/error.rs index 77002702e5..70da2ca80a 100644 --- a/ant-bootstrap/src/error.rs +++ b/ant-bootstrap/src/error.rs @@ -20,6 +20,8 @@ pub enum Error { 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..daf20d1480 100644 --- a/ant-bootstrap/src/initial_peers.rs +++ b/ant-bootstrap/src/initial_peers.rs @@ -13,13 +13,14 @@ use crate::{ }; use clap::Args; use libp2p::Multiaddr; +use serde::{Deserialize, Serialize}; 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 +42,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,7 +59,7 @@ 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. @@ -115,23 +115,21 @@ 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); } @@ -185,8 +183,27 @@ impl PeersArgs { 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 + } } diff --git a/ant-bootstrap/tests/address_format_tests.rs b/ant-bootstrap/tests/address_format_tests.rs index 55d9246b8b..09d73e22b2 100644 --- a/ant-bootstrap/tests/address_format_tests.rs +++ b/ant-bootstrap/tests/address_format_tests.rs @@ -45,7 +45,7 @@ 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, diff --git a/ant-bootstrap/tests/cli_integration_tests.rs b/ant-bootstrap/tests/cli_integration_tests.rs index 1afee9176e..4f70c23228 100644 --- a/ant-bootstrap/tests/cli_integration_tests.rs +++ b/ant-bootstrap/tests/cli_integration_tests.rs @@ -31,7 +31,7 @@ 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, @@ -56,7 +56,7 @@ 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, @@ -90,7 +90,7 @@ 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, @@ -155,7 +155,7 @@ 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, 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..e2eb37aca5 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,17 @@ 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, + }; + 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 +131,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 +141,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 +163,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 +211,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 +258,15 @@ 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, + }; let mut node_registry = NodeRegistry { auditor: None, faucet: None, @@ -272,10 +285,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 +295,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 +312,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 +330,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 +393,17 @@ 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, + }; let latest_version = "0.96.4"; let temp_dir = assert_fs::TempDir::new()?; @@ -402,21 +418,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 +481,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 +505,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 +516,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 +526,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 +553,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 +564,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 +574,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 +602,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 +612,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 +622,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 +645,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 +744,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 +761,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 +780,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 +793,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 +803,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 +814,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 +825,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 +871,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 +896,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 +960,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 +978,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 +1011,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 +1053,873 @@ 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, + }; + + 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); + + 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, + }; + + 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); + + 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, + }; + + 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); + + 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, + }; + + 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); + + 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, + }; + + 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); Ok(()) } #[tokio::test] -async fn add_new_node_should_add_another_service() -> Result<()> { +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 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: true, + }; + 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("--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); @@ -1173,25 +1927,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 +1969,12 @@ 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") - ); - assert_eq!( - 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); + 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); Ok(()) } @@ -1253,7 +1992,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 +2070,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 +2135,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 +2158,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 +2169,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 +2179,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 +2202,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 +2267,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 +2459,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 +2535,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 +2547,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 +2562,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 +2578,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 +2652,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 +2661,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 +2679,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 +2695,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 +2757,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 +2773,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 +2840,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 +2856,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 +2924,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 +3001,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 +3060,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 +3138,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 +3198,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 +3276,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 +3336,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 +3528,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 +3601,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 +3613,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 +3628,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 +3644,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 +3719,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 +3731,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 +3746,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 +3762,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 +3826,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 +3997,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 +4081,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 +4093,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 +4108,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 +4124,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 +4199,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 +4211,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 +4226,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 +4242,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 +4306,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 +4328,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 +4339,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 +4349,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 +4371,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 +4432,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 +4454,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 +4465,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 +4475,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 +4497,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 +4558,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 +4580,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 +4591,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 +4601,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 +4623,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 +4685,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 +4709,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 +4780,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 +4814,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 +4865,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 +4884,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 +4926,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 +4962,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 +5014,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 +5049,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 +5100,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 +5120,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 +5161,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 +5238,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 +5297,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 +5321,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 +5332,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 +5342,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 +5365,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 +5425,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 +5449,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 +5470,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 +5493,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 +5553,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 +5577,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 +5588,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 +5598,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 +5621,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 +5679,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 +5702,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 +5713,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 +5723,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 +5746,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 +5810,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 +5882,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 +5948,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 +6020,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/node.rs b/ant-node-manager/src/cmd/node.rs index d21de2b45e..a96a0bb118 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, @@ -105,47 +104,17 @@ 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()); 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 +122,7 @@ pub async fn add( node_ip, node_port, owner, + peers_args, rewards_address, rpc_address, rpc_port, @@ -535,7 +505,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 +582,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 +590,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 +686,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 +694,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/lib.rs b/ant-node-manager/src/lib.rs index 696eb93463..7987c55224 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,1037 @@ 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, + }, + 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, + }, + 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, + }, + 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, + }, + 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, + }, + 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, + }, + 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_upnp_flag() -> Result<()> { let current_version = "0.1.0"; @@ -2737,10 +3745,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 +3759,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 +3785,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -2900,10 +3906,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 +3920,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 +3946,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3066,10 +4070,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 +4084,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 +4110,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3229,10 +4231,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 +4245,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 +4271,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3395,10 +4395,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 +4409,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 +4435,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3557,10 +4555,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 +4569,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 +4596,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3723,10 +4719,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 +4733,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 +4760,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -3887,10 +4881,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 +4895,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 +4921,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4053,10 +5045,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 +5059,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 +5085,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4219,10 +5209,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 +5223,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 +5249,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4385,10 +5373,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 +5387,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 +5413,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4562,10 +5548,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 +5562,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 +5589,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4740,10 +5724,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 +5738,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 +5765,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: true, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4906,10 +5888,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 +5902,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 +5931,6 @@ mod tests { service_manager .upgrade(UpgradeOptions { auto_restart: false, - bootstrap_peers: Vec::new(), env_variables: None, force: false, start_service: true, @@ -4992,10 +5972,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 +5983,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 +6040,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 +6051,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 +6123,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 +6134,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 +6201,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 +6213,7 @@ mod tests { number: 1, owner: None, pid: None, + peers_args: PeersArgs::default(), peer_id: None, rewards_address: RewardsAddress::from_str( "0x03B770D9cD32077cC0bF330c13C114a87643B124", @@ -5301,10 +6277,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 +6289,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..9b8b61e4e3 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,14 @@ 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, + }, pid: Some(node_info.pid), rewards_address: run_options.rewards_address, reward_balance: None, @@ -564,7 +563,7 @@ mod tests { mock_launcher .expect_launch_node() .with( - eq(vec![]), + eq(true), eq(None), eq(None), eq(None), @@ -611,8 +610,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 +627,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-service-management/Cargo.toml b/ant-service-management/Cargo.toml index 88e6dd313f..4014c90089 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..e1b5378bbc 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,40 @@ 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")); + } +} 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,