diff --git a/automap/Cargo.toml b/automap/Cargo.toml index c02b587ba..f2f76db80 100644 --- a/automap/Cargo.toml +++ b/automap/Cargo.toml @@ -27,3 +27,6 @@ path = "src/main.rs" [lib] name = "automap_lib" path = "src/lib.rs" + +[features] +no_test_share = [] \ No newline at end of file diff --git a/automap/src/comm_layer/igdp.rs b/automap/src/comm_layer/igdp.rs index 81805877e..10fcce9c2 100644 --- a/automap/src/comm_layer/igdp.rs +++ b/automap/src/comm_layer/igdp.rs @@ -27,7 +27,7 @@ use std::time::{Duration, Instant}; pub const HOUSEKEEPING_THREAD_LOOP_DELAY_MS: u64 = 100; pub const PUBLIC_IP_POLL_DELAY_SECONDS: u64 = 60; -trait GatewayFactory { +trait GatewayFactory: Send { fn make(&self, options: SearchOptions) -> Result, SearchError>; } @@ -580,20 +580,15 @@ impl MappingAdderReal { #[cfg(test)] mod tests { use super::*; - use crate::control_layer::automap_control::AutomapChange; use crate::mocks::LocalIpFinderMock; use core::ptr::addr_of; - use crossbeam_channel::unbounded; use igd::RequestError; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; - use masq_lib::utils::AutomapProtocol; use std::cell::RefCell; use std::net::Ipv6Addr; use std::ops::Sub; use std::str::FromStr; use std::sync::{Arc, Mutex}; - use std::thread; - use std::time::Duration; fn clone_get_external_ip_error(error: &GetExternalIpError) -> GetExternalIpError { match error { diff --git a/automap/src/comm_layer/mod.rs b/automap/src/comm_layer/mod.rs index 598f5a999..e6437f6d9 100644 --- a/automap/src/comm_layer/mod.rs +++ b/automap/src/comm_layer/mod.rs @@ -94,7 +94,7 @@ impl AutomapError { } } -pub trait Transactor { +pub trait Transactor: Send { fn find_routers(&self) -> Result, AutomapError>; fn get_public_ip(&self, router_ip: IpAddr) -> Result; fn add_mapping( diff --git a/automap/src/control_layer/automap_control.rs b/automap/src/control_layer/automap_control.rs index d1a8292e3..c68a91ada 100644 --- a/automap/src/control_layer/automap_control.rs +++ b/automap/src/control_layer/automap_control.rs @@ -332,234 +332,31 @@ impl AutomapControlReal { } } +#[cfg(any(test, not(feature = "no_test_share")))] +pub fn replace_transactor( + subject: AutomapControlReal, + transactor: Box, +) -> AutomapControlReal { + let idx = AutomapControlReal::find_transactor_index( + subject.transactors.borrow_mut(), + transactor.protocol(), + ); + subject.transactors.borrow_mut()[idx] = transactor; + subject +} + #[cfg(test)] mod tests { use super::*; use crate::comm_layer::Transactor; + use crate::mocks::{TransactorMock, PUBLIC_IP, ROUTER_IP}; use crossbeam_channel::{unbounded, TryRecvError}; - use lazy_static::lazy_static; - use std::any::Any; use std::cell::RefCell; use std::net::IpAddr; use std::ptr::addr_of; use std::str::FromStr; use std::sync::{Arc, Mutex}; - lazy_static! { - static ref ROUTER_IP: IpAddr = IpAddr::from_str("1.2.3.4").unwrap(); - static ref PUBLIC_IP: IpAddr = IpAddr::from_str("2.3.4.5").unwrap(); - } - - struct TransactorMock { - housekeeping_thread_started: bool, - protocol: AutomapProtocol, - find_routers_results: RefCell, AutomapError>>>, - get_public_ip_params: Arc>>, - get_public_ip_results: RefCell>>, - add_mapping_params: Arc>>, - add_mapping_results: RefCell>>, - add_permanent_mapping_params: Arc>>, - add_permanent_mapping_results: RefCell>>, - delete_mapping_params: Arc>>, - delete_mapping_results: RefCell>>, - start_housekeeping_thread_params: Arc>>, - start_housekeeping_thread_results: - RefCell, AutomapError>>>, - stop_housekeeping_thread_params: Arc>>, - stop_housekeeping_thread_results: RefCell>>, - } - - impl Transactor for TransactorMock { - fn find_routers(&self) -> Result, AutomapError> { - self.find_routers_results.borrow_mut().remove(0) - } - - fn get_public_ip(&self, router_ip: IpAddr) -> Result { - if !self.housekeeping_thread_started { - panic!("Housekeeping thread must be started before get_public_ip()") - } - self.get_public_ip_params.lock().unwrap().push(router_ip); - self.get_public_ip_results.borrow_mut().remove(0) - } - - fn add_mapping( - &self, - router_ip: IpAddr, - hole_port: u16, - lifetime: u32, - ) -> Result { - if !self.housekeeping_thread_started { - panic!("Housekeeping thread must be started before add_mapping()") - } - self.add_mapping_params - .lock() - .unwrap() - .push((router_ip, hole_port, lifetime)); - self.add_mapping_results.borrow_mut().remove(0) - } - - fn add_permanent_mapping( - &self, - router_ip: IpAddr, - hole_port: u16, - ) -> Result { - if !self.housekeeping_thread_started { - panic!("Housekeeping thread must be started before add_permanent_mapping()") - } - self.add_permanent_mapping_params - .lock() - .unwrap() - .push((router_ip, hole_port)); - self.add_permanent_mapping_results.borrow_mut().remove(0) - } - - fn delete_mapping(&self, router_ip: IpAddr, hole_port: u16) -> Result<(), AutomapError> { - self.delete_mapping_params - .lock() - .unwrap() - .push((router_ip, hole_port)); - self.delete_mapping_results.borrow_mut().remove(0) - } - - fn protocol(&self) -> AutomapProtocol { - self.protocol - } - - fn start_housekeeping_thread( - &mut self, - change_handler: ChangeHandler, - router_ip: IpAddr, - ) -> Result, AutomapError> { - self.start_housekeeping_thread_params - .lock() - .unwrap() - .push((change_handler, router_ip)); - let result = self - .start_housekeeping_thread_results - .borrow_mut() - .remove(0); - self.housekeeping_thread_started = true; - result - } - - fn stop_housekeeping_thread(&mut self) -> Result { - self.stop_housekeeping_thread_params - .lock() - .unwrap() - .push(()); - let result = self.stop_housekeeping_thread_results.borrow_mut().remove(0); - self.housekeeping_thread_started = false; - result - } - - fn as_any(&self) -> &dyn Any { - self - } - } - - impl TransactorMock { - pub fn new(protocol: AutomapProtocol) -> Self { - Self { - housekeeping_thread_started: false, - protocol, - find_routers_results: RefCell::new(vec![]), - get_public_ip_params: Arc::new(Mutex::new(vec![])), - get_public_ip_results: RefCell::new(vec![]), - add_mapping_params: Arc::new(Mutex::new(vec![])), - add_mapping_results: RefCell::new(vec![]), - add_permanent_mapping_params: Arc::new(Mutex::new(vec![])), - add_permanent_mapping_results: RefCell::new(vec![]), - delete_mapping_params: Arc::new(Mutex::new(vec![])), - delete_mapping_results: RefCell::new(vec![]), - start_housekeeping_thread_params: Arc::new(Mutex::new(vec![])), - start_housekeeping_thread_results: RefCell::new(vec![]), - stop_housekeeping_thread_params: Arc::new(Mutex::new(vec![])), - stop_housekeeping_thread_results: RefCell::new(vec![]), - } - } - - pub fn find_routers_result(self, result: Result, AutomapError>) -> Self { - self.find_routers_results.borrow_mut().push(result); - self - } - - pub fn get_public_ip_params(mut self, params: &Arc>>) -> Self { - self.get_public_ip_params = params.clone(); - self - } - - pub fn get_public_ip_result(self, result: Result) -> Self { - self.get_public_ip_results.borrow_mut().push(result); - self - } - - pub fn add_mapping_params(mut self, params: &Arc>>) -> Self { - self.add_mapping_params = params.clone(); - self - } - - pub fn add_mapping_result(self, result: Result) -> Self { - self.add_mapping_results.borrow_mut().push(result); - self - } - - pub fn add_permanent_mapping_params( - mut self, - params: &Arc>>, - ) -> Self { - self.add_permanent_mapping_params = params.clone(); - self - } - - pub fn add_permanent_mapping_result(self, result: Result) -> Self { - self.add_permanent_mapping_results.borrow_mut().push(result); - self - } - - pub fn delete_mapping_params(mut self, params: &Arc>>) -> Self { - self.delete_mapping_params = params.clone(); - self - } - - pub fn delete_mapping_result(self, result: Result<(), AutomapError>) -> Self { - self.delete_mapping_results.borrow_mut().push(result); - self - } - - pub fn start_housekeeping_thread_result( - self, - result: Result, AutomapError>, - ) -> Self { - self.start_housekeeping_thread_results - .borrow_mut() - .push(result); - self - } - - pub fn start_housekeeping_thread_params( - mut self, - params: &Arc>>, - ) -> Self { - self.start_housekeeping_thread_params = params.clone(); - self - } - - pub fn stop_housekeeping_thread_params(mut self, params: &Arc>>) -> Self { - self.stop_housekeeping_thread_params = params.clone(); - self - } - - pub fn stop_housekeeping_thread_result( - self, - result: Result, - ) -> Self { - self.stop_housekeeping_thread_results - .borrow_mut() - .push(result); - self - } - } - fn choose_working_protocol_works_for_success(protocol: AutomapProtocol) { let mut subject = make_multirouter_specific_success_subject( protocol, @@ -1586,18 +1383,6 @@ mod tests { subject } - fn replace_transactor( - subject: AutomapControlReal, - transactor: Box, - ) -> AutomapControlReal { - let idx = AutomapControlReal::find_transactor_index( - subject.transactors.borrow_mut(), - transactor.protocol(), - ); - subject.transactors.borrow_mut()[idx] = transactor; - subject - } - fn assert_all_protocols_failed( result: Result, pcp: AutomapError, diff --git a/automap/src/lib.rs b/automap/src/lib.rs index 1a07282bf..ce95d5ef3 100644 --- a/automap/src/lib.rs +++ b/automap/src/lib.rs @@ -7,5 +7,4 @@ pub mod logger; pub mod probe_researcher; pub mod protocols; -#[cfg(test)] pub mod mocks; diff --git a/automap/src/mocks.rs b/automap/src/mocks.rs index e15f59a8e..5bfe23983 100644 --- a/automap/src/mocks.rs +++ b/automap/src/mocks.rs @@ -1,16 +1,31 @@ // Copyright (c) 2019-2021, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +#![cfg(any(test, not(feature = "no_test_share")))] + use crate::comm_layer::pcp_pmp_common::{ FindRoutersCommand, FreePortFactory, UdpSocketWrapper, UdpSocketWrapperFactory, }; -use crate::comm_layer::{AutomapError, LocalIpFinder}; +use crate::comm_layer::{AutomapError, HousekeepingThreadCommand, LocalIpFinder, Transactor}; +use crate::control_layer::automap_control::{ + replace_transactor, AutomapControlReal, ChangeHandler, +}; +use crossbeam_channel::Sender; +use lazy_static::lazy_static; +use masq_lib::utils::AutomapProtocol; +use std::any::Any; use std::cell::RefCell; use std::io::ErrorKind; use std::net::{IpAddr, SocketAddr}; +use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::Duration; use std::{io, thread}; +lazy_static! { + pub static ref ROUTER_IP: IpAddr = IpAddr::from_str("1.2.3.4").unwrap(); + pub static ref PUBLIC_IP: IpAddr = IpAddr::from_str("2.3.4.5").unwrap(); +} + pub struct LocalIpFinderMock { find_results: RefCell>>, } @@ -22,6 +37,7 @@ impl LocalIpFinder for LocalIpFinderMock { } impl LocalIpFinderMock { + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { find_results: RefCell::new(vec![]), @@ -34,6 +50,7 @@ impl LocalIpFinderMock { } } +#[allow(clippy::type_complexity)] pub struct UdpSocketWrapperMock { recv_from_params: Arc>>, recv_from_results: RefCell, Vec)>>, @@ -52,7 +69,7 @@ impl UdpSocketWrapper for UdpSocketWrapperMock { if !set_read_timeout_params_locked.is_empty() { let duration_opt = &set_read_timeout_params_locked[0]; match &duration_opt { - Some(duration) => thread::sleep(duration.clone()), + Some(duration) => thread::sleep(*duration), None => (), } } @@ -60,9 +77,7 @@ impl UdpSocketWrapper for UdpSocketWrapperMock { return Err(io::Error::from(ErrorKind::WouldBlock)); } let (result, bytes) = self.recv_from_results.borrow_mut().remove(0); - for n in 0..bytes.len() { - buf[n] = bytes[n]; - } + buf[..bytes.len()].clone_from_slice(&bytes[..]); result } @@ -81,6 +96,7 @@ impl UdpSocketWrapper for UdpSocketWrapperMock { } impl UdpSocketWrapperMock { + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { recv_from_params: Arc::new(Mutex::new(vec![])), @@ -102,6 +118,7 @@ impl UdpSocketWrapperMock { self } + #[allow(clippy::type_complexity)] pub fn send_to_params(mut self, params: &Arc, SocketAddr)>>>) -> Self { self.send_to_params = params.clone(); self @@ -136,6 +153,7 @@ impl UdpSocketWrapperFactory for UdpSocketWrapperFactoryMock { } impl UdpSocketWrapperFactoryMock { + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { make_params: Arc::new(Mutex::new(vec![])), @@ -168,6 +186,7 @@ impl FreePortFactory for FreePortFactoryMock { } impl FreePortFactoryMock { + #[allow(clippy::new_without_default)] pub fn new() -> Self { Self { make_results: RefCell::new(vec![]), @@ -200,3 +219,227 @@ impl FindRoutersCommandMock { } } } + +pub struct TransactorMock { + pub housekeeping_thread_started: bool, + protocol: AutomapProtocol, + find_routers_results: RefCell, AutomapError>>>, + get_public_ip_params: Arc>>, + get_public_ip_results: RefCell>>, + add_mapping_params: Arc>>, + add_mapping_results: RefCell>>, + add_permanent_mapping_params: Arc>>, + add_permanent_mapping_results: RefCell>>, + delete_mapping_params: Arc>>, + delete_mapping_results: RefCell>>, + start_housekeeping_thread_params: Arc>>, + start_housekeeping_thread_results: + RefCell, AutomapError>>>, + stop_housekeeping_thread_params: Arc>>, + stop_housekeeping_thread_results: RefCell>>, +} + +impl Transactor for TransactorMock { + fn find_routers(&self) -> Result, AutomapError> { + self.find_routers_results.borrow_mut().remove(0) + } + + fn get_public_ip(&self, router_ip: IpAddr) -> Result { + if !self.housekeeping_thread_started { + panic!("Housekeeping thread must be started before get_public_ip()") + } + self.get_public_ip_params.lock().unwrap().push(router_ip); + self.get_public_ip_results.borrow_mut().remove(0) + } + + fn add_mapping( + &self, + router_ip: IpAddr, + hole_port: u16, + lifetime: u32, + ) -> Result { + if !self.housekeeping_thread_started { + panic!("Housekeeping thread must be started before add_mapping()") + } + self.add_mapping_params + .lock() + .unwrap() + .push((router_ip, hole_port, lifetime)); + self.add_mapping_results.borrow_mut().remove(0) + } + + fn add_permanent_mapping( + &self, + router_ip: IpAddr, + hole_port: u16, + ) -> Result { + if !self.housekeeping_thread_started { + panic!("Housekeeping thread must be started before add_permanent_mapping()") + } + self.add_permanent_mapping_params + .lock() + .unwrap() + .push((router_ip, hole_port)); + self.add_permanent_mapping_results.borrow_mut().remove(0) + } + + fn delete_mapping(&self, router_ip: IpAddr, hole_port: u16) -> Result<(), AutomapError> { + self.delete_mapping_params + .lock() + .unwrap() + .push((router_ip, hole_port)); + self.delete_mapping_results.borrow_mut().remove(0) + } + + fn protocol(&self) -> AutomapProtocol { + self.protocol + } + + fn start_housekeeping_thread( + &mut self, + change_handler: ChangeHandler, + router_ip: IpAddr, + ) -> Result, AutomapError> { + self.start_housekeeping_thread_params + .lock() + .unwrap() + .push((change_handler, router_ip)); + let result = self + .start_housekeeping_thread_results + .borrow_mut() + .remove(0); + self.housekeeping_thread_started = true; + result + } + + fn stop_housekeeping_thread(&mut self) -> Result { + self.stop_housekeeping_thread_params + .lock() + .unwrap() + .push(()); + let result = self.stop_housekeeping_thread_results.borrow_mut().remove(0); + self.housekeeping_thread_started = false; + result + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +impl TransactorMock { + pub fn new(protocol: AutomapProtocol) -> Self { + Self { + housekeeping_thread_started: false, + protocol, + find_routers_results: RefCell::new(vec![]), + get_public_ip_params: Arc::new(Mutex::new(vec![])), + get_public_ip_results: RefCell::new(vec![]), + add_mapping_params: Arc::new(Mutex::new(vec![])), + add_mapping_results: RefCell::new(vec![]), + add_permanent_mapping_params: Arc::new(Mutex::new(vec![])), + add_permanent_mapping_results: RefCell::new(vec![]), + delete_mapping_params: Arc::new(Mutex::new(vec![])), + delete_mapping_results: RefCell::new(vec![]), + start_housekeeping_thread_params: Arc::new(Mutex::new(vec![])), + start_housekeeping_thread_results: RefCell::new(vec![]), + stop_housekeeping_thread_params: Arc::new(Mutex::new(vec![])), + stop_housekeeping_thread_results: RefCell::new(vec![]), + } + } + + pub fn find_routers_result(self, result: Result, AutomapError>) -> Self { + self.find_routers_results.borrow_mut().push(result); + self + } + + pub fn get_public_ip_params(mut self, params: &Arc>>) -> Self { + self.get_public_ip_params = params.clone(); + self + } + + pub fn get_public_ip_result(self, result: Result) -> Self { + self.get_public_ip_results.borrow_mut().push(result); + self + } + + #[allow(clippy::type_complexity)] + pub fn add_mapping_params(mut self, params: &Arc>>) -> Self { + self.add_mapping_params = params.clone(); + self + } + + pub fn add_mapping_result(self, result: Result) -> Self { + self.add_mapping_results.borrow_mut().push(result); + self + } + + pub fn add_permanent_mapping_params(mut self, params: &Arc>>) -> Self { + self.add_permanent_mapping_params = params.clone(); + self + } + + pub fn add_permanent_mapping_result(self, result: Result) -> Self { + self.add_permanent_mapping_results.borrow_mut().push(result); + self + } + + pub fn delete_mapping_params(mut self, params: &Arc>>) -> Self { + self.delete_mapping_params = params.clone(); + self + } + + pub fn delete_mapping_result(self, result: Result<(), AutomapError>) -> Self { + self.delete_mapping_results.borrow_mut().push(result); + self + } + + pub fn start_housekeeping_thread_result( + self, + result: Result, AutomapError>, + ) -> Self { + self.start_housekeeping_thread_results + .borrow_mut() + .push(result); + self + } + + pub fn start_housekeeping_thread_params( + mut self, + params: &Arc>>, + ) -> Self { + self.start_housekeeping_thread_params = params.clone(); + self + } + + pub fn stop_housekeeping_thread_params(mut self, params: &Arc>>) -> Self { + self.stop_housekeeping_thread_params = params.clone(); + self + } + + pub fn stop_housekeeping_thread_result( + self, + result: Result, + ) -> Self { + self.stop_housekeeping_thread_results + .borrow_mut() + .push(result); + self + } +} + +pub fn pmp_protocol_scenario_for_actor_system_factory_test( + sender: Sender, +) -> AutomapControlReal { + let change_handler = Box::new(|_| ()); + let subject = AutomapControlReal::new(None, change_handler); + let pcp_mock = TransactorMock::new(AutomapProtocol::Pcp).find_routers_result(Ok(vec![])); + let pmp_mock = TransactorMock::new(AutomapProtocol::Pmp) + .find_routers_result(Ok(vec![*ROUTER_IP])) + .start_housekeeping_thread_result(Ok(sender)) + .stop_housekeeping_thread_result(Ok(Box::new(|_| ()))) + .get_public_ip_result(Ok(*PUBLIC_IP)) + .add_mapping_result(Ok(1000)); + let subject = replace_transactor(subject, Box::new(pcp_mock)); + replace_transactor(subject, Box::new(pmp_mock)) +} diff --git a/node/Cargo.toml b/node/Cargo.toml index 292de9b7c..39e473866 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -13,7 +13,7 @@ members = ["../multinode_integration_tests", "../masq_lib", "../masq"] [dependencies] actix = "0.7.9" -automap = { path = "../automap" } +automap = { path = "../automap"} backtrace = "0.3.57" base64 = "0.13.0" bytes = "0.4.12" diff --git a/node/ci/build.sh b/node/ci/build.sh index 506487dbb..31e727204 100755 --- a/node/ci/build.sh +++ b/node/ci/build.sh @@ -3,5 +3,5 @@ CI_DIR="$( cd "$( dirname "$0" )" && pwd )" pushd "$CI_DIR/.." -cargo build --all --lib --bins --release --verbose --features masq_lib/no_test_share +cargo build --all --lib --bins --release --verbose --features masq_lib/no_test_share automap/no_test_share popd diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index 06c64ded8..8b70d5f22 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -1,6 +1,5 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use super::accountant::Accountant; -use super::bootstrapper; use super::bootstrapper::BootstrapperConfig; use super::dispatcher::Dispatcher; use super::hopper::Hopper; @@ -13,6 +12,7 @@ use super::stream_messages::PoolBindMessage; use super::ui_gateway::UiGateway; use crate::banned_dao::{BannedCacheLoader, BannedCacheLoaderReal}; use crate::blockchain::blockchain_bridge::BlockchainBridge; +use crate::bootstrapper::CryptdePair; use crate::database::db_initializer::{connection_or_panic, DbInitializer, DbInitializerReal}; use crate::database::db_migrations::MigratorConfig; use crate::db_config::persistent_configuration::PersistentConfiguration; @@ -49,7 +49,7 @@ pub trait ActorSystemFactory: Send { &self, config: BootstrapperConfig, actor_factory: Box, - persist_config: &dyn PersistentConfiguration, + persist_config: &mut dyn PersistentConfiguration, ) -> StreamHandlerPoolSubs; } @@ -62,13 +62,13 @@ impl ActorSystemFactory for ActorSystemFactoryReal { &self, config: BootstrapperConfig, actor_factory: Box, - persist_config: &dyn PersistentConfiguration, + persist_config: &mut dyn PersistentConfiguration, ) -> StreamHandlerPoolSubs { self.t .validate_database_chain(persist_config, config.blockchain_bridge_config.chain); - let (main_cryptde, alias_cryptde) = self.t.cryptdes(); + let cryptdes = self.t.cryptde_pair(); self.t - .prepare_initial_messages(main_cryptde, alias_cryptde, config, actor_factory) + .prepare_initial_messages(cryptdes, config, persist_config, actor_factory) } } @@ -81,12 +81,12 @@ impl ActorSystemFactoryReal { pub trait ActorSystemFactoryTools: Send { fn prepare_initial_messages( &self, - main_cryptde: &'static dyn CryptDE, - alias_cryptde: &'static dyn CryptDE, + cryptdes: CryptdePair, config: BootstrapperConfig, + persistent_config: &mut dyn PersistentConfiguration, actor_factory: Box, ) -> StreamHandlerPoolSubs; - fn cryptdes(&self) -> (&'static dyn CryptDE, &'static dyn CryptDE); + fn cryptde_pair(&self) -> CryptdePair; fn validate_database_chain( &self, persistent_config: &dyn PersistentConfiguration, @@ -101,20 +101,19 @@ pub struct ActorSystemFactoryToolsReal { impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { fn prepare_initial_messages( &self, - main_cryptde: &'static dyn CryptDE, - alias_cryptde: &'static dyn CryptDE, + cryptdes: CryptdePair, config: BootstrapperConfig, + persistent_config: &mut dyn PersistentConfiguration, actor_factory: Box, ) -> StreamHandlerPoolSubs { let db_initializer = DbInitializerReal::default(); - // make all the actors let (dispatcher_subs, pool_bind_sub) = actor_factory.make_and_start_dispatcher(&config); let proxy_server_subs = - actor_factory.make_and_start_proxy_server(main_cryptde, alias_cryptde, &config); + actor_factory.make_and_start_proxy_server(cryptdes.main, cryptdes.alias, &config); let proxy_client_subs_opt = if !config.neighborhood_config.mode.is_consume_only() { Some( actor_factory.make_and_start_proxy_client(ProxyClientConfig { - cryptde: main_cryptde, + cryptde: cryptdes.main, dns_servers: config.dns_servers.clone(), exit_service_rate: config .neighborhood_config @@ -129,8 +128,8 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { None }; let hopper_subs = actor_factory.make_and_start_hopper(HopperConfig { - main_cryptde, - alias_cryptde, + main_cryptde: cryptdes.main, + alias_cryptde: cryptdes.alias, per_routing_service: config .neighborhood_config .mode @@ -145,7 +144,7 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { crashable: is_crashable(&config), }); let blockchain_bridge_subs = actor_factory.make_and_start_blockchain_bridge(&config); - let neighborhood_subs = actor_factory.make_and_start_neighborhood(main_cryptde, &config); + let neighborhood_subs = actor_factory.make_and_start_neighborhood(cryptdes.main, &config); let accountant_subs = actor_factory.make_and_start_accountant( &config, &config.data_directory.clone(), @@ -199,6 +198,7 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { self.start_automap( &config, + persistent_config, vec![ peer_actors.neighborhood.new_public_ip.clone(), peer_actors.dispatcher.new_ip_sub.clone(), @@ -211,11 +211,8 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { stream_handler_pool_subs } - fn cryptdes(&self) -> (&'static dyn CryptDE, &'static dyn CryptDE) { - ( - bootstrapper::main_cryptde_ref(), - bootstrapper::alias_cryptde_ref(), - ) + fn cryptde_pair(&self) -> CryptdePair { + CryptdePair::default() } fn validate_database_chain( @@ -261,9 +258,29 @@ impl ActorSystemFactoryToolsReal { exit_process(1, &format!("Automap failure: {}{:?}", prefix, error)); } + fn maybe_write_protocol_down( + automap_control: &dyn AutomapControl, + persistent_config: &mut dyn PersistentConfiguration, + b_config_entry_opt: Option, + ) { + match (b_config_entry_opt, automap_control.get_mapping_protocol()) { + (Some(_), None) => { + unreachable!("get_public_ip would've returned AllProtocolsFailed first") + } + (old_protocol, new_protocol) => { + if old_protocol != new_protocol { + persistent_config + .set_mapping_protocol(new_protocol) + .expect("write of mapping protocol failed") + } + } + } + } + fn start_automap( &self, config: &BootstrapperConfig, + persistent_config: &mut dyn PersistentConfiguration, new_ip_recipients: Vec>, ) { if let NeighborhoodMode::Standard(node_addr, _, _) = &config.neighborhood_config.mode { @@ -290,6 +307,11 @@ impl ActorSystemFactoryToolsReal { return; // never happens; handle_automap_error doesn't return. } }; + Self::maybe_write_protocol_down( + automap_control.as_ref(), + persistent_config, + config.mapping_protocol_opt, + ); Self::notify_of_public_ip_change(new_ip_recipients.as_slice(), public_ip); node_addr.ports().iter().for_each(|port| { if let Err(e) = automap_control.add_mapping(*port) { @@ -566,7 +588,6 @@ mod tests { use crate::sub_lib::stream_handler_pool::TransmitDataMsg; use crate::sub_lib::ui_gateway::UiGatewayConfig; use crate::test_utils::automap_mocks::{AutomapControlFactoryMock, AutomapControlMock}; - use crate::test_utils::main_cryptde; use crate::test_utils::make_wallet; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::{ @@ -580,10 +601,13 @@ mod tests { make_populated_accountant_config_with_defaults, CleanUpMessage, DummyActor, }; use crate::test_utils::{alias_cryptde, rate_pack}; + use crate::test_utils::{main_cryptde, make_cryptde_pair}; use crate::{hopper, proxy_client, proxy_server, stream_handler_pool, ui_gateway}; use actix::{Actor, Arbiter, System}; use automap_lib::control_layer::automap_control::AutomapChange; - use crossbeam_channel::bounded; + #[cfg(all(test, not(feature = "no_test_share")))] + use automap_lib::mocks::pmp_protocol_scenario_for_actor_system_factory_test; + use crossbeam_channel::{bounded, unbounded}; use log::LevelFilter; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::crash_point::CrashPoint; @@ -591,6 +615,7 @@ mod tests { use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use masq_lib::ui_gateway::NodeFromUiMessage; use masq_lib::utils::running_test; + use masq_lib::utils::AutomapProtocol::Igdp; use std::cell::RefCell; use std::collections::HashMap; use std::convert::TryFrom; @@ -616,29 +641,29 @@ mod tests { >, >, prepare_initial_messages_results: RefCell>, - cryptdes_results: RefCell>, //first main, second alias + cryptde_pair_results: RefCell>, validate_database_chain_params: Arc>>, } impl ActorSystemFactoryTools for ActorSystemFactoryToolsMock { fn prepare_initial_messages( &self, - main_cryptde: &'static dyn CryptDE, - alias_cryptde: &'static dyn CryptDE, + cryptdes: CryptdePair, config: BootstrapperConfig, + _persistent_config: &mut dyn PersistentConfiguration, actor_factory: Box, ) -> StreamHandlerPoolSubs { self.prepare_initial_messages_params.lock().unwrap().push(( - Box::new(<&CryptDENull>::from(main_cryptde).clone()), - Box::new(<&CryptDENull>::from(alias_cryptde).clone()), + Box::new(<&CryptDENull>::from(cryptdes.main).clone()), + Box::new(<&CryptDENull>::from(cryptdes.alias).clone()), config, actor_factory, )); self.prepare_initial_messages_results.borrow_mut().remove(0) } - fn cryptdes(&self) -> (&'static dyn CryptDE, &'static dyn CryptDE) { - self.cryptdes_results.borrow_mut().remove(0) + fn cryptde_pair(&self) -> CryptdePair { + self.cryptde_pair_results.borrow_mut().remove(0) } fn validate_database_chain( @@ -657,8 +682,8 @@ mod tests { } impl ActorSystemFactoryToolsMock { - pub fn cryptdes_result(self, result: (&'static dyn CryptDE, &'static dyn CryptDE)) -> Self { - self.cryptdes_results.borrow_mut().push(result); + pub fn cryptdes_result(self, result: CryptdePair) -> Self { + self.cryptde_pair_results.borrow_mut().push(result); self } @@ -982,7 +1007,7 @@ mod tests { ), }, }; - let persistent_config = + let mut persistent_config = PersistentConfigurationMock::default().chain_name_result("eth-ropsten".to_string()); Bootstrapper::pub_initialize_cryptdes_for_testing( &Some(main_cryptde()), @@ -990,16 +1015,16 @@ mod tests { ); let mut tools = ActorSystemFactoryToolsReal::new(); tools.automap_control_factory = Box::new( - AutomapControlFactoryMock::new().make_result( + AutomapControlFactoryMock::new().make_result(Box::new( AutomapControlMock::new() .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) .add_mapping_result(Ok(())), - ), + )), ); let subject = ActorSystemFactoryReal::new(Box::new(tools)); let system = System::new("test"); - subject.make_and_start_actors(config, Box::new(actor_factory), &persistent_config); + subject.make_and_start_actors(config, Box::new(actor_factory), &mut persistent_config); System::current().stop(); system.run(); @@ -1043,7 +1068,7 @@ mod tests { node_descriptor: NodeDescriptor::try_from ((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap(), main_cryptde_null_opt: None, alias_cryptde_null_opt: None, - mapping_protocol_opt: None, + mapping_protocol_opt: Some(AutomapProtocol::Igdp), real_user: RealUser::null(), neighborhood_config: NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -1056,19 +1081,20 @@ mod tests { let add_mapping_params_arc = Arc::new(Mutex::new(vec![])); let mut subject = ActorSystemFactoryToolsReal::new(); subject.automap_control_factory = Box::new( - AutomapControlFactoryMock::new().make_result( + AutomapControlFactoryMock::new().make_result(Box::new( AutomapControlMock::new() .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) + .get_mapping_protocol_result(Some(AutomapProtocol::Igdp)) .add_mapping_params(&add_mapping_params_arc) .add_mapping_result(Ok(())) .add_mapping_result(Ok(())), - ), + )), ); let _ = subject.prepare_initial_messages( - main_cryptde(), - alias_cryptde(), + make_cryptde_pair(), config.clone(), + &mut PersistentConfigurationMock::new(), Box::new(actor_factory), ); @@ -1163,6 +1189,7 @@ mod tests { running_test(); let actor_factory = ActorFactoryMock::new(); let mut config = BootstrapperConfig::default(); + config.mapping_protocol_opt = Some(AutomapProtocol::Pcp); config.neighborhood_config = NeighborhoodConfig { mode: NeighborhoodMode::Standard( NodeAddr::new(&IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), &[1234]), @@ -1175,17 +1202,18 @@ mod tests { subject.automap_control_factory = Box::new( AutomapControlFactoryMock::new() .make_params(&make_params_arc) - .make_result( + .make_result(Box::new( AutomapControlMock::new() .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) + .get_mapping_protocol_result(Some(AutomapProtocol::Pcp)) .add_mapping_result(Ok(())), - ), + )), ); let _ = subject.prepare_initial_messages( - main_cryptde(), - alias_cryptde(), + make_cryptde_pair(), config.clone(), + &mut PersistentConfigurationMock::new(), Box::new(actor_factory), ); @@ -1198,6 +1226,87 @@ mod tests { system.run(); } + #[test] + fn automap_protocol_discovery_is_written_into_the_db_when_none_from_before() { + let set_mapping_protocol_params_arc = Arc::new(Mutex::new(vec![])); + let (tx, _rx) = unbounded(); + let mut config = BootstrapperConfig::default(); + config.neighborhood_config.mode = NeighborhoodMode::Standard( + NodeAddr::new(&IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), &[1234]), + vec![], + DEFAULT_RATE_PACK, + ); + let mut persistent_config = PersistentConfigurationMock::default() + .set_mapping_protocol_params(&set_mapping_protocol_params_arc) + .set_mapping_protocol_result(Ok(())); + let (recorder, _, _) = make_recorder(); + let new_ip_recipient = recorder.start().recipient(); + let automap_control: Box = + Box::new(pmp_protocol_scenario_for_actor_system_factory_test(tx)); + let automap_control_factory = + Box::new(AutomapControlFactoryMock::default().make_result(automap_control)); + let mut subject = ActorSystemFactoryToolsReal::new(); + subject.automap_control_factory = automap_control_factory; + + subject.start_automap(&config, &mut persistent_config, vec![new_ip_recipient]); + + let set_mapping_protocol_params = set_mapping_protocol_params_arc.lock().unwrap(); + assert_eq!( + *set_mapping_protocol_params, + vec![Some(AutomapProtocol::Pmp)] + ) + } + + #[test] + fn automap_protocol_discovery_is_not_set_if_indifferent_from_last_time() { + let config_entry = Some(AutomapProtocol::Igdp); + let automap_control = + AutomapControlMock::default().get_mapping_protocol_result(Some(AutomapProtocol::Igdp)); + + ActorSystemFactoryToolsReal::maybe_write_protocol_down( + &automap_control, + &mut PersistentConfigurationMock::new(), + config_entry, + ); + + //result for set_mapping_protocol not provided so it hasn't been required if no panic + } + + #[test] + fn automap_protocol_discovery_is_set_if_both_values_populated_but_different() { + let set_mapping_protocol_params_arc = Arc::new(Mutex::new(vec![])); + let mut persistent_config = PersistentConfigurationMock::new() + .set_mapping_protocol_params(&set_mapping_protocol_params_arc) + .set_mapping_protocol_result(Ok(())); + let config_entry = Some(AutomapProtocol::Pmp); + let automap_control = + AutomapControlMock::default().get_mapping_protocol_result(Some(AutomapProtocol::Igdp)); + + ActorSystemFactoryToolsReal::maybe_write_protocol_down( + &automap_control, + &mut persistent_config, + config_entry, + ); + + let set_mapping_protocol_params = set_mapping_protocol_params_arc.lock().unwrap(); + assert_eq!(*set_mapping_protocol_params, vec![Some(Igdp)]) + } + + #[test] + #[should_panic( + expected = "entered unreachable code: get_public_ip would've returned AllProtocolsFailed first" + )] + fn automap_usual_protocol_with_some_and_then_none_is_not_possible() { + let config_entry = Some(AutomapProtocol::Pmp); + let automap_control = AutomapControlMock::default().get_mapping_protocol_result(None); + + ActorSystemFactoryToolsReal::maybe_write_protocol_down( + &automap_control, + &mut PersistentConfigurationMock::default(), + config_entry, + ); + } + #[test] fn prepare_initial_messages_doesnt_start_up_proxy_client_or_automap_if_consume_only_mode() { let actor_factory = ActorFactoryMock::new(); @@ -1234,9 +1343,9 @@ mod tests { subject.automap_control_factory = Box::new(AutomapControlFactoryMock::new()); let _ = subject.prepare_initial_messages( - main_cryptde(), - alias_cryptde(), + make_cryptde_pair(), config.clone(), + &mut PersistentConfigurationMock::new(), Box::new(actor_factory), ); @@ -1257,7 +1366,7 @@ mod tests { #[test] fn start_automap_aborts_if_neighborhood_mode_is_standard_and_public_ip_is_supplied() { let mut subject = ActorSystemFactoryToolsReal::new(); - let automap_control = AutomapControlMock::new(); + let automap_control = Box::new(AutomapControlMock::new()); subject.automap_control_factory = Box::new(AutomapControlFactoryMock::new().make_result(automap_control)); let mut config = BootstrapperConfig::default(); @@ -1269,7 +1378,11 @@ mod tests { let (recorder, _, _) = make_recorder(); let new_ip_recipient = recorder.start().recipient(); - subject.start_automap(&config, vec![new_ip_recipient]); + subject.start_automap( + &config, + &mut PersistentConfigurationMock::new(), + vec![new_ip_recipient], + ); // no not-enough-results-provided error: test passes } @@ -1280,9 +1393,14 @@ mod tests { running_test(); let mut subject = ActorSystemFactoryToolsReal::new(); let make_params_arc = Arc::new(Mutex::new(vec![])); - let automap_control = AutomapControlMock::new() - .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) - .add_mapping_result(Ok(())); + let mut persistent_configuration = + PersistentConfigurationMock::new().set_mapping_protocol_result(Ok(())); + let automap_control = Box::new( + AutomapControlMock::new() + .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) + .get_mapping_protocol_result(Some(AutomapProtocol::Pmp)) + .add_mapping_result(Ok(())), + ); subject.automap_control_factory = Box::new( AutomapControlFactoryMock::new() .make_params(&make_params_arc) @@ -1296,7 +1414,7 @@ mod tests { DEFAULT_RATE_PACK, ); - subject.start_automap(&config, vec![]); + subject.start_automap(&config, &mut persistent_configuration, vec![]); let make_params = make_params_arc.lock().unwrap(); assert_eq!(make_params[0].0, None); @@ -1314,8 +1432,10 @@ mod tests { fn start_automap_change_handler_handles_get_public_ip_errors_properly() { running_test(); let mut subject = ActorSystemFactoryToolsReal::new(); - let automap_control = AutomapControlMock::new() - .get_public_ip_result(Err(AutomapError::AllProtocolsFailed(vec![]))); + let automap_control = Box::new( + AutomapControlMock::new() + .get_public_ip_result(Err(AutomapError::AllProtocolsFailed(vec![]))), + ); subject.automap_control_factory = Box::new(AutomapControlFactoryMock::new().make_result(automap_control)); let mut config = BootstrapperConfig::default(); @@ -1326,7 +1446,7 @@ mod tests { DEFAULT_RATE_PACK, ); - subject.start_automap(&config, vec![]); + subject.start_automap(&config, &mut PersistentConfigurationMock::new(), vec![]); let system = System::new("test"); System::current().stop(); @@ -1340,9 +1460,14 @@ mod tests { fn start_automap_change_handler_handles_initial_mapping_error_properly() { running_test(); let mut subject = ActorSystemFactoryToolsReal::new(); - let automap_control = AutomapControlMock::new() - .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) - .add_mapping_result(Err(AutomapError::AllProtocolsFailed(vec![]))); + let mut persistent_config = + PersistentConfigurationMock::new().set_mapping_protocol_result(Ok(())); + let automap_control = Box::new( + AutomapControlMock::new() + .get_public_ip_result(Ok(IpAddr::from_str("1.2.3.4").unwrap())) + .get_mapping_protocol_result(Some(AutomapProtocol::Pcp)) + .add_mapping_result(Err(AutomapError::AllProtocolsFailed(vec![]))), + ); subject.automap_control_factory = Box::new(AutomapControlFactoryMock::new().make_result(automap_control)); let mut config = BootstrapperConfig::default(); @@ -1353,7 +1478,7 @@ mod tests { DEFAULT_RATE_PACK, ); - subject.start_automap(&config, vec![]); + subject.start_automap(&config, &mut persistent_config, vec![]); let system = System::new("test"); System::current().stop(); @@ -1400,9 +1525,9 @@ mod tests { let system = System::new("MASQNode"); let _ = subject.prepare_initial_messages( - main_cryptde(), - alias_cryptde(), + make_cryptde_pair(), config.clone(), + &mut PersistentConfigurationMock::new(), Box::new(actor_factory), ); @@ -1599,7 +1724,7 @@ mod tests { fn make_and_start_actors_does_not_tolerate_differences_in_setup_chain_and_database_chain() { let mut bootstrapper_config = BootstrapperConfig::new(); bootstrapper_config.blockchain_bridge_config.chain = TEST_DEFAULT_CHAIN; - let persistent_config = + let mut persistent_config = PersistentConfigurationMock::default().chain_name_result("eth-mainnet".to_string()); Bootstrapper::pub_initialize_cryptdes_for_testing( &Some(main_cryptde().clone()), @@ -1610,7 +1735,7 @@ mod tests { let _ = subject.make_and_start_actors( bootstrapper_config, Box::new(ActorFactoryReal {}), - &persistent_config, + &mut persistent_config, ); } @@ -1632,13 +1757,16 @@ mod tests { let alias_cryptde_public_key_before = public_key_for_dyn_cryptde_being_null(alias_cryptde); let actor_factory = Box::new(ActorFactoryReal {}) as Box; let actor_factory_raw_address = addr_of!(*actor_factory); - let persistent_config = PersistentConfigurationMock::default() + let mut persistent_config = PersistentConfigurationMock::default() .chain_name_params(&chain_name_params_arc) .chain_name_result( "believe or not, supplied for nothing but prevention of panicking".to_string(), ); let tools = ActorSystemFactoryToolsMock::default() - .cryptdes_result((main_cryptde, alias_cryptde)) + .cryptdes_result(CryptdePair { + main: main_cryptde, + alias: alias_cryptde, + }) .validate_database_chain_params(&database_chain_assertion_params_arc) .prepare_initial_messages_params(&prepare_initial_messages_params_arc) .prepare_initial_messages_result(stream_holder_pool_subs); @@ -1647,7 +1775,7 @@ mod tests { let result = subject.make_and_start_actors( bootstrapper_config, Box::new(ActorFactoryReal {}), - &persistent_config, + &mut persistent_config, ); let database_chain_assertion_params = database_chain_assertion_params_arc.lock().unwrap(); diff --git a/node/src/bootstrapper.rs b/node/src/bootstrapper.rs index 6ddab3bb0..b28a4d781 100644 --- a/node/src/bootstrapper.rs +++ b/node/src/bootstrapper.rs @@ -60,7 +60,7 @@ use tokio::prelude::Stream; static mut MAIN_CRYPTDE_BOX_OPT: Option> = None; static mut ALIAS_CRYPTDE_BOX_OPT: Option> = None; -pub fn main_cryptde_ref<'a>() -> &'a dyn CryptDE { +fn main_cryptde_ref<'a>() -> &'a dyn CryptDE { unsafe { MAIN_CRYPTDE_BOX_OPT .as_ref() @@ -69,7 +69,7 @@ pub fn main_cryptde_ref<'a>() -> &'a dyn CryptDE { } } -pub fn alias_cryptde_ref<'a>() -> &'a dyn CryptDE { +fn alias_cryptde_ref<'a>() -> &'a dyn CryptDE { unsafe { ALIAS_CRYPTDE_BOX_OPT .as_ref() @@ -78,6 +78,20 @@ pub fn alias_cryptde_ref<'a>() -> &'a dyn CryptDE { } } +pub struct CryptdePair { + pub main: &'static dyn CryptDE, + pub alias: &'static dyn CryptDE, +} + +impl Default for CryptdePair { + fn default() -> Self { + CryptdePair { + main: main_cryptde_ref(), + alias: alias_cryptde_ref(), + } + } +} + #[derive(Clone, Debug)] pub struct PortConfiguration { pub discriminator_factories: Vec>, @@ -457,13 +471,13 @@ impl ConfiguredByPrivilege for Bootstrapper { self.config.merge_unprivileged(unprivileged_config); let _ = self.set_up_clandestine_port(); let (alias_cryptde_null_opt, main_cryptde_null_opt) = self.null_cryptdes_as_trait_objects(); - let (cryptde_ref, _) = Bootstrapper::initialize_cryptdes( + let cryptdes = Bootstrapper::initialize_cryptdes( &main_cryptde_null_opt, &alias_cryptde_null_opt, self.config.blockchain_bridge_config.chain, ); let node_descriptor = Bootstrapper::make_local_descriptor( - cryptde_ref, + cryptdes.main, self.config.neighborhood_config.mode.node_addr_opt(), self.config.blockchain_bridge_config.chain, ); @@ -474,7 +488,7 @@ impl ConfiguredByPrivilege for Bootstrapper { match &self.config.neighborhood_config.mode { NeighborhoodMode::Standard(node_addr, _, _) if node_addr.ip_addr() == Ipv4Addr::new(0, 0, 0, 0) => {} // node_addr still coming - _ => Bootstrapper::report_local_descriptor(cryptde_ref, &self.config.node_descriptor), // here or not coming + _ => Bootstrapper::report_local_descriptor(cryptdes.main, &self.config.node_descriptor), // here or not coming } let stream_handler_pool_subs = self.actor_system_factory.make_and_start_actors( self.config.clone(), @@ -484,7 +498,7 @@ impl ConfiguredByPrivilege for Bootstrapper { false, MigratorConfig::panic_on_migration(), ) - .as_ref(), + .as_mut(), ); self.listener_handlers @@ -509,10 +523,10 @@ impl Bootstrapper { } #[cfg(test)] // The real ones are private, but ActorSystemFactory needs to use them for testing - pub fn pub_initialize_cryptdes_for_testing<'a, 'b>( + pub fn pub_initialize_cryptdes_for_testing( main_cryptde_null_opt: &Option<&dyn CryptDE>, alias_cryptde_null_opt: &Option<&dyn CryptDE>, - ) -> (&'a dyn CryptDE, &'b dyn CryptDE) { + ) -> CryptdePair { Self::initialize_cryptdes( main_cryptde_null_opt, alias_cryptde_null_opt, @@ -520,11 +534,11 @@ impl Bootstrapper { ) } - fn initialize_cryptdes<'a, 'b>( + fn initialize_cryptdes( main_cryptde_null_opt: &Option<&dyn CryptDE>, alias_cryptde_null_opt: &Option<&dyn CryptDE>, chain: Chain, - ) -> (&'a dyn CryptDE, &'b dyn CryptDE) { + ) -> CryptdePair { unsafe { Self::initialize_single_cryptde(main_cryptde_null_opt, &mut MAIN_CRYPTDE_BOX_OPT, chain) }; @@ -535,7 +549,7 @@ impl Bootstrapper { chain, ) } - (main_cryptde_ref(), alias_cryptde_ref()) + CryptdePair::default() } fn initialize_single_cryptde( @@ -1429,12 +1443,12 @@ mod tests { #[test] fn initialize_cryptde_without_cryptde_null_uses_cryptde_real() { let _lock = INITIALIZATION.lock(); - let (cryptde_init, _) = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); + let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); - assert_eq!(main_cryptde_ref().public_key(), cryptde_init.public_key()); + assert_eq!(main_cryptde_ref().public_key(), cryptdes.main.public_key()); // Brittle assertion: this may not be true forever let cryptde_null = main_cryptde(); - assert!(cryptde_init.public_key().len() > cryptde_null.public_key().len()); + assert!(cryptdes.main.public_key().len() > cryptde_null.public_key().len()); } #[test] @@ -1443,11 +1457,11 @@ mod tests { let cryptde_null = main_cryptde().clone(); let cryptde_null_public_key = cryptde_null.public_key().clone(); - let (cryptde, _) = + let cryptdes = Bootstrapper::initialize_cryptdes(&Some(cryptde_null), &None, TEST_DEFAULT_CHAIN); - assert_eq!(cryptde.public_key(), &cryptde_null_public_key); - assert_eq!(main_cryptde_ref().public_key(), cryptde.public_key()); + assert_eq!(cryptdes.main.public_key(), &cryptde_null_public_key); + assert_eq!(main_cryptde_ref().public_key(), cryptdes.main.public_key()); } #[test] @@ -1459,16 +1473,15 @@ mod tests { &[3456u16, 4567u16], ); let cryptde_ref = { - let (cryptde_ref, _) = - Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); + let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); let descriptor = Bootstrapper::make_local_descriptor( - cryptde_ref, + cryptdes.main, Some(node_addr), TEST_DEFAULT_CHAIN, ); - Bootstrapper::report_local_descriptor(cryptde_ref, &descriptor); + Bootstrapper::report_local_descriptor(cryptdes.main, &descriptor); - cryptde_ref + cryptdes.main }; let expected_descriptor = format!( "masq://eth-ropsten:{}@2.3.4.5:3456/4567", @@ -1502,18 +1515,19 @@ mod tests { fn initialize_cryptdes_and_report_local_descriptor_without_ip_address() { let _lock = INITIALIZATION.lock(); init_test_logging(); - let (main_cryptde_ref, alias_cryptde_ref) = { - let (main_cryptde_ref, alias_cryptde_ref) = - Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); + let cryptdes = { + let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); let descriptor = - Bootstrapper::make_local_descriptor(main_cryptde_ref, None, TEST_DEFAULT_CHAIN); - Bootstrapper::report_local_descriptor(main_cryptde_ref, &descriptor); + Bootstrapper::make_local_descriptor(cryptdes.main, None, TEST_DEFAULT_CHAIN); + Bootstrapper::report_local_descriptor(cryptdes.main, &descriptor); - (main_cryptde_ref, alias_cryptde_ref) + cryptdes }; let expected_descriptor = format!( "masq://eth-ropsten:{}@:", - main_cryptde_ref.public_key_to_descriptor_fragment(main_cryptde_ref.public_key()) + cryptdes + .main + .public_key_to_descriptor_fragment(cryptdes.main.public_key()) ); TestLogHandler::new().exists_log_containing( format!( @@ -1539,8 +1553,8 @@ mod tests { )); assert_eq!(decrypted_data, expected_data) }; - assert_round_trip(main_cryptde_ref); - assert_round_trip(alias_cryptde_ref); + assert_round_trip(cryptdes.main); + assert_round_trip(cryptdes.alias); } #[test] @@ -2074,7 +2088,7 @@ mod tests { &self, config: BootstrapperConfig, _actor_factory: Box, - _persist_config: &dyn PersistentConfiguration, + _persist_config: &mut dyn PersistentConfiguration, ) -> StreamHandlerPoolSubs { let mut parameter_guard = self.dnss.lock().unwrap(); let parameter_ref = parameter_guard.deref_mut(); diff --git a/node/src/test_utils/automap_mocks.rs b/node/src/test_utils/automap_mocks.rs index c2278eb33..93f33024f 100644 --- a/node/src/test_utils/automap_mocks.rs +++ b/node/src/test_utils/automap_mocks.rs @@ -11,7 +11,7 @@ use std::sync::{Arc, Mutex}; #[allow(clippy::type_complexity)] pub struct AutomapControlFactoryMock { make_params: Arc, ChangeHandler)>>>, - make_results: RefCell>, + make_results: RefCell>>, } impl AutomapControlFactory for AutomapControlFactoryMock { @@ -24,7 +24,7 @@ impl AutomapControlFactory for AutomapControlFactoryMock { .lock() .unwrap() .push((usual_protocol_opt, change_handler)); - Box::new(self.make_results.borrow_mut().remove(0)) + self.make_results.borrow_mut().remove(0) } } @@ -51,7 +51,7 @@ impl AutomapControlFactoryMock { self } - pub fn make_result(self, result: AutomapControlMock) -> Self { + pub fn make_result(self, result: Box) -> Self { self.make_results.borrow_mut().push(result); self } diff --git a/node/src/test_utils/mod.rs b/node/src/test_utils/mod.rs index cde71c74d..66a2ce92a 100644 --- a/node/src/test_utils/mod.rs +++ b/node/src/test_utils/mod.rs @@ -17,6 +17,7 @@ pub mod tokio_wrapper_mocks; use crate::blockchain::bip32::Bip32ECKeyProvider; use crate::blockchain::payer::Payer; +use crate::bootstrapper::CryptdePair; use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::cryptde::CryptData; use crate::sub_lib::cryptde::PlainData; @@ -74,6 +75,13 @@ pub fn alias_cryptde() -> &'static dyn CryptDE { ALIAS_CRYPTDE_NULL.as_ref() } +pub fn make_cryptde_pair() -> CryptdePair { + CryptdePair { + main: main_cryptde(), + alias: alias_cryptde(), + } +} + pub struct ArgsBuilder { args: Vec, }