diff --git a/masq_lib/src/blockchains/chains.rs b/masq_lib/src/blockchains/chains.rs index b7733b8427..c8f4a1ab70 100644 --- a/masq_lib/src/blockchains/chains.rs +++ b/masq_lib/src/blockchains/chains.rs @@ -7,6 +7,7 @@ use crate::constants::{ POLYGON_AMOY_FULL_IDENTIFIER, POLYGON_MAINNET_FULL_IDENTIFIER, }; use serde_derive::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum Chain { @@ -47,6 +48,21 @@ impl From<&str> for Chain { } } +impl Display for Chain { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let chain_name = match self { + Chain::EthMainnet => ETH_MAINNET_FULL_IDENTIFIER, + Chain::EthRopsten => ETH_ROPSTEN_FULL_IDENTIFIER, + Chain::PolyMainnet => POLYGON_MAINNET_FULL_IDENTIFIER, + Chain::PolyAmoy => POLYGON_AMOY_FULL_IDENTIFIER, + Chain::BaseMainnet => BASE_MAINNET_FULL_IDENTIFIER, + Chain::BaseSepolia => BASE_SEPOLIA_FULL_IDENTIFIER, + Chain::Dev => DEV_CHAIN_FULL_IDENTIFIER, + }; + write!(f, "{}", chain_name) + } +} + impl Chain { pub fn rec(&self) -> &BlockchainRecord { CHAINS @@ -158,6 +174,37 @@ mod tests { }) } + #[test] + fn display_is_properly_implemented() { + let chains = [ + Chain::EthMainnet, + Chain::EthRopsten, + Chain::PolyMainnet, + Chain::PolyAmoy, + Chain::BaseMainnet, + Chain::BaseSepolia, + Chain::Dev, + ]; + + let strings = chains + .iter() + .map(|chain| chain.to_string()) + .collect::>(); + + assert_eq!( + strings, + vec![ + ETH_MAINNET_FULL_IDENTIFIER.to_string(), + ETH_ROPSTEN_FULL_IDENTIFIER.to_string(), + POLYGON_MAINNET_FULL_IDENTIFIER.to_string(), + POLYGON_AMOY_FULL_IDENTIFIER.to_string(), + BASE_MAINNET_FULL_IDENTIFIER.to_string(), + BASE_SEPOLIA_FULL_IDENTIFIER.to_string(), + DEV_CHAIN_FULL_IDENTIFIER.to_string(), + ] + ); + } + fn assert_mainnet_exist() { assert!(CHAINS .iter() diff --git a/masq_lib/src/constants.rs b/masq_lib/src/constants.rs index e1e4c0fe40..6beea57487 100644 --- a/masq_lib/src/constants.rs +++ b/masq_lib/src/constants.rs @@ -5,7 +5,7 @@ use crate::data_version::DataVersion; use const_format::concatcp; pub const DEFAULT_CHAIN: Chain = Chain::PolyMainnet; -pub const CURRENT_SCHEMA_VERSION: usize = 10; +pub const CURRENT_SCHEMA_VERSION: usize = 11; pub const HIGHEST_RANDOM_CLANDESTINE_PORT: u16 = 9999; pub const HTTP_PORT: u16 = 80; diff --git a/masq_lib/src/test_utils/environment_guard.rs b/masq_lib/src/test_utils/environment_guard.rs index e19c52278b..c43174fb06 100644 --- a/masq_lib/src/test_utils/environment_guard.rs +++ b/masq_lib/src/test_utils/environment_guard.rs @@ -3,9 +3,11 @@ use lazy_static::lazy_static; use std::ffi::OsString; use std::sync::{Mutex, MutexGuard}; +use std::thread::ThreadId; lazy_static! { static ref ENVIRONMENT_GUARD_MUTEX: Mutex<()> = Mutex::new(()); + static ref ENVIRONMENT_GUARD_THREAD_ID: Mutex> = Mutex::new(None); static ref CLAP_GUARD_MUTEX: Mutex<()> = Mutex::new(()); static ref LOGFILE_NAME_GUARD_MUTEX: Mutex<()> = Mutex::new(()); } @@ -17,10 +19,9 @@ pub struct ConcurrencyPreventer<'a> { impl<'a> ConcurrencyPreventer<'a> { pub fn new(mutex: &'a Mutex<()>) -> ConcurrencyPreventer<'a> { ConcurrencyPreventer { - _lock: match mutex.lock() { - Ok(guard) => guard, - Err(poisoned) => poisoned.into_inner(), - }, + _lock: mutex + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()), } } } @@ -43,16 +44,50 @@ impl<'a> Drop for EnvironmentGuard<'a> { self.environment .iter() .for_each(|(name, value)| std::env::set_var(name, value)); + let mut thread_id_guard = ENVIRONMENT_GUARD_THREAD_ID + .lock() + .unwrap_or_else(|e| e.into_inner()); + *thread_id_guard = None; // Clear the thread ID guard } } impl<'a> EnvironmentGuard<'a> { pub fn new() -> EnvironmentGuard<'a> { - EnvironmentGuard { - _preventer: ConcurrencyPreventer::new(&ENVIRONMENT_GUARD_MUTEX), - environment: std::env::vars_os().collect(), + // TODO: Consider a #[cfg(not(test))] line here to panic if production code tries this + loop { + { + let mut thread_id_guard = Self::thread_id_guard(); + let current_thread_id = std::thread::current().id(); + match *thread_id_guard { + Some(id) => { + if id == current_thread_id { + panic!( + "Thread {:?} is trying to claim multiple EnvironmentGuards", + current_thread_id + ); + } + } + None => { + // Set thread ID, claim environment guard, release thread ID lock + *thread_id_guard = Some(current_thread_id); + return EnvironmentGuard { + _preventer: ConcurrencyPreventer::new(&ENVIRONMENT_GUARD_MUTEX), + environment: std::env::vars_os().collect(), + }; + } + } + } + // Somebody else has the EnvironmentGuard. We've released the thread ID lock; now + // wait for a little while and try again. + std::thread::sleep(std::time::Duration::from_millis(10)); } } + + pub fn thread_id_guard() -> MutexGuard<'a, Option> { + ENVIRONMENT_GUARD_THREAD_ID + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()) + } } impl<'a> Default for EnvironmentGuard<'a> { diff --git a/multinode_integration_tests/src/masq_node_server.rs b/multinode_integration_tests/src/masq_node_server.rs index 15b4792fd4..d1edb91164 100644 --- a/multinode_integration_tests/src/masq_node_server.rs +++ b/multinode_integration_tests/src/masq_node_server.rs @@ -2,23 +2,24 @@ use crate::masq_node_cluster::DockerHostSocketAddr; use crate::utils; -use std::io; +use crossbeam_channel::{unbounded, Receiver, Sender}; use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream}; use std::time::Duration; +use std::{io, thread}; pub struct MASQNodeServer { + docker_host_addr: Option, local_addr: SocketAddr, - listener: TcpListener, stream_opt: Option, } impl MASQNodeServer { pub fn new(port: u16) -> MASQNodeServer { - let socket_addr = DockerHostSocketAddr::new(port); - let listener = TcpListener::bind(socket_addr).unwrap(); + let dummy_listener = TcpListener::bind(DockerHostSocketAddr::new(port)).unwrap(); + let local_addr = dummy_listener.local_addr().unwrap(); MASQNodeServer { - local_addr: listener.local_addr().unwrap(), - listener, + docker_host_addr: Some(DockerHostSocketAddr::new(port)), + local_addr, stream_opt: None, } } @@ -37,10 +38,17 @@ impl MASQNodeServer { pub fn wait_for_chunk(&mut self, duration: Duration) -> Result, io::Error> { match &mut self.stream_opt { None => { - let (stream, _) = self.listener.accept().unwrap(); - stream - .set_read_timeout(Some(Duration::from_millis(250))) - .unwrap(); + let (tx, rx): (Sender, Receiver) = unbounded(); + let local_addr = self.docker_host_addr.take().unwrap(); + let listener = TcpListener::bind(local_addr).unwrap(); + thread::spawn(move || { + let (stream, _) = listener.accept().unwrap(); + stream + .set_read_timeout(Some(Duration::from_millis(250))) + .unwrap(); + tx.send(stream).unwrap(); + }); + let stream = rx.recv_timeout(duration).unwrap(); self.stream_opt = Some(stream); self.wait_for_chunk(duration) } diff --git a/multinode_integration_tests/tests/bookkeeping_test.rs b/multinode_integration_tests/tests/bookkeeping_test.rs index 6c7552eae4..36d07bad6b 100644 --- a/multinode_integration_tests/tests/bookkeeping_test.rs +++ b/multinode_integration_tests/tests/bookkeeping_test.rs @@ -29,13 +29,13 @@ fn provided_and_consumed_services_are_recorded_in_databases() { let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); client.set_timeout(Duration::from_secs(10)); - let request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".as_bytes(); + let request = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n".as_bytes(); client.send_chunk(request); let response = String::from_utf8(client.wait_for_chunk()).unwrap(); assert!( response.contains("

Example Domain

"), - "Not from example.com:\n{}", + "Not from www.example.com:\n{}", response ); @@ -112,6 +112,7 @@ pub fn start_real_node(cluster: &mut MASQNodeCluster, neighbor: NodeReference) - let index = cluster.next_index(); cluster.start_real_node( NodeStartupConfigBuilder::standard() + .db_password(None) .neighbor(neighbor) .earning_wallet_info(make_earning_wallet_info(&index.to_string())) .chain(cluster.chain) diff --git a/multinode_integration_tests/tests/communication_failure_test.rs b/multinode_integration_tests/tests/communication_failure_test.rs index 65d31dd4fc..6b82383f1c 100644 --- a/multinode_integration_tests/tests/communication_failure_test.rs +++ b/multinode_integration_tests/tests/communication_failure_test.rs @@ -103,7 +103,7 @@ fn neighborhood_notified_of_newly_missing_node() { //Establish a client on the originating Node and send some ill-fated traffic. let mut client = originating_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS); - client.send_chunk("GET http://example.com HTTP/1.1\r\n\r\n".as_bytes()); + client.send_chunk("GET http://www.example.com HTTP/1.1\r\n\r\n".as_bytes()); // Now direct the witness Node to wait for Gossip about the disappeared Node. let (disappearance_gossip, _) = witness_node @@ -236,6 +236,7 @@ fn dns_resolution_failure_with_real_nodes() { let mut cluster = MASQNodeCluster::start().unwrap(); let first_node = cluster.start_real_node( NodeStartupConfigBuilder::standard() + .db_password(None) .consuming_wallet_info(make_consuming_wallet_info("first_node")) .chain(cluster.chain) .build(), @@ -244,6 +245,7 @@ fn dns_resolution_failure_with_real_nodes() { .map(|_| { cluster.start_real_node( NodeStartupConfigBuilder::standard() + .db_password(None) .neighbor(first_node.node_reference()) .chain(cluster.chain) .build(), @@ -280,6 +282,7 @@ fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { let mut cluster = MASQNodeCluster::start().unwrap(); let exit_node = cluster.start_real_node( NodeStartupConfigBuilder::standard() + .db_password(None) .chain(cluster.chain) .consuming_wallet_info(make_consuming_wallet_info("exit_node")) .dns_servers(vec![dns_server_that_fails]) @@ -287,6 +290,7 @@ fn dns_resolution_failure_for_wildcard_ip_with_real_nodes() { ); let originating_node = cluster.start_real_node( NodeStartupConfigBuilder::standard() + .db_password(None) .neighbor(exit_node.node_reference()) .consuming_wallet_info(make_consuming_wallet_info("originating_node")) .chain(cluster.chain) @@ -405,7 +409,7 @@ fn dns_resolution_failure_no_longer_blacklists_exit_node_for_all_hosts() { ), ); - client.send_chunk("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".as_bytes()); + client.send_chunk("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n".as_bytes()); let cheapest_node = node_list.first().unwrap(); let cheapest_node_expired_cores_package = cheapest_node .wait_for_specific_package( diff --git a/multinode_integration_tests/tests/connection_progress_test.rs b/multinode_integration_tests/tests/connection_progress_test.rs index 023ad4c880..336cef2c22 100644 --- a/multinode_integration_tests/tests/connection_progress_test.rs +++ b/multinode_integration_tests/tests/connection_progress_test.rs @@ -18,10 +18,15 @@ fn connection_progress_is_properly_broadcast() { let ui_port = find_free_port(); let mut cluster = MASQNodeCluster::start().unwrap(); // Set up small preexisting network that is much too small to route - let relay_2 = cluster.start_real_node(NodeStartupConfigBuilder::standard().build()); + let relay_2 = cluster.start_real_node( + NodeStartupConfigBuilder::standard() + .db_password(Some("relay_2")) + .build(), + ); let relay_1 = cluster.start_real_node( NodeStartupConfigBuilder::standard() .neighbor(relay_2.node_reference()) + .db_password(Some("relay_1")) .build(), ); // Set up Node from which we will get connection-progress information @@ -32,6 +37,7 @@ fn connection_progress_is_properly_broadcast() { "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF".to_string(), )) .neighbor(relay_1.node_reference()) + .db_password(Some("subject")) .ui_port(ui_port) .build(), ); @@ -40,10 +46,11 @@ fn connection_progress_is_properly_broadcast() { // Hook up enough new Nodes to make the subject fully connected let _additional_nodes = (0..3) .into_iter() - .map(|_| { + .map(|i| { cluster.start_real_node( NodeStartupConfigBuilder::standard() .neighbor(relay_2.node_reference()) + .db_password(Some(format!("additional_{}", i).as_str())) .build(), ) }) diff --git a/multinode_integration_tests/tests/data_routing_test.rs b/multinode_integration_tests/tests/data_routing_test.rs index cdefcd354e..98dd460a11 100644 --- a/multinode_integration_tests/tests/data_routing_test.rs +++ b/multinode_integration_tests/tests/data_routing_test.rs @@ -175,7 +175,7 @@ fn tls_end_to_end_routing_test() { .expect("Could not set read timeout to 1000ms"); let connector = TlsConnector::new().expect("Could not build TlsConnector"); match connector.connect( - "example.com", + "www.example.com", stream.try_clone().expect("Couldn't clone TcpStream"), ) { Ok(s) => { @@ -199,7 +199,7 @@ fn tls_end_to_end_routing_test() { tls_stream.expect("Couldn't handshake") }; - let request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".as_bytes(); + let request = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n".as_bytes(); tls_stream .write(request.clone()) .expect("Could not write request to TLS stream"); diff --git a/multinode_integration_tests/tests/self_test.rs b/multinode_integration_tests/tests/self_test.rs index bbbca61ec1..973affaf06 100644 --- a/multinode_integration_tests/tests/self_test.rs +++ b/multinode_integration_tests/tests/self_test.rs @@ -1,5 +1,6 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. +use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use multinode_integration_tests_lib::command::Command; use multinode_integration_tests_lib::main::CONTROL_STREAM_PORT; use multinode_integration_tests_lib::masq_cores_client::MASQCoresClient; @@ -10,11 +11,12 @@ use multinode_integration_tests_lib::masq_node_cluster::MASQNodeCluster; use multinode_integration_tests_lib::masq_real_node::NodeStartupConfigBuilder; use node_lib::json_masquerader::JsonMasquerader; use node_lib::sub_lib::cryptde::PublicKey; +use node_lib::sub_lib::cryptde_null::CryptDENull; use node_lib::sub_lib::dispatcher::Component; use node_lib::sub_lib::hopper::IncipientCoresPackage; use node_lib::sub_lib::route::Route; use node_lib::sub_lib::route::RouteSegment; -use node_lib::test_utils::{main_cryptde, make_meaningless_message_type, make_paying_wallet}; +use node_lib::test_utils::{make_meaningless_message_type, make_paying_wallet}; use std::collections::HashSet; use std::io::ErrorKind; use std::net::IpAddr; @@ -108,7 +110,7 @@ fn one_mock_node_talks_to_another() { cluster.start_mock_node_with_public_key(vec![5551], &PublicKey::new(&[2, 3, 4, 5])); let mock_node_1 = cluster.get_mock_node_by_name("mock_node_1").unwrap(); let mock_node_2 = cluster.get_mock_node_by_name("mock_node_2").unwrap(); - let cryptde = main_cryptde(); + let cryptde = CryptDENull::new(TEST_DEFAULT_CHAIN); let route = Route::one_way( RouteSegment::new( vec![ @@ -117,13 +119,13 @@ fn one_mock_node_talks_to_another() { ], Component::Hopper, ), - cryptde, + &cryptde, Some(make_paying_wallet(b"consuming")), Some(cluster.chain.rec().contract), ) .unwrap(); let incipient_cores_package = IncipientCoresPackage::new( - cryptde, + &cryptde, route, make_meaningless_message_type(), &mock_node_2.main_public_key(), diff --git a/node/ci/integration_tests.sh b/node/ci/integration_tests.sh index 3a41b27cb6..bca7c3bf6b 100755 --- a/node/ci/integration_tests.sh +++ b/node/ci/integration_tests.sh @@ -15,12 +15,12 @@ case "$OSTYPE" in Darwin | darwin*) echo "macOS" [[ $GITHUB_ACTIONS -eq true ]] && sudo launchctl limit maxfiles 524288 524288 && ulimit -Sn 524288 && sudo launchctl limit maxfiles - sudo --preserve-env ci/run_integration_tests.sh "$TOOLCHAIN_HOME" + sudo --preserve-env ci/run_integration_tests.sh ;; linux-gnu) echo "Linux" [[ $GITHUB_ACTIONS -eq true ]] && sudo --preserve-env ci/free-port-53.sh - sudo --preserve-env ci/run_integration_tests.sh "$TOOLCHAIN_HOME" + sudo --preserve-env ci/run_integration_tests.sh ;; *) exit 1 diff --git a/node/ci/run_integration_tests.sh b/node/ci/run_integration_tests.sh index 1239bb5431..15870d86b0 100755 --- a/node/ci/run_integration_tests.sh +++ b/node/ci/run_integration_tests.sh @@ -8,9 +8,19 @@ export RUST_BACKTRACE=full export RUSTFLAGS="-D warnings -Anon-snake-case" umask 000 -pushd "$CI_DIR/.." -cargo test --release --no-fail-fast -- --nocapture --test-threads=1 _integration +if [ "$1" == "" ]; then + TEST_NAME_FRAGMENT="_integration" +else + if [[ "$USER" != "root" ]]; then + echo "run_integration_tests.sh must be run as root" + exit 1 + fi + TEST_NAME_FRAGMENT="$1" +fi + +pushd "$CI_DIR/.." || { echo "Failed to pushd $CI_DIR/.."; exit 1; } +cargo test --release --no-fail-fast -- --nocapture --test-threads=1 "$TEST_NAME_FRAGMENT" BUILD_RESULT=$? chmod -R 777 target -popd +popd || { echo "Failed to popd"; exit 1; } exit "$BUILD_RESULT" diff --git a/node/src/actor_system_factory.rs b/node/src/actor_system_factory.rs index 8ab3426cf1..25e20aa7eb 100644 --- a/node/src/actor_system_factory.rs +++ b/node/src/actor_system_factory.rs @@ -21,7 +21,6 @@ use crate::node_configurator::configurator::Configurator; use crate::sub_lib::accountant::{AccountantSubs, AccountantSubsFactoryReal, DaoFactories}; use crate::sub_lib::blockchain_bridge::BlockchainBridgeSubs; use crate::sub_lib::configurator::ConfiguratorSubs; -use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::dispatcher::DispatcherSubs; use crate::sub_lib::hopper::HopperConfig; use crate::sub_lib::hopper::HopperSubs; @@ -72,9 +71,8 @@ impl ActorSystemFactory for ActorSystemFactoryReal { ) -> StreamHandlerPoolSubs { self.tools .validate_database_chain(&*persistent_config, config.blockchain_bridge_config.chain); - let cryptdes = self.tools.cryptdes(); self.tools - .prepare_initial_messages(cryptdes, config, persistent_config, actor_factory) + .prepare_initial_messages(config, persistent_config, actor_factory) } } @@ -87,12 +85,10 @@ impl ActorSystemFactoryReal { pub trait ActorSystemFactoryTools { fn prepare_initial_messages( &self, - cryptdes: CryptDEPair, config: BootstrapperConfig, persistent_config: Box, actor_factory: Box, ) -> StreamHandlerPoolSubs; - fn cryptdes(&self) -> CryptDEPair; fn validate_database_chain( &self, persistent_config: &dyn PersistentConfiguration, @@ -108,18 +104,17 @@ pub struct ActorSystemFactoryToolsReal { impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { fn prepare_initial_messages( &self, - cryptdes: CryptDEPair, config: BootstrapperConfig, persistent_config: Box, actor_factory: Box, ) -> StreamHandlerPoolSubs { let db_initializer = DbInitializerReal::default(); let (dispatcher_subs, pool_bind_sub) = actor_factory.make_and_start_dispatcher(&config); - let proxy_server_subs = actor_factory.make_and_start_proxy_server(cryptdes, &config); + let proxy_server_subs = actor_factory.make_and_start_proxy_server(&config); let proxy_client_subs_opt = if !config.neighborhood_config.mode.is_consume_only() { Some( actor_factory.make_and_start_proxy_client(ProxyClientConfig { - cryptde: cryptdes.main, + cryptde_pair: config.cryptde_pair.clone(), dns_servers: config.dns_servers.clone(), exit_service_rate: config .neighborhood_config @@ -135,7 +130,7 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { None }; let hopper_subs = actor_factory.make_and_start_hopper(HopperConfig { - cryptdes, + cryptde_pair: config.cryptde_pair.clone(), per_routing_service: config .neighborhood_config .mode @@ -151,7 +146,7 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { }); let blockchain_bridge_subs = actor_factory .make_and_start_blockchain_bridge(&config, &BlockchainBridgeSubsFactoryReal {}); - let neighborhood_subs = actor_factory.make_and_start_neighborhood(cryptdes.main, &config); + let neighborhood_subs = actor_factory.make_and_start_neighborhood(&config); let accountant_subs = actor_factory.make_and_start_accountant( config.clone(), &db_initializer, @@ -221,10 +216,6 @@ impl ActorSystemFactoryTools for ActorSystemFactoryToolsReal { stream_handler_pool_subs } - fn cryptdes(&self) -> CryptDEPair { - CryptDEPair::default() - } - fn validate_database_chain( &self, persistent_config: &dyn PersistentConfiguration, @@ -347,17 +338,9 @@ pub trait ActorFactory { &self, config: &BootstrapperConfig, ) -> (DispatcherSubs, Recipient); - fn make_and_start_proxy_server( - &self, - cryptdes: CryptDEPair, - config: &BootstrapperConfig, - ) -> ProxyServerSubs; + fn make_and_start_proxy_server(&self, config: &BootstrapperConfig) -> ProxyServerSubs; fn make_and_start_hopper(&self, config: HopperConfig) -> HopperSubs; - fn make_and_start_neighborhood( - &self, - cryptde: &'static dyn CryptDE, - config: &BootstrapperConfig, - ) -> NeighborhoodSubs; + fn make_and_start_neighborhood(&self, config: &BootstrapperConfig) -> NeighborhoodSubs; fn make_and_start_accountant( &self, config: BootstrapperConfig, @@ -380,12 +363,14 @@ pub trait ActorFactory { } pub struct ActorFactoryReal { + cryptde_pair: CryptDEPair, logger: Logger, } impl ActorFactoryReal { - pub fn new() -> Self { + pub fn new(cryptde_pair: &CryptDEPair) -> Self { Self { + cryptde_pair: cryptde_pair.clone(), logger: Logger::new("ActorFactory"), } } @@ -409,21 +394,18 @@ impl ActorFactory for ActorFactoryReal { config: &BootstrapperConfig, ) -> (DispatcherSubs, Recipient) { let node_descriptor = config.node_descriptor.clone(); + let cryptde_pair_thread = self.cryptde_pair.clone(); let crashable = is_crashable(config); let arbiter = Arbiter::builder().stop_system_on_panic(true); - let addr: Addr = - arbiter.start(move |_| Dispatcher::new(node_descriptor, crashable)); + let addr: Addr = arbiter + .start(move |_| Dispatcher::new(node_descriptor, cryptde_pair_thread, crashable)); ( Dispatcher::make_subs_from(&addr), addr.recipient::(), ) } - fn make_and_start_proxy_server( - &self, - cryptdes: CryptDEPair, - config: &BootstrapperConfig, - ) -> ProxyServerSubs { + fn make_and_start_proxy_server(&self, config: &BootstrapperConfig) -> ProxyServerSubs { let is_running_in_integration_test = is_running_in_integration_test(); let is_decentralized = config.neighborhood_config.mode.is_decentralized(); let consuming_wallet_balance = if config.consuming_wallet_opt.is_some() { @@ -431,12 +413,12 @@ impl ActorFactory for ActorFactoryReal { } else { None }; + let cryptde_pair_thread = self.cryptde_pair.clone(); let crashable = is_crashable(config); let arbiter = Arbiter::builder().stop_system_on_panic(true); let addr: Addr = arbiter.start(move |_| { ProxyServer::new( - cryptdes.main, - cryptdes.alias, + cryptde_pair_thread, is_decentralized, consuming_wallet_balance, crashable, @@ -452,15 +434,12 @@ impl ActorFactory for ActorFactoryReal { Hopper::make_subs_from(&addr) } - fn make_and_start_neighborhood( - &self, - cryptde: &'static dyn CryptDE, - config: &BootstrapperConfig, - ) -> NeighborhoodSubs { + fn make_and_start_neighborhood(&self, config: &BootstrapperConfig) -> NeighborhoodSubs { let config_clone = config.clone(); let arbiter = Arbiter::builder().stop_system_on_panic(true); + let cryptde_pair_thread = config.cryptde_pair.clone(); let addr: Addr = - arbiter.start(move |_| Neighborhood::new(cryptde, &config_clone)); + arbiter.start(move |_| Neighborhood::new(cryptde_pair_thread, &config_clone)); Neighborhood::make_subs_from(&addr) } @@ -552,8 +531,9 @@ impl ActorFactory for ActorFactoryReal { let data_directory = config.data_directory.clone(); let crashable = is_crashable(config); let arbiter = Arbiter::builder().stop_system_on_panic(true); - let addr: Addr = - arbiter.start(move |_| Configurator::new(data_directory, crashable)); + let cryptde_pair_thread = self.cryptde_pair.clone(); + let addr: Addr = arbiter + .start(move |_| Configurator::new(data_directory, cryptde_pair_thread, crashable)); ConfiguratorSubs { bind: recipient!(addr, BindMessage), node_from_ui_sub: recipient!(addr, NodeFromUiMessage), @@ -643,13 +623,13 @@ mod tests { use super::*; use crate::accountant::exportable_test_parts::test_accountant_is_constructed_with_upgraded_db_connection_recognizing_our_extra_sqlite_functions; use crate::accountant::DEFAULT_PENDING_TOO_LONG_SEC; - use crate::bootstrapper::{Bootstrapper, RealUser}; + use crate::bootstrapper::RealUser; use crate::node_test_utils::{ make_stream_handler_pool_subs_from_recorder, start_recorder_refcell_opt, }; use crate::sub_lib::accountant::{PaymentThresholds, ScanIntervals}; use crate::sub_lib::blockchain_bridge::BlockchainBridgeConfig; - use crate::sub_lib::cryptde::{PlainData, PublicKey}; + use crate::sub_lib::cryptde::{CryptDE, PlainData, PublicKey}; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::dispatcher::{InboundClientData, StreamShutdownMsg}; use crate::sub_lib::neighborhood::NeighborhoodMode; @@ -664,6 +644,7 @@ mod tests { use crate::test_utils::make_wallet; use crate::test_utils::neighborhood_test_utils::MIN_HOPS_FOR_TEST; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; + use crate::test_utils::rate_pack; use crate::test_utils::recorder::{ make_accountant_subs_from_recorder, make_blockchain_bridge_subs_from_recorder, make_configurator_subs_from_recorder, make_hopper_subs_from_recorder, @@ -676,8 +657,6 @@ mod tests { use crate::test_utils::unshared_test_utils::{ assert_on_initialization_with_panic_on_migration, SubsFactoryTestAddrLeaker, }; - 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; @@ -686,6 +665,7 @@ mod tests { parameterizable_automap_control, TransactorMock, PUBLIC_IP, ROUTER_IP, }; use crossbeam_channel::unbounded; + use lazy_static::lazy_static; use log::LevelFilter; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::crash_point::CrashPoint; @@ -709,6 +689,10 @@ mod tests { use std::thread; use std::time::Duration; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + struct LogRecipientSetterNull {} impl LogRecipientSetterNull { @@ -726,8 +710,6 @@ mod tests { prepare_initial_messages_params: Arc< Mutex< Vec<( - Box, - Box, BootstrapperConfig, Box, Box, @@ -742,14 +724,11 @@ mod tests { impl ActorSystemFactoryTools for ActorSystemFactoryToolsMock { fn prepare_initial_messages( &self, - cryptdes: CryptDEPair, config: BootstrapperConfig, persistent_config: Box, actor_factory: Box, ) -> StreamHandlerPoolSubs { self.prepare_initial_messages_params.lock().unwrap().push(( - Box::new(<&CryptDENull>::from(cryptdes.main).clone()), - Box::new(<&CryptDENull>::from(cryptdes.alias).clone()), config, actor_factory, persistent_config, @@ -757,10 +736,6 @@ mod tests { self.prepare_initial_messages_results.borrow_mut().remove(0) } - fn cryptdes(&self) -> CryptDEPair { - self.cryptdes_results.borrow_mut().remove(0) - } - fn validate_database_chain( &self, persistent_config: &dyn PersistentConfiguration, @@ -792,8 +767,6 @@ mod tests { params: &Arc< Mutex< Vec<( - Box, - Box, BootstrapperConfig, Box, Box, @@ -813,7 +786,7 @@ mod tests { } } - struct ActorFactoryMock<'a> { + struct ActorFactoryMock { dispatcher: RefCell>, proxy_client: RefCell>, proxy_server: RefCell>, @@ -825,10 +798,10 @@ mod tests { blockchain_bridge: RefCell>, configurator: RefCell>, - parameters: Parameters<'a>, + parameters: Parameters, } - impl<'a> ActorFactory for ActorFactoryMock<'a> { + impl<'a> ActorFactory for ActorFactoryMock { fn make_and_start_dispatcher( &self, config: &BootstrapperConfig, @@ -850,16 +823,12 @@ mod tests { (dispatcher_subs, addr.recipient::()) } - fn make_and_start_proxy_server( - &self, - cryptdes: CryptDEPair, - config: &BootstrapperConfig, - ) -> ProxyServerSubs { + fn make_and_start_proxy_server(&self, config: &BootstrapperConfig) -> ProxyServerSubs { self.parameters .proxy_server_params .lock() .unwrap() - .get_or_insert((cryptdes, config.clone())); + .get_or_insert(config.clone()); let addr: Addr = ActorFactoryMock::start_recorder(&self.proxy_server); make_proxy_server_subs_from_recorder(&addr) } @@ -874,16 +843,12 @@ mod tests { make_hopper_subs_from_recorder(&addr) } - fn make_and_start_neighborhood( - &self, - cryptde: &'a dyn CryptDE, - config: &BootstrapperConfig, - ) -> NeighborhoodSubs { + fn make_and_start_neighborhood(&self, config: &BootstrapperConfig) -> NeighborhoodSubs { self.parameters .neighborhood_params .lock() .unwrap() - .get_or_insert((cryptde, config.clone())); + .get_or_insert(config.clone()); let addr: Addr = start_recorder_refcell_opt(&self.neighborhood); make_neighborhood_subs_from_recorder(&addr) } @@ -971,20 +936,20 @@ mod tests { } #[derive(Clone)] - struct Parameters<'a> { + struct Parameters { dispatcher_params: Arc>>, proxy_client_params: Arc>>, - proxy_server_params: Arc>>, + proxy_server_params: Arc>>, hopper_params: Arc>>, - neighborhood_params: Arc>>, + neighborhood_params: Arc>>, accountant_params: Arc>>, ui_gateway_params: Arc>>, blockchain_bridge_params: Arc>>, configurator_params: Arc>>, } - impl<'a> Parameters<'a> { - pub fn new() -> Parameters<'a> { + impl<'a> Parameters { + pub fn new() -> Parameters { Parameters { dispatcher_params: Arc::new(Mutex::new(None)), proxy_client_params: Arc::new(Mutex::new(None)), @@ -1004,8 +969,8 @@ mod tests { } } - impl<'a> ActorFactoryMock<'a> { - pub fn new() -> ActorFactoryMock<'a> { + impl<'a> ActorFactoryMock { + pub fn new() -> ActorFactoryMock { ActorFactoryMock { dispatcher: RefCell::new(Some(Recorder::new())), proxy_client: RefCell::new(Some(Recorder::new())), @@ -1047,7 +1012,7 @@ mod tests { } } - pub fn make_parameters(&self) -> Parameters<'a> { + pub fn make_parameters(&self) -> Parameters { self.parameters.clone() } @@ -1061,15 +1026,9 @@ mod tests { let validate_database_chain_params_arc = Arc::new(Mutex::new(vec![])); let prepare_initial_messages_params_arc = Arc::new(Mutex::new(vec![])); let (stream_handler_pool, _, stream_handler_pool_recording_arc) = make_recorder(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); - let cryptde_pair = CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }; - let main_cryptde_public_key_expected = pk_from_cryptde_null(main_cryptde); - let alias_cryptde_public_key_expected = pk_from_cryptde_null(alias_cryptde); - let actor_factory = Box::new(ActorFactoryReal::new()); + let main_cryptde_public_key_expected = pk_from_cryptde_null(CRYPTDE_PAIR.main.as_ref()); + let alias_cryptde_public_key_expected = pk_from_cryptde_null(CRYPTDE_PAIR.alias.as_ref()); + let actor_factory = Box::new(ActorFactoryReal::new(&CRYPTDE_PAIR)); let actor_factory_raw_address_expected = addr_of!(*actor_factory); let persistent_config_expected_arbitrary_id = ArbitraryIdStamp::new(); let persistent_config = Box::new( @@ -1080,7 +1039,7 @@ mod tests { make_stream_handler_pool_subs_from_recorder(&stream_handler_pool.start()); let actor_system_factor_tools = ActorSystemFactoryToolsMock::default() .validate_database_chain_params(&validate_database_chain_params_arc) - .cryptdes_result(cryptde_pair) + .cryptdes_result(CRYPTDE_PAIR.clone()) .prepare_initial_messages_params(&prepare_initial_messages_params_arc) .prepare_initial_messages_result(stream_holder_pool_subs); let data_dir = PathBuf::new().join("parent_directory/child_directory"); @@ -1089,6 +1048,7 @@ mod tests { bootstrapper_config.blockchain_bridge_config.chain = Chain::PolyMainnet; bootstrapper_config.data_directory = data_dir.clone(); bootstrapper_config.db_password_opt = Some("password".to_string()); + bootstrapper_config.cryptde_pair = CRYPTDE_PAIR.clone(); let result = subject.make_and_start_actors(bootstrapper_config, actor_factory, persistent_config); @@ -1104,19 +1064,16 @@ mod tests { assert!(validate_database_chain_params.is_empty()); let mut prepare_initial_messages_params = prepare_initial_messages_params_arc.lock().unwrap(); - let ( - main_cryptde_actual, - alias_cryptde_actual, - bootstrapper_config_actual, - actor_factory_actual, - persistent_config_actual, - ) = prepare_initial_messages_params.remove(0); - let main_cryptde_public_key_actual = pk_from_cryptde_null(main_cryptde_actual.as_ref()); + let (bootstrapper_config_actual, actor_factory_actual, persistent_config_actual) = + prepare_initial_messages_params.remove(0); + let main_cryptde_public_key_actual = + pk_from_cryptde_null(bootstrapper_config_actual.cryptde_pair.main.as_ref()); assert_eq!( main_cryptde_public_key_actual, main_cryptde_public_key_expected ); - let alias_cryptde_public_key_actual = pk_from_cryptde_null(alias_cryptde_actual.as_ref()); + let alias_cryptde_public_key_actual = + pk_from_cryptde_null(bootstrapper_config_actual.cryptde_pair.alias.as_ref()); assert_eq!( alias_cryptde_public_key_actual, alias_cryptde_public_key_expected @@ -1179,10 +1136,9 @@ mod tests { clandestine_port_opt: None, earning_wallet: make_wallet("earning"), consuming_wallet_opt: Some(make_wallet("consuming")), + cryptde_pair: CRYPTDE_PAIR.clone(), data_directory: PathBuf::new(), node_descriptor: NodeDescriptor::default(), - main_cryptde_null_opt: None, - alias_cryptde_null_opt: None, mapping_protocol_opt: None, real_user: RealUser::null(), neighborhood_config: NeighborhoodConfig { @@ -1199,10 +1155,6 @@ mod tests { let persistent_config = PersistentConfigurationMock::default() .chain_name_result("base-sepolia".to_string()) .set_min_hops_result(Ok(())); - Bootstrapper::pub_initialize_cryptdes_for_testing( - &Some(main_cryptde()), - &Some(alias_cryptde()), - ); let mut tools = make_subject_with_null_setter(); tools.automap_control_factory = Box::new( AutomapControlFactoryMock::new().make_result(Box::new( @@ -1255,10 +1207,9 @@ mod tests { earning_wallet: make_wallet("earning"), consuming_wallet_opt: Some(make_wallet("consuming")), data_directory: PathBuf::new(), - 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: Some(AutomapProtocol::Igdp), + node_descriptor: NodeDescriptor::try_from((CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap(), + cryptde_pair: CRYPTDE_PAIR.clone(), + mapping_protocol_opt: Some(Igdp), real_user: RealUser::null(), neighborhood_config: NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -1277,7 +1228,7 @@ mod tests { 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)) + .get_mapping_protocol_result(Some(Igdp)) .add_mapping_params(&add_mapping_params_arc) .add_mapping_result(Ok(())) .add_mapping_result(Ok(())), @@ -1285,7 +1236,6 @@ mod tests { ); let _ = subject.prepare_initial_messages( - make_cryptde_pair(), config.clone(), Box::new(PersistentConfigurationMock::new()), Box::new(actor_factory), @@ -1313,22 +1263,21 @@ mod tests { ); check_start_message(&recordings.neighborhood, 2); let hopper_config = Parameters::get(parameters.hopper_params); - check_cryptde(hopper_config.cryptdes.main); + check_cryptde(hopper_config.cryptde_pair.main.as_ref()); assert_eq!(hopper_config.per_routing_service, 300); assert_eq!(hopper_config.per_routing_byte, 101); let proxy_client_config = Parameters::get(parameters.proxy_client_params); - check_cryptde(proxy_client_config.cryptde); + check_cryptde(proxy_client_config.cryptde_pair.main.as_ref()); assert_eq!(proxy_client_config.exit_service_rate, 500); assert_eq!(proxy_client_config.exit_byte_rate, 103); assert_eq!(proxy_client_config.dns_servers, config.dns_servers); assert_eq!(proxy_client_config.is_decentralized, true); - let (actual_cryptde_pair, bootstrapper_config) = - Parameters::get(parameters.proxy_server_params); - check_cryptde(actual_cryptde_pair.main); - check_cryptde(actual_cryptde_pair.alias); + let bootstrapper_config = Parameters::get(parameters.proxy_server_params); + check_cryptde(bootstrapper_config.cryptde_pair.main.as_ref()); + check_cryptde(bootstrapper_config.cryptde_pair.alias.as_ref()); assert_ne!( - actual_cryptde_pair.main.public_key(), - actual_cryptde_pair.alias.public_key() + bootstrapper_config.cryptde_pair.main.public_key(), + bootstrapper_config.cryptde_pair.alias.public_key() ); assert_eq!( bootstrapper_config @@ -1341,8 +1290,7 @@ mod tests { bootstrapper_config.consuming_wallet_opt, Some(make_wallet("consuming")) ); - let (cryptde, neighborhood_config) = Parameters::get(parameters.neighborhood_params); - check_cryptde(cryptde); + let neighborhood_config = Parameters::get(parameters.neighborhood_params); assert_eq!( neighborhood_config.neighborhood_config, config.neighborhood_config @@ -1356,7 +1304,7 @@ mod tests { let dispatcher_param = Parameters::get(parameters.dispatcher_params); assert_eq!( dispatcher_param.node_descriptor, - NodeDescriptor::try_from((main_cryptde(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap() + NodeDescriptor::try_from((CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap() ); let blockchain_bridge_param = Parameters::get(parameters.blockchain_bridge_params); assert_eq!( @@ -1427,7 +1375,6 @@ mod tests { ); let _ = subject.prepare_initial_messages( - make_cryptde_pair(), config.clone(), Box::new(PersistentConfigurationMock::new()), Box::new(actor_factory), @@ -1464,7 +1411,7 @@ mod tests { .stop_housekeeping_thread_result(Ok(Box::new(|_| ()))) .get_public_ip_result(Ok(*PUBLIC_IP)) .add_mapping_result(Ok(1000)); - let igdp_mock = TransactorMock::new(AutomapProtocol::Igdp).find_routers_result(Ok(vec![])); + let igdp_mock = TransactorMock::new(Igdp).find_routers_result(Ok(vec![])); let change_handler = Box::new(|_| ()); let automap_control: Box = Box::new(parameterizable_automap_control( change_handler, @@ -1487,9 +1434,8 @@ mod tests { #[test] fn automap_protocol_is_not_saved_if_indifferent_from_last_time() { - let config_entry = Some(AutomapProtocol::Igdp); - let automap_control = - AutomapControlMock::default().get_mapping_protocol_result(Some(AutomapProtocol::Igdp)); + let config_entry = Some(Igdp); + let automap_control = AutomapControlMock::default().get_mapping_protocol_result(Some(Igdp)); ActorSystemFactoryToolsReal::maybe_save_usual_protocol( &automap_control, @@ -1507,8 +1453,7 @@ mod tests { .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)); + let automap_control = AutomapControlMock::default().get_mapping_protocol_result(Some(Igdp)); ActorSystemFactoryToolsReal::maybe_save_usual_protocol( &automap_control, @@ -1558,9 +1503,8 @@ mod tests { earning_wallet: make_wallet("earning"), consuming_wallet_opt: Some(make_wallet("consuming")), data_directory: PathBuf::new(), - 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, + node_descriptor: NodeDescriptor::try_from((CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@172.50.48.6:9342")).unwrap(), + cryptde_pair: CRYPTDE_PAIR.clone(), mapping_protocol_opt: None, real_user: RealUser::null(), neighborhood_config: NeighborhoodConfig { @@ -1575,7 +1519,6 @@ mod tests { subject.automap_control_factory = Box::new(AutomapControlFactoryMock::new()); let _ = subject.prepare_initial_messages( - make_cryptde_pair(), config.clone(), Box::new(PersistentConfigurationMock::new().set_min_hops_result(Ok(()))), Box::new(actor_factory), @@ -1744,8 +1687,7 @@ mod tests { consuming_wallet_opt: None, earning_wallet: make_wallet("earning"), data_directory: PathBuf::new(), - main_cryptde_null_opt: None, - alias_cryptde_null_opt: None, + cryptde_pair: CRYPTDE_PAIR.clone(), mapping_protocol_opt: None, real_user: RealUser::null(), neighborhood_config: NeighborhoodConfig { @@ -1764,7 +1706,6 @@ mod tests { let system = System::new("MASQNode"); let _ = subject.prepare_initial_messages( - make_cryptde_pair(), config.clone(), Box::new(PersistentConfigurationMock::new().set_min_hops_result(Ok(()))), Box::new(actor_factory), @@ -1772,7 +1713,7 @@ mod tests { System::current().stop(); system.run(); - let (_, bootstrapper_config) = Parameters::get(parameters.proxy_server_params); + let bootstrapper_config = Parameters::get(parameters.proxy_server_params); assert_eq!(bootstrapper_config.consuming_wallet_opt, None); } @@ -1781,8 +1722,8 @@ mod tests { let closure = || { let mut bootstrapper_config = BootstrapperConfig::default(); bootstrapper_config.crash_point = CrashPoint::Message; - let subscribers = ActorFactoryReal::new() - .make_and_start_proxy_server(make_cryptde_pair(), &bootstrapper_config); + let subscribers = ActorFactoryReal::new(&CRYPTDE_PAIR) + .make_and_start_proxy_server(&bootstrapper_config); subscribers.node_from_ui }; @@ -1793,7 +1734,7 @@ mod tests { fn proxy_client_drags_down_the_whole_system_due_to_local_panic() { let closure = || { let proxy_cl_config = ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::V4( SocketAddrV4::from_str("1.1.1.1:45").unwrap(), )], @@ -1802,7 +1743,8 @@ mod tests { crashable: true, exit_byte_rate: 50, }; - let subscribers = ActorFactoryReal::new().make_and_start_proxy_client(proxy_cl_config); + let subscribers = + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_proxy_client(proxy_cl_config); subscribers.node_from_ui }; @@ -1813,13 +1755,14 @@ mod tests { fn hopper_drags_down_the_whole_system_due_to_local_panic() { let closure = || { let hopper_config = HopperConfig { - cryptdes: make_cryptde_pair(), + cryptde_pair: CRYPTDE_PAIR.clone(), per_routing_service: 100, per_routing_byte: 50, is_decentralized: false, crashable: true, }; - let subscribers = ActorFactoryReal::new().make_and_start_hopper(hopper_config); + let subscribers = + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_hopper(hopper_config); subscribers.node_from_ui }; @@ -1831,8 +1774,8 @@ mod tests { let closure = || { let mut bootstrapper_config = BootstrapperConfig::default(); bootstrapper_config.crash_point = CrashPoint::Message; - let subscribers = - ActorFactoryReal::new().make_and_start_ui_gateway(&bootstrapper_config); + let subscribers = ActorFactoryReal::new(&CRYPTDE_PAIR) + .make_and_start_ui_gateway(&bootstrapper_config); subscribers.node_from_ui_message_sub }; @@ -1844,8 +1787,8 @@ mod tests { let closure = || { let mut bootstrapper_config = BootstrapperConfig::default(); bootstrapper_config.crash_point = CrashPoint::Message; - let subscribers = - ActorFactoryReal::new().make_and_start_stream_handler_pool(&bootstrapper_config); + let subscribers = ActorFactoryReal::new(&CRYPTDE_PAIR) + .make_and_start_stream_handler_pool(&bootstrapper_config); subscribers.node_from_ui_sub }; @@ -1960,15 +1903,11 @@ mod tests { bootstrapper_config.blockchain_bridge_config.chain = TEST_DEFAULT_CHAIN; let persistent_config = PersistentConfigurationMock::default().chain_name_result("eth-mainnet".to_string()); - Bootstrapper::pub_initialize_cryptdes_for_testing( - &Some(main_cryptde().clone()), - &Some(alias_cryptde().clone()), - ); let subject = ActorSystemFactoryReal::new(Box::new(ActorSystemFactoryToolsReal::new())); let _ = subject.make_and_start_actors( bootstrapper_config, - Box::new(ActorFactoryReal::new()), + Box::new(ActorFactoryReal::new(&CRYPTDE_PAIR)), Box::new(persistent_config), ); } @@ -1980,7 +1919,7 @@ mod tests { db_initializer: DbInitializerReal, banned_cache_loader: BannedCacheLoaderMock, address_leaker: SubsFactoryTestAddrLeaker| { - ActorFactoryReal::new().make_and_start_accountant( + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_accountant( bootstrapper_config, &db_initializer, &banned_cache_loader, diff --git a/node/src/blockchain/blockchain_bridge.rs b/node/src/blockchain/blockchain_bridge.rs index e4275b036e..a0e501393b 100644 --- a/node/src/blockchain/blockchain_bridge.rs +++ b/node/src/blockchain/blockchain_bridge.rs @@ -662,7 +662,7 @@ mod tests { #[test] fn blockchain_interface_is_constructed_with_a_blockchain_service_url() { init_test_logging(); - let blockchain_service_url = "https://example.com"; + let blockchain_service_url = "https://www.example.com"; let subject = BlockchainBridge::initialize_blockchain_interface( Some(blockchain_service_url.to_string()), TEST_DEFAULT_CHAIN, diff --git a/node/src/bootstrapper.rs b/node/src/bootstrapper.rs index cf82499b6e..b70bc208c2 100644 --- a/node/src/bootstrapper.rs +++ b/node/src/bootstrapper.rs @@ -28,6 +28,7 @@ use crate::sub_lib::accountant; use crate::sub_lib::accountant::{PaymentThresholds, ScanIntervals}; use crate::sub_lib::blockchain_bridge::BlockchainBridgeConfig; use crate::sub_lib::cryptde::CryptDE; +#[cfg(test)] use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::neighborhood::NodeDescriptor; @@ -62,52 +63,65 @@ use tokio::prelude::Async; use tokio::prelude::Future; use tokio::prelude::Stream; -static mut MAIN_CRYPTDE_BOX_OPT: Option> = None; -static mut ALIAS_CRYPTDE_BOX_OPT: Option> = None; +pub struct CryptDEPair { + // This has the public key by which this Node is known to other Nodes on the network + pub main: Box, + // This has the public key with which this Node instructs exit Nodes to encrypt responses. + // In production, it is unrelated to the main public key to prevent the exit Node from + // identifying the originating Node. In tests using --fake-public-key, the alias public key + // is the main public key reversed. + pub alias: Box, +} -fn main_cryptde_ref<'a>() -> &'a dyn CryptDE { - unsafe { - MAIN_CRYPTDE_BOX_OPT - .as_ref() - .expect("Internal error: Main CryptDE uninitialized") - .as_ref() +impl Clone for CryptDEPair { + fn clone(&self) -> Self { + CryptDEPair { + main: self.main.dup(), + alias: self.alias.dup(), + } } } -fn alias_cryptde_ref<'a>() -> &'a dyn CryptDE { - unsafe { - ALIAS_CRYPTDE_BOX_OPT - .as_ref() - .expect("Internal error: Alias CryptDE uninitialized") - .as_ref() +impl Debug for CryptDEPair { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "CryptDEPair {{ main: {:?}, alias: {:?} }}", + self.main.public_key(), + self.alias.public_key() + ) } } -impl Clone for CryptDEPair { - fn clone(&self) -> Self { - Self { - main: self.main, - alias: self.alias, +impl From for CryptDEPair { + fn from(chain: Chain) -> Self { + let main = CryptDEReal::new(chain); + let alias = CryptDEReal::new(chain); + CryptDEPair { + main: Box::new(main), + alias: Box::new(alias), } } } -#[derive(Copy)] -pub struct CryptDEPair { - // This has the public key by which this Node is known to other Nodes on the network - pub main: &'static dyn CryptDE, - // This has the public key with which this Node instructs exit Nodes to encrypt responses. - // In production, it is unrelated to the main public key to prevent the exit Node from - // identifying the originating Node. In tests using --fake-public-key, the alias public key - // is the main public key reversed. - pub alias: &'static dyn CryptDE, -} +impl CryptDEPair { + pub fn new(main: Box, alias: Box) -> Self { + CryptDEPair { main, alias } + } -impl Default for CryptDEPair { - fn default() -> Self { - CryptDEPair { - main: main_cryptde_ref(), - alias: alias_cryptde_ref(), + pub fn null() -> Self { + #[cfg(test)] + { + let main = CryptDENull::new(TEST_DEFAULT_CHAIN); + let alias = CryptDENull::new(TEST_DEFAULT_CHAIN); + CryptDEPair { + main: Box::new(main), + alias: Box::new(alias), + } + } + #[cfg(not(test))] + { + panic!("You should not use CryptDEPair::null() in production code. It is only for testing purposes."); } } } @@ -345,8 +359,7 @@ pub struct BootstrapperConfig { pub port_configurations: HashMap, pub data_directory: PathBuf, pub node_descriptor: NodeDescriptor, - pub main_cryptde_null_opt: Option, - pub alias_cryptde_null_opt: Option, + pub cryptde_pair: CryptDEPair, pub mapping_protocol_opt: Option, pub real_user: RealUser, pub payment_thresholds_opt: Option, @@ -386,8 +399,12 @@ impl BootstrapperConfig { port_configurations: HashMap::new(), data_directory: PathBuf::new(), node_descriptor: NodeDescriptor::default(), - main_cryptde_null_opt: None, - alias_cryptde_null_opt: None, + // This value should not be used in production; it should be replaced during bootstrapping. + // If it isn't, it should be impossible to put up a network. + cryptde_pair: CryptDEPair::new( + Box::new(CryptDEReal::disabled()), + Box::new(CryptDEReal::disabled()), + ), mapping_protocol_opt: None, real_user: RealUser::new(None, None, None), payment_thresholds_opt: Default::default(), @@ -414,6 +431,7 @@ impl BootstrapperConfig { self.neighborhood_config = unprivileged.neighborhood_config; self.earning_wallet = unprivileged.earning_wallet; self.consuming_wallet_opt = unprivileged.consuming_wallet_opt; + self.cryptde_pair = unprivileged.cryptde_pair; self.db_password_opt = unprivileged.db_password_opt; self.scan_intervals_opt = unprivileged.scan_intervals_opt; self.suppress_initial_scans = unprivileged.suppress_initial_scans; @@ -454,7 +472,8 @@ impl Future for Bootstrapper { type Error = (); fn poll(&mut self) -> Result::Item>, ::Error> { - try_ready!(CrashTestDummy::new(self.config.crash_point, BootstrapperConfig::new()).poll()); + // TODO: The config parameter below doesn't appear to be used. At any rate, it should probably be self.config, not a new object. + try_ready!(CrashTestDummy::new(self.config.crash_point).poll()); try_ready!(self.listener_handlers.poll()); Ok(Async::Ready(())) } @@ -498,18 +517,13 @@ impl ConfiguredByPrivilege for Bootstrapper { fdlimit::raise_fd_limit(); let unprivileged_config = NodeConfiguratorStandardUnprivileged::new(&self.config).configure(multi_config)?; + let cryptde_pair = unprivileged_config.cryptde_pair.clone(); 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 cryptdes = Bootstrapper::initialize_cryptdes( - &main_cryptde_null_opt, - &alias_cryptde_null_opt, - self.config.blockchain_bridge_config.chain, - ); // initialization of CountryFinder let _ = get_node_location(Some(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)))); let node_descriptor = Bootstrapper::make_local_descriptor( - cryptdes.main, + self.config.cryptde_pair.main.as_ref(), self.config.neighborhood_config.mode.node_addr_opt(), self.config.blockchain_bridge_config.chain, ); @@ -520,7 +534,10 @@ 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(cryptdes.main, &self.config.node_descriptor), // here or not coming + _ => Bootstrapper::report_local_descriptor( + cryptde_pair.main.as_ref(), + &self.config.node_descriptor, + ), // here or not coming } let stream_handler_pool_subs = self.start_actors_and_return_shp_subs(); self.listener_handlers @@ -544,51 +561,6 @@ impl Bootstrapper { } } - #[cfg(test)] // The real ones are private, but ActorSystemFactory needs to use them for testing - pub fn pub_initialize_cryptdes_for_testing( - main_cryptde_null_opt: &Option<&dyn CryptDE>, - alias_cryptde_null_opt: &Option<&dyn CryptDE>, - ) -> CryptDEPair { - Self::initialize_cryptdes( - main_cryptde_null_opt, - alias_cryptde_null_opt, - masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN, - ) - } - - fn initialize_cryptdes( - main_cryptde_null_opt: &Option<&dyn CryptDE>, - alias_cryptde_null_opt: &Option<&dyn CryptDE>, - chain: Chain, - ) -> CryptDEPair { - unsafe { - Self::initialize_single_cryptde(main_cryptde_null_opt, &mut MAIN_CRYPTDE_BOX_OPT, chain) - }; - unsafe { - Self::initialize_single_cryptde( - alias_cryptde_null_opt, - &mut ALIAS_CRYPTDE_BOX_OPT, - chain, - ) - } - CryptDEPair::default() - } - - fn initialize_single_cryptde( - cryptde_null_opt: &Option<&dyn CryptDE>, - boxed_cryptde: &mut Option>, - chain: Chain, - ) { - match cryptde_null_opt { - Some(cryptde) => { - let _ = boxed_cryptde.replace(Box::new(<&CryptDENull>::from(*cryptde).clone())); - } - None => { - let _ = boxed_cryptde.replace(Box::new(CryptDEReal::new(chain))); - } - } - } - fn make_local_descriptor( cryptde: &dyn CryptDE, node_addr_opt: Option, @@ -614,10 +586,11 @@ impl Bootstrapper { fn start_actors_and_return_shp_subs(&self) -> StreamHandlerPoolSubs { self.actor_system_factory.make_and_start_actors( self.config.clone(), - Box::new(ActorFactoryReal::new()), + Box::new(ActorFactoryReal::new(&self.config.cryptde_pair)), initialize_database( &self.config.data_directory, DbInitializationConfig::panic_on_migration(), + &self.config.db_password_opt, ), ) } @@ -695,19 +668,6 @@ impl Bootstrapper { ), } } - - fn null_cryptdes_as_trait_objects(&self) -> (Option<&dyn CryptDE>, Option<&dyn CryptDE>) { - ( - self.config - .alias_cryptde_null_opt - .as_ref() - .map(|cryptde_null| cryptde_null as &dyn CryptDE), - self.config - .main_cryptde_null_opt - .as_ref() - .map(|cryptde_null| cryptde_null as &dyn CryptDE), - ) - } } #[cfg(test)] @@ -715,7 +675,7 @@ mod tests { use crate::accountant::DEFAULT_PENDING_TOO_LONG_SEC; use crate::actor_system_factory::{ActorFactory, ActorSystemFactory}; use crate::bootstrapper::{ - main_cryptde_ref, Bootstrapper, BootstrapperConfig, EnvironmentWrapper, PortConfiguration, + Bootstrapper, BootstrapperConfig, CryptDEPair, EnvironmentWrapper, PortConfiguration, RealUser, }; use crate::database::db_initializer::DbInitializationConfig; @@ -743,6 +703,7 @@ mod tests { use crate::sub_lib::node_addr::NodeAddr; use crate::sub_lib::socket_server::ConfiguredByPrivilege; use crate::sub_lib::stream_connector::ConnectionInfo; + use crate::test_utils::make_wallet; use crate::test_utils::neighborhood_test_utils::MIN_HOPS_FOR_TEST; use crate::test_utils::persistent_configuration_mock::PersistentConfigurationMock; use crate::test_utils::recorder::make_recorder; @@ -754,7 +715,6 @@ mod tests { assert_on_initialization_with_panic_on_migration, make_simplified_multi_config, }; use crate::test_utils::{assert_contains, rate_pack}; - use crate::test_utils::{main_cryptde, make_wallet}; use actix::System; use actix::{Actor, Recipient}; use crossbeam_channel::unbounded; @@ -770,6 +730,8 @@ mod tests { use masq_lib::test_utils::logging::{init_test_logging, TestLog, TestLogHandler}; use masq_lib::test_utils::utils::{ensure_node_home_directory_exists, TEST_DEFAULT_CHAIN}; use masq_lib::utils::{find_free_port, to_string}; + use sodiumoxide::crypto::box_::curve25519xsalsa20poly1305 as cxsp; + use sodiumoxide::crypto::sign as signing; use std::cell::RefCell; use std::collections::HashMap; use std::io; @@ -786,6 +748,7 @@ mod tests { use tokio::prelude::Async; lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); pub static ref INITIALIZATION: Mutex = Mutex::new(false); } @@ -1204,13 +1167,12 @@ mod tests { .unwrap(); let config = subject.config; + assert_eq!(config.node_descriptor.blockchain, Chain::BaseSepolia); assert_eq!( - config.node_descriptor, - NodeDescriptor::from(( - main_cryptde_ref().public_key(), - &NodeAddr::new(&IpAddr::from_str("1.2.3.4").unwrap(), &[5123]), - Chain::BaseSepolia, - main_cryptde_ref() + config.node_descriptor.node_addr_opt, + Some(NodeAddr::new( + &IpAddr::from_str("1.2.3.4").unwrap(), + &[5123] )) ); TestLogHandler::new().exists_log_matching("INFO: Bootstrapper: MASQ Node local descriptor: masq://base-sepolia:.+@1\\.2\\.3\\.4:5123"); @@ -1320,15 +1282,22 @@ mod tests { .unwrap(); let config = subject.config; + assert_eq!(config.node_descriptor.blockchain, Chain::BaseSepolia); assert_eq!( - config.node_descriptor, - NodeDescriptor::from(( - main_cryptde_ref().public_key(), - &NodeAddr::new(&IpAddr::from_str("1.2.3.4").unwrap(), &[5123]), - Chain::BaseSepolia, - main_cryptde_ref() + config.node_descriptor.node_addr_opt, + Some(NodeAddr::new( + &IpAddr::from_str("1.2.3.4").unwrap(), + &[5123] )) ); + assert_ne!( + config.cryptde_pair.main.public_key().as_slice(), + &[0u8; cxsp::PUBLICKEYBYTES + signing::PUBLICKEYBYTES] + ); + assert_ne!( + config.cryptde_pair.alias.public_key().as_slice(), + &[0u8; cxsp::PUBLICKEYBYTES + signing::PUBLICKEYBYTES] + ); TestLogHandler::new().exists_log_matching("INFO: Bootstrapper: MASQ Node local descriptor: masq://base-sepolia:.+@1\\.2\\.3\\.4:5123"); } @@ -1530,30 +1499,6 @@ mod tests { .unwrap(); } - #[test] - fn initialize_cryptde_without_cryptde_null_uses_cryptde_real() { - let _lock = INITIALIZATION.lock(); - let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); - - 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!(cryptdes.main.public_key().len() > cryptde_null.public_key().len()); - } - - #[test] - fn initialize_cryptde_with_cryptde_null_uses_cryptde_null() { - let _lock = INITIALIZATION.lock(); - let cryptde_null = main_cryptde().clone(); - let cryptde_null_public_key = cryptde_null.public_key().clone(); - - let cryptdes = - Bootstrapper::initialize_cryptdes(&Some(cryptde_null), &None, TEST_DEFAULT_CHAIN); - - assert_eq!(cryptdes.main.public_key(), &cryptde_null_public_key); - assert_eq!(main_cryptde_ref().public_key(), cryptdes.main.public_key()); - } - #[test] fn initialize_cryptde_and_report_local_descriptor_with_ip_address() { let _lock = INITIALIZATION.lock(); @@ -1563,15 +1508,14 @@ mod tests { &[3456u16, 4567u16], ); let cryptde_ref = { - let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); let descriptor = Bootstrapper::make_local_descriptor( - cryptdes.main, + CRYPTDE_PAIR.main.as_ref(), Some(node_addr), TEST_DEFAULT_CHAIN, ); - Bootstrapper::report_local_descriptor(cryptdes.main, &descriptor); + Bootstrapper::report_local_descriptor(CRYPTDE_PAIR.main.as_ref(), &descriptor); - cryptdes.main + CRYPTDE_PAIR.main.as_ref() }; let expected_descriptor = format!( "masq://base-sepolia:{}@2.3.4.5:3456/4567", @@ -1606,12 +1550,14 @@ mod tests { let _lock = INITIALIZATION.lock(); init_test_logging(); let cryptdes = { - let cryptdes = Bootstrapper::initialize_cryptdes(&None, &None, TEST_DEFAULT_CHAIN); - let descriptor = - Bootstrapper::make_local_descriptor(cryptdes.main, None, TEST_DEFAULT_CHAIN); - Bootstrapper::report_local_descriptor(cryptdes.main, &descriptor); + let descriptor = Bootstrapper::make_local_descriptor( + CRYPTDE_PAIR.main.as_ref(), + None, + TEST_DEFAULT_CHAIN, + ); + Bootstrapper::report_local_descriptor(CRYPTDE_PAIR.main.as_ref(), &descriptor); - cryptdes + CRYPTDE_PAIR.clone() }; let expected_descriptor = format!( "masq://base-sepolia:{}@:", @@ -1643,8 +1589,8 @@ mod tests { )); assert_eq!(decrypted_data, expected_data) }; - assert_round_trip(cryptdes.main); - assert_round_trip(cryptdes.alias); + assert_round_trip(cryptdes.main.as_ref()); + assert_round_trip(cryptdes.alias.as_ref()); } #[test] diff --git a/node/src/crash_test_dummy.rs b/node/src/crash_test_dummy.rs index f2263dc422..d6e740442b 100644 --- a/node/src/crash_test_dummy.rs +++ b/node/src/crash_test_dummy.rs @@ -5,20 +5,15 @@ use masq_lib::crash_point::CrashPoint; use masq_lib::logger::Logger; use tokio::prelude::future::Future; -pub struct CrashTestDummy { - pub configuration: C, +pub struct CrashTestDummy { crash_point: CrashPoint, message: String, logger: Logger, } -impl CrashTestDummy -where - C: Send, -{ - pub fn new(crash_point: CrashPoint, configuration: C) -> CrashTestDummy { +impl CrashTestDummy { + pub fn new(crash_point: CrashPoint) -> CrashTestDummy { CrashTestDummy { - configuration, crash_point, message: "CrashTestDummy".to_owned(), logger: Logger::new("CrashTestDummy"), @@ -26,9 +21,8 @@ where } #[cfg(test)] - pub fn panic(message: String, configuration: C) -> CrashTestDummy { + pub fn panic(message: String) -> CrashTestDummy { CrashTestDummy { - configuration, crash_point: CrashPoint::Panic, message, logger: Logger::new("CrashTestDummy"), @@ -36,10 +30,7 @@ where } } -impl Future for CrashTestDummy -where - C: Send, -{ +impl Future for CrashTestDummy { type Item = (); type Error = (); @@ -66,13 +57,13 @@ mod tests { #[test] #[should_panic(expected = "CrashTestDummy")] fn create_a_future_that_panics() { - let crash_future = CrashTestDummy::new(CrashPoint::Panic, ()); + let crash_future = CrashTestDummy::new(CrashPoint::Panic); crash_future.wait().unwrap(); } #[test] fn create_a_future_that_returns_an_error() { - let crash_future = CrashTestDummy::new(CrashPoint::Error, ()); + let crash_future = CrashTestDummy::new(CrashPoint::Error); let result = crash_future.wait(); @@ -81,7 +72,7 @@ mod tests { #[test] fn should_not_crash_if_no_crash_point_is_set() { - let crash_future = CrashTestDummy::new(CrashPoint::None, ()); + let crash_future = CrashTestDummy::new(CrashPoint::None); let result = crash_future.wait(); @@ -91,8 +82,7 @@ mod tests { #[test] #[should_panic(expected = "CrashTestDummy Mmm Mmm Mmm Mmm")] fn should_panic_with_provided_message() { - let crash_future = - CrashTestDummy::panic(String::from("CrashTestDummy Mmm Mmm Mmm Mmm"), ()); + let crash_future = CrashTestDummy::panic(String::from("CrashTestDummy Mmm Mmm Mmm Mmm")); crash_future.wait().ok(); } diff --git a/node/src/daemon/setup_reporter.rs b/node/src/daemon/setup_reporter.rs index 4d31683a03..e12713cda7 100644 --- a/node/src/daemon/setup_reporter.rs +++ b/node/src/daemon/setup_reporter.rs @@ -1,7 +1,7 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::apps::app_head; -use crate::bootstrapper::BootstrapperConfig; +use crate::bootstrapper::{BootstrapperConfig, CryptDEPair}; use crate::daemon::dns_inspector::dns_inspector_factory::{ DnsInspectorFactory, DnsInspectorFactoryReal, }; @@ -22,10 +22,11 @@ use crate::node_configurator::{ }; use crate::sub_lib::accountant::PaymentThresholds as PaymentThresholdsFromAccountant; use crate::sub_lib::accountant::DEFAULT_SCAN_INTERVALS; +use crate::sub_lib::cryptde::CryptDE; +use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::neighborhood::NodeDescriptor; use crate::sub_lib::neighborhood::{NeighborhoodMode as NeighborhoodModeEnum, DEFAULT_RATE_PACK}; use crate::sub_lib::utils::make_new_multi_config; -use crate::test_utils::main_cryptde; use clap::{value_t, App}; use itertools::Itertools; use masq_lib::blockchains::chains::Chain as BlockChain; @@ -536,6 +537,16 @@ impl SetupReporterReal { ) { let mut error_so_far = ConfiguratorError::new(vec![]); let mut bootstrapper_config = BootstrapperConfig::new(); + // The guts of these CryptDEs don't matter. All that matters is that they're Real + // instead of Null, so that the key length is correct. + bootstrapper_config.cryptde_pair = CryptDEPair::new( + Box::new(CryptDEReal::new( + masq_lib::blockchains::chains::Chain::PolyMainnet, + )), + Box::new(CryptDEReal::new( + masq_lib::blockchains::chains::Chain::PolyMainnet, + )), + ); bootstrapper_config.data_directory = data_directory.to_path_buf(); match privileged_parse_args( self.dirs_wrapper.as_ref(), @@ -983,10 +994,14 @@ impl ValueRetriever for NeighborhoodMode { } } -fn node_descriptors_to_neighbors(node_descriptors: Vec) -> String { +// Note: no interior state from cryptde is used; the important thing is whether it's Real or Null. +fn node_descriptors_to_neighbors( + node_descriptors: Vec, + cryptde: &dyn CryptDE, +) -> String { node_descriptors .into_iter() - .map(|nd| nd.to_string(main_cryptde())) + .map(|nd| nd.to_string(cryptde)) .collect_vec() .join(",") } @@ -999,13 +1014,19 @@ impl ValueRetriever for Neighbors { fn computed_default( &self, - _bootstrapper_config: &BootstrapperConfig, + bootstrapper_config: &BootstrapperConfig, persistent_config: &dyn PersistentConfiguration, db_password_opt: &Option, ) -> Option<(String, UiSetupResponseValueStatus)> { match db_password_opt { Some(pw) => match persistent_config.past_neighbors(pw) { - Ok(Some(pns)) => Some((node_descriptors_to_neighbors(pns), Configured)), + Ok(Some(pns)) => Some(( + node_descriptors_to_neighbors( + pns, + bootstrapper_config.cryptde_pair.main.as_ref(), + ), + Configured, + )), _ => None, }, None => None, @@ -1220,6 +1241,7 @@ mod tests { PaymentThresholds as PaymentThresholdsFromAccountant, DEFAULT_PAYMENT_THRESHOLDS, }; use crate::sub_lib::cryptde::PublicKey; + use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::neighborhood::Hops; use crate::sub_lib::node_addr::NodeAddr; use crate::sub_lib::wallet::Wallet; @@ -1337,7 +1359,7 @@ mod tests { ); let data_dir = home_dir.join("data_dir"); let chain_specific_data_dir = data_dir.join(DEFAULT_CHAIN.rec().literal_identifier); - std::fs::create_dir_all(&chain_specific_data_dir).unwrap(); + create_dir_all(&chain_specific_data_dir).unwrap(); let db_initializer = DbInitializerReal::default(); let conn = db_initializer .initialize( @@ -1357,7 +1379,7 @@ mod tests { .unwrap(); config.set_gas_price(1234567890).unwrap(); let neighbor1 = NodeDescriptor { - encryption_public_key: PublicKey::new(b"ABCD"), + encryption_public_key: PublicKey::new(b"ABCD5678901234567892123456789312"), blockchain: Blockchain::EthMainnet, node_addr_opt: Some(NodeAddr::new( &IpAddr::from_str("1.2.3.4").unwrap(), @@ -1365,7 +1387,7 @@ mod tests { )), }; let neighbor2 = NodeDescriptor { - encryption_public_key: PublicKey::new(b"EFGH"), + encryption_public_key: PublicKey::new(b"EFGH5678901234567892123456789312"), blockchain: Blockchain::EthMainnet, node_addr_opt: Some(NodeAddr::new( &IpAddr::from_str("5.6.7.8").unwrap(), @@ -1429,7 +1451,7 @@ mod tests { ("neighborhood-mode", "standard", Default), ( "neighbors", - "masq://eth-mainnet:QUJDRA@1.2.3.4:1234,masq://eth-mainnet:RUZHSA@5.6.7.8:5678", + "masq://eth-mainnet:QUJDRDU2Nzg5MDEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@1.2.3.4:1234,masq://eth-mainnet:RUZHSDU2Nzg5MDEyMzQ1Njc4OTIxMjM0NTY3ODkzMTI@5.6.7.8:5678", Configured, ), ( @@ -1695,7 +1717,7 @@ mod tests { // misleading. You can't change a database from one chain to another, because in so doing all // its wallet addresses, balance amounts, and transaction numbers would be invalidated. fn switching_config_files_changes_setup() { - let _ = EnvironmentGuard::new(); + let _guard = EnvironmentGuard::new(); let home_dir = ensure_node_home_directory_exists( "setup_reporter", "switching_config_files_changes_setup", @@ -1705,7 +1727,7 @@ mod tests { .join("MASQ") .join(DEFAULT_CHAIN.rec().literal_identifier); { - std::fs::create_dir_all(mainnet_dir.clone()).unwrap(); + create_dir_all(mainnet_dir.clone()).unwrap(); let mut config_file = File::create(mainnet_dir.join("config.toml")).unwrap(); config_file .write_all(b"blockchain-service-url = \"https://www.mainnet.com\"\n") @@ -1742,14 +1764,14 @@ mod tests { .write_all(b"scan-intervals = \"111|100|99\"\n") .unwrap() } - let ropsten_dir = data_root + let base_sepolia_dir = data_root .join("MASQ") .join(TEST_DEFAULT_CHAIN.rec().literal_identifier); { - std::fs::create_dir_all(ropsten_dir.clone()).unwrap(); - let mut config_file = File::create(ropsten_dir.join("config.toml")).unwrap(); + create_dir_all(base_sepolia_dir.clone()).unwrap(); + let mut config_file = File::create(base_sepolia_dir.join("config.toml")).unwrap(); config_file - .write_all(b"blockchain-service-url = \"https://www.ropsten.com\"\n") + .write_all(b"blockchain-service-url = \"https://www.base-sepolia.com\"\n") .unwrap(); config_file .write_all(b"clandestine-port = \"8877\"\n") @@ -1758,12 +1780,11 @@ mod tests { config_file.write_all(b"consuming-private-key = \"FFEEDDCCBBAA99887766554433221100FFEEDDCCBBAA99887766554433221100\"\n").unwrap(); config_file.write_all(b"crash-point = \"None\"\n").unwrap(); config_file - .write_all(b"db-password = \"ropstenPassword\"\n") + .write_all(b"db-password = \"sepoliaPassword\"\n") .unwrap(); config_file .write_all(b"dns-servers = \"8.7.6.5\"\n") .unwrap(); - // NOTE: You can't really change consuming-private-key without starting a new database config_file .write_all(b"earning-wallet = \"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n") .unwrap(); @@ -1807,7 +1828,7 @@ mod tests { let expected_result = vec![ ( "blockchain-service-url", - "https://www.ropsten.com", + "https://www.base-sepolia.com", Configured, ), ("chain", TEST_DEFAULT_CHAIN.rec().literal_identifier, Set), @@ -1821,10 +1842,10 @@ mod tests { ("crash-point", "None", Configured), ( "data-directory", - &ropsten_dir.to_string_lossy().to_string(), + &base_sepolia_dir.to_string_lossy().to_string(), Default, ), - ("db-password", "ropstenPassword", Configured), + ("db-password", "sepoliaPassword", Configured), ("dns-servers", "8.7.6.5", Configured), ( "earning-wallet", @@ -2316,6 +2337,7 @@ mod tests { #[test] fn get_modified_setup_does_not_support_database_migration() { + let _guard = EnvironmentGuard::new(); let data_dir = ensure_node_home_directory_exists( "setup_reporter", "get_modified_setup_does_not_support_database_migration", @@ -2425,6 +2447,7 @@ mod tests { #[test] fn run_configuration_suppresses_db_migration_which_implies_just_use_of_config_dao_null() { + let _guard = EnvironmentGuard::new(); let data_dir = ensure_node_home_directory_exists( "setup_reporter", "run_configuration_suppresses_db_migration_which_implies_just_use_of_config_dao_null", @@ -2639,6 +2662,52 @@ mod tests { ); } + #[test] + fn calculate_setup_with_chain_specific_dir_on_user_specified_directory() { + let _guard = EnvironmentGuard::new(); + let existing_setup = + setup_cluster_from(vec![("real-user", "1111:1111:/home/booga", Default)]); + let masqhome = Path::new("/home/booga/masqhome"); + let incoming_setup = vec![UiSetupRequestValue::new( + "data-directory", + &masqhome.to_str().unwrap(), + )]; + let dirs_wrapper = Box::new(DirsWrapperReal::default()); + let subject = SetupReporterReal::new(dirs_wrapper); + + let result = subject.get_modified_setup(existing_setup, incoming_setup); + + let expected = masqhome.join("polygon-mainnet"); + assert_eq!( + result.unwrap().get("data-directory").unwrap().value, + expected.to_str().unwrap() + ); + } + + #[test] + fn calculate_setup_with_chain_specific_dir_on_default_directory() { + let _guard = EnvironmentGuard::new(); + let existing_setup = + setup_cluster_from(vec![("real-user", "1111:1111:/home/booga", Default)]); + let incoming_setup = vec![UiSetupRequestValue::new("chain", "polygon-amoy")]; + let home_directory = Path::new("/home/booga"); + let data_directory = home_directory.join("data"); + let expected = data_directory.join("MASQ").join("polygon-amoy"); + let dirs_wrapper = Box::new( + DirsWrapperMock::new() + .data_dir_result(Some(data_directory)) + .home_dir_result(Some(home_directory.to_path_buf())), + ); + let subject = SetupReporterReal::new(dirs_wrapper); + + let result = subject.get_modified_setup(existing_setup, incoming_setup); + + assert_eq!( + result.unwrap().get("data-directory").unwrap().value, + expected.to_str().unwrap() + ); + } + #[test] fn choose_uisrv_chooses_higher_priority_incoming_over_lower_priority_existing() { let existing = UiSetupResponseValue::new("name", "existing", Configured); @@ -2671,6 +2740,7 @@ mod tests { #[test] fn config_file_not_specified_and_nonexistent() { + let _guard = EnvironmentGuard::new(); let data_directory = ensure_node_home_directory_exists( "setup_reporter", "config_file_not_specified_and_nonexistent", @@ -2777,6 +2847,7 @@ mod tests { #[test] fn config_file_has_relative_directory_that_does_not_exist_in_data_directory() { + let _guard = EnvironmentGuard::new(); let data_directory = ensure_node_home_directory_exists( "setup_reporter", "config_file_has_relative_directory_that_does_not_exist_in_data_directory", @@ -2807,6 +2878,7 @@ mod tests { #[test] fn config_file_has_absolute_path_to_file_that_exists() { + let _guard = EnvironmentGuard::new(); let data_dir = ensure_node_home_directory_exists( "setup_reporter", "config_file_has_absolute_path_to_file_that_exists", @@ -2841,6 +2913,7 @@ mod tests { #[test] fn config_file_has_absolute_path_to_file_that_does_not_exist() { + let _guard = EnvironmentGuard::new(); let config_file_dir = ensure_node_home_directory_exists( "setup_reporter", "config_file_has_absolute_path_to_file_that_does_not_exist", @@ -3213,17 +3286,18 @@ mod tests { #[test] fn neighbors_computed_default_persistent_config_present_password_present_values_present() { + let cryptde = CryptDEReal::new(masq_lib::blockchains::chains::Chain::Dev); let past_neighbors_params_arc = Arc::new(Mutex::new(vec![])); let persistent_config = PersistentConfigurationMock::new() .past_neighbors_params(&past_neighbors_params_arc) .past_neighbors_result(Ok(Some(vec![ NodeDescriptor::try_from(( - main_cryptde(), + &cryptde as &dyn CryptDE, "masq://eth-mainnet:MTEyMjMzNDQ1NTY2Nzc4ODExMjIzMzQ0NTU2Njc3ODg@1.2.3.4:1234", )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + &cryptde as &dyn CryptDE, "masq://eth-mainnet:ODg3NzY2NTU0NDMzMjIxMTg4Nzc2NjU1NDQzMzIyMTE@4.3.2.1:4321", )) .unwrap(), @@ -3690,50 +3764,4 @@ mod tests { ); assert_eq!(Scans {}.value_name(), "scans"); } - - #[test] - fn calculate_setup_with_chain_specific_dir_on_user_specified_directory() { - let _guard = EnvironmentGuard::new(); - let existing_setup = - setup_cluster_from(vec![("real-user", "1111:1111:/home/booga", Default)]); - let masqhome = Path::new("/home/booga/masqhome"); - let incoming_setup = vec![UiSetupRequestValue::new( - "data-directory", - &masqhome.to_str().unwrap(), - )]; - let dirs_wrapper = Box::new(DirsWrapperReal::default()); - let subject = SetupReporterReal::new(dirs_wrapper); - - let result = subject.get_modified_setup(existing_setup, incoming_setup); - - let expected = masqhome.join("polygon-mainnet"); - assert_eq!( - result.unwrap().get("data-directory").unwrap().value, - expected.to_str().unwrap() - ); - } - - #[test] - fn calculate_setup_with_chain_specific_dir_on_default_directory() { - let _guard = EnvironmentGuard::new(); - let existing_setup = - setup_cluster_from(vec![("real-user", "1111:1111:/home/booga", Default)]); - let incoming_setup = vec![UiSetupRequestValue::new("chain", "polygon-amoy")]; - let home_directory = Path::new("/home/booga"); - let data_directory = home_directory.join("data"); - let expected = data_directory.join("MASQ").join("polygon-amoy"); - let dirs_wrapper = Box::new( - DirsWrapperMock::new() - .data_dir_result(Some(data_directory)) - .home_dir_result(Some(home_directory.to_path_buf())), - ); - let subject = SetupReporterReal::new(dirs_wrapper); - - let result = subject.get_modified_setup(existing_setup, incoming_setup); - - assert_eq!( - result.unwrap().get("data-directory").unwrap().value, - expected.to_str().unwrap() - ); - } } diff --git a/node/src/database/config_dumper.rs b/node/src/database/config_dumper.rs index 17e24899eb..d191a8a70a 100644 --- a/node/src/database/config_dumper.rs +++ b/node/src/database/config_dumper.rs @@ -159,6 +159,7 @@ fn distill_args( mod tests { use super::*; use crate::blockchain::bip39::Bip39; + use crate::bootstrapper::CryptDEPair; use crate::database::db_initializer::ExternalData; use crate::database::rusqlite_wrappers::ConnectionWrapperReal; use crate::db_config::config_dao::ConfigDao; @@ -172,7 +173,8 @@ mod tests { use crate::sub_lib::cryptde::PlainData; use crate::sub_lib::neighborhood::{NodeDescriptor, DEFAULT_RATE_PACK}; use crate::test_utils::database_utils::bring_db_0_back_to_life_and_return_connection; - use crate::test_utils::{main_cryptde, ArgsBuilder}; + use crate::test_utils::ArgsBuilder; + use lazy_static::lazy_static; use masq_lib::constants::CURRENT_SCHEMA_VERSION; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::test_utils::environment_guard::{ClapGuard, EnvironmentGuard}; @@ -184,6 +186,10 @@ mod tests { use std::io::ErrorKind; use std::panic::{catch_unwind, AssertUnwindSafe}; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn database_must_be_created_by_node_before_dump_config_is_used() { let _ = EnvironmentGuard::new(); @@ -282,12 +288,12 @@ mod tests { .set_past_neighbors( Some(vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:QUJDREVGRw@1.2.3.4:1234", )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:QkNERUZHSA@2.3.4.5:2345", )) .unwrap(), @@ -311,9 +317,7 @@ mod tests { data_dir_result: Some(PathBuf::from("/home/booga/.local/share".to_string())), home_dir_result: Some(PathBuf::from("/home/booga".to_string())), })); - let subject = DumpConfigRunnerReal { - dirs_wrapper: dirs_wrapper, - }; + let subject = DumpConfigRunnerReal { dirs_wrapper }; let result = subject.go(&mut holder.streams(), args_vec.as_slice()); @@ -442,12 +446,12 @@ mod tests { .set_past_neighbors( Some(vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU@1.2.3.4:1234", )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY@2.3.4.5:2345", )) .unwrap(), @@ -546,12 +550,12 @@ mod tests { .set_past_neighbors( Some(vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU@1.2.3.4:1234", )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://polygon-mainnet:QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY@2.3.4.5:2345", )) .unwrap(), @@ -632,7 +636,7 @@ mod tests { expected = "Database is corrupt: pastNeighbors byte string 'PlainData { data: [192, 193] }' cannot be interpreted as UTF-8" )] fn decode_bytes_handles_decode_error_for_past_neighbors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let data = PlainData::new(&[192, 193]); let _ = translate_bytes("pastNeighbors", data, cryptde); @@ -641,7 +645,7 @@ mod tests { #[test] #[should_panic(expected = "Database is corrupt: past_neighbors cannot be decoded")] fn decode_bytes_handles_utf8_error_for_past_neighbors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let data = PlainData::new(b"invalid hex"); let _ = translate_bytes("pastNeighbors", data, cryptde); @@ -650,7 +654,7 @@ mod tests { #[test] #[should_panic(expected = "Database is corrupt: past_neighbors contains bad CBOR")] fn decode_bytes_handles_bad_cbor_for_past_neighbors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let data = PlainData::new(b"AABBCC"); let _ = translate_bytes("pastNeighbors", data, cryptde); diff --git a/node/src/database/db_initializer.rs b/node/src/database/db_initializer.rs index be55475764..aea696d6ca 100644 --- a/node/src/database/db_initializer.rs +++ b/node/src/database/db_initializer.rs @@ -151,6 +151,7 @@ impl DbInitializerReal { ) .expect("Can't create config table"); } + fn initialize_config(conn: &Connection, external_params: ExternalData) { Self::set_config_value(conn, EXAMPLE_ENCRYPTED, None, true, "example_encrypted"); Self::set_config_value( @@ -219,6 +220,13 @@ impl DbInitializerReal { false, "gas price", ); + Self::set_config_value( + conn, + "last_cryptde", + None, + true, + "CryptDE that gave us the public key we used last time", + ); Self::set_config_value(conn, "past_neighbors", None, true, "past neighbors"); Self::set_config_value( conn, @@ -641,6 +649,7 @@ mod tests { use rusqlite::Error::InvalidColumnType; use rusqlite::{Error, OpenFlags}; use std::collections::HashMap; + use std::collections::HashSet; use std::fs::File; use std::io::{Read, Write}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; @@ -652,7 +661,7 @@ mod tests { #[test] fn constants_have_correct_values() { assert_eq!(DATABASE_FILE, "node-data.db"); - assert_eq!(CURRENT_SCHEMA_VERSION, 10); + assert_eq!(CURRENT_SCHEMA_VERSION, 11); } #[test] @@ -926,6 +935,7 @@ mod tests { Some(&DEFAULT_GAS_PRICE.to_string()), false, ); + verify(&mut config_vec, "last_cryptde", None, true); verify(&mut config_vec, "mapping_protocol", None, false); verify(&mut config_vec, "max_block_count", None, false); verify(&mut config_vec, "min_hops", Some("3"), false); @@ -965,6 +975,118 @@ mod tests { assert_eq!(config_vec, vec![]); } + #[test] + fn new_database_is_initialized_correctly() { + let home_dir = ensure_node_home_directory_exists( + "db_initializer", + "new_database_is_initialized_correctly", + ); + let subject = DbInitializerReal::default(); + + subject + .initialize(&home_dir, DbInitializationConfig::test_default()) + .unwrap(); + + let mut flags = OpenFlags::empty(); + flags.insert(OpenFlags::SQLITE_OPEN_READ_ONLY); + let conn = Connection::open_with_flags(&home_dir.join(DATABASE_FILE), flags).unwrap(); + let mut stmt = conn + .prepare("SELECT name FROM sqlite_master WHERE type='table'") + .unwrap(); + let table_names = stmt + .query_map([], |row| row.get(0)) + .unwrap() + .map(|x| x.unwrap()) + .collect::>(); + assert_eq!( + table_names, + HashSet::from([ + "config".to_string(), + "payable".to_string(), + "pending_payable".to_string(), + "receivable".to_string(), + "banned".to_string(), + ]), + ); + let config_map = extract_configurations(&conn); + let mut config_vec: Vec<(String, (Option, bool))> = + config_map.into_iter().collect(); + config_vec.sort_by_key(|(name, _)| name.clone()); + let verify = |cv: &mut Vec<(String, (Option, bool))>, + name: &str, + value: Option<&str>, + encrypted: bool| { + let actual = cv.remove(0); + let expected = (name.to_string(), (value.map(|v| v.to_string()), encrypted)); + assert_eq!(actual, expected) + }; + let verify_but_value = |cv: &mut Vec<(String, (Option, bool))>, + expected_name: &str, + expected_encrypted: bool| { + let (actual_name, (value, actual_encrypted)) = cv.remove(0); + assert_eq!(actual_name, expected_name); + assert_eq!(actual_encrypted, expected_encrypted); + value + }; + verify(&mut config_vec, "blockchain_service_url", None, false); + verify( + &mut config_vec, + "chain_name", + Some(TEST_DEFAULT_CHAIN.rec().literal_identifier), + false, + ); + let clandestine_port_str_opt = verify_but_value(&mut config_vec, "clandestine_port", false); + let clandestine_port: u16 = clandestine_port_str_opt.unwrap().parse().unwrap(); + assert!(clandestine_port >= 1025); + assert!(clandestine_port < 10000); + verify(&mut config_vec, "consuming_wallet_private_key", None, true); + verify(&mut config_vec, "earning_wallet_address", None, false); + verify(&mut config_vec, EXAMPLE_ENCRYPTED, None, true); + verify( + &mut config_vec, + "gas_price", + Some(&DEFAULT_GAS_PRICE.to_string()), + false, + ); + verify(&mut config_vec, "last_cryptde", None, true); + verify(&mut config_vec, "mapping_protocol", None, false); + verify(&mut config_vec, "max_block_count", None, false); + verify(&mut config_vec, "min_hops", Some("3"), false); + verify( + &mut config_vec, + "neighborhood_mode", + Some("standard"), + false, + ); + verify(&mut config_vec, "past_neighbors", None, true); + verify( + &mut config_vec, + "payment_thresholds", + Some(&DEFAULT_PAYMENT_THRESHOLDS.to_string()), + false, + ); + verify( + &mut config_vec, + "rate_pack", + Some(&DEFAULT_RATE_PACK.to_string()), + false, + ); + verify( + &mut config_vec, + "scan_intervals", + Some(&DEFAULT_SCAN_INTERVALS.to_string()), + false, + ); + verify( + &mut config_vec, + "schema_version", + Some(&CURRENT_SCHEMA_VERSION.to_string()), + false, + ); + verify(&mut config_vec, "start_block", None, false); + assert_eq!(config_vec, vec![]); + } + #[test] fn existing_database_with_no_version_is_rejected() { let home_dir = ensure_node_home_directory_exists( diff --git a/node/src/database/db_migrations/db_migrator.rs b/node/src/database/db_migrations/db_migrator.rs index 7d1ec4f8cc..369a78788f 100644 --- a/node/src/database/db_migrations/db_migrator.rs +++ b/node/src/database/db_migrations/db_migrator.rs @@ -2,6 +2,7 @@ use crate::database::db_initializer::ExternalData; use crate::database::db_migrations::migrations::migration_0_to_1::Migrate_0_to_1; +use crate::database::db_migrations::migrations::migration_10_to_11::Migrate_10_to_11; use crate::database::db_migrations::migrations::migration_1_to_2::Migrate_1_to_2; use crate::database::db_migrations::migrations::migration_2_to_3::Migrate_2_to_3; use crate::database::db_migrations::migrations::migration_3_to_4::Migrate_3_to_4; @@ -80,6 +81,7 @@ impl DbMigratorReal { &Migrate_7_to_8, &Migrate_8_to_9, &Migrate_9_to_10, + &Migrate_10_to_11, ] } diff --git a/node/src/database/db_migrations/migrations/migration_10_to_11.rs b/node/src/database/db_migrations/migrations/migration_10_to_11.rs new file mode 100644 index 0000000000..51b7ebd4f8 --- /dev/null +++ b/node/src/database/db_migrations/migrations/migration_10_to_11.rs @@ -0,0 +1,69 @@ +// Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. + +use crate::database::db_migrations::db_migrator::DatabaseMigration; +use crate::database::db_migrations::migrator_utils::DBMigDeclarator; + +#[allow(non_camel_case_types)] +pub struct Migrate_10_to_11; + +impl DatabaseMigration for Migrate_10_to_11 { + fn migrate<'a>( + &self, + declaration_utils: Box, + ) -> rusqlite::Result<()> { + declaration_utils.execute_upon_transaction(&[ + &"INSERT INTO config (name, value, encrypted) VALUES ('last_cryptde', null, 1)", + ]) + } + + fn old_version(&self) -> usize { + 10 + } +} + +#[cfg(test)] +mod tests { + use crate::database::db_initializer::{ + DbInitializationConfig, DbInitializer, DbInitializerReal, DATABASE_FILE, + }; + use crate::test_utils::database_utils::{ + bring_db_0_back_to_life_and_return_connection, make_external_data, retrieve_config_row, + }; + use masq_lib::test_utils::utils::ensure_node_home_directory_exists; + use std::fs::create_dir_all; + + #[test] + fn migration_from_10_to_11_is_properly_set() { + let dir_path = ensure_node_home_directory_exists( + "db_migrations", + "migration_from_10_to_11_is_properly_set", + ); + create_dir_all(&dir_path).unwrap(); + let db_path = dir_path.join(DATABASE_FILE); + let _ = bring_db_0_back_to_life_and_return_connection(&db_path); + let subject = DbInitializerReal::default(); + + let result = subject.initialize_to_version( + &dir_path, + 10, + DbInitializationConfig::create_or_migrate(make_external_data()), + ); + + assert!(result.is_ok()); + + let result = subject.initialize_to_version( + &dir_path, + 11, + DbInitializationConfig::create_or_migrate(make_external_data()), + ); + + assert!(result.is_ok()); + let connection = result.unwrap(); + let (lc_value, lc_encrypted) = retrieve_config_row(connection.as_ref(), "last_cryptde"); + let (cs_value, cs_encrypted) = retrieve_config_row(connection.as_ref(), "schema_version"); + assert_eq!(lc_value, None); + assert_eq!(lc_encrypted, true); + assert_eq!(cs_value, Some("11".to_string())); + assert_eq!(cs_encrypted, false) + } +} diff --git a/node/src/database/db_migrations/migrations/mod.rs b/node/src/database/db_migrations/migrations/mod.rs index bcdb14176f..53b7b7bb67 100644 --- a/node/src/database/db_migrations/migrations/mod.rs +++ b/node/src/database/db_migrations/migrations/mod.rs @@ -1,6 +1,7 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. pub mod migration_0_to_1; +pub mod migration_10_to_11; pub mod migration_1_to_2; pub mod migration_2_to_3; pub mod migration_3_to_4; diff --git a/node/src/db_config/config_dao_null.rs b/node/src/db_config/config_dao_null.rs index f1fc58cd49..fd7fb7e059 100644 --- a/node/src/db_config/config_dao_null.rs +++ b/node/src/db_config/config_dao_null.rs @@ -100,6 +100,7 @@ impl Default for ConfigDaoNull { false, ), ); + data.insert("last_cryptde".to_string(), (None, true)); data.insert( "gas_price".to_string(), (Some(DEFAULT_GAS_PRICE.to_string()), false), @@ -157,7 +158,6 @@ mod tests { use masq_lib::blockchains::chains::Chain; use masq_lib::constants::{DEFAULT_CHAIN, ETH_MAINNET_CONTRACT_CREATION_BLOCK}; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; - use std::collections::HashSet; #[test] fn get_works() { @@ -241,12 +241,13 @@ mod tests { assert_eq!(null_pairs, real_pairs); } - fn return_parameter_pairs(dao: &dyn ConfigDao) -> HashSet<(String, bool)> { + fn return_parameter_pairs(dao: &dyn ConfigDao) -> Vec<(String, bool)> { dao.get_all() .unwrap() .into_iter() .map(|r| (r.name, r.encrypted)) - .collect() + .sorted_by_key(|pair| pair.0.clone()) + .collect::>() } #[test] diff --git a/node/src/db_config/persistent_configuration.rs b/node/src/db_config/persistent_configuration.rs index 532048a341..ba25999ccb 100644 --- a/node/src/db_config/persistent_configuration.rs +++ b/node/src/db_config/persistent_configuration.rs @@ -11,9 +11,12 @@ use crate::db_config::typed_config_layer::{ TypedConfigLayerError, }; use crate::sub_lib::accountant::{PaymentThresholds, ScanIntervals}; -use crate::sub_lib::cryptde::PlainData; +use crate::sub_lib::cryptde::{CryptDE, PlainData}; +use crate::sub_lib::cryptde_null::CryptDENull; +use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::neighborhood::{Hops, NodeDescriptor, RatePack}; use crate::sub_lib::wallet::Wallet; +use masq_lib::blockchains::chains::Chain; use masq_lib::constants::{HIGHEST_USABLE_PORT, LOWEST_USABLE_INSECURE_PORT}; use masq_lib::shared_schema::{ConfiguratorError, ParamError}; use masq_lib::utils::NeighborhoodModeLight; @@ -105,6 +108,13 @@ pub trait PersistentConfiguration { fn clandestine_port(&self) -> Result; fn set_clandestine_port(&mut self, port: u16) -> Result<(), PersistentConfigError>; // WARNING: Actors should get earning-wallet information from their startup config, not from here + fn cryptde(&self, db_password: &str) + -> Result>, PersistentConfigError>; + fn set_cryptde( + &mut self, + cryptde: &dyn CryptDE, + db_password: &str, + ) -> Result<(), PersistentConfigError>; fn earning_wallet(&self) -> Result, PersistentConfigError>; // WARNING: Actors should get earning-wallet information from their startup config, not from here fn earning_wallet_address(&self) -> Result, PersistentConfigError>; @@ -292,6 +302,69 @@ impl PersistentConfiguration for PersistentConfigurationReal { .set("clandestine_port", encode_u64(Some(u64::from(port)))?)?) } + fn cryptde( + &self, + db_password: &str, + ) -> Result>, PersistentConfigError> { + let record = match self.get_record("last_cryptde") { + Ok(record) => record, + Err(ConfigDaoError::NotPresent) => return Err(PersistentConfigError::NotPresent), + Err(e) => { + return Err(PersistentConfigError::DatabaseError(format!( + "Can't continue; last_cryptde is inaccessible: {:?}", + e + ))) + } + }; + let cryptde_text = match self + .scl + .decrypt(record, Some(db_password.to_string()), &self.dao) + { + Ok(Some(text)) => text, + Ok(None) => return Ok(None), + Err(_) => return Err(PersistentConfigError::PasswordError), + }; + let chain_name = self.chain_name(); + let chain = Chain::from(chain_name.as_str()); + if cryptde_text.contains(',') { + match CryptDEReal::new(chain).make_from_str(cryptde_text.as_str(), chain) { + Ok(c) => Ok(Some(c)), + Err(e) => Err(PersistentConfigError::BadCoupledParamsFormat(format!( + "CryptDEReal string '{}' is not valid: {:?}", + cryptde_text, e + ))), + } + } else { + match CryptDENull::new(chain).make_from_str(cryptde_text.as_str(), chain) { + Ok(c) => Ok(Some(c)), + Err(e) => Err(PersistentConfigError::BadCoupledParamsFormat(format!( + "CryptDENull string '{}' is not valid: {:?}", + cryptde_text, e + ))), + } + } + } + + fn set_cryptde( + &mut self, + cryptde: &dyn CryptDE, + db_password: &str, + ) -> Result<(), PersistentConfigError> { + let cryptde_text = cryptde.to_string(); + + let cryptde_crypt = self + .scl + .encrypt( + "last_cryptde", + Some(cryptde_text), + Some(db_password.to_string()), + &self.dao, + )? + .expect("Can't be None here: both cryptde_text and db_password are supplied"); + self.dao.set("last_cryptde", Some(cryptde_crypt))?; + Ok(()) + } + fn earning_wallet(&self) -> Result, PersistentConfigError> { match self.earning_wallet_address()? { None => Ok(None), @@ -604,17 +677,21 @@ impl PersistentConfigurationReal { mod tests { use super::*; use crate::blockchain::bip39::Bip39; + use crate::bootstrapper::CryptDEPair; use crate::database::db_initializer::{ DbInitializationConfig, DbInitializer, DbInitializerReal, }; use crate::database::test_utils::transaction_wrapper_mock::TransactionInnerWrapperMockBuilder; use crate::db_config::config_dao::ConfigDaoRecord; + use crate::db_config::db_encryption_layer::DbEncryptionLayer; use crate::db_config::mocks::ConfigDaoMock; use crate::db_config::secure_config_layer::EXAMPLE_ENCRYPTED; - use crate::test_utils::main_cryptde; + use crate::sub_lib::cryptde_real::CryptDEReal; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; use bip39::{Language, MnemonicType}; + use itertools::Itertools; use lazy_static::lazy_static; + use masq_lib::blockchains::chains::Chain; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; use masq_lib::utils::{derivation_path, find_free_port}; use paste::paste; @@ -625,6 +702,7 @@ mod tests { use tiny_hderive::bip32::ExtendedPrivKey; lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); static ref CONFIG_TABLE_PARAMETERS: Vec = list_of_config_parameters(); } @@ -988,6 +1066,255 @@ mod tests { ); } + #[test] + fn cryptde_null_success() { + let db_password = "bellybutton".to_string(); + let cryptde = CryptDENull::new(Chain::Dev); + let cryptde_string = cryptde.to_string(); + let cryptde_crypt = DbEncryptionLayer::encrypt_value( + &Some(cryptde_string), + &Some(db_password.clone()), + "last_cryptde", + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Ok(ConfigDaoRecord::new( + "last_cryptde", + Some(&cryptde_crypt), + true, + ))) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(cryptde_crypt.as_str()), // just has to be something encrypted with the same password + true, + ))) + .get_result(Ok(ConfigDaoRecord::new("chain_name", Some("dev"), false))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde("bellybutton").unwrap().unwrap(); + + assert_eq!(result.public_key(), cryptde.public_key()); + let get_params = get_params_arc.lock().unwrap(); + assert_eq!( + *get_params, + vec!["last_cryptde", "example_encrypted", "chain_name"] + .into_iter() + .map(|s| s.to_string()) + .collect_vec() + ); + } + + #[test] + fn cryptde_real_success() { + let db_password = "bellybutton".to_string(); + let cryptde = CryptDEReal::new(Chain::Dev); + let cryptde_string = cryptde.to_string(); + let cryptde_crypt = DbEncryptionLayer::encrypt_value( + &Some(cryptde_string), + &Some(db_password.clone()), + "last_cryptde", + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Ok(ConfigDaoRecord::new( + "last_cryptde", + Some(cryptde_crypt.as_str()), + true, + ))) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(cryptde_crypt.as_str()), // just has to be something encrypted with the same password + true, + ))) + .get_result(Ok(ConfigDaoRecord::new("chain_name", Some("dev"), false))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde(db_password.as_str()).unwrap().unwrap(); + + assert_eq!(result.public_key(), cryptde.public_key()); + let get_params = get_params_arc.lock().unwrap(); + assert_eq!( + *get_params, + vec!["last_cryptde", "example_encrypted", "chain_name"] + .into_iter() + .map(|s| s.to_string()) + .collect_vec() + ); + } + + #[test] + fn cryptde_failure_null_value_in_database() { + let db_password = "bellybutton".to_string(); + let example_encrypted = DbEncryptionLayer::encrypt_value( + &Some("Example plaintext".to_string()), + &Some(db_password.clone()), + EXAMPLE_ENCRYPTED, + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Ok(ConfigDaoRecord::new("last_cryptde", None, true))) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(example_encrypted.as_str()), + true, + ))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde(db_password.as_str()).unwrap(); + + assert_eq!(result.is_none(), true); + } + + #[test] + fn cryptde_failure_not_present_means_database_schema_is_wrong() { + let db_password = "bellybutton".to_string(); + let example_encrypted = DbEncryptionLayer::encrypt_value( + &Some("Example plaintext".to_string()), + &Some(db_password.clone()), + EXAMPLE_ENCRYPTED, + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Err(ConfigDaoError::NotPresent)) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(example_encrypted.as_str()), + true, + ))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde(db_password.as_str()); + + assert_eq!(result.err().unwrap(), PersistentConfigError::NotPresent); + } + + #[test] + fn cryptde_bad_password() { + let bad_password = "bad password".to_string(); + let cryptde = CryptDEReal::new(Chain::Dev); + let cryptde_string = cryptde.to_string(); + let cryptde_crypt = DbEncryptionLayer::encrypt_value( + &Some(cryptde_string), + &Some("good_password".to_string()), + "last_cryptde", + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Ok(ConfigDaoRecord::new( + "last_cryptde", + Some(cryptde_crypt.as_str()), + true, + ))) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(cryptde_crypt.as_str()), // just has to be something encrypted with the same password + true, + ))) + .get_result(Ok(ConfigDaoRecord::new("chain_name", Some("dev"), false))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde(bad_password.as_str()); + + assert_eq!(result.err().unwrap(), PersistentConfigError::PasswordError); + } + + #[test] + fn cryptde_failure_other() { + let db_password = "bellybutton".to_string(); + let example_encrypted = DbEncryptionLayer::encrypt_value( + &Some("Example plaintext".to_string()), + &Some(db_password.clone()), + EXAMPLE_ENCRYPTED, + ) + .unwrap() + .unwrap(); + let get_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .get_params(&get_params_arc) + .get_result(Err(ConfigDaoError::DatabaseError( + "The database is itchy".to_string(), + ))) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(example_encrypted.as_str()), + true, + ))); + let subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + let result = subject.cryptde(db_password.as_str()); + + assert_eq!( + result.err().unwrap(), + PersistentConfigError::DatabaseError("Can't continue; last_cryptde is inaccessible: DatabaseError(\"The database is itchy\")".to_string()) + ); + } + + #[test] + fn set_cryptde_success() { + // We need two tests for cryptde(), because the code path for Null is different from the + // code path for Real. However, the code path for Null and Real is the same for + // set_cryptde(); so we only need one test. + let db_password = "bellybutton".to_string(); + let expected_cryptde = CryptDEReal::new(Chain::Dev); + let cryptde_string = expected_cryptde.to_string(); + let cryptde_crypt = DbEncryptionLayer::encrypt_value( + &Some(cryptde_string), + &Some(db_password.clone()), + "last_cryptde", + ) + .unwrap() + .unwrap(); + let set_params_arc = Arc::new(Mutex::new(vec![])); + let config_dao = ConfigDaoMock::new() + .set_params(&set_params_arc) + .get_result(Ok(ConfigDaoRecord::new( + EXAMPLE_ENCRYPTED, + Some(cryptde_crypt.as_str()), // just has to be something encrypted with the same password + true, + ))) + .get_result(Ok(ConfigDaoRecord::new( + "last_cryptde", + Some(cryptde_crypt.as_str()), + true, + ))) + .set_result(Ok(())); + let mut subject = PersistentConfigurationReal::new(Box::new(config_dao)); + + subject + .set_cryptde(&expected_cryptde, db_password.as_str()) + .unwrap(); + + let mut set_params = set_params_arc.lock().unwrap(); + let (_, crypt_text_opt) = set_params.remove(0); + let plain_text = DbEncryptionLayer::decrypt_value( + &crypt_text_opt, + &Some(db_password.clone()), + "last_cryptde", + ) + .unwrap() + .unwrap(); + let actual_cryptde = expected_cryptde + .make_from_str(plain_text.as_str(), Chain::Dev) + .unwrap(); + assert_eq!(actual_cryptde.public_key(), expected_cryptde.public_key()); + assert_eq!(set_params.len(), 0); + } + #[test] fn consuming_wallet_private_key_when_password_is_wrong() { let get_params_arc = Arc::new(Mutex::new(vec![])); @@ -1624,10 +1951,16 @@ mod tests { let example = "Aside from that, Mrs. Lincoln, how was the play?".as_bytes(); let example_encrypted = Bip39::encrypt_bytes(&example, "password").unwrap(); let node_descriptors = vec![ - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AQIDBA@1.2.3.4:1234")) - .unwrap(), - NodeDescriptor::try_from((main_cryptde(), "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345")) - .unwrap(), + NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", + )) + .unwrap(), + NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345", + )) + .unwrap(), ]; let node_descriptors_bytes = PlainData::new(&serde_cbor::ser::to_vec(&node_descriptors).unwrap()); @@ -1666,10 +1999,16 @@ mod tests { let example = "Aside from that, Mrs. Lincoln, how was the play?".as_bytes(); let example_encrypted = Bip39::encrypt_bytes(&example, "password").unwrap(); let node_descriptors = vec![ - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AQIDBA@1.2.3.4:1234")) - .unwrap(), - NodeDescriptor::try_from((main_cryptde(), "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345")) - .unwrap(), + NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", + )) + .unwrap(), + NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345", + )) + .unwrap(), ]; let set_params_arc = Arc::new(Mutex::new(vec![])); let config_dao = Box::new( diff --git a/node/src/dispatcher.rs b/node/src/dispatcher.rs index 067ddf22a3..ac698e043e 100644 --- a/node/src/dispatcher.rs +++ b/node/src/dispatcher.rs @@ -1,5 +1,5 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use crate::bootstrapper::Bootstrapper; +use crate::bootstrapper::{Bootstrapper, CryptDEPair}; use crate::stream_messages::{PoolBindMessage, RemovedStreamType}; use crate::sub_lib::dispatcher::InboundClientData; use crate::sub_lib::dispatcher::{DispatcherSubs, StreamShutdownMsg}; @@ -8,7 +8,6 @@ use crate::sub_lib::node_addr::NodeAddr; use crate::sub_lib::peer_actors::{BindMessage, NewPublicIp}; use crate::sub_lib::stream_handler_pool::TransmitDataMsg; use crate::sub_lib::utils::{handle_ui_crash_request, NODE_MAILBOX_CAPACITY}; -use crate::test_utils::main_cryptde; use actix::Actor; use actix::Addr; use actix::Context; @@ -40,6 +39,7 @@ pub struct Dispatcher { crashable: bool, node_descriptor: NodeDescriptor, to_stream: Option>, + cryptde_pair: CryptDEPair, logger: Logger, } @@ -144,19 +144,27 @@ impl Handler for Dispatcher { Some(node_addr) => { let ports = &node_addr.ports(); self.node_descriptor.node_addr_opt = Some(NodeAddr::new(&msg.new_ip, ports)); - Bootstrapper::report_local_descriptor(main_cryptde(), &self.node_descriptor); + Bootstrapper::report_local_descriptor( + self.cryptde_pair.main.as_ref(), + &self.node_descriptor, + ); } } } } impl Dispatcher { - pub fn new(node_descriptor: NodeDescriptor, crashable: bool) -> Dispatcher { + pub fn new( + node_descriptor: NodeDescriptor, + cryptde_pair: CryptDEPair, + crashable: bool, + ) -> Dispatcher { Dispatcher { subs: None, crashable, node_descriptor, to_stream: None, + cryptde_pair, logger: Logger::new("Dispatcher"), } } @@ -189,7 +197,10 @@ impl Dispatcher { fn handle_descriptor_request(&mut self, client_id: u64, context_id: u64) { let node_desc_str_opt = match &self.node_descriptor.node_addr_opt { Some(node_addr) if node_addr.ip_addr() == *NULL_IP_ADDRESS => None, - Some(_) => Some(self.node_descriptor.to_string(main_cryptde())), + Some(_) => Some( + self.node_descriptor + .to_string(self.cryptde_pair.main.as_ref()), + ), None => None, }; let response_inner = UiDescriptorResponse { @@ -210,14 +221,12 @@ impl Dispatcher { mod tests { use super::*; use crate::actor_system_factory::{ActorFactory, ActorFactoryReal}; - use crate::bootstrapper::BootstrapperConfig; + use crate::bootstrapper::{BootstrapperConfig, CryptDEPair}; use crate::node_test_utils::make_stream_handler_pool_subs_from_recorder; use crate::stream_messages::NonClandestineAttributes; - use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::dispatcher::Endpoint; use crate::sub_lib::neighborhood::NodeDescriptor; use crate::sub_lib::node_addr::NodeAddr; - use crate::test_utils::main_cryptde; use crate::test_utils::recorder::Recorder; use crate::test_utils::recorder::{make_recorder, peer_actors_builder}; use crate::test_utils::unshared_test_utils::prove_that_crash_request_handler_is_hooked_up; @@ -234,6 +243,15 @@ mod tests { use std::thread; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + static ref NODE_DESCRIPTOR: NodeDescriptor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-ropsten:gBviQbjOS3e5ReFQCvIhUM3i02d1zPleo1iXgXEN6zQ@12.23.45.67:1234" + )) + .unwrap(); + } + #[test] fn constants_have_correct_values() { assert_eq!(CRASH_KEY, "DISPATCHER"); @@ -243,18 +261,10 @@ mod tests { ); } - lazy_static! { - static ref NODE_DESCRIPTOR: NodeDescriptor = NodeDescriptor::try_from(( - main_cryptde(), - "masq://eth-ropsten:gBviQbjOS3e5ReFQCvIhUM3i02d1zPleo1iXgXEN6zQ@12.23.45.67:1234" - )) - .unwrap(); - } - #[test] fn sends_inbound_data_for_proxy_server_to_proxy_server() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let subject_ibcd = subject_addr.clone().recipient::(); let proxy_server = Recorder::new(); @@ -296,7 +306,7 @@ mod tests { #[test] fn sends_inbound_data_for_hopper_to_hopper() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let (hopper, hopper_awaiter, hopper_recording_arc) = make_recorder(); let client_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); @@ -336,7 +346,7 @@ mod tests { #[should_panic(expected = "ProxyServer unbound in Dispatcher")] fn inbound_client_data_handler_panics_when_proxy_server_is_unbound() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let subject_ibcd = subject_addr.recipient::(); let client_addr = SocketAddr::from_str("1.2.3.4:8765").unwrap(); @@ -362,7 +372,7 @@ mod tests { #[should_panic(expected = "Hopper unbound in Dispatcher")] fn inbound_client_data_handler_panics_when_hopper_is_unbound() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let subject_ibcd = subject_addr.recipient::(); let client_addr = SocketAddr::from_str("1.2.3.4:8765").unwrap(); @@ -388,7 +398,7 @@ mod tests { #[should_panic(expected = "StreamHandlerPool unbound in Dispatcher")] fn panics_when_stream_handler_pool_is_unbound() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let subject_obcd = subject_addr.recipient::(); let socket_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); @@ -409,7 +419,7 @@ mod tests { #[test] fn forwards_outbound_data_to_stream_handler_pool() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let subject_addr = subject.start(); let subject_obcd = subject_addr.clone().recipient::(); let stream_handler_pool = Recorder::new(); @@ -453,7 +463,7 @@ mod tests { #[test] fn handle_stream_shutdown_msg_routes_non_clandestine_to_proxy_server() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let addr = subject.start(); let (proxy_server, _, proxy_server_recording_arc) = make_recorder(); let (neighborhood, _, neighborhood_recording_arc) = make_recorder(); @@ -487,7 +497,7 @@ mod tests { #[test] fn handle_stream_shutdown_msg_routes_clandestine_to_neighborhood() { let system = System::new("test"); - let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), false); + let subject = Dispatcher::new(NODE_DESCRIPTOR.clone(), CRYPTDE_PAIR.clone(), false); let addr = subject.start(); let (proxy_server, _, proxy_server_recording_arc) = make_recorder(); let (neighborhood, _, neighborhood_recording_arc) = make_recorder(); @@ -521,7 +531,7 @@ mod tests { )] fn dispatcher_can_be_crashed_properly_but_not_improperly() { let crashable = true; - let actor = Dispatcher::new(NodeDescriptor::default(), crashable); + let actor = Dispatcher::new(NodeDescriptor::default(), CRYPTDE_PAIR.clone(), crashable); prove_that_crash_request_handler_is_hooked_up(actor, CRASH_KEY); } @@ -536,7 +546,7 @@ mod tests { &IpAddr::from_str("0.0.0.0").unwrap(), &node_descriptor.node_addr_opt.as_ref().unwrap().ports(), )); - let subject = Dispatcher::new(node_descriptor.clone(), false); + let subject = Dispatcher::new(node_descriptor.clone(), CRYPTDE_PAIR.clone(), false); let addr = subject.start(); let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); addr.try_send(BindMessage { peer_actors }).unwrap(); @@ -576,7 +586,9 @@ mod tests { &NodeToUiMessage { target: MessageTarget::ClientId(1234), body: UiDescriptorResponse { - node_descriptor_opt: Some(new_node_descriptor.to_string(main_cryptde())), + node_descriptor_opt: Some( + new_node_descriptor.to_string(CRYPTDE_PAIR.main.as_ref()) + ), } .tmb(4321) } @@ -584,7 +596,7 @@ mod tests { TestLogHandler::new().exists_log_containing( format!( "INFO: Bootstrapper: MASQ Node local descriptor: {}", - new_node_descriptor.to_string(main_cryptde()) + new_node_descriptor.to_string(CRYPTDE_PAIR.main.as_ref()) ) .as_str(), ); @@ -597,7 +609,7 @@ mod tests { let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); let mut bootstrapper_config = BootstrapperConfig::new(); let node_descriptor = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@13.23.13.23:4545", )) .unwrap(); @@ -608,7 +620,7 @@ mod tests { }; // Here dispatcher takes what it needs from the BootstrapperConfig let (dispatcher_subs, _) = - ActorFactoryReal::new().make_and_start_dispatcher(&bootstrapper_config); + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_dispatcher(&bootstrapper_config); let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); dispatcher_subs .bind @@ -627,7 +639,9 @@ mod tests { &NodeToUiMessage { target: MessageTarget::ClientId(1234), body: UiDescriptorResponse { - node_descriptor_opt: Some(node_descriptor.to_string(main_cryptde())), + node_descriptor_opt: Some( + node_descriptor.to_string(CRYPTDE_PAIR.main.as_ref()) + ), } .tmb(4321) } @@ -642,7 +656,7 @@ mod tests { let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); let mut bootstrapper_config = BootstrapperConfig::new(); let node_descriptor = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@0.0.0.0:4545", )) .unwrap(); @@ -653,7 +667,7 @@ mod tests { }; // Here dispatcher doesn't get what it needs from the BootstrapperConfig let (dispatcher_subs, _) = - ActorFactoryReal::new().make_and_start_dispatcher(&bootstrapper_config); + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_dispatcher(&bootstrapper_config); let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); dispatcher_subs .bind @@ -687,7 +701,7 @@ mod tests { let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); let mut bootstrapper_config = BootstrapperConfig::new(); let node_descriptor = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:OHsC2CAm4rmfCkaFfiynwxflUgVTJRb2oY5mWxNCQkY@0.0.0.0:4545", )) .unwrap(); @@ -698,7 +712,7 @@ mod tests { }; // Here dispatcher doesn't get what it needs from the BootstrapperConfig let (dispatcher_subs, _) = - ActorFactoryReal::new().make_and_start_dispatcher(&bootstrapper_config); + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_dispatcher(&bootstrapper_config); let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); dispatcher_subs .bind @@ -738,10 +752,10 @@ mod tests { let (ui_gateway, _, ui_gateway_recording_arc) = make_recorder(); let mut bootstrapper_config = BootstrapperConfig::new(); let mut node_descriptor = NodeDescriptor::from(( - main_cryptde().public_key(), + CRYPTDE_PAIR.main.public_key(), &NodeAddr::default(), Chain::default(), - main_cryptde() as &dyn CryptDE, + CRYPTDE_PAIR.main.as_ref(), )); node_descriptor.node_addr_opt = None; bootstrapper_config.node_descriptor = node_descriptor; @@ -750,7 +764,7 @@ mod tests { body: UiDescriptorRequest {}.tmb(4321), }; let (dispatcher_subs, _) = - ActorFactoryReal::new().make_and_start_dispatcher(&bootstrapper_config); + ActorFactoryReal::new(&CRYPTDE_PAIR).make_and_start_dispatcher(&bootstrapper_config); let peer_actors = peer_actors_builder().ui_gateway(ui_gateway).build(); dispatcher_subs .bind diff --git a/node/src/hopper/consuming_service.rs b/node/src/hopper/consuming_service.rs index b0df18b1f2..7d5660a8be 100644 --- a/node/src/hopper/consuming_service.rs +++ b/node/src/hopper/consuming_service.rs @@ -13,7 +13,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::time::SystemTime; pub struct ConsumingService { - cryptde: &'static dyn CryptDE, + cryptde: Box, to_dispatcher: Recipient, to_hopper: Recipient, logger: Logger, @@ -21,7 +21,7 @@ pub struct ConsumingService { impl ConsumingService { pub fn new( - cryptde: &'static dyn CryptDE, + cryptde: Box, to_dispatcher: Recipient, to_hopper: Recipient, ) -> Self { @@ -41,18 +41,22 @@ impl ConsumingService { ); let target_key = incipient_cores_package.public_key.clone(); let target_node_addr = incipient_cores_package.node_addr.clone(); - match LiveCoresPackage::from_no_lookup_incipient(incipient_cores_package, self.cryptde) { + match LiveCoresPackage::from_no_lookup_incipient( + incipient_cores_package, + self.cryptde.as_ref(), + ) { Ok((live_package, _)) => { - let encrypted_package = match encodex(self.cryptde, &target_key, &live_package) { - Ok(p) => p, - Err(e) => { - error!( - self.logger, - "Could not accept CORES package for transmission: {:?}", e - ); - return; - } - }; + let encrypted_package = + match encodex(self.cryptde.as_ref(), &target_key, &live_package) { + Ok(p) => p, + Err(e) => { + error!( + self.logger, + "Could not accept CORES package for transmission: {:?}", e + ); + return; + } + }; // This port should eventually be chosen by the Traffic Analyzer somehow. let socket_addrs: Vec = target_node_addr.into(); self.launch_lcp(encrypted_package, Endpoint::Socket(socket_addrs[0])); @@ -75,7 +79,7 @@ impl ConsumingService { match LiveCoresPackage::from_incipient(incipient_cores_package, self.cryptde.borrow()) { Ok((live_package, next_hop)) => { let encrypted_package = - match encodex(self.cryptde, &next_hop.public_key, &live_package) { + match encodex(self.cryptde.as_ref(), &next_hop.public_key, &live_package) { Ok(p) => p, Err(e) => { error!(self.logger, "Couldn't encode package: {:?}", e); @@ -132,6 +136,7 @@ impl ConsumingService { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::node_test_utils::check_timestamp; use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::dispatcher::{Component, InboundClientData}; @@ -140,8 +145,9 @@ mod tests { use crate::sub_lib::route::RouteSegment; use crate::test_utils::recorder::make_recorder; use crate::test_utils::recorder::peer_actors_builder; - use crate::test_utils::{main_cryptde, make_meaningless_message_type, make_paying_wallet}; + use crate::test_utils::{make_meaningless_message_type, make_paying_wallet}; use actix::System; + use lazy_static::lazy_static; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; @@ -149,13 +155,17 @@ mod tests { use std::str::FromStr; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn converts_no_lookup_incipient_message_to_live_and_sends_to_dispatcher() { let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); let target_key = PublicKey::new(&[1, 2]); let target_node_addr = NodeAddr::new(&IpAddr::from_str("1.2.1.2").unwrap(), &[1212, 2121]); let package = NoLookupIncipientCoresPackage::new( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), &target_key, &target_node_addr, make_meaningless_message_type(), @@ -164,7 +174,7 @@ mod tests { let system = System::new(""); let peer_actors = peer_actors_builder().dispatcher(dispatcher).build(); let subject = ConsumingService::new( - main_cryptde(), + CRYPTDE_PAIR.main.dup(), peer_actors.dispatcher.from_dispatcher_client, peer_actors.hopper.from_dispatcher, ); @@ -175,13 +185,17 @@ mod tests { system.run(); let dispatcher_recording = dispatcher_recording_arc.lock().unwrap(); let transmit_data_msg = dispatcher_recording.get_record::(0); - let (lcp, _) = LiveCoresPackage::from_no_lookup_incipient(package, main_cryptde()).unwrap(); + let (lcp, _) = + LiveCoresPackage::from_no_lookup_incipient(package, CRYPTDE_PAIR.main.as_ref()) + .unwrap(); assert_eq!( &TransmitDataMsg { endpoint: Endpoint::Socket(SocketAddr::from_str("1.2.1.2:1212").unwrap()), last_data: false, sequence_number: None, - data: encodex(main_cryptde(), &target_key, &lcp).unwrap().into(), + data: encodex(CRYPTDE_PAIR.main.as_ref(), &target_key, &lcp) + .unwrap() + .into(), }, transmit_data_msg ); @@ -200,7 +214,7 @@ mod tests { let system = System::new(""); let peer_actors = peer_actors_builder().build(); let subject = ConsumingService::new( - main_cryptde(), + CRYPTDE_PAIR.main.dup(), peer_actors.dispatcher.from_dispatcher_client, peer_actors.hopper.from_dispatcher, ); @@ -214,7 +228,7 @@ mod tests { #[test] fn consume_converts_incipient_message_to_live_and_sends_to_dispatcher() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); let destination_key = PublicKey::new(&[65, 65, 65]); @@ -234,7 +248,7 @@ mod tests { let system = System::new("converts_incipient_message_to_live_and_sends_to_dispatcher"); let peer_actors = peer_actors_builder().dispatcher(dispatcher).build(); let subject = ConsumingService::new( - cryptde, + cryptde.dup(), peer_actors.dispatcher.from_dispatcher_client, peer_actors.hopper.from_dispatcher, ); @@ -261,7 +275,7 @@ mod tests { #[test] fn consume_sends_zero_hop_incipient_directly_to_hopper() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let (hopper, _, hopper_recording_arc) = make_recorder(); let destination_key = cryptde.public_key(); @@ -281,7 +295,7 @@ mod tests { let system = System::new("consume_sends_zero_hop_incipient_directly_to_hopper"); let peer_actors = peer_actors_builder().hopper(hopper).build(); let subject = ConsumingService::new( - cryptde, + cryptde.dup(), peer_actors.dispatcher.from_dispatcher_client, peer_actors.hopper.from_dispatcher, ); @@ -320,11 +334,11 @@ mod tests { let to_dispatcher = peer_actors.dispatcher.from_dispatcher_client; let to_hopper = peer_actors.hopper.from_dispatcher; - let subject = ConsumingService::new(main_cryptde(), to_dispatcher, to_hopper); + let subject = ConsumingService::new(CRYPTDE_PAIR.main.dup(), to_dispatcher, to_hopper); subject.consume( IncipientCoresPackage::new( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), Route { hops: vec![] }, make_meaningless_message_type(), &PublicKey::new(&[1, 2]), diff --git a/node/src/hopper/live_cores_package.rs b/node/src/hopper/live_cores_package.rs index 9ec2106788..2b05b27e87 100644 --- a/node/src/hopper/live_cores_package.rs +++ b/node/src/hopper/live_cores_package.rs @@ -91,6 +91,7 @@ impl LiveCoresPackage { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::cryptde::encodex; use crate::sub_lib::cryptde::PlainData; use crate::sub_lib::cryptde_null::CryptDENull; @@ -100,16 +101,21 @@ mod tests { use crate::sub_lib::route::RouteSegment; use crate::sub_lib::route::{Route, RouteError}; use crate::test_utils::{ - main_cryptde, make_meaningless_message_type, make_meaningless_route, make_paying_wallet, + make_meaningless_message_type, make_meaningless_route, make_paying_wallet, }; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::net::{IpAddr, SocketAddr}; use std::str::FromStr; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn live_cores_package_can_be_constructed_from_scratch() { let payload = CryptData::new(&[5, 6]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let route = Route::one_way( RouteSegment::new( @@ -134,7 +140,7 @@ mod tests { let destination_cryptde = CryptDENull::from(&destination_key, TEST_DEFAULT_CHAIN); let relay_key = PublicKey::new(&[1, 2]); let relay_cryptde = CryptDENull::from(&relay_key, TEST_DEFAULT_CHAIN); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let serialized_payload = serde_cbor::ser::to_vec(&make_meaningless_message_type()).unwrap(); let encrypted_payload = cryptde .encode(&destination_key, &PlainData::new(&serialized_payload)) @@ -184,7 +190,7 @@ mod tests { fn to_next_live_complains_about_bad_input() { let subject = LiveCoresPackage::new(Route { hops: vec![] }, CryptData::new(&[])); - let result = subject.into_next_live(main_cryptde()); + let result = subject.into_next_live(CRYPTDE_PAIR.main.as_ref()); assert_eq!( result, @@ -194,7 +200,7 @@ mod tests { #[test] fn live_cores_package_can_be_constructed_from_no_lookup_incipient_cores_package() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key34 = PublicKey::new(&[3, 4]); let node_addr34 = NodeAddr::new(&IpAddr::from_str("3.4.3.4").unwrap(), &[1234]); let mut route = Route::single_hop(&key34, cryptde).unwrap(); @@ -214,7 +220,7 @@ mod tests { #[test] fn from_no_lookup_incipient_relays_errors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let blank_key = PublicKey::new(&[]); let node_addr34 = NodeAddr::new(&IpAddr::from_str("3.4.3.4").unwrap(), &[1234]); @@ -235,7 +241,7 @@ mod tests { #[test] fn live_cores_package_can_be_constructed_from_incipient_cores_package() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let key12 = cryptde.public_key(); let key34 = PublicKey::new(&[3, 4]); @@ -270,7 +276,7 @@ mod tests { #[test] fn from_incipient_complains_about_problems_decrypting_next_hop() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let incipient = IncipientCoresPackage::new( cryptde, Route { hops: vec![] }, @@ -298,7 +304,7 @@ mod tests { let relay_cryptde = CryptDENull::from(&relay_key, TEST_DEFAULT_CHAIN); let second_stop_key = PublicKey::new(&[5, 6]); let second_stop_cryptde = CryptDENull::from(&second_stop_key, TEST_DEFAULT_CHAIN); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let encrypted_payload = encodex(cryptde, &first_stop_key, &payload).unwrap(); let paying_wallet = make_paying_wallet(b"wallet"); let contract_address = TEST_DEFAULT_CHAIN.rec().contract; @@ -384,13 +390,13 @@ mod tests { fn to_expired_complains_about_bad_route() { let subject = LiveCoresPackage::new( Route { hops: vec![] }, - CryptData::new(main_cryptde().private_key().as_slice()), + CryptData::new(CRYPTDE_PAIR.main.as_ref().private_key().as_slice()), ); let result = subject.to_expired( SocketAddr::from_str("1.2.3.4:1234").unwrap(), - main_cryptde(), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), + CRYPTDE_PAIR.main.as_ref(), ); assert_eq!( @@ -401,8 +407,10 @@ mod tests { #[test] fn live_cores_package_serialization_deserialization() { - let original = - LiveCoresPackage::new(make_meaningless_route(), CryptData::new(&[1, 2, 3, 4])); + let original = LiveCoresPackage::new( + make_meaningless_route(&CRYPTDE_PAIR), + CryptData::new(&[1, 2, 3, 4]), + ); let serialized = serde_cbor::ser::to_vec(&original).unwrap(); diff --git a/node/src/hopper/mod.rs b/node/src/hopper/mod.rs index 8cfe5e9553..5880164408 100644 --- a/node/src/hopper/mod.rs +++ b/node/src/hopper/mod.rs @@ -24,7 +24,7 @@ use routing_service::RoutingService; pub const CRASH_KEY: &str = "HOPPER"; pub struct Hopper { - cryptdes: CryptDEPair, + cryptde_pair: CryptDEPair, consuming_service: Option, routing_service: Option, per_routing_service: u64, @@ -44,12 +44,12 @@ impl Handler for Hopper { fn handle(&mut self, msg: BindMessage, ctx: &mut Self::Context) -> Self::Result { ctx.set_mailbox_capacity(NODE_MAILBOX_CAPACITY); self.consuming_service = Some(ConsumingService::new( - self.cryptdes.main, + self.cryptde_pair.main.dup(), msg.peer_actors.dispatcher.from_dispatcher_client.clone(), msg.peer_actors.hopper.from_dispatcher.clone(), )); self.routing_service = Some(RoutingService::new( - self.cryptdes, + self.cryptde_pair.clone(), RoutingServiceSubs { proxy_client_subs_opt: msg.peer_actors.proxy_client_opt, proxy_server_subs: msg.peer_actors.proxy_server, @@ -117,7 +117,7 @@ impl Handler for Hopper { impl Hopper { pub fn new(config: HopperConfig) -> Hopper { Hopper { - cryptdes: config.cryptdes, + cryptde_pair: config.cryptde_pair, consuming_service: None, routing_service: None, crashable: config.crashable, @@ -151,16 +151,20 @@ mod tests { use crate::sub_lib::route::RouteSegment; use crate::test_utils::unshared_test_utils::prove_that_crash_request_handler_is_hooked_up; use crate::test_utils::{ - alias_cryptde, main_cryptde, make_cryptde_pair, make_meaningless_message_type, - make_paying_wallet, route_to_proxy_client, + make_meaningless_message_type, make_paying_wallet, route_to_proxy_client, }; use actix::Actor; use actix::System; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::net::SocketAddr; use std::str::FromStr; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!(CRASH_KEY, "HOPPER"); @@ -169,8 +173,7 @@ mod tests { #[test] #[should_panic(expected = "Hopper unbound: no RoutingService")] fn panics_if_routing_service_is_unbound() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let client_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); let route = route_to_proxy_client(&main_cryptde.public_key(), main_cryptde); let serialized_payload = serde_cbor::ser::to_vec(&make_meaningless_message_type()).unwrap(); @@ -198,10 +201,7 @@ mod tests { }; let system = System::new("panics_if_routing_service_is_unbound"); let subject = Hopper::new(HopperConfig { - cryptdes: CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + cryptde_pair: CRYPTDE_PAIR.clone(), per_routing_service: 100, per_routing_byte: 200, is_decentralized: false, @@ -218,8 +218,7 @@ mod tests { #[test] #[should_panic(expected = "Hopper unbound: no ConsumingService")] fn panics_if_consuming_service_is_unbound() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let next_key = PublicKey::new(&[65, 65, 65]); let route = Route::one_way( @@ -241,10 +240,7 @@ mod tests { .unwrap(); let system = System::new("panics_if_consuming_service_is_unbound"); let subject = Hopper::new(HopperConfig { - cryptdes: CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + cryptde_pair: CRYPTDE_PAIR.clone(), per_routing_service: 100, per_routing_byte: 200, is_decentralized: false, @@ -264,7 +260,7 @@ mod tests { )] fn hopper_can_be_crashed_properly_but_not_improperly() { let hopper = Hopper::new(HopperConfig { - cryptdes: make_cryptde_pair(), + cryptde_pair: CRYPTDE_PAIR.clone(), per_routing_service: 100, per_routing_byte: 200, is_decentralized: false, diff --git a/node/src/hopper/routing_service.rs b/node/src/hopper/routing_service.rs index 05d8af9d68..7f7134d203 100644 --- a/node/src/hopper/routing_service.rs +++ b/node/src/hopper/routing_service.rs @@ -31,7 +31,7 @@ pub struct RoutingServiceSubs { } pub struct RoutingService { - cryptdes: CryptDEPair, + cryptde_pair: CryptDEPair, routing_service_subs: RoutingServiceSubs, per_routing_service: u64, per_routing_byte: u64, @@ -41,14 +41,14 @@ pub struct RoutingService { impl RoutingService { pub fn new( - cryptdes: CryptDEPair, + cryptde_pair: CryptDEPair, routing_service_subs: RoutingServiceSubs, per_routing_service: u64, per_routing_byte: u64, is_decentralized: bool, ) -> RoutingService { RoutingService { - cryptdes, + cryptde_pair, routing_service_subs, per_routing_service, per_routing_byte, @@ -70,7 +70,7 @@ impl RoutingService { let ibcd_but_data = ibcd.clone_but_data(); let live_package = match decodex::( - self.cryptdes.main, + self.cryptde_pair.main.as_ref(), &CryptData::new(&ibcd.data[..]), ) { Ok(lcp) => lcp, @@ -86,7 +86,7 @@ impl RoutingService { } }; - let next_hop = match live_package.route.next_hop(self.cryptdes.main.borrow()) { + let next_hop = match live_package.route.next_hop(self.cryptde_pair.main.borrow()) { Ok(hop) => hop, Err(e) => { error!( @@ -128,7 +128,7 @@ impl RoutingService { } fn is_destined_for_here(&self, next_hop: &LiveHop) -> bool { - &next_hop.public_key == self.cryptdes.main.public_key() + &next_hop.public_key == self.cryptde_pair.main.public_key() } fn route_data_internally( @@ -160,7 +160,7 @@ impl RoutingService { next_hop.component, immediate_neighbor_addr, live_package, - next_hop.payer_owns_secret_key(&self.cryptdes.main.digest()), + next_hop.payer_owns_secret_key(&self.cryptde_pair.main.digest()), ) } } @@ -170,7 +170,7 @@ impl RoutingService { live_package: LiveCoresPackage, ibcd_but_data: &InboundClientData, ) { - let (_, next_lcp) = match live_package.into_next_live(self.cryptdes.main) { + let (_, next_lcp) = match live_package.into_next_live(self.cryptde_pair.main.as_ref()) { Ok(x) => x, Err(e) => { error!(self.logger, "bad zero-hop route: {:?}", e); @@ -178,8 +178,8 @@ impl RoutingService { } }; let payload = encodex( - self.cryptdes.main, - self.cryptdes.main.public_key(), + self.cryptde_pair.main.as_ref(), + self.cryptde_pair.main.public_key(), &next_lcp, ) .expect("Encryption of LiveCoresPackage failed"); @@ -227,12 +227,12 @@ impl RoutingService { ) -> Option> { let data_len = live_package.payload.len(); let (payload_cryptde, cryptde_name) = match component { - Component::ProxyServer => (self.cryptdes.alias, "alias"), - _ => (self.cryptdes.main, "main"), + Component::ProxyServer => (self.cryptde_pair.alias.as_ref(), "alias"), + _ => (self.cryptde_pair.main.as_ref(), "main"), }; let expired_package = match live_package.to_expired( immediate_neighbor_addr, - self.cryptdes.main, + self.cryptde_pair.main.as_ref(), payload_cryptde, ) { Ok(pkg) => pkg, @@ -403,7 +403,7 @@ impl RoutingService { let payload_size = live_package.payload.len(); match payer { Some(payer) => { - if !payer.owns_secret_key(&self.cryptdes.main.digest()) { + if !payer.owns_secret_key(&self.cryptde_pair.main.digest()) { warning!(self.logger, "Refusing to route Live CORES package with {}-byte payload without proof of {} paying wallet ownership.", payload_size, payer.wallet @@ -468,7 +468,7 @@ impl RoutingService { last_data: bool, ) -> Result { let (next_hop, next_live_package) = - match live_package.into_next_live(self.cryptdes.main.borrow()) { + match live_package.into_next_live(self.cryptde_pair.main.borrow()) { Err(e) => { let msg = format!( "Couldn't get next hop and outgoing LCP from incoming LCP: {:?}", @@ -479,15 +479,18 @@ impl RoutingService { } Ok(p) => p, }; - let next_live_package_enc = - match encodex(self.cryptdes.main, &next_hop.public_key, &next_live_package) { - Ok(nlpe) => nlpe, - Err(e) => { - let msg = format!("Couldn't serialize or encrypt outgoing LCP: {:?}", e); - error!(self.logger, "{}", &msg); - return Err(CryptdecError::OtherError(msg)); - } - }; + let next_live_package_enc = match encodex( + self.cryptde_pair.main.as_ref(), + &next_hop.public_key, + &next_live_package, + ) { + Ok(nlpe) => nlpe, + Err(e) => { + let msg = format!("Couldn't serialize or encrypt outgoing LCP: {:?}", e); + error!(self.logger, "{}", &msg); + return Err(CryptdecError::OtherError(msg)); + } + }; Ok(TransmitDataMsg { endpoint: Endpoint::Key(next_hop.public_key), last_data, @@ -501,7 +504,6 @@ impl RoutingService { mod tests { use super::*; use crate::accountant::db_access_objects::banned_dao::BAN_CACHE; - use crate::bootstrapper::Bootstrapper; use crate::neighborhood::gossip::{GossipBuilder, Gossip_0v1}; use crate::node_test_utils::check_timestamp; use crate::sub_lib::accountant::ReportRoutingServiceProvidedMessage; @@ -521,11 +523,12 @@ mod tests { use crate::test_utils::recorder::{make_recorder, peer_actors_builder}; use crate::test_utils::unshared_test_utils::{make_request_payload, make_response_payload}; use crate::test_utils::{ - alias_cryptde, main_cryptde, make_cryptde_pair, make_meaningless_message_type, - make_paying_wallet, rate_pack_routing, rate_pack_routing_byte, route_from_proxy_client, - route_to_proxy_client, route_to_proxy_server, + make_meaningless_message_type, make_paying_wallet, rate_pack_routing, + rate_pack_routing_byte, route_from_proxy_client, route_to_proxy_client, + route_to_proxy_server, }; use actix::System; + use lazy_static::lazy_static; use masq_lib::test_utils::environment_guard::EnvironmentGuard; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; @@ -533,17 +536,22 @@ mod tests { use std::str::FromStr; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn dns_resolution_failures_are_reported_to_the_proxy_server() { - let cryptdes = make_cryptde_pair(); - let route = route_to_proxy_server(&cryptdes.main.public_key(), cryptdes.main); + let cryptde_pair = CRYPTDE_PAIR.clone(); + let route = + route_to_proxy_server(&cryptde_pair.main.public_key(), cryptde_pair.main.as_ref()); let stream_key = StreamKey::make_meaningless_stream_key(); let dns_resolve_failure = DnsResolveFailure_0v1::new(stream_key); let lcp = LiveCoresPackage::new( route, encodex( - cryptdes.alias, - &cryptdes.alias.public_key(), + cryptde_pair.alias.as_ref(), + &cryptde_pair.alias.public_key(), &MessageType::DnsResolveFailed(VersionedData::new( &crate::sub_lib::migrations::dns_resolve_failure::MIGRATIONS, &dns_resolve_failure.clone(), @@ -551,7 +559,12 @@ mod tests { ) .unwrap(), ); - let data_enc = encodex(cryptdes.main, &cryptdes.main.public_key(), &lcp).unwrap(); + let data_enc = encodex( + cryptde_pair.main.as_ref(), + &cryptde_pair.main.public_key(), + &lcp, + ) + .unwrap(); let inbound_client_data = InboundClientData { timestamp: SystemTime::now(), client_addr: SocketAddr::from_str("1.2.3.4:5678").unwrap(), @@ -566,7 +579,7 @@ mod tests { let system = System::new("dns_resolution_failures_are_reported_to_the_proxy_server"); let peer_actors = peer_actors_builder().proxy_server(proxy_server).build(); let subject = RoutingService::new( - cryptdes, + cryptde_pair, RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -593,13 +606,24 @@ mod tests { #[test] fn logs_and_ignores_message_that_cannot_be_deserialized() { init_test_logging(); - let cryptdes = make_cryptde_pair(); - let route = route_from_proxy_client(&cryptdes.main.public_key(), cryptdes.main); + let cryptde_pair = CRYPTDE_PAIR.clone(); + let route = + route_from_proxy_client(&cryptde_pair.main.public_key(), cryptde_pair.main.as_ref()); let lcp = LiveCoresPackage::new( route, - encodex(cryptdes.main, &cryptdes.main.public_key(), &[42u8]).unwrap(), + encodex( + cryptde_pair.main.as_ref(), + &cryptde_pair.main.public_key(), + &[42u8], + ) + .unwrap(), ); - let data_enc = encodex(cryptdes.main, &cryptdes.main.public_key(), &lcp).unwrap(); + let data_enc = encodex( + cryptde_pair.main.as_ref(), + &cryptde_pair.main.public_key(), + &lcp, + ) + .unwrap(); let inbound_client_data = InboundClientData { timestamp: SystemTime::now(), client_addr: SocketAddr::from_str("1.2.3.4:5678").unwrap(), @@ -611,7 +635,7 @@ mod tests { }; let peer_actors = peer_actors_builder().build(); let subject = RoutingService::new( - cryptdes, + cryptde_pair, RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -635,18 +659,14 @@ mod tests { #[test] fn logs_and_ignores_message_that_cannot_be_decrypted() { init_test_logging(); - let (main_cryptde, alias_cryptde) = { - //initialization to real CryptDEs - let pair = Bootstrapper::pub_initialize_cryptdes_for_testing(&None, &None); - (pair.main, pair.alias) - }; + let main_cryptde = CryptDEReal::new(TEST_DEFAULT_CHAIN); let rogue_cryptde = CryptDEReal::new(TEST_DEFAULT_CHAIN); - let route = route_from_proxy_client(main_cryptde.public_key(), main_cryptde); + let route = route_from_proxy_client(main_cryptde.public_key(), &main_cryptde); let lcp = LiveCoresPackage::new( route, encodex(&rogue_cryptde, rogue_cryptde.public_key(), &[42u8]).unwrap(), ); - let data_enc = encodex(main_cryptde, main_cryptde.public_key(), &lcp).unwrap(); + let data_enc = encodex(&main_cryptde, main_cryptde.public_key(), &lcp).unwrap(); let inbound_client_data = InboundClientData { timestamp: SystemTime::now(), client_addr: SocketAddr::from_str("1.2.3.4:5678").unwrap(), @@ -657,11 +677,12 @@ mod tests { data: data_enc.into(), }; let peer_actors = peer_actors_builder().build(); + let cryptde_pair = CryptDEPair::new( + main_cryptde.dup(), + Box::new(CryptDEReal::new(TEST_DEFAULT_CHAIN)), + ); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + cryptde_pair, RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -685,8 +706,7 @@ mod tests { #[test] fn logs_and_ignores_message_that_had_invalid_destination() { init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let route = route_from_proxy_client(&main_cryptde.public_key(), main_cryptde); let payload = GossipBuilder::empty(); let lcp = LiveCoresPackage::new( @@ -710,10 +730,7 @@ mod tests { }; let peer_actors = peer_actors_builder().build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -734,8 +751,7 @@ mod tests { fn converts_live_message_to_expired_for_existing_proxy_client() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let (component, _, component_recording_arc) = make_recorder(); let route = route_to_proxy_client(&main_cryptde.public_key(), main_cryptde); let payload = make_request_payload(0, main_cryptde); @@ -766,10 +782,7 @@ mod tests { let system = System::new("converts_live_message_to_expired_for_proxy_client"); let peer_actors = peer_actors_builder().proxy_client(component).build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -809,8 +822,7 @@ mod tests { let _eg = EnvironmentGuard::new(); init_test_logging(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let route = route_to_proxy_client(&main_cryptde.public_key(), main_cryptde); let payload = make_request_payload(0, main_cryptde); let lcp = LiveCoresPackage::new( @@ -839,10 +851,7 @@ mod tests { let system = System::new("converts_live_message_to_expired_for_proxy_client"); let peer_actors = peer_actors_builder().build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: None, proxy_server_subs: peer_actors.proxy_server, @@ -869,8 +878,8 @@ mod tests { fn converts_live_message_to_expired_for_proxy_server() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let (proxy_server, _, proxy_server_recording_arc) = make_recorder(); let route = route_to_proxy_server(&main_cryptde.public_key(), main_cryptde); let payload = make_response_payload(0); @@ -898,10 +907,7 @@ mod tests { let system = System::new("converts_live_message_to_expired_for_proxy_server"); let peer_actors = peer_actors_builder().proxy_server(proxy_server).build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -940,8 +946,7 @@ mod tests { fn converts_live_gossip_message_to_expired_for_neighborhood() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let (component, _, component_recording_arc) = make_recorder(); let mut route = Route::one_way( RouteSegment::new( @@ -979,10 +984,7 @@ mod tests { let system = System::new("converts_live_gossip_message_to_expired_for_neighborhood"); let peer_actors = peer_actors_builder().neighborhood(component).build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1020,7 +1022,7 @@ mod tests { fn converts_live_gossip_failure_message_to_expired_for_neighborhood() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (component, _, component_recording_arc) = make_recorder(); let mut route = Route::one_way( RouteSegment::new( @@ -1056,10 +1058,7 @@ mod tests { System::new("converts_live_gossip_failure_message_to_expired_for_neighborhood"); let peer_actors = peer_actors_builder().neighborhood(component).build(); let subject = RoutingService::new( - CryptDEPair { - main: cryptde, - alias: alias_cryptde(), - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1097,8 +1096,7 @@ mod tests { fn passes_on_inbound_client_data_not_meant_for_this_node() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let address_paying_wallet = Wallet::from(paying_wallet.address()); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); @@ -1138,10 +1136,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1195,8 +1190,7 @@ mod tests { fn reprocesses_inbound_client_data_meant_for_this_node_and_destined_for_hopper() { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let (hopper, _, hopper_recording_arc) = make_recorder(); let route = Route::one_way( @@ -1233,10 +1227,7 @@ mod tests { ); let peer_actors = peer_actors_builder().hopper(hopper).build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1281,8 +1272,7 @@ mod tests { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let origin_key = PublicKey::new(&[1, 2]); let origin_cryptde = CryptDENull::from(&origin_key, TEST_DEFAULT_CHAIN); let destination_key = PublicKey::new(&[3, 4]); @@ -1329,10 +1319,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1366,8 +1353,7 @@ mod tests { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let public_key = main_cryptde.public_key(); let payload = ClientRequest(VersionedData::new( &crate::sub_lib::migrations::client_response_payload::MIGRATIONS, @@ -1430,10 +1416,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1467,8 +1450,7 @@ mod tests { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let current_key = main_cryptde.public_key(); let origin_key = PublicKey::new(&[1, 2]); let destination_key = PublicKey::new(&[5, 6]); @@ -1528,10 +1510,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1568,8 +1547,7 @@ mod tests { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let contract_address = TEST_DEFAULT_CHAIN.rec().contract; BAN_CACHE.insert(paying_wallet.clone()); @@ -1604,10 +1582,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1638,8 +1613,7 @@ mod tests { let _eg = EnvironmentGuard::new(); BAN_CACHE.clear(); init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); BAN_CACHE.insert(paying_wallet.clone()); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); @@ -1678,10 +1652,7 @@ mod tests { .accountant(accountant) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1731,7 +1702,7 @@ mod tests { .dispatcher(dispatcher) .build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1761,8 +1732,7 @@ mod tests { #[test] fn route_logs_and_ignores_invalid_live_cores_package() { init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); let lcp = LiveCoresPackage::new(Route { hops: vec![] }, CryptData::new(&[])); let data_ser = PlainData::new(&serde_cbor::ser::to_vec(&lcp).unwrap()[..]); let data_enc = main_cryptde @@ -1789,10 +1759,7 @@ mod tests { .dispatcher(dispatcher) .build(); let subject = RoutingService::new( - CryptDEPair { - main: main_cryptde, - alias: alias_cryptde, - }, + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1824,7 +1791,7 @@ mod tests { init_test_logging(); let peer_actors = peer_actors_builder().build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -1874,14 +1841,15 @@ mod tests { { let peer_actors = peer_actors_builder().build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), make_routing_service_subs(peer_actors), 100, 200, true, ); - let route = Route::single_hop(&PublicKey::new(b"1234"), subject.cryptdes.main).unwrap(); - let payload = payload_factory(&subject.cryptdes); + let route = Route::single_hop(&PublicKey::new(b"1234"), subject.cryptde_pair.main.as_ref()) + .unwrap(); + let payload = payload_factory(&subject.cryptde_pair); let live_package = LiveCoresPackage::new(route, payload); subject.route_data_to_peripheral_component( @@ -1896,10 +1864,10 @@ mod tests { #[test] fn route_data_to_peripheral_component_uses_main_key_on_payload_for_proxy_client() { - let payload_factory = |cryptdes: &CryptDEPair| { + let payload_factory = |cryptde_pair: &CryptDEPair| { encodex( - cryptdes.main, - cryptdes.main.public_key(), + cryptde_pair.main.as_ref(), + cryptde_pair.main.public_key(), &MessageType::ClientRequest(VersionedData::new( &crate::sub_lib::migrations::client_request_payload::MIGRATIONS, &ClientRequestPayload_0v1 { @@ -1922,10 +1890,10 @@ mod tests { #[test] fn route_data_to_peripheral_component_uses_alias_key_on_payload_for_proxy_server() { - let payload_factory = |cryptdes: &CryptDEPair| { + let payload_factory = |cryptde_pair: &CryptDEPair| { encodex( - cryptdes.alias, - cryptdes.alias.public_key(), + cryptde_pair.alias.as_ref(), + cryptde_pair.alias.public_key(), &MessageType::DnsResolveFailed(VersionedData::new( &crate::sub_lib::migrations::dns_resolve_failure::MIGRATIONS, &DnsResolveFailure_0v1 { @@ -1943,10 +1911,10 @@ mod tests { #[test] fn route_data_to_peripheral_component_uses_main_key_on_payload_for_neighborhood() { - let payload_factory = |cryptdes: &CryptDEPair| { + let payload_factory = |cryptde_pair: &CryptDEPair| { encodex( - cryptdes.main, - cryptdes.main.public_key(), + cryptde_pair.main.as_ref(), + cryptde_pair.main.public_key(), &MessageType::GossipFailure(VersionedData::new( &crate::sub_lib::migrations::gossip_failure::MIGRATIONS, &GossipFailure_0v1::Unknown, @@ -1962,10 +1930,10 @@ mod tests { #[test] fn route_data_to_peripheral_component_uses_main_key_on_payload_for_hopper() { - let payload_factory = |cryptdes: &CryptDEPair| { + let payload_factory = |cryptde_pair: &CryptDEPair| { encodex( - cryptdes.main, - cryptdes.main.public_key(), + cryptde_pair.main.as_ref(), + cryptde_pair.main.public_key(), &MessageType::ClientResponse(VersionedData::new( &crate::sub_lib::migrations::client_request_payload::MIGRATIONS, &ClientResponsePayload_0v1 { @@ -1988,7 +1956,7 @@ mod tests { let (neighborhood, _, neighborhood_recording_arc) = make_recorder(); let peer_actors = peer_actors_builder().neighborhood(neighborhood).build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -2027,7 +1995,7 @@ mod tests { let (proxy_client, _, proxy_client_recording_arc) = make_recorder(); let peer_actors = peer_actors_builder().proxy_client(proxy_client).build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -2066,7 +2034,7 @@ mod tests { let (proxy_server, _, proxy_server_recording_arc) = make_recorder(); let peer_actors = peer_actors_builder().proxy_server(proxy_server).build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -2105,7 +2073,7 @@ mod tests { let (hopper, _, hopper_recording_arc) = make_recorder(); let peer_actors = peer_actors_builder().hopper(hopper).build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, @@ -2144,7 +2112,7 @@ mod tests { let (neighborhood, _, neighborhood_recording_arc) = make_recorder(); let peer_actors = peer_actors_builder().neighborhood(neighborhood).build(); let subject = RoutingService::new( - make_cryptde_pair(), + CRYPTDE_PAIR.clone(), RoutingServiceSubs { proxy_client_subs_opt: peer_actors.proxy_client_opt, proxy_server_subs: peer_actors.proxy_server, diff --git a/node/src/neighborhood/gossip_acceptor.rs b/node/src/neighborhood/gossip_acceptor.rs index 935c984341..f99eba27d9 100644 --- a/node/src/neighborhood/gossip_acceptor.rs +++ b/node/src/neighborhood/gossip_acceptor.rs @@ -731,13 +731,13 @@ impl GossipHandler for IntroductionHandler { )); } } - let connection_progess_message = ConnectionProgressMessage { + let connection_progress_message = ConnectionProgressMessage { peer_addr: introducer_ip_addr, event: ConnectionProgressEvent::IntroductionGossipReceived(introducee_ip_addr), }; neighborhood_metadata .cpm_recipient - .try_send(connection_progess_message) + .try_send(connection_progress_message) .expect("Neighborhood is dead"); let (debut, target_key, target_node_addr) = GossipAcceptorReal::make_debut_triple(database, &introducee) @@ -1322,13 +1322,13 @@ pub trait GossipAcceptor: Send /* Send because lazily-written tests require it * ) -> GossipAcceptanceResult; } -pub struct GossipAcceptorReal<'a> { - cryptde: &'a dyn CryptDE, +pub struct GossipAcceptorReal { + cryptde: Box, gossip_handlers: Vec>, logger: Logger, } -impl<'a> GossipAcceptor for GossipAcceptorReal<'a> { +impl GossipAcceptor for GossipAcceptorReal { fn handle( &self, database: &mut NeighborhoodDatabase, @@ -1350,7 +1350,7 @@ impl<'a> GossipAcceptor for GossipAcceptorReal<'a> { handler_ref.type_name() ); handler_ref.handle( - self.cryptde, + self.cryptde.as_ref(), database, agrs, gossip_source, @@ -1365,8 +1365,8 @@ impl<'a> GossipAcceptor for GossipAcceptorReal<'a> { } } -impl<'a> GossipAcceptorReal<'a> { - pub fn new(cryptde: &'a dyn CryptDE) -> GossipAcceptorReal { +impl GossipAcceptorReal { + pub fn new(cryptde: Box) -> GossipAcceptorReal { let logger = Logger::new("GossipAcceptor"); GossipAcceptorReal { gossip_handlers: vec![ @@ -1417,6 +1417,7 @@ impl<'a> GossipAcceptorReal<'a> { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::neighborhood::gossip_producer::GossipProducer; use crate::neighborhood::gossip_producer::GossipProducerReal; use crate::neighborhood::node_record::NodeRecord; @@ -1433,10 +1434,11 @@ mod tests { make_node_records, public_keys_from_node_records, DB_PATCH_SIZE_FOR_TEST, }; use crate::test_utils::unshared_test_utils::make_cpm_recipient; - use crate::test_utils::{assert_contains, main_cryptde, vec_to_set}; + use crate::test_utils::{assert_contains, vec_to_set}; use actix::System; use ip_country_lib::dbip_country::COUNTRIES; use itertools::Itertools; + use lazy_static::lazy_static; use masq_lib::messages::ExitLocation; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; @@ -1446,6 +1448,10 @@ mod tests { use std::str::FromStr; use std::time::Duration; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!(MAX_DEGREE, 5); @@ -1635,7 +1641,7 @@ mod tests { assert_eq!( result, Qualification::Malformed( - format! ("Debut from 200.200.200.200:2000 for AgMEBQ does not accept connections, yet contained NodeAddr") + "Debut from 200.200.200.200:2000 for AgMEBQ does not accept connections, yet contained NodeAddr".to_string() ), ); } @@ -2344,9 +2350,10 @@ mod tests { assert_eq!( result, - Qualification::Malformed(format!( + Qualification::Malformed( "Standard Gossip from 1.2.3.4:1234 contains a record with this Node's public key" - )), + .to_string() + ), ); } @@ -2416,9 +2423,9 @@ mod tests { assert_eq!( result, - Qualification::Malformed(format!( - "Standard Gossip from 1.2.3.4:1234 contains multiple records claiming to be from 3.4.5.6" - )), + Qualification::Malformed( + "Standard Gossip from 1.2.3.4:1234 contains multiple records claiming to be from 3.4.5.6".to_string() + ), ); } @@ -2536,8 +2543,7 @@ mod tests { /* Over here, root node is A and patch contains [A, B, C, D]. A---B---C---D---E - What does this test proves: - The distance of A and E is more than 3 hops, hence E is being excluded. + This test proves that E is excluded, because the distance of A and E is more than 3 hops. */ let subject = StandardGossipHandler::new(Logger::new("test")); @@ -2697,7 +2703,7 @@ mod tests { */ - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let subject = StandardGossipHandler::new(Logger::new("test")); let node_a = make_node_record(1111, true); let node_b = make_node_record(2222, true); @@ -2780,7 +2786,7 @@ mod tests { // instead of the GossipAcceptor (which would identify it as a Debut), // so the test is unrealistic. Also that the Gossip is ignored because // Node B isn't in Node A's patch, which matters to a StandardGossipHandler. - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1111, true); let mut root_db = db_from_node(&root_node); let src_node = make_node_record(2222, true); @@ -2814,7 +2820,7 @@ mod tests { #[test] fn cpm_is_sent_in_case_full_neighborship_doesn_t_exist_and_is_created() { // Received Reply for Acceptance of Debut Gossip - (false, true) - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1111, true); let mut root_db = db_from_node(&root_node); let src_node = make_node_record(2222, true); @@ -2862,7 +2868,7 @@ mod tests { #[test] fn cpm_is_not_sent_in_case_full_neighborship_exists_and_is_destroyed() { // Somebody banned us. (true, false) - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1111, true); let mut root_db = db_from_node(&root_node); let src_node = make_node_record(2222, true); @@ -2901,7 +2907,7 @@ mod tests { #[test] fn cpm_is_not_sent_in_case_full_neighborship_exists_and_continues() { // Standard Gossips received after Neighborship is established (true, true) - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1111, true); let mut root_db = db_from_node(&root_node); let src_node = make_node_record(2222, true); @@ -2980,7 +2986,7 @@ mod tests { #[test] fn last_gossip_handler_rejects_everything() { - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let reject_handler = subject.gossip_handlers.last().unwrap(); let db = make_meaningless_db(); let (debut, _, debut_gossip_source) = make_debut(1234, Mode::Standard); @@ -3050,7 +3056,7 @@ mod tests { .node(node_a.public_key(), false) .node(node_b.public_key(), false) .build(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let result = subject.handle( &mut dest_db, @@ -3446,7 +3452,7 @@ mod tests { .node(src_node.public_key(), true) .build(); let gossip_source: SocketAddr = src_node.node_addr_opt().unwrap().into(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let result = subject.handle( &mut dest_db, @@ -3484,7 +3490,7 @@ mod tests { .build(); let debut_agrs = debut.try_into().unwrap(); let gossip_source: SocketAddr = src_node.node_addr_opt().unwrap().into(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let begin_at = time_t_timestamp(); let result = subject.handle( @@ -3518,7 +3524,7 @@ mod tests { .build(); let debut_agrs = debut.try_into().unwrap(); let gossip_source = src_node.node_addr_opt().unwrap().into(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let result = subject.handle( &mut dest_db, @@ -3535,7 +3541,7 @@ mod tests { let gnr = GossipNodeRecord::from(( root_node.inner.clone(), root_node.node_addr_opt(), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), )); let debut_gossip = Gossip_0v1 { node_records: vec![gnr], @@ -3567,7 +3573,7 @@ mod tests { .build(); let debut_agrs = debut.try_into().unwrap(); let gossip_source = src_node.node_addr_opt().unwrap().into(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let result = subject.handle( &mut dest_db, @@ -3584,7 +3590,7 @@ mod tests { let gnr = GossipNodeRecord::from(( root_node.inner.clone(), root_node.node_addr_opt(), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), )); let debut_gossip = Gossip_0v1 { node_records: vec![gnr], @@ -3613,7 +3619,7 @@ mod tests { #[test] fn introduction_gossip_handler_sends_cpm_for_neighborship_established() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let subject = IntroductionHandler::new(Logger::new("test")); @@ -3661,7 +3667,7 @@ mod tests { let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let (gossip, pass_target, gossip_source) = make_pass(2345); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let result = subject.handle( &mut db, @@ -3686,7 +3692,7 @@ mod tests { #[test] fn handles_a_new_pass_target() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let subject = PassHandler::new(); @@ -3733,7 +3739,7 @@ mod tests { #[test] fn handles_pass_target_that_is_not_yet_expired() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let subject = PassHandler::new(); @@ -3780,7 +3786,7 @@ mod tests { #[test] fn handles_pass_target_that_is_a_part_of_a_different_connection_progress() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let subject = PassHandler::new(); @@ -3817,7 +3823,7 @@ mod tests { #[test] fn handles_pass_target_that_has_expired() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let root_node = make_node_record(1234, true); let mut db = db_from_node(&root_node); let subject = PassHandler::new(); @@ -3938,7 +3944,7 @@ mod tests { .node(node_e.public_key(), true) .node(node_f.public_key(), true) .build(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let before = time_t_timestamp(); let result = subject.handle( @@ -4170,7 +4176,7 @@ mod tests { .node(current_node.public_key(), false) .node(obsolete_node.public_key(), false) .build(); - let subject = make_subject(main_cryptde()); + let subject = make_subject(CRYPTDE_PAIR.main.as_ref()); let original_dest_db = dest_db.clone(); let before = time_t_timestamp(); @@ -4536,7 +4542,7 @@ mod tests { } fn make_subject(crypt_de: &dyn CryptDE) -> GossipAcceptorReal { - GossipAcceptorReal::new(crypt_de) + GossipAcceptorReal::new(crypt_de.dup()) } fn assert_node_records_eq(actual: &NodeRecord, expected: &NodeRecord, before: u32, after: u32) { diff --git a/node/src/neighborhood/gossip_producer.rs b/node/src/neighborhood/gossip_producer.rs index cf528c4021..158a63ab5b 100644 --- a/node/src/neighborhood/gossip_producer.rs +++ b/node/src/neighborhood/gossip_producer.rs @@ -69,7 +69,12 @@ impl GossipProducer for GossipProducerReal { && ( node_record_ref.public_key() == database.root().public_key() || target_node_ref.has_half_neighbor(node_record_ref.public_key()) - // TODO SC-894/GH-132: Do we really want to reveal this? + // TODO The OR clause here is so that we don't tell the target Node the IP + // address of any Node it doesn't already know the IP address of. However, + // if the target Node does already know this Node's IP address, why should + // we not tell it? What if the target Node is evil, and it claimed to know + // that the IP address of every Node in its Gossip was 1.2.3.4? Then this + // code would helpfully correct it. ); so_far.node(node_record_ref.public_key(), reveal_node_addr) }); diff --git a/node/src/neighborhood/mod.rs b/node/src/neighborhood/mod.rs index e76c5f5667..aaa9d0f889 100644 --- a/node/src/neighborhood/mod.rs +++ b/node/src/neighborhood/mod.rs @@ -9,7 +9,7 @@ pub mod node_location; pub mod node_record; pub mod overall_connection_status; -use crate::bootstrapper::BootstrapperConfig; +use crate::bootstrapper::{BootstrapperConfig, CryptDEPair}; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::persistent_configuration::{ @@ -92,7 +92,7 @@ pub const ZZ_COUNTRY_CODE_STRING: &str = "ZZ"; pub const DEFAULT_PREALLOCATION_VEC: usize = 10; pub struct Neighborhood { - cryptde: &'static dyn CryptDE, + cryptde: Box, hopper_opt: Option>, hopper_no_lookup_opt: Option>, connected_signal_opt: Option>, @@ -379,7 +379,7 @@ enum RouteDirection { } impl Neighborhood { - pub fn new(cryptde: &'static dyn CryptDE, config: &BootstrapperConfig) -> Self { + pub fn new(cryptde_pair: CryptDEPair, config: &BootstrapperConfig) -> Self { let neighborhood_config = &config.neighborhood_config; let min_hops = neighborhood_config.min_hops; let db_patch_size = Neighborhood::calculate_db_patch_size(min_hops); @@ -392,10 +392,9 @@ impl Neighborhood { ) } let neighborhood_database = NeighborhoodDatabase::new( - cryptde.public_key(), neighborhood_mode.clone(), config.earning_wallet.clone(), - cryptde, + cryptde_pair.main.as_ref(), ); let is_mainnet = config.blockchain_bridge_config.chain.is_mainnet(); let initial_neighbors: Vec = neighbor_configs @@ -405,7 +404,7 @@ impl Neighborhood { if mainnet_nc != is_mainnet { panic!( "Neighbor {} is {}on the mainnet blockchain", - nc.to_string(cryptde), + nc.to_string(cryptde_pair.main.as_ref()), if mainnet_nc { "" } else { "not " } ); } @@ -416,12 +415,12 @@ impl Neighborhood { let overall_connection_status = OverallConnectionStatus::new(initial_neighbors); Neighborhood { - cryptde, + cryptde: cryptde_pair.main.dup(), hopper_opt: None, hopper_no_lookup_opt: None, connected_signal_opt: None, node_to_ui_recipient_opt: None, - gossip_acceptor: Box::new(GossipAcceptorReal::new(cryptde)), + gossip_acceptor: Box::new(GossipAcceptorReal::new(cryptde_pair.main.dup())), gossip_producer: Box::new(GossipProducerReal::new()), neighborhood_database, consuming_wallet_opt: config.consuming_wallet_opt.clone(), @@ -738,7 +737,7 @@ impl Neighborhood { .node_by_key(k) .expectv("NodeRecord"), self.chain, - self.cryptde, + self.cryptde.as_ref(), )) }) .collect() @@ -918,7 +917,7 @@ impl Neighborhood { fn gossip_to_neighbors(&mut self) { self.neighborhood_database .root_mut() - .regenerate_signed_gossip(self.cryptde); + .regenerate_signed_gossip(self.cryptde.as_ref()); let neighbors = self .neighborhood_database .root() @@ -939,9 +938,13 @@ impl Neighborhood { fn gossip_to_neighbor(&self, neighbor: &PublicKey, gossip: Gossip_0v1) { let gossip_len = gossip.node_records.len(); let route = self.create_single_hop_route(neighbor); - let package = - IncipientCoresPackage::new(self.cryptde, route, gossip.clone().into(), neighbor) - .expect("Key magically disappeared"); + let package = IncipientCoresPackage::new( + self.cryptde.as_ref(), + route, + gossip.clone().into(), + neighbor, + ) + .expect("Key magically disappeared"); info!( self.logger, "Sending update Gossip about {} Nodes to Node {}", gossip_len, neighbor @@ -969,7 +972,7 @@ impl Neighborhood { vec![self.cryptde.public_key(), destination], Component::Neighborhood, ), - self.cryptde, + self.cryptde.as_ref(), None, None, ) @@ -987,7 +990,7 @@ impl Neighborhood { vec![self.cryptde.public_key(), self.cryptde.public_key()], Component::ProxyServer, ), - self.cryptde, + self.cryptde.as_ref(), None, return_route_id, None, @@ -1069,7 +1072,7 @@ impl Neighborhood { route: Route::round_trip( over, back, - self.cryptde, + self.cryptde.as_ref(), self.consuming_wallet_opt.clone(), return_route_id, Some(self.chain.rec().contract), @@ -1942,7 +1945,7 @@ impl Neighborhood { target_node_addr: &NodeAddr, ) { let package = match NoLookupIncipientCoresPackage::new( - self.cryptde, + self.cryptde.as_ref(), target_key, target_node_addr, message_type, @@ -2169,6 +2172,7 @@ mod tests { use actix::Recipient; use actix::System; use itertools::Itertools; + use lazy_static::lazy_static; use serde_cbor; use std::any::TypeId; use std::cell::RefCell; @@ -2214,6 +2218,7 @@ mod tests { use crate::sub_lib::versioned_data::VersionedData; use crate::test_utils::assert_contains; use crate::test_utils::make_meaningless_route; + use crate::test_utils::make_paying_wallet; use crate::test_utils::make_wallet; use crate::test_utils::neighborhood_test_utils::{ cryptdes_from_node_records, db_from_node, linearly_connect_nodes, @@ -2233,10 +2238,10 @@ mod tests { prove_that_crash_request_handler_is_hooked_up, AssertionsMessage, }; use crate::test_utils::vec_to_set; - use crate::test_utils::{main_cryptde, make_paying_wallet}; use super::*; use crate::accountant::test_utils::bc_from_earning_wallet; + use crate::bootstrapper::CryptDEPair; use crate::neighborhood::overall_connection_status::ConnectionStageErrors::{ NoGossipResponseReceived, PassLoopFound, TcpConnectionFailed, }; @@ -2246,6 +2251,10 @@ mod tests { use crate::test_utils::unshared_test_utils::notify_handlers::NotifyLaterHandleMock; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + impl Neighborhood { fn get_node_country_undesirability(&self, pubkey: &PublicKey) -> u32 { self.neighborhood_database @@ -2298,7 +2307,7 @@ mod tests { let neighborhood_config = NeighborhoodConfig { mode, min_hops }; let subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( neighborhood_config, make_wallet("earning"), @@ -2398,8 +2407,8 @@ mod tests { #[test] fn introduction_results_in_full_neighborship_in_debutant_db_and_enrich_db_countries_on_one_hop() { - let debut_node = make_global_cryptde_node_record(1111, true); - let mut debut_subject = neighborhood_from_nodes(&debut_node, None); + let debut_node = make_global_cryptde_node_record(1111, true, &CRYPTDE_PAIR); + let mut debut_subject = neighborhood_from_nodes(&debut_node, None, &CRYPTDE_PAIR); debut_subject.min_hops = Hops::OneHop; let persistent_config = PersistentConfigurationMock::new().set_past_neighbors_result(Ok(())); @@ -2440,7 +2449,7 @@ mod tests { expected = "Neighbor masq://eth-ropsten:AQIDBA@1.2.3.4:1234 is not on the mainnet blockchain" )] fn cant_create_mainnet_neighborhood_with_non_mainnet_neighbors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let mut bc = bc_from_nc_plus( NeighborhoodConfig { @@ -2457,7 +2466,7 @@ mod tests { ); bc.blockchain_bridge_config.chain = DEFAULT_CHAIN; - let _ = Neighborhood::new(cryptde, &bc); + let _ = Neighborhood::new(CRYPTDE_PAIR.clone(), &bc); } #[test] @@ -2465,7 +2474,7 @@ mod tests { expected = "Neighbor masq://eth-mainnet:AQIDBA@1.2.3.4:1234 is on the mainnet blockchain" )] fn cant_create_non_mainnet_neighborhood_with_mainnet_neighbors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let mut bc = bc_from_nc_plus( NeighborhoodConfig { @@ -2482,16 +2491,16 @@ mod tests { ); bc.blockchain_bridge_config.chain = TEST_DEFAULT_CHAIN; - let _ = Neighborhood::new(cryptde, &bc); + let _ = Neighborhood::new(CRYPTDE_PAIR.clone(), &bc); } #[test] fn node_with_zero_hop_config_creates_single_node_database() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::ZeroHop, @@ -2512,12 +2521,12 @@ mod tests { #[test] fn node_with_originate_only_config_is_decentralized_with_neighbor_but_not_ip() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let neighbor: NodeRecord = make_node_record(1234, true); let earning_wallet = make_wallet("earning"); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::OriginateOnly( @@ -2553,13 +2562,12 @@ mod tests { .initialize(&data_dir, DbInitializationConfig::test_default()) .unwrap(); } - let cryptde = main_cryptde(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let system = System::new("node_with_no_neighbor_configs_ignores_bootstrap_neighborhood_now_message"); let mut subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::ZeroHop, @@ -2592,7 +2600,7 @@ mod tests { #[test] fn neighborhood_adds_nodes_and_links() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let one_neighbor_node = make_node_record(3456, true); @@ -2600,7 +2608,7 @@ mod tests { let this_node_addr = NodeAddr::new(&IpAddr::from_str("5.4.3.2").unwrap(), &[5678]); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -2699,7 +2707,7 @@ mod tests { }; let bootstrap_config = bc_from_nc_plus(neighborhood_config, make_wallet("earning"), None, "test"); - let mut subject = Neighborhood::new(main_cryptde(), &bootstrap_config); + let mut subject = Neighborhood::new(CRYPTDE_PAIR.clone(), &bootstrap_config); subject .overall_connection_status .get_connection_progress_by_ip(peer_1) @@ -3167,7 +3175,7 @@ mod tests { min_hops: MIN_HOPS_FOR_TEST, }; let mut subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( neighborhood_config, make_wallet("earning"), @@ -3219,14 +3227,14 @@ mod tests { #[test] fn gossip_failures_eventually_stop_the_neighborhood() { init_test_logging(); - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let one_neighbor_node: NodeRecord = make_node_record(3456, true); let another_neighbor_node: NodeRecord = make_node_record(4567, true); let this_node_addr = NodeAddr::new(&IpAddr::from_str("5.4.3.2").unwrap(), &[5678]); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -3251,14 +3259,14 @@ mod tests { let ecp1 = ExpiredCoresPackage::new( one_neighbor_node.node_addr_opt().unwrap().into(), None, - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), GossipFailure_0v1::NoNeighbors, 0, ); let ecp2 = ExpiredCoresPackage::new( another_neighbor_node.node_addr_opt().unwrap().into(), None, - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), GossipFailure_0v1::ManualRejection, 0, ); @@ -3311,7 +3319,7 @@ mod tests { #[test] fn route_query_works_when_node_is_set_for_one_hop_and_no_consuming_wallet() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let system = System::new("route_query_works_when_node_is_set_for_one_hop_and_no_consuming_wallet"); @@ -3413,7 +3421,7 @@ mod tests { #[test] fn route_query_responds_with_standard_zero_hop_route_when_requested() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let system = System::new("responds_with_standard_zero_hop_route_when_requested"); let mut subject = make_standard_subject(); subject.mode = NeighborhoodModeLight::ZeroHop; @@ -3484,7 +3492,7 @@ mod tests { #[test] fn route_query_messages() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let system = System::new("route_query_messages"); let mut subject = make_standard_subject(); @@ -3605,7 +3613,7 @@ mod tests { #[test] fn return_route_ids_increase() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let system = System::new("return_route_ids_increase"); let (_, _, _, mut subject) = make_o_r_e_subject(); subject.min_hops = Hops::TwoHops; @@ -5063,7 +5071,7 @@ mod tests { #[test] fn gossips_after_removing_a_neighbor() { let (hopper, hopper_awaiter, hopper_recording) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let this_node = NodeRecord::new_for_tests( @@ -5086,7 +5094,7 @@ mod tests { thread::spawn(move || { let system = System::new("gossips_after_removing_a_neighbor"); let mut subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -5203,9 +5211,9 @@ mod tests { let gossip_acceptor = GossipAcceptorMock::new() .handle_params(&handle_params_arc) .handle_result(GossipAcceptanceResult::Ignored); - let mut subject_node = make_global_cryptde_node_record(1234, true); // 9e7p7un06eHs6frl5A + let mut subject_node = make_global_cryptde_node_record(1234, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); subject.gossip_acceptor = Box::new(gossip_acceptor); let gossip = GossipBuilder::new(&subject.neighborhood_database) .node(subject_node.public_key(), true) @@ -5213,7 +5221,7 @@ mod tests { let cores_package = ExpiredCoresPackage { immediate_neighbor: subject_node.node_addr_opt().unwrap().into(), paying_wallet: None, - remaining_route: make_meaningless_route(), + remaining_route: make_meaningless_route(&CRYPTDE_PAIR), payload: gossip.clone(), payload_len: 0, }; @@ -5246,9 +5254,9 @@ mod tests { #[test] fn neighborhood_sends_only_an_acceptance_debut_when_an_acceptance_debut_is_provided() { let introduction_target_node = make_node_record(7345, true); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1050, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(introduction_target_node.clone()) @@ -5297,7 +5305,7 @@ mod tests { #[test] fn neighborhood_transmits_gossip_failure_properly() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); let public_key = PublicKey::new(&[1, 2, 3, 4]); let node_addr = NodeAddr::from_str("1.2.3.4:1234").unwrap(); @@ -5307,7 +5315,8 @@ mod tests { public_key.clone(), node_addr.clone(), )); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let (hopper, _, hopper_recording_arc) = make_recorder(); let system = System::new("neighborhood_transmits_gossip_failure_properly"); let peer_actors = peer_actors_builder().hopper(hopper).build(); @@ -5397,9 +5406,10 @@ mod tests { #[test] fn neighborhood_does_not_start_accountant_if_no_route_can_be_made() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let mut replacement_database = subject.neighborhood_database.clone(); replacement_database.add_node(neighbor.clone()).unwrap(); replacement_database @@ -5427,9 +5437,10 @@ mod tests { #[test] fn neighborhood_does_not_start_accountant_if_already_connected() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let replacement_database = subject.neighborhood_database.clone(); subject.gossip_acceptor = Box::new(DatabaseReplacementGossipAcceptor { replacement_database, @@ -5484,8 +5495,8 @@ mod tests { let (node_to_ui_recipient, _) = make_node_to_ui_recipient(); let peer_1 = make_node_record(1234, true); let peer_2 = make_node_record(6721, true); - let desc_1 = peer_1.node_descriptor(Chain::Dev, main_cryptde()); - let desc_2 = peer_2.node_descriptor(Chain::Dev, main_cryptde()); + let desc_1 = peer_1.node_descriptor(Chain::Dev, CRYPTDE_PAIR.main.as_ref()); + let desc_2 = peer_2.node_descriptor(Chain::Dev, CRYPTDE_PAIR.main.as_ref()); let this_node = make_node_record(7777, true); let initial_node_descriptors = vec![desc_1, desc_2]; let neighborhood_config = NeighborhoodConfig { @@ -5498,7 +5509,7 @@ mod tests { }; let bootstrap_config = bc_from_nc_plus(neighborhood_config, make_wallet("earning"), None, "test"); - let mut subject = Neighborhood::new(main_cryptde(), &bootstrap_config); + let mut subject = Neighborhood::new(CRYPTDE_PAIR.clone(), &bootstrap_config); subject.node_to_ui_recipient_opt = Some(node_to_ui_recipient); subject.gossip_acceptor = Box::new(gossip_acceptor); subject.db_patch_size = 6; @@ -5644,11 +5655,12 @@ mod tests { #[test] fn neighborhood_updates_past_neighbors_when_neighbor_list_changes() { - let cryptde: &dyn CryptDE = main_cryptde(); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&old_neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&old_neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(old_neighbor.clone()) @@ -5689,9 +5701,10 @@ mod tests { #[test] fn neighborhood_removes_past_neighbors_when_neighbor_list_goes_empty() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(neighbor.clone()) @@ -5723,10 +5736,10 @@ mod tests { #[test] fn neighborhood_does_not_update_past_neighbors_when_neighbor_list_does_not_change() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let steadfast_neighbor = make_node_record(1111, true); let mut subject: Neighborhood = - neighborhood_from_nodes(&subject_node, Some(&steadfast_neighbor)); + neighborhood_from_nodes(&subject_node, Some(&steadfast_neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(steadfast_neighbor.clone()) @@ -5757,10 +5770,11 @@ mod tests { #[test] fn neighborhood_does_not_update_past_neighbors_without_password_even_when_neighbor_list_changes( ) { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&old_neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&old_neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(old_neighbor.clone()) @@ -5791,10 +5805,11 @@ mod tests { #[test] fn neighborhood_warns_when_past_neighbors_update_fails_because_of_database_lock() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&old_neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&old_neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(old_neighbor.clone()) @@ -5823,10 +5838,11 @@ mod tests { #[test] fn neighborhood_logs_error_when_past_neighbors_update_fails_for_another_reason() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let old_neighbor = make_node_record(1111, true); let new_neighbor = make_node_record(2222, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&old_neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&old_neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(old_neighbor.clone()) @@ -5855,9 +5871,10 @@ mod tests { #[test] fn handle_new_public_ip_changes_public_ip_and_country_code_nothing_else() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(1234, true); + let subject_node = make_global_cryptde_node_record(1234, true, &CRYPTDE_PAIR); let neighbor = make_node_record(1050, true); - let mut subject: Neighborhood = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject: Neighborhood = + neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); subject .neighborhood_database .root_mut() @@ -5905,9 +5922,9 @@ mod tests { #[test] fn neighborhood_sends_from_gossip_producer_when_acceptance_introductions_are_not_provided() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1050, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let full_neighbor = make_node_record(1234, true); let half_neighbor = make_node_record(2345, true); subject @@ -5955,7 +5972,11 @@ mod tests { assert_eq!(hopper_recording.len(), 2); fn digest(package: IncipientCoresPackage) -> (PublicKey, CryptData) { ( - package.route.next_hop(main_cryptde()).unwrap().public_key, + package + .route + .next_hop(CRYPTDE_PAIR.main.as_ref()) + .unwrap() + .public_key, package.payload, ) } @@ -5965,7 +5986,7 @@ mod tests { ( full_neighbor.public_key().clone(), encodex( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), full_neighbor.public_key(), &MessageType::Gossip(gossip.clone().into()), ) @@ -5974,7 +5995,7 @@ mod tests { ( half_neighbor.public_key().clone(), encodex( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), half_neighbor.public_key(), &MessageType::Gossip(gossip.into()), ) @@ -5998,18 +6019,19 @@ mod tests { ) .as_str(), ); - let key_as_str = format!("{}", main_cryptde().public_key()); + let key_as_str = format!("{}", CRYPTDE_PAIR.main.as_ref().public_key()); tlh.exists_log_containing(&format!("Sent Gossip: digraph db {{ \"src\" [label=\"Gossip From:\\n{}\\n5.5.5.5\"]; \"dest\" [label=\"Gossip To:\\nAQIDBA\\n1.2.3.4\"]; \"src\" -> \"dest\" [arrowhead=empty]; }}", &key_as_str[..8])); tlh.exists_log_containing(&format!("Sent Gossip: digraph db {{ \"src\" [label=\"Gossip From:\\n{}\\n5.5.5.5\"]; \"dest\" [label=\"Gossip To:\\nAgMEBQ\\n2.3.4.5\"]; \"src\" -> \"dest\" [arrowhead=empty]; }}", &key_as_str[..8])); } #[test] fn neighborhood_sends_no_gossip_when_target_does_not_exist() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A - // This is ungossippable not because of any attribute of its own, but because the - // GossipProducerMock is set to return None when ordered to target it. + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A + // This is ungossippable not because of any attribute of its own, but because the + // GossipProducerMock is set to return None when ordered to target it. let ungossippable = make_node_record(1050, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&ungossippable)); + let mut subject = + neighborhood_from_nodes(&subject_node, Some(&ungossippable), &CRYPTDE_PAIR); subject .neighborhood_database .add_node(ungossippable.clone()) @@ -6046,9 +6068,12 @@ mod tests { #[test] fn neighborhood_sends_only_relay_gossip_when_gossip_acceptor_relays() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A - let mut subject = - neighborhood_from_nodes(&subject_node, Some(&make_node_record(1111, true))); + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A + let mut subject = neighborhood_from_nodes( + &subject_node, + Some(&make_node_record(1111, true)), + &CRYPTDE_PAIR, + ); let debut_node = make_node_record(1234, true); let debut_gossip = GossipBuilder::new(&subject.neighborhood_database) .node(subject_node.public_key(), true) @@ -6097,9 +6122,9 @@ mod tests { #[test] fn neighborhood_sends_no_gossip_when_gossip_acceptor_ignores() { - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let gossip_acceptor = GossipAcceptorMock::new().handle_result(GossipAcceptanceResult::Ignored); subject.gossip_acceptor = Box::new(gossip_acceptor); @@ -6124,9 +6149,9 @@ mod tests { #[test] fn neighborhood_complains_about_inability_to_ban_when_gossip_acceptor_requests_it() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A let neighbor = make_node_record(1111, true); - let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor)); + let mut subject = neighborhood_from_nodes(&subject_node, Some(&neighbor), &CRYPTDE_PAIR); let gossip_acceptor = GossipAcceptorMock::new() .handle_result(GossipAcceptanceResult::Ban("Bad guy".to_string())); subject.gossip_acceptor = Box::new(gossip_acceptor); @@ -6199,7 +6224,7 @@ mod tests { #[test] fn neighborhood_logs_received_gossip_in_dot_graph_format() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let this_node = NodeRecord::new_for_tests( &cryptde.public_key(), Some(&NodeAddr::new( @@ -6233,7 +6258,7 @@ mod tests { let cores_package = ExpiredCoresPackage { immediate_neighbor: SocketAddr::from_str("1.2.3.4:1234").unwrap(), paying_wallet: Some(make_paying_wallet(b"consuming")), - remaining_route: make_meaningless_route(), + remaining_route: make_meaningless_route(&CRYPTDE_PAIR), payload: gossip, payload_len: 0, }; @@ -6242,7 +6267,7 @@ mod tests { thread::spawn(move || { let system = System::new(""); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6269,7 +6294,7 @@ mod tests { }); let tlh = TestLogHandler::new(); tlh.await_log_containing( - &format!("\"BAYFBw\" [label=\"AR v0 US\\nBAYFBw\\n4.6.5.7:4657\"];"), + "\"BAYFBw\" [label=\"AR v0 US\\nBAYFBw\\n4.6.5.7:4657\"];", 5000, ); @@ -6297,15 +6322,15 @@ mod tests { .initialize(&data_dir, DbInitializationConfig::test_default()) .unwrap(); } - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let debut_target = NodeDescriptor::try_from(( - main_cryptde(), // Used to provide default cryptde + CRYPTDE_PAIR.main.as_ref(), // Used to provide default cryptde "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", )) .unwrap(); let (hopper, _, hopper_recording) = make_recorder(); let mut subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6362,7 +6387,7 @@ mod tests { let min_hops_in_neighborhood = Hops::SixHops; let min_hops_in_persistent_configuration = min_hops_in_neighborhood; let mut subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6405,7 +6430,7 @@ mod tests { let min_hops_in_neighborhood = Hops::SixHops; let min_hops_in_db = Hops::TwoHops; let mut subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6531,13 +6556,13 @@ mod tests { } fn node_record_to_neighbor_config(node_record_ref: &NodeRecord) -> NodeDescriptor { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); NodeDescriptor::from((node_record_ref, Chain::EthRopsten, cryptde)) } #[test] fn neighborhood_sends_node_query_response_with_none_when_initially_configured_with_no_data() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (recorder, awaiter, recording_arc) = make_recorder(); thread::spawn(move || { let system = System::new("responds_with_none_when_initially_configured_with_no_data"); @@ -6576,7 +6601,7 @@ mod tests { #[test] fn neighborhood_sends_node_query_response_with_none_when_key_query_matches_no_configured_data() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let (recorder, awaiter, recording_arc) = make_recorder(); @@ -6587,7 +6612,7 @@ mod tests { addr.recipient::(); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6638,7 +6663,7 @@ mod tests { #[test] fn neighborhood_sends_node_query_response_with_result_when_key_query_matches_configured_data() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let (recorder, awaiter, recording_arc) = make_recorder(); @@ -6657,7 +6682,7 @@ mod tests { let addr: Addr = recorder.start(); let recipient = addr.recipient::(); let mut subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6706,7 +6731,7 @@ mod tests { #[test] fn neighborhood_sends_node_query_response_with_none_when_ip_address_query_matches_no_configured_data( ) { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let earning_wallet = make_wallet("earning"); let consuming_wallet = Some(make_paying_wallet(b"consuming")); let (recorder, awaiter, recording_arc) = make_recorder(); @@ -6716,7 +6741,7 @@ mod tests { let recipient: Recipient = addr.recipient::(); let subject = Neighborhood::new( - cryptde, + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::Standard( @@ -6768,7 +6793,7 @@ mod tests { #[test] fn neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data( ) { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let (recorder, awaiter, recording_arc) = make_recorder(); let node_record = make_node_record(1234, true); let another_node_record = make_node_record(2345, true); @@ -6802,7 +6827,7 @@ mod tests { None, "neighborhood_sends_node_query_response_with_result_when_ip_address_query_matches_configured_data", ); - let mut subject = Neighborhood::new(cryptde, &config); + let mut subject = Neighborhood::new(CRYPTDE_PAIR.clone(), &config); subject .neighborhood_database .add_node(another_node_record_a) @@ -6841,8 +6866,9 @@ mod tests { let min_hops = Hops::TwoHops; let one_next_door_neighbor = make_node_record(3333, true); let another_next_door_neighbor = make_node_record(4444, true); - let subject_node = make_global_cryptde_node_record(5555, true); // 9e7p7un06eHs6frl5A - let mut subject = neighborhood_from_nodes(&subject_node, Some(&one_next_door_neighbor)); + let subject_node = make_global_cryptde_node_record(5555, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A + let mut subject = + neighborhood_from_nodes(&subject_node, Some(&one_next_door_neighbor), &CRYPTDE_PAIR); subject.min_hops = min_hops; subject @@ -6879,7 +6905,7 @@ mod tests { Err(format!( "Couldn't find any routes: at least {}-hop from {} to ProxyClient at Unknown", min_hops as usize, - main_cryptde().public_key() + CRYPTDE_PAIR.main.as_ref().public_key() )), result ); @@ -6890,8 +6916,9 @@ mod tests { let next_door_neighbor = make_node_record(3333, true); let exit_node = make_node_record(5, false); - let subject_node = make_global_cryptde_node_record(666, true); // 9e7p7un06eHs6frl5A - let mut subject = neighborhood_from_nodes(&subject_node, Some(&next_door_neighbor)); + let subject_node = make_global_cryptde_node_record(666, true, &CRYPTDE_PAIR); // 9e7p7un06eHs6frl5A + let mut subject = + neighborhood_from_nodes(&subject_node, Some(&next_door_neighbor), &CRYPTDE_PAIR); subject.min_hops = Hops::TwoHops; subject @@ -6927,7 +6954,7 @@ mod tests { let hops = result.clone().unwrap().route.hops; let actual_keys: Vec = match hops.as_slice() { [hop, exit, hop_back, origin, empty, _accounting] => vec![ - decodex::(main_cryptde(), hop) + decodex::(CRYPTDE_PAIR.main.as_ref(), hop) .expect("hop") .public_key, decodex::(&next_door_neighbor_cryptde, exit) @@ -6939,7 +6966,7 @@ mod tests { decodex::(&next_door_neighbor_cryptde, origin) .expect("origin") .public_key, - decodex::(main_cryptde(), empty) + decodex::(CRYPTDE_PAIR.main.as_ref(), empty) .expect("empty") .public_key, ], @@ -6958,11 +6985,11 @@ mod tests { fn assert_route_query_message(min_hops: Hops) { let hops = min_hops as usize; let nodes_count = hops + 1; - let root_node = make_global_cryptde_node_record(4242, true); + let root_node = make_global_cryptde_node_record(4242, true, &CRYPTDE_PAIR); let mut nodes = make_node_records(nodes_count as u16); nodes[0] = root_node; let db = linearly_connect_nodes(&nodes); - let mut subject = neighborhood_from_nodes(db.root(), nodes.get(1)); + let mut subject = neighborhood_from_nodes(db.root(), nodes.get(1), &CRYPTDE_PAIR); subject.min_hops = min_hops; subject.neighborhood_database = db; @@ -7093,7 +7120,7 @@ mod tests { #[test] fn node_record_metadata_message_is_handled_properly() { init_test_logging(); - let subject_node = make_global_cryptde_node_record(1345, true); + let subject_node = make_global_cryptde_node_record(1345, true, &CRYPTDE_PAIR); let public_key = PublicKey::from(&b"exit_node"[..]); let node_record_inputs = NodeRecordInputs { earning_wallet: make_wallet("earning"), @@ -7103,9 +7130,10 @@ mod tests { version: 0, location_opt: None, }; - let node_record = NodeRecord::new(&public_key, main_cryptde(), node_record_inputs); + let node_record = + NodeRecord::new(&public_key, CRYPTDE_PAIR.main.as_ref(), node_record_inputs); let unreachable_host = String::from("facebook.com"); - let mut subject = neighborhood_from_nodes(&subject_node, None); + let mut subject = neighborhood_from_nodes(&subject_node, None, &CRYPTDE_PAIR); let _ = subject.neighborhood_database.add_node(node_record); let addr = subject.start(); let system = System::new("test"); @@ -7126,9 +7154,9 @@ mod tests { .metadata .unreachable_hosts .contains(&unreachable_host)); - TestLogHandler::new().exists_log_matching(&format!( + TestLogHandler::new().exists_log_matching( "DEBUG: Neighborhood: Marking host facebook.com unreachable for the Node with public key 0x657869745F6E6F6465" - )); + ); }); addr.try_send(AssertionsMessage { assertions }).unwrap(); System::current().stop(); @@ -7140,8 +7168,8 @@ mod tests { expected = "Neighborhood should never get ShutdownStreamMsg about non-clandestine stream" )] fn handle_stream_shutdown_complains_about_non_clandestine_message() { - let subject_node = make_global_cryptde_node_record(1345, true); - let mut subject = neighborhood_from_nodes(&subject_node, None); + let subject_node = make_global_cryptde_node_record(1345, true, &CRYPTDE_PAIR); + let mut subject = neighborhood_from_nodes(&subject_node, None, &CRYPTDE_PAIR); subject.handle_stream_shutdown_msg(StreamShutdownMsg { peer_addr: SocketAddr::from_str("1.2.3.4:5678").unwrap(), @@ -7164,8 +7192,8 @@ mod tests { unrecognized_node_addr.ip_addr(), unrecognized_node_addr.ports()[0], ); - let subject_node = make_global_cryptde_node_record(1345, true); - let mut subject = neighborhood_from_nodes(&subject_node, None); + let subject_node = make_global_cryptde_node_record(1345, true, &CRYPTDE_PAIR); + let mut subject = neighborhood_from_nodes(&subject_node, None, &CRYPTDE_PAIR); let peer_actors = peer_actors_builder().hopper(hopper).build(); subject.hopper_opt = Some(peer_actors.hopper.from_hopper_client); @@ -7196,8 +7224,8 @@ mod tests { inactive_neighbor_node_addr.ip_addr(), inactive_neighbor_node_addr.ports()[0], ); - let subject_node = make_global_cryptde_node_record(1345, true); - let mut subject = neighborhood_from_nodes(&subject_node, None); + let subject_node = make_global_cryptde_node_record(1345, true, &CRYPTDE_PAIR); + let mut subject = neighborhood_from_nodes(&subject_node, None, &CRYPTDE_PAIR); subject .neighborhood_database .add_node(gossip_neighbor_node.clone()) @@ -7251,8 +7279,8 @@ mod tests { shutdown_neighbor_node_addr.ip_addr(), shutdown_neighbor_node_addr.ports()[0], ); - let subject_node = make_global_cryptde_node_record(1345, true); - let mut subject = neighborhood_from_nodes(&subject_node, None); + let subject_node = make_global_cryptde_node_record(1345, true, &CRYPTDE_PAIR); + let mut subject = neighborhood_from_nodes(&subject_node, None, &CRYPTDE_PAIR); subject .neighborhood_database .add_node(gossip_neighbor_node.clone()) @@ -7304,7 +7332,7 @@ mod tests { init_test_logging(); let system = System::new("test"); let subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::ZeroHop, @@ -7453,7 +7481,7 @@ mod tests { let act = |data_dir: &Path| { let mut subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_earning_wallet(make_wallet("earning_wallet")), ); subject.data_directory = data_dir.to_path_buf(); @@ -7464,9 +7492,9 @@ mod tests { } fn make_standard_subject() -> Neighborhood { - let root_node = make_global_cryptde_node_record(9999, true); + let root_node = make_global_cryptde_node_record(9999, true, &CRYPTDE_PAIR); let neighbor_node = make_node_record(9998, true); - let mut subject = neighborhood_from_nodes(&root_node, Some(&neighbor_node)); + let mut subject = neighborhood_from_nodes(&root_node, Some(&neighbor_node), &CRYPTDE_PAIR); let persistent_config = PersistentConfigurationMock::new(); subject.persistent_config_opt = Some(Box::new(persistent_config)); subject @@ -7635,7 +7663,7 @@ mod tests { let bootstrap_config = bc_from_nc_plus(neighborhood_config, make_wallet("earning"), None, test_name); - let mut neighborhood = Neighborhood::new(main_cryptde(), &bootstrap_config); + let mut neighborhood = Neighborhood::new(CRYPTDE_PAIR.clone(), &bootstrap_config); let (node_to_ui_recipient, _) = make_node_to_ui_recipient(); neighborhood.node_to_ui_recipient_opt = Some(node_to_ui_recipient); @@ -7650,7 +7678,7 @@ mod tests { ) -> Option { let system = System::new("test"); let mut subject = Neighborhood::new( - main_cryptde(), + CRYPTDE_PAIR.clone(), &bc_from_nc_plus( NeighborhoodConfig { mode: NeighborhoodMode::ConsumeOnly(vec![make_node_descriptor(make_ip(1))]), @@ -7689,11 +7717,11 @@ mod tests { } fn make_neighborhood_with_linearly_connected_nodes(nodes_count: u16) -> Neighborhood { - let root_node = make_global_cryptde_node_record(4242, true); + let root_node = make_global_cryptde_node_record(4242, true, &CRYPTDE_PAIR); let mut nodes = make_node_records(nodes_count); nodes[0] = root_node; let db = linearly_connect_nodes(&nodes); - let mut neighborhood = neighborhood_from_nodes(db.root(), nodes.get(1)); + let mut neighborhood = neighborhood_from_nodes(db.root(), nodes.get(1), &CRYPTDE_PAIR); neighborhood.neighborhood_database = db; neighborhood diff --git a/node/src/neighborhood/neighborhood_database.rs b/node/src/neighborhood/neighborhood_database.rs index 0b6ef20c4d..c8bd222124 100644 --- a/node/src/neighborhood/neighborhood_database.rs +++ b/node/src/neighborhood/neighborhood_database.rs @@ -42,13 +42,12 @@ impl Debug for NeighborhoodDatabase { impl NeighborhoodDatabase { pub fn new( - public_key: &PublicKey, neighborhood_mode: NeighborhoodMode, earning_wallet: Wallet, cryptde: &dyn CryptDE, ) -> NeighborhoodDatabase { let mut result = NeighborhoodDatabase { - this_node: public_key.clone(), + this_node: cryptde.public_key().clone(), by_public_key: HashMap::new(), by_ip_addr: HashMap::new(), logger: Logger::new("NeighborhoodDatabase"), @@ -65,7 +64,7 @@ impl NeighborhoodDatabase { version: 0, location_opt, }; - let mut node_record = NodeRecord::new(public_key, cryptde, node_record_data); + let mut node_record = NodeRecord::new(cryptde.public_key(), cryptde, node_record_data); if let Some(node_addr) = neighborhood_mode.node_addr_opt() { node_record .set_node_addr(&node_addr) @@ -437,7 +436,6 @@ mod tests { let mut this_node = make_node_record(1234, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), this_node.earning_wallet(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), @@ -507,7 +505,6 @@ mod tests { let one_node = make_node_record(4567, true); let another_node = make_node_record(5678, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), Wallet::from_str("0x546900db8d6e0937497133d1ae6fdf5f4b75bcd0").unwrap(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), @@ -572,7 +569,6 @@ mod tests { let node_a = make_node_record(2345, false); let node_b = make_node_record(3456, true); let mut subject = NeighborhoodDatabase::new( - root_node.public_key(), (&root_node).into(), Wallet::from_str("0x0000000000000000000000000000000000004444").unwrap(), &CryptDENull::from(root_node.public_key(), TEST_DEFAULT_CHAIN), @@ -615,7 +611,6 @@ mod tests { let one_node = make_node_record(2345, false); let another_node = make_node_record(3456, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), Wallet::from_str("0x0000000000000000000000000000000000001234").unwrap(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), @@ -717,9 +712,7 @@ mod tests { assert_eq!( result, - Err(NeighborhoodDatabaseError::NodeKeyNotFound( - nonexistent_node.public_key().clone() - )) + Err(NodeKeyNotFound(nonexistent_node.public_key().clone())) ) } @@ -743,7 +736,6 @@ mod tests { let this_node = make_node_record(1234, true); let other_node = make_node_record(2345, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), Wallet::from_str("0x0000000000000000000000000000000000001234").unwrap(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), @@ -869,7 +861,6 @@ mod tests { let this_node = make_node_record(1234, true); let mut old_node = this_node.clone(); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), this_node.earning_wallet(), &CryptDENull::from(this_node.public_key(), DEFAULT_CHAIN), @@ -897,7 +888,6 @@ mod tests { fn remove_neighbor_returns_error_when_given_nonexistent_node_key() { let this_node = make_node_record(123, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), Wallet::from_str("0x0000000000000000000000000000000000000123").unwrap(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), @@ -943,7 +933,6 @@ mod tests { fn remove_neighbor_returns_false_when_neighbor_was_not_removed() { let this_node = make_node_record(123, true); let mut subject = NeighborhoodDatabase::new( - this_node.public_key(), (&this_node).into(), Wallet::from_str("0x0000000000000000000000000000000000000123").unwrap(), &CryptDENull::from(this_node.public_key(), TEST_DEFAULT_CHAIN), diff --git a/node/src/neighborhood/node_record.rs b/node/src/neighborhood/node_record.rs index 2cd96cc5de..a3105f1dfb 100644 --- a/node/src/neighborhood/node_record.rs +++ b/node/src/neighborhood/node_record.rs @@ -75,7 +75,7 @@ pub struct NodeRecordInputs { impl NodeRecord { pub fn new( public_key: &PublicKey, - cryptde: &dyn CryptDE, // Must be the new NodeRecord's CryptDE: used for signing + cryptde: &dyn CryptDE, node_record_inputs: NodeRecordInputs, ) -> NodeRecord { let country_opt = node_record_inputs @@ -372,16 +372,22 @@ impl NodeRecordMetadata { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::neighborhood::gossip::GossipBuilder; use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::neighborhood::ZERO_RATE_PACK; use crate::test_utils::make_wallet; use crate::test_utils::neighborhood_test_utils::{db_from_node, make_node_record}; - use crate::test_utils::{assert_contains, main_cryptde, rate_pack}; + use crate::test_utils::{assert_contains, rate_pack}; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::net::IpAddr; use std::str::FromStr; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn can_create_node_record_with_node_location_opt_none() { let mut node_record_wo_location = make_node_record(2222, false); @@ -456,7 +462,7 @@ mod tests { #[test] fn node_descriptor_works_when_node_addr_is_present() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let mut subject = make_node_record(1234, true); subject.metadata.node_addr_opt = Some(NodeAddr::new( &subject.metadata.node_addr_opt.unwrap().ip_addr(), @@ -467,24 +473,21 @@ mod tests { assert_eq!( result, - NodeDescriptor::try_from(( - main_cryptde(), - "masq://base-sepolia:AQIDBA@1.2.3.4:1234/2345" - )) - .unwrap() + NodeDescriptor::try_from((cryptde, "masq://base-sepolia:AQIDBA@1.2.3.4:1234/2345")) + .unwrap() ); } #[test] fn node_descriptor_works_when_node_addr_is_not_present() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let subject: NodeRecord = make_node_record(1234, false); let result = subject.node_descriptor(TEST_DEFAULT_CHAIN, cryptde); assert_eq!( result, - NodeDescriptor::try_from((main_cryptde(), "masq://base-sepolia:AQIDBA@:")).unwrap() + NodeDescriptor::try_from((cryptde, "masq://base-sepolia:AQIDBA@:")).unwrap() ); } @@ -653,22 +656,22 @@ mod tests { }; let exemplar = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); let duplicate = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); let mut with_neighbor = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); let mod_key = NodeRecord::new( &PublicKey::new(&b"kope"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); with_neighbor @@ -676,7 +679,7 @@ mod tests { .unwrap(); let mut mod_node_addr = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); mod_node_addr @@ -689,39 +692,39 @@ mod tests { node_record_data_mod_earning_wallet.earning_wallet = make_wallet("booga"); let mod_earning_wallet = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data_mod_earning_wallet, ); let mut node_record_data_mod_rate_pack = node_record_data.clone(); node_record_data_mod_rate_pack.rate_pack = rate_pack(200); let mod_rate_pack = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data_mod_rate_pack, ); let mut node_record_data_mod_accepts_connections = node_record_data.clone(); node_record_data_mod_accepts_connections.accepts_connections = false; let mod_accepts_connections = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data_mod_accepts_connections, ); let mut node_record_data_mod_routes_data = node_record_data.clone(); node_record_data_mod_routes_data.routes_data = false; let mod_routes_data = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data_mod_routes_data, ); let mut mod_signed_gossip = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); mod_signed_gossip.signed_gossip = mod_rate_pack.signed_gossip.clone(); let mut mod_signature = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data.clone(), ); mod_signature.signature = CryptData::new(&[]); @@ -729,7 +732,7 @@ mod tests { node_record_data_mod_version.version = 1; let mod_version = NodeRecord::new( &PublicKey::new(&b"poke"[..]), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), node_record_data_mod_version, ); diff --git a/node/src/node_configurator/configurator.rs b/node/src/node_configurator/configurator.rs index 19b0b958ad..fb5dd565bc 100644 --- a/node/src/node_configurator/configurator.rs +++ b/node/src/node_configurator/configurator.rs @@ -20,6 +20,7 @@ use masq_lib::ui_gateway::{ use crate::blockchain::bip32::Bip32EncryptionKeyProvider; use crate::blockchain::bip39::Bip39; +use crate::bootstrapper::CryptDEPair; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::config_dao::ConfigDaoReal; @@ -30,7 +31,6 @@ use crate::sub_lib::neighborhood::{ConfigChange, ConfigChangeMsg, Hops, WalletPa use crate::sub_lib::peer_actors::{BindMessage, ConfigChangeSubs}; use crate::sub_lib::utils::{db_connection_launch_panic, handle_ui_crash_request}; use crate::sub_lib::wallet::Wallet; -use crate::test_utils::main_cryptde; use bip39::{Language, Mnemonic, MnemonicType, Seed}; use masq_lib::constants::{ BAD_PASSWORD_ERROR, CONFIGURATOR_READ_ERROR, CONFIGURATOR_WRITE_ERROR, DERIVATION_PATH_ERROR, @@ -48,6 +48,7 @@ pub struct Configurator { persistent_config: Box, node_to_ui_sub_opt: Option>, config_change_subs_opt: Option, + cryptde_pair: CryptDEPair, crashable: bool, logger: Logger, } @@ -95,7 +96,7 @@ impl Handler for Configurator { type MessageError = (u64, String); impl Configurator { - pub fn new(data_directory: PathBuf, crashable: bool) -> Self { + pub fn new(data_directory: PathBuf, cryptde_pair: CryptDEPair, crashable: bool) -> Self { let initializer = DbInitializerReal::default(); let conn = initializer .initialize( @@ -110,6 +111,7 @@ impl Configurator { persistent_config, node_to_ui_sub_opt: None, config_change_subs_opt: None, + cryptde_pair, crashable, logger: Logger::new("Configurator"), } @@ -513,7 +515,12 @@ impl Configurator { msg: UiConfigurationRequest, context_id: u64, ) -> MessageBody { - match Self::unfriendly_handle_configuration(msg, context_id, &mut self.persistent_config) { + match Self::unfriendly_handle_configuration( + msg, + context_id, + &mut self.persistent_config, + &self.cryptde_pair, + ) { Ok(message_body) => message_body, Err((code, msg)) => MessageBody { opcode: "configuration".to_string(), @@ -527,6 +534,7 @@ impl Configurator { msg: UiConfigurationRequest, context_id: u64, persistent_config: &mut Box, + cryptde_pair: &CryptDEPair, ) -> Result { let good_password_opt = match &msg.db_password_opt { None => None, @@ -594,7 +602,7 @@ impl Configurator { None => vec![], Some(pns) => pns .into_iter() - .map(|nd| nd.to_string(main_cryptde())) + .map(|nd| nd.to_string(cryptde_pair.main.as_ref())) .collect::>(), }; ( @@ -897,10 +905,11 @@ mod tests { use crate::blockchain::bip32::Bip32EncryptionKeyProvider; use crate::blockchain::bip39::Bip39; use crate::blockchain::test_utils::make_meaningless_phrase_words; + use crate::bootstrapper::CryptDEPair; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::sub_lib::accountant::{PaymentThresholds, ScanIntervals}; + use crate::sub_lib::cryptde::PlainData; use crate::sub_lib::cryptde::PublicKey as PK; - use crate::sub_lib::cryptde::{CryptDE, PlainData}; use crate::sub_lib::neighborhood::{ConfigChange, NodeDescriptor, RatePack}; use crate::sub_lib::node_addr::NodeAddr; use crate::sub_lib::wallet::Wallet; @@ -910,6 +919,7 @@ mod tests { }; use crate::test_utils::{make_paying_wallet, make_wallet}; use bip39::{Language, Mnemonic}; + use lazy_static::lazy_static; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::MISSING_DATA; use masq_lib::test_utils::utils::ensure_node_home_directory_exists; @@ -917,6 +927,10 @@ mod tests { use rustc_hex::FromHex; use tiny_hderive::bip32::ExtendedPrivKey; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!(CRASH_KEY, "CONFIGURATOR") @@ -932,7 +946,7 @@ mod tests { .unwrap(), ))); let peer_actors = peer_actors_builder().build(); - let mut subject = Configurator::new(data_dir, false); + let mut subject = Configurator::new(data_dir, CRYPTDE_PAIR.clone(), false); subject.config_change_subs_opt = Some(peer_actors.config_change_subs()); subject.node_to_ui_sub_opt = Some(peer_actors.ui_gateway.node_to_ui_message_sub); @@ -959,7 +973,7 @@ mod tests { ); let act = |data_dir: &Path| { - Configurator::new(data_dir.to_path_buf(), false); + Configurator::new(data_dir.to_path_buf(), CRYPTDE_PAIR.clone(), false); }; assert_on_initialization_with_panic_on_migration(&data_dir, &act); @@ -1018,7 +1032,7 @@ mod tests { assert_eq!( ui_gateway_recording.get_record::(0), &NodeToUiMessage { - target: MessageTarget::ClientId(1234), + target: ClientId(1234), body: UiCheckPasswordResponse { matches: false }.tmb(4321) } ); @@ -1098,7 +1112,7 @@ mod tests { assert_eq!( ui_gateway_recording.get_record::(1), &NodeToUiMessage { - target: MessageTarget::ClientId(1234), + target: ClientId(1234), body: UiChangePasswordResponse {}.tmb(4321) } ); @@ -1275,7 +1289,7 @@ mod tests { assert_eq!( ui_gateway_recording.get_record::(0), &NodeToUiMessage { - target: MessageTarget::ClientId(1234), + target: ClientId(1234), body: UiWalletAddressesResponse { consuming_wallet_address: "0x1234567890123456789012345678901234567890" .to_string(), @@ -2525,13 +2539,14 @@ mod tests { let consuming_wallet_private_key = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF".to_string(); let earning_wallet_address = "4a5e43b54c6C56Ebf7".to_string(); + let cryptde_pair = CryptDEPair::null(); let public_key = PK::from(&b"xaca4sf4a56"[..]); let node_addr = NodeAddr::from_str("1.2.1.3:4545").unwrap(); let node_descriptor = NodeDescriptor::from(( &public_key, &node_addr, Chain::EthRopsten, - main_cryptde() as &dyn CryptDE, + cryptde_pair.main.as_ref(), )); let persistent_config = PersistentConfigurationMock::new() .blockchain_service_url_result(Ok(None)) @@ -2654,13 +2669,14 @@ mod tests { .address() ); let earning_wallet_address = "4a5e43b54c6C56Ebf7".to_string(); + let cryptde_pair = CryptDEPair::null(); let public_key = PK::from(&b"xaca4sf4a56"[..]); let node_addr = NodeAddr::from_str("1.2.1.3:4545").unwrap(); let node_descriptor = NodeDescriptor::from(( &public_key, &node_addr, Chain::EthRopsten, - main_cryptde() as &dyn CryptDE, + cryptde_pair.main.as_ref(), )); let persistent_config = PersistentConfigurationMock::new() .blockchain_service_url_result(Ok(None)) @@ -2705,7 +2721,7 @@ mod tests { consuming_wallet_address_opt: Some(consuming_wallet_address), earning_wallet_address_opt: Some(earning_wallet_address), port_mapping_protocol_opt: Some(AutomapProtocol::Igdp.to_string()), - past_neighbors: vec![node_descriptor.to_string(main_cryptde())], + past_neighbors: vec![node_descriptor.to_string(cryptde_pair.main.as_ref())], payment_thresholds: UiPaymentThresholds { threshold_interval_sec: 10_000, debt_threshold_gwei: 5_000_000, @@ -2990,12 +3006,14 @@ mod tests { } } + // For tests only. Don't move this into the production tree without significant changes. impl From> for Configurator { fn from(persistent_config: Box) -> Self { Configurator { persistent_config, node_to_ui_sub_opt: None, config_change_subs_opt: None, + cryptde_pair: CRYPTDE_PAIR.clone(), crashable: false, logger: Logger::new("Configurator"), } diff --git a/node/src/node_configurator/mod.rs b/node/src/node_configurator/mod.rs index e75683f2ec..5738fe3b3a 100644 --- a/node/src/node_configurator/mod.rs +++ b/node/src/node_configurator/mod.rs @@ -244,11 +244,23 @@ pub fn determine_user_specific_data( pub fn initialize_database( data_directory: &Path, migrator_config: DbInitializationConfig, + db_password_opt: &Option, ) -> Box { let conn = DbInitializerReal::default() .initialize(data_directory, migrator_config) .unwrap_or_else(|e| db_connection_launch_panic(e, data_directory)); - Box::new(PersistentConfigurationReal::from(conn)) + let mut persistent_config = Box::new(PersistentConfigurationReal::from(conn)); + if let Some(password) = db_password_opt { + if persistent_config + .check_password(None) + .expect("Failed to check password") + { + persistent_config + .change_password(None, password) + .expect("Failed to establish password") + } + } + persistent_config } pub fn real_user_from_multi_config_or_populate( @@ -391,6 +403,7 @@ mod tests { .param("--config-file", "booga.toml"); let args_vec: Vec = args.into(); let app = determine_config_file_path_app(); + let user_specific_data = determine_user_specific_data(&DirsWrapperReal::default(), &app, args_vec.as_slice()) .unwrap(); @@ -433,6 +446,7 @@ mod tests { ); std::env::set_var("MASQ_CONFIG_FILE", "booga.toml"); let app = determine_config_file_path_app(); + let user_specific_data = determine_user_specific_data(&DirsWrapperReal::default(), &app, args_vec.as_slice()) .unwrap(); @@ -576,6 +590,65 @@ mod tests { assert_eq!(user_specific_data.real_user.user_specified, false); } + #[test] + fn initialize_database_handles_preexisting_database_with_existing_password() { + let data_directory = ensure_node_home_directory_exists( + "node_configurator", + "initialize_database_handles_preexisting_database_with_existing_password", + ); + { + let conn = DbInitializerReal::default() + .initialize(&data_directory, DbInitializationConfig::test_default()) + .unwrap(); + let mut persistent_config = Box::new(PersistentConfigurationReal::from(conn)); + persistent_config + .change_password(None, "existing password") + .unwrap(); + } + let db_password = Some("command-line password".to_string()); + + let persistent_config = initialize_database( + &data_directory, + DbInitializationConfig::test_default(), + &db_password, + ); + + assert_eq!( + persistent_config.check_password(Some("existing password".to_string())), + Ok(true) + ); + } + + #[test] + fn initialize_database_handles_preexisting_database_with_existing_password_but_nothing_on_the_command_line( + ) { + let data_directory = ensure_node_home_directory_exists( + "node_configurator", + "initialize_database_handles_preexisting_database_with_existing_password_but_nothing_on_the_command_line", + ); + { + let conn = DbInitializerReal::default() + .initialize(&data_directory, DbInitializationConfig::test_default()) + .unwrap(); + let mut persistent_config = Box::new(PersistentConfigurationReal::from(conn)); + persistent_config + .change_password(None, "existing password") + .unwrap(); + } + let db_password = None; + + let persistent_config = initialize_database( + &data_directory, + DbInitializationConfig::test_default(), + &db_password, + ); + + assert_eq!( + persistent_config.check_password(Some("existing password".to_string())), + Ok(true) + ); + } + #[test] pub fn port_is_busy_detects_free_port() { let port = find_free_port(); diff --git a/node/src/node_configurator/node_configurator_standard.rs b/node/src/node_configurator/node_configurator_standard.rs index 79e65aff52..3cad6c9834 100644 --- a/node/src/node_configurator/node_configurator_standard.rs +++ b/node/src/node_configurator/node_configurator_standard.rs @@ -1,6 +1,6 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use crate::bootstrapper::BootstrapperConfig; +use crate::bootstrapper::{BootstrapperConfig, CryptDEPair}; use crate::node_configurator::{initialize_database, DirsWrapper, FieldPair, NodeConfigurator}; use crate::node_configurator::{ConfigInitializationData, DirsWrapperReal}; use masq_lib::crash_point::CrashPoint; @@ -26,10 +26,12 @@ use crate::node_configurator::{ data_directory_from_context, determine_user_specific_data, real_user_data_directory_path_and_chain, }; -use crate::sub_lib::cryptde::PublicKey; +use crate::sub_lib::cryptde::{CryptDE, PublicKey}; use crate::sub_lib::cryptde_null::CryptDENull; +use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::utils::make_new_multi_config; use crate::tls_discriminator_factory::TlsDiscriminatorFactory; +use masq_lib::blockchains::chains::Chain; use masq_lib::constants::{DEFAULT_UI_PORT, HTTP_PORT, TLS_PORT}; use masq_lib::multi_config::{CommandLineVcl, ConfigFileVcl, EnvironmentVcl}; use std::str::FromStr; @@ -81,6 +83,7 @@ impl NodeConfigurator for NodeConfiguratorStandardUnprivileg let mut persistent_config = initialize_database( &self.privileged_config.data_directory, DbInitializationConfig::create_or_migrate(ExternalData::from((self, multi_config))), + &value_m!(multi_config, "db-password", String), ); let mut unprivileged_config = BootstrapperConfig::new(); let parse_args_configurator = UnprivilegedParseArgsConfigurationDaoReal {}; @@ -91,6 +94,15 @@ impl NodeConfigurator for NodeConfiguratorStandardUnprivileg &self.logger, )?; configure_database(&unprivileged_config, persistent_config.as_mut())?; + let cryptde_pair = if multi_config.occurrences_of("fake-public-key") == 0 { + configure_cryptdes( + persistent_config.as_mut(), + &unprivileged_config.db_password_opt, + ) + } else { + configure_fake_cryptdes(multi_config) + }; + unprivileged_config.cryptde_pair = cryptde_pair; Ok(unprivileged_config) } } @@ -221,7 +233,7 @@ pub fn server_initializer_collected_params<'a>( Box::new(CommandLineVcl::new(commandline_vcl.args())), ], ) - .expect("expexted MultiConfig"); + .expect("expected MultiConfig"); let specified_vec = extract_values_vcl_fill_multiconfig_vec( multiconfig_for_values_extraction, initialization_data, @@ -296,28 +308,6 @@ pub fn privileged_parse_args( privileged_config.crash_point = value_m!(multi_config, "crash-point", CrashPoint).unwrap_or(CrashPoint::None); - - if let Some(public_key_str) = value_m!(multi_config, "fake-public-key", String) { - let (main_public_key, alias_public_key) = match base64::decode(&public_key_str) { - Ok(mut key) => { - let main_public_key = PublicKey::new(&key); - key.reverse(); - let alias_public_key = PublicKey::new(&key); - (main_public_key, alias_public_key) - } - Err(e) => panic!("Invalid fake public key: {} ({:?})", public_key_str, e), - }; - let main_cryptde_null = CryptDENull::from( - &main_public_key, - privileged_config.blockchain_bridge_config.chain, - ); - let alias_cryptde_null = CryptDENull::from( - &alias_public_key, - privileged_config.blockchain_bridge_config.chain, - ); - privileged_config.main_cryptde_null_opt = Some(main_cryptde_null); - privileged_config.alias_cryptde_null_opt = Some(alias_cryptde_null); - } Ok(()) } @@ -354,11 +344,64 @@ fn configure_database( Ok(()) } +fn configure_cryptdes( + persistent_config: &mut dyn PersistentConfiguration, + db_password_opt: &Option, +) -> CryptDEPair { + let cryptde_pair = if let Some(db_password) = db_password_opt { + let chain = Chain::from(persistent_config.chain_name().as_str()); + let main_result = persistent_config.cryptde(db_password); + match main_result { + Ok(Some(last_main_cryptde)) => { + CryptDEPair::new(last_main_cryptde, Box::new(CryptDEReal::new(chain))) + } + Ok(None) => { + let main_cryptde: Box = Box::new(CryptDEReal::new(chain)); + persistent_config + .set_cryptde(main_cryptde.as_ref(), db_password) + .expect("Failed to set cryptde"); + let alias_cryptde: Box = Box::new(CryptDEReal::new(chain)); + CryptDEPair::new(main_cryptde, alias_cryptde) + } + Err(e) => panic!("Could not read last cryptde from database: {:?}", e), + } + } else { + let chain = Chain::from(persistent_config.chain_name().as_str()); + let main_cryptde: Box = Box::new(CryptDEReal::new(chain)); + let alias_cryptde: Box = Box::new(CryptDEReal::new(chain)); + CryptDEPair::new(main_cryptde, alias_cryptde) + }; + cryptde_pair +} + +fn configure_fake_cryptdes(multi_config: &MultiConfig) -> CryptDEPair { + let public_key_str = + value_m!(multi_config, "fake-public-key", String).expect("fake-public-key disappeared"); + let main_public_key_data = + base64::decode(&public_key_str).expect("fake-public-key: invalid Base64"); + let main_public_key = PublicKey::new(&main_public_key_data); + let main_cryptde = CryptDENull::from( + &main_public_key, + Chain::Dev, // Always Dev chain for signing with --fake-public-key + ); + let alias_public_key_data = main_public_key_data + .iter() + .rev() + .cloned() + .collect::>(); + let alias_public_key = PublicKey::new(&alias_public_key_data); + let alias_cryptde = CryptDENull::from( + &alias_public_key, + Chain::Dev, // Always Dev chain for signing with --fake-public-key + ); + CryptDEPair::new(Box::new(main_cryptde), Box::new(alias_cryptde)) +} + #[cfg(test)] mod tests { use super::*; use crate::blockchain::bip32::Bip32EncryptionKeyProvider; - use crate::bootstrapper::{BootstrapperConfig, RealUser}; + use crate::bootstrapper::{BootstrapperConfig, CryptDEPair, RealUser}; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::config_dao::ConfigDaoReal; use crate::db_config::persistent_configuration::PersistentConfigError; @@ -366,6 +409,7 @@ mod tests { use crate::node_configurator::unprivileged_parse_args_configuration::UnprivilegedParseArgsConfigurationDaoNull; use crate::node_test_utils::DirsWrapperMock; use crate::sub_lib::cryptde::CryptDE; + use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::neighborhood::NeighborhoodMode::ZeroHop; use crate::sub_lib::neighborhood::{ Hops, NeighborhoodConfig, NeighborhoodMode, NodeDescriptor, @@ -375,7 +419,8 @@ mod tests { use crate::test_utils::unshared_test_utils::{ make_pre_populated_mocked_directory_wrapper, make_simplified_multi_config, }; - use crate::test_utils::{assert_string_contains, main_cryptde, ArgsBuilder}; + use crate::test_utils::{assert_string_contains, ArgsBuilder}; + use lazy_static::lazy_static; use masq_lib::blockchains::chains::Chain; use masq_lib::constants::DEFAULT_CHAIN; use masq_lib::multi_config::VirtualCommandLine; @@ -392,6 +437,10 @@ mod tests { use std::sync::{Arc, Mutex}; use std::vec; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn node_configurator_standard_unprivileged_uses_parse_args_configurator_dao_real() { let home_dir = ensure_node_home_directory_exists( @@ -399,7 +448,7 @@ mod tests { "node_configurator_standard_unprivileged_uses_parse_args_configurator_dao_real", ); let neighbor = vec![NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:MTEyMjMzNDQ1NTY2Nzc4ODExMjIzMzQ0NTU2Njc3ODg@1.2.3.4:1234", )) .unwrap()]; @@ -443,8 +492,68 @@ mod tests { assert_eq!(set_neighbors, neighbor) } + #[test] + fn node_configurator_standard_unprivileged_sets_db_password_for_the_first_time() { + let home_dir = ensure_node_home_directory_exists( + "node_configurator_standard", + "node_configurator_standard_unprivileged_sets_db_password_for_the_first_time", + ); + let persistent_config = { + let conn = DbInitializerReal::default() + .initialize(home_dir.as_path(), DbInitializationConfig::test_default()) + .unwrap(); + PersistentConfigurationReal::from(conn) + }; + let multi_config = make_simplified_multi_config([ + "--chain", + "eth-mainnet", + "--db-password", + "password", + "--ip", + "1.2.3.4", + ]); + let mut privileged_config = BootstrapperConfig::default(); + privileged_config.data_directory = home_dir; + let subject = NodeConfiguratorStandardUnprivileged { + privileged_config, + logger: Logger::new("test"), + }; + + let result = subject.configure(&multi_config).unwrap(); + + assert_eq!(result.db_password_opt, Some("password".to_string())); + assert_eq!( + persistent_config + .check_password(Some("password".to_string())) + .unwrap(), + true + ); + } + + #[test] + fn node_configurator_standard_unprivileged_handles_fake_public_key() { + let home_dir = ensure_node_home_directory_exists( + "node_configurator_standard", + "node_configurator_standard_unprivileged_handles_fake_public_key", + ); + let multi_config = + make_simplified_multi_config(["--chain", "eth-mainnet", "--fake-public-key", "AQIDBA"]); + let mut privileged_config = BootstrapperConfig::default(); + privileged_config.data_directory = home_dir; + let subject = NodeConfiguratorStandardUnprivileged { + privileged_config, + logger: Logger::new("test"), + }; + + let result = subject.configure(&multi_config).unwrap(); + + assert_eq!(result.cryptde_pair.main.public_key().to_string(), "AQIDBA"); + assert_eq!(result.cryptde_pair.alias.public_key().to_string(), "BAMCAQ"); + } + #[test] fn configure_database_handles_error_during_setting_clandestine_port() { + let _guard = EnvironmentGuard::new(); let mut config = BootstrapperConfig::new(); config.clandestine_port_opt = Some(1000); let mut persistent_config = PersistentConfigurationMock::new() @@ -460,6 +569,7 @@ mod tests { #[test] fn configure_database_handles_error_during_setting_gas_price() { + let _guard = EnvironmentGuard::new(); let mut config = BootstrapperConfig::new(); config.clandestine_port_opt = None; let mut persistent_config = PersistentConfigurationMock::new() @@ -477,6 +587,7 @@ mod tests { #[test] fn configure_database_handles_error_during_setting_blockchain_service_url() { + let _guard = EnvironmentGuard::new(); let mut config = BootstrapperConfig::new(); config.blockchain_bridge_config.blockchain_service_url_opt = Some("https://infura.io/ID".to_string()); @@ -496,6 +607,7 @@ mod tests { #[test] fn configure_database_handles_error_during_setting_neighborhood_mode() { + let _guard = EnvironmentGuard::new(); let mut config = BootstrapperConfig::new(); config.neighborhood_config.mode = ZeroHop; let mut persistent_config = PersistentConfigurationMock::new() @@ -512,6 +624,7 @@ mod tests { #[test] fn configure_database_handles_error_during_setting_min_hops() { + let _guard = EnvironmentGuard::new(); let mut config = BootstrapperConfig::new(); config.neighborhood_config.min_hops = Hops::FourHops; let mut persistent_config = PersistentConfigurationMock::new() @@ -526,6 +639,75 @@ mod tests { ) } + #[test] + fn configure_cryptdes_handles_missing_password_with_uninitialized_cryptdes() { + let cryptde_params_arc = Arc::new(Mutex::new(vec![])); + let set_cryptde_params_arc = Arc::new(Mutex::new(vec![])); + let mut persistent_config = PersistentConfigurationMock::new() + .cryptde_params(&cryptde_params_arc) + .set_cryptde_params(&set_cryptde_params_arc) + .chain_name_result(TEST_DEFAULT_CHAIN.to_string()); + + let _result = configure_cryptdes(&mut persistent_config, &None); + + let cryptde_params = cryptde_params_arc.lock().unwrap(); + assert_eq!(cryptde_params.len(), 0); + let set_cryptde_params = set_cryptde_params_arc.lock().unwrap(); + assert_eq!(set_cryptde_params.len(), 0); + } + + #[test] + fn configure_cryptdes_handles_missing_last_cryptde() { + let cryptde_params_arc = Arc::new(Mutex::new(vec![])); + let set_cryptde_params_arc = Arc::new(Mutex::new(vec![])); + let mut persistent_config = PersistentConfigurationMock::new() + .cryptde_params(&cryptde_params_arc) + .chain_name_result(TEST_DEFAULT_CHAIN.to_string()) + .cryptde_result(Ok(None)) + .set_cryptde_params(&set_cryptde_params_arc) + .set_cryptde_result(Ok(())); + + let result = configure_cryptdes(&mut persistent_config, &Some("db_password".to_string())); + + let cryptde_params = cryptde_params_arc.lock().unwrap(); + assert_eq!(*cryptde_params, vec!["db_password".to_string()]); + let set_cryptde_params = set_cryptde_params_arc.lock().unwrap(); + let call = &set_cryptde_params[0]; + assert_eq!(call.0.public_key(), result.main.public_key()); + assert_eq!(call.1, "db_password".to_string()); + } + + #[test] + #[should_panic(expected = "Could not read last cryptde from database: NotPresent")] + fn configure_cryptdes_panics_if_database_throws_error() { + let _guard = EnvironmentGuard::new(); + let mut persistent_config = PersistentConfigurationMock::new() + .chain_name_result(TEST_DEFAULT_CHAIN.to_string()) + .cryptde_result(Err(PersistentConfigError::NotPresent)); + + let _ = configure_cryptdes(&mut persistent_config, &Some("db_password".to_string())); + } + + #[test] + fn configure_cryptdes_handles_populated_database() { + let _guard = EnvironmentGuard::new(); + let stored_main_cryptde_box = Box::new(CryptDEReal::new(TEST_DEFAULT_CHAIN)); + let cryptde_params_arc = Arc::new(Mutex::new(vec![])); + let mut persistent_config = PersistentConfigurationMock::new() + .cryptde_params(&cryptde_params_arc) + .chain_name_result(TEST_DEFAULT_CHAIN.to_string()) + .cryptde_result(Ok(Some(stored_main_cryptde_box.dup()))); + + let result = configure_cryptdes(&mut persistent_config, &Some("db_password".to_string())); + + assert_eq!( + result.main.public_key(), + stored_main_cryptde_box.public_key() + ); + let cryptde_params = cryptde_params_arc.lock().unwrap(); + assert_eq!(*cryptde_params, vec!["db_password".to_string()]); + } + fn make_default_cli_params() -> ArgsBuilder { ArgsBuilder::new().param("--ip", "1.2.3.4") } @@ -562,6 +744,7 @@ mod tests { #[test] fn can_read_dns_servers_and_consuming_private_key_from_config_file() { + let _guard = EnvironmentGuard::new(); running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", @@ -634,6 +817,7 @@ mod tests { #[test] fn privileged_parse_args_creates_configurations() { + let _guard = EnvironmentGuard::new(); running_test(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", @@ -652,7 +836,6 @@ mod tests { .param("--data-directory", home_dir.to_str().unwrap()) .param("--blockchain-service-url", "http://127.0.0.1:8545") .param("--log-level", "trace") - .param("--fake-public-key", "AQIDBA") .param("--db-password", "secret-db-password") .param( "--earning-wallet", @@ -686,7 +869,7 @@ mod tests { assert_eq!( config.neighborhood_config, NeighborhoodConfig { - mode: NeighborhoodMode::ZeroHop, // not populated on the privileged side + mode: ZeroHop, // not populated on the privileged side min_hops: Hops::ThreeHops, } ); @@ -695,10 +878,6 @@ mod tests { None, ); assert_eq!(config.data_directory, home_dir); - assert_eq!( - config.main_cryptde_null_opt.unwrap().public_key(), - &PublicKey::new(&[1, 2, 3, 4]), - ); assert_eq!( config.real_user, RealUser::new(Some(999), Some(999), Some(PathBuf::from("/home/booga"))) @@ -707,6 +886,7 @@ mod tests { #[test] fn privileged_parse_args_creates_configuration_with_defaults() { + let _guard = EnvironmentGuard::new(); running_test(); let args = ArgsBuilder::new().param("--ip", "1.2.3.4"); let mut config = BootstrapperConfig::new(); @@ -723,7 +903,6 @@ mod tests { ); assert_eq!(config.crash_point, CrashPoint::None); assert_eq!(config.ui_gateway_config.ui_port, DEFAULT_UI_PORT); - assert!(config.main_cryptde_null_opt.is_none()); assert_eq!( config.real_user, RealUser::new(None, None, None).populate(&DirsWrapperReal::default()) @@ -733,6 +912,7 @@ mod tests { #[test] #[cfg(not(target_os = "windows"))] fn privileged_parse_args_with_real_user_defaults_data_directory_properly() { + let _guard = EnvironmentGuard::new(); running_test(); let args = ArgsBuilder::new() .param("--ip", "1.2.3.4") @@ -761,6 +941,7 @@ mod tests { #[test] fn privileged_parse_args_with_no_command_line_params() { + let _guard = EnvironmentGuard::new(); running_test(); let args = ArgsBuilder::new(); let mut config = BootstrapperConfig::new(); @@ -777,7 +958,6 @@ mod tests { ); assert_eq!(config.crash_point, CrashPoint::None); assert_eq!(config.ui_gateway_config.ui_port, DEFAULT_UI_PORT); - assert!(config.main_cryptde_null_opt.is_none()); assert_eq!( config.real_user, RealUser::new(None, None, None).populate(&DirsWrapperReal::default()) @@ -786,6 +966,7 @@ mod tests { #[test] fn no_parameters_produces_configuration_for_crash_point() { + let _guard = EnvironmentGuard::new(); running_test(); let args = make_default_cli_params(); let mut config = BootstrapperConfig::new(); @@ -799,6 +980,7 @@ mod tests { #[test] fn with_parameters_produces_configuration_for_crash_point() { + let _guard = EnvironmentGuard::new(); running_test(); let args = make_default_cli_params().param("--crash-point", "panic"); let mut config = BootstrapperConfig::new(); @@ -1014,8 +1196,8 @@ mod tests { #[test] fn server_initializer_collected_params_rewrite_config_files_parameters_from_environment() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", @@ -1075,8 +1257,8 @@ mod tests { #[test] fn tilde_in_config_file_path_from_commandline_and_args_uploaded_from_config_file() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", @@ -1148,8 +1330,8 @@ mod tests { #[test] fn config_file_from_env_and_real_user_from_config_file_with_data_directory_from_command_line() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","config_file_from_env_and_real_user_from_config_file_with_data_directory_from_command_line"); let data_dir = &home_dir.join("data_dir"); @@ -1192,8 +1374,8 @@ mod tests { expected = "If the config file is given with a naked relative path (config/config.toml), the data directory must be given to serve as the root for the config-file path." )] fn server_initializer_collected_params_fails_on_naked_dir_config_file_without_data_directory() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard","server_initializer_collected_params_fails_on_naked_dir_config_file_without_data_directory"); let data_dir = &home_dir.join("data_dir"); @@ -1211,8 +1393,8 @@ mod tests { #[test] fn server_initializer_collected_params_combine_vcls_properly() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let home_dir = ensure_node_home_directory_exists( "node_configurator_standard", @@ -1275,6 +1457,7 @@ mod tests { #[test] fn server_initializer_collected_params_senses_when_user_specifies_config_file() { + let _guard = EnvironmentGuard::new(); running_test(); let home_dir = PathBuf::from("/unexisting_home/unexisting_alice"); let data_dir = home_dir.join("data_dir"); @@ -1306,6 +1489,7 @@ mod tests { #[test] fn privileged_configuration_accepts_network_chain_selection_for_multinode() { + let _guard = EnvironmentGuard::new(); running_test(); let _clap_guard = ClapGuard::new(); let subject = NodeConfiguratorStandardPrivileged::new(); @@ -1320,6 +1504,7 @@ mod tests { #[test] fn privileged_configuration_accepts_network_chain_selection_for_ropsten() { + let _guard = EnvironmentGuard::new(); running_test(); let subject = NodeConfiguratorStandardPrivileged::new(); let args = [ @@ -1338,6 +1523,7 @@ mod tests { #[test] fn privileged_configuration_defaults_network_chain_selection_to_mainnet() { + let _guard = EnvironmentGuard::new(); running_test(); let _clap_guard = ClapGuard::new(); let subject = NodeConfiguratorStandardPrivileged::new(); @@ -1359,6 +1545,7 @@ mod tests { #[test] fn privileged_configuration_accepts_ropsten_network_chain_selection() { + let _guard = EnvironmentGuard::new(); running_test(); let subject = NodeConfiguratorStandardPrivileged::new(); let args = [ @@ -1379,6 +1566,7 @@ mod tests { #[test] fn unprivileged_configuration_gets_parameter_gas_price() { + let _guard = EnvironmentGuard::new(); running_test(); let _clap_guard = ClapGuard::new(); let data_dir = ensure_node_home_directory_exists( @@ -1399,6 +1587,7 @@ mod tests { #[test] fn unprivileged_configuration_sets_default_gas_price_when_not_provided() { + let _guard = EnvironmentGuard::new(); running_test(); let _clap_guard = ClapGuard::new(); let data_dir = ensure_node_home_directory_exists( @@ -1422,8 +1611,8 @@ mod tests { )] #[test] fn server_initializer_collected_params_rejects_invalid_gas_price() { - running_test(); let _guard = EnvironmentGuard::new(); + running_test(); let _clap_guard = ClapGuard::new(); let args = ArgsBuilder::new().param("--gas-price", "unleaded"); let args_vec: Vec = args.into(); @@ -1441,14 +1630,16 @@ mod tests { #[test] fn configure_database_with_data_specified_on_command_line_and_in_database() { + let _guard = EnvironmentGuard::new(); running_test(); + let cryptde_pair = CryptDEPair::null(); let mut config = BootstrapperConfig::new(); let gas_price = 4u64; config.clandestine_port_opt = Some(1234); config.blockchain_bridge_config.gas_price = gas_price; config.neighborhood_config.mode = NeighborhoodMode::ConsumeOnly(vec![NodeDescriptor::try_from(( - main_cryptde(), + cryptde_pair.main.as_ref(), format!( "masq://{}:AQIDBA@1.2.3.4:1234/2345", TEST_DEFAULT_CHAIN.rec().literal_identifier @@ -1499,6 +1690,7 @@ mod tests { #[test] fn configure_database_with_no_data_specified() { + let _guard = EnvironmentGuard::new(); running_test(); let config = BootstrapperConfig::new(); let set_blockchain_service_params_arc = Arc::new(Mutex::new(vec![])); @@ -1530,6 +1722,7 @@ mod tests { #[test] fn external_data_is_properly_created_when_password_is_provided() { + let _guard = EnvironmentGuard::new(); let mut configurator_standard = NodeConfiguratorStandardUnprivileged::new(&BootstrapperConfig::new()); configurator_standard @@ -1555,6 +1748,7 @@ mod tests { #[test] fn external_data_is_properly_created_when_no_password_is_provided() { + let _guard = EnvironmentGuard::new(); let mut configurator_standard = NodeConfiguratorStandardUnprivileged::new(&BootstrapperConfig::new()); configurator_standard diff --git a/node/src/node_configurator/unprivileged_parse_args_configuration.rs b/node/src/node_configurator/unprivileged_parse_args_configuration.rs index 4238bd8d54..41cd9a4245 100644 --- a/node/src/node_configurator/unprivileged_parse_args_configuration.rs +++ b/node/src/node_configurator/unprivileged_parse_args_configuration.rs @@ -24,6 +24,7 @@ use masq_lib::utils::{to_string, AutomapProtocol, ExpectValue}; use rustc_hex::FromHex; use std::net::{IpAddr, Ipv4Addr}; use std::str::FromStr; +use PersistentConfigError::PasswordError; pub trait UnprivilegedParseArgsConfiguration { // Only initialization that cannot be done with privilege should happen here. @@ -83,27 +84,25 @@ impl UnprivilegedParseArgsConfiguration for UnprivilegedParseArgsConfigurationDa persistent_config: &mut dyn PersistentConfiguration, unprivileged_config: &mut BootstrapperConfig, ) -> Result, ConfiguratorError> { - Ok( - match &get_db_password(unprivileged_config, persistent_config)? { - Some(db_password) => match persistent_config.past_neighbors(db_password) { - Ok(Some(past_neighbors)) => past_neighbors, - Ok(None) => vec![], - Err(PersistentConfigError::PasswordError) => { - return Err(ConfiguratorError::new(vec![ParamError::new( - "db-password", - "PasswordError", - )])) - } - Err(e) => { - return Err(ConfiguratorError::new(vec![ParamError::new( - "[past neighbors]", - &format!("{:?}", e), - )])) - } - }, - None => vec![], + Ok(match &unprivileged_config.db_password_opt { + Some(db_password) => match persistent_config.past_neighbors(db_password) { + Ok(Some(past_neighbors)) => past_neighbors, + Ok(None) => vec![], + Err(PasswordError) => { + return Err(ConfiguratorError::new(vec![ParamError::new( + "db-password", + "PasswordError", + )])) + } + Err(e) => { + return Err(ConfiguratorError::new(vec![ParamError::new( + "[past neighbors]", + &format!("{:?}", e), + )])) + } }, - ) + None => vec![], + }) } } @@ -129,7 +128,7 @@ pub fn get_wallets( let pc_consuming_opt = if let Some(db_password) = &config.db_password_opt { match persistent_config.consuming_wallet_private_key(db_password.as_str()) { Ok(pco) => pco, - Err(PersistentConfigError::PasswordError) => None, + Err(PasswordError) => None, Err(e) => return Err(e.into_configurator_error("consuming-private-key")), } } else { @@ -589,31 +588,6 @@ where ) } -fn get_db_password( - config: &mut BootstrapperConfig, - persistent_config: &mut dyn PersistentConfiguration, -) -> Result, ConfiguratorError> { - if let Some(db_password) = &config.db_password_opt { - set_db_password_at_first_mention(db_password, persistent_config)?; - return Ok(Some(db_password.clone())); - } - Ok(None) -} - -fn set_db_password_at_first_mention( - db_password: &str, - persistent_config: &mut dyn PersistentConfiguration, -) -> Result { - match persistent_config.check_password(None) { - Ok(true) => match persistent_config.change_password(None, db_password) { - Ok(_) => Ok(true), - Err(e) => Err(e.into_configurator_error("db-password")), - }, - Ok(false) => Ok(false), - Err(e) => Err(e.into_configurator_error("db-password")), - } -} - fn is_user_specified(multi_config: &MultiConfig, parameter: &str) -> bool { multi_config.occurrences_of(parameter) > 0 } @@ -624,6 +598,7 @@ mod tests { use crate::accountant::db_access_objects::utils::ThresholdUtils; use crate::apps::app_node; use crate::blockchain::bip32::Bip32EncryptionKeyProvider; + use crate::bootstrapper::CryptDEPair; use crate::database::db_initializer::DbInitializationConfig; use crate::database::db_initializer::{DbInitializer, DbInitializerReal}; use crate::db_config::config_dao::{ConfigDao, ConfigDaoReal}; @@ -641,7 +616,8 @@ mod tests { make_persistent_config_real_with_config_dao_null, make_simplified_multi_config, ACCOUNTANT_CONFIG_PARAMS, MAPPING_PROTOCOL, RATE_PACK, ZERO, }; - use crate::test_utils::{main_cryptde, ArgsBuilder}; + use crate::test_utils::ArgsBuilder; + use lazy_static::lazy_static; use masq_lib::constants::DEFAULT_GAS_PRICE; use masq_lib::multi_config::{CommandLineVcl, NameValueVclArg, VclArg, VirtualCommandLine}; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; @@ -651,6 +627,11 @@ mod tests { use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::Duration; + use PersistentConfigError::{DatabaseError, TransactionError}; + + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } #[test] fn convert_ci_configs_handles_blockchain_mismatch() { @@ -736,8 +717,8 @@ mod tests { ))], ) .unwrap(); - let mut persistent_config = PersistentConfigurationMock::new() - .min_hops_result(Err(PersistentConfigError::NotPresent)); + let mut persistent_config = + PersistentConfigurationMock::new().min_hops_result(Err(NotPresent)); let _result = make_neighborhood_config( &UnprivilegedParseArgsConfigurationDaoReal {}, @@ -889,7 +870,7 @@ mod tests { NeighborhoodMode::OriginateOnly( vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:QmlsbA@1.2.3.4:1234/2345", DEFAULT_CHAIN.rec().literal_identifier @@ -898,7 +879,7 @@ mod tests { )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:VGVk@2.3.4.5:3456/4567", DEFAULT_CHAIN.rec().literal_identifier @@ -964,7 +945,7 @@ mod tests { result.unwrap().mode, NeighborhoodMode::ConsumeOnly(vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:QmlsbA@1.2.3.4:1234/2345", DEFAULT_CHAIN.rec().literal_identifier @@ -973,7 +954,7 @@ mod tests { )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:VGVk@2.3.4.5:3456/4567", DEFAULT_CHAIN.rec().literal_identifier @@ -1095,7 +1076,7 @@ mod tests { running_test(); let mut persistent_config = PersistentConfigurationMock::new() .check_password_result(Ok(false)) - .past_neighbors_result(Err(PersistentConfigError::NotPresent)); + .past_neighbors_result(Err(NotPresent)); let mut unprivileged_config = BootstrapperConfig::new(); unprivileged_config.db_password_opt = Some("password".to_string()); let subject = UnprivilegedParseArgsConfigurationDaoReal {}; @@ -1145,118 +1126,6 @@ mod tests { //Nothing panicked so we could not call real persistent config's methods. } - #[test] - fn set_db_password_at_first_mention_handles_existing_password() { - let check_password_params_arc = Arc::new(Mutex::new(vec![])); - let mut persistent_config = configure_default_persistent_config(ZERO) - .check_password_params(&check_password_params_arc) - .check_password_result(Ok(false)); - - let result = set_db_password_at_first_mention("password", &mut persistent_config); - - assert_eq!(result, Ok(false)); - let check_password_params = check_password_params_arc.lock().unwrap(); - assert_eq!(*check_password_params, vec![None]) - } - - #[test] - fn set_db_password_at_first_mention_sets_password_correctly() { - let change_password_params_arc = Arc::new(Mutex::new(vec![])); - let mut persistent_config = configure_default_persistent_config(ZERO) - .check_password_result(Ok(true)) - .change_password_params(&change_password_params_arc) - .change_password_result(Ok(())); - - let result = set_db_password_at_first_mention("password", &mut persistent_config); - - assert_eq!(result, Ok(true)); - let change_password_params = change_password_params_arc.lock().unwrap(); - assert_eq!( - *change_password_params, - vec![(None, "password".to_string())] - ) - } - - #[test] - fn set_db_password_at_first_mention_handles_password_check_error() { - let check_password_params_arc = Arc::new(Mutex::new(vec![])); - let mut persistent_config = configure_default_persistent_config(ZERO) - .check_password_params(&check_password_params_arc) - .check_password_result(Err(PersistentConfigError::NotPresent)); - - let result = set_db_password_at_first_mention("password", &mut persistent_config); - - assert_eq!( - result, - Err(PersistentConfigError::NotPresent.into_configurator_error("db-password")) - ); - let check_password_params = check_password_params_arc.lock().unwrap(); - assert_eq!(*check_password_params, vec![None]) - } - - #[test] - fn set_db_password_at_first_mention_handles_password_set_error() { - let change_password_params_arc = Arc::new(Mutex::new(vec![])); - let mut persistent_config = configure_default_persistent_config(ZERO) - .check_password_result(Ok(true)) - .change_password_params(&change_password_params_arc) - .change_password_result(Err(PersistentConfigError::NotPresent)); - - let result = set_db_password_at_first_mention("password", &mut persistent_config); - - assert_eq!( - result, - Err(NotPresent.into_configurator_error("db-password")) - ); - let change_password_params = change_password_params_arc.lock().unwrap(); - assert_eq!( - *change_password_params, - vec![(None, "password".to_string())] - ) - } - - #[test] - fn get_db_password_if_supplied() { - running_test(); - let mut config = BootstrapperConfig::new(); - let mut persistent_config = - configure_default_persistent_config(ZERO).check_password_result(Ok(false)); - config.db_password_opt = Some("password".to_string()); - - let result = get_db_password(&mut config, &mut persistent_config); - - assert_eq!(result, Ok(Some("password".to_string()))); - } - - #[test] - fn get_db_password_doesnt_bother_if_database_has_no_password_yet() { - running_test(); - let mut config = BootstrapperConfig::new(); - let mut persistent_config = - configure_default_persistent_config(ZERO).check_password_result(Ok(true)); - - let result = get_db_password(&mut config, &mut persistent_config); - - assert_eq!(result, Ok(None)); - } - - #[test] - fn get_db_password_handles_database_write_error() { - running_test(); - let mut config = BootstrapperConfig::new(); - config.db_password_opt = Some("password".to_string()); - let mut persistent_config = configure_default_persistent_config(ZERO) - .check_password_result(Ok(true)) - .change_password_result(Err(PersistentConfigError::NotPresent)); - - let result = get_db_password(&mut config, &mut persistent_config); - - assert_eq!( - result, - Err(PersistentConfigError::NotPresent.into_configurator_error("db-password")) - ); - } - #[test] fn convert_ci_configs_handles_leftover_whitespaces_between_descriptors_and_commas() { let multi_config = make_simplified_multi_config([ @@ -1371,7 +1240,7 @@ mod tests { *set_past_neighbors_params, vec![( Some(vec![NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:UJNoZW5p-PDVqEjpr3b_8jZ_93yPG8i5dOAgE1bhK_A@2.3.4.5:2345" )) .unwrap()]), @@ -1417,7 +1286,7 @@ mod tests { let mut persistent_config = PersistentConfigurationMock::new(); //no results prepared for set_past_neighbors() and no panic so it was not called let descriptor_list = vec![NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:UJNoZW5p-PDVqEjpr3b_8jZ_93yPG8i5dOAgE1bhK_A@2.3.4.5:2345", )) .unwrap()]; @@ -1437,11 +1306,10 @@ mod tests { #[test] fn configure_zero_hop_with_neighbors_but_setting_values_failed() { running_test(); - let mut persistent_config = PersistentConfigurationMock::new().set_past_neighbors_result( - Err(PersistentConfigError::DatabaseError("Oh yeah".to_string())), - ); + let mut persistent_config = PersistentConfigurationMock::new() + .set_past_neighbors_result(Err(DatabaseError("Oh yeah".to_string()))); let descriptor_list = vec![NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:UJNoZW5p-PDVqEjpr3b_8jZ_93yPG8i5dOAgE1bhK_A@2.3.4.5:2345", )) .unwrap()]; @@ -1566,7 +1434,7 @@ mod tests { NodeAddr::new(&IpAddr::from_str("34.56.78.90").unwrap(), &[]), vec![ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:QmlsbA@1.2.3.4:1234/2345", DEFAULT_CHAIN.rec().literal_identifier @@ -1575,7 +1443,7 @@ mod tests { )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), format!( "masq://{}:VGVk@2.3.4.5:3456/4567", DEFAULT_CHAIN.rec().literal_identifier @@ -1682,12 +1550,12 @@ mod tests { config.neighborhood_config.mode.neighbor_configs(), &[ NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:AQIDBA@1.2.3.4:1234" )) .unwrap(), NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345" )) .unwrap(), @@ -2247,8 +2115,8 @@ mod tests { #[should_panic(expected = "rate-pack: database query failed due to NotPresent")] fn process_combined_params_panics_on_persistent_config_getter_method_with_cli_present() { let multi_config = make_simplified_multi_config(["--rate-pack", "4|5|6|7"]); - let mut persist_config = PersistentConfigurationMock::default() - .rate_pack_result(Err(PersistentConfigError::NotPresent)); + let mut persist_config = + PersistentConfigurationMock::default().rate_pack_result(Err(NotPresent)); let _ = execute_process_combined_params_for_rate_pack(&multi_config, &mut persist_config); } @@ -2259,7 +2127,7 @@ mod tests { let multi_config = make_simplified_multi_config(["--rate-pack", "4|5|6|7"]); let mut persist_config = PersistentConfigurationMock::default() .rate_pack_result(Ok(RatePack::try_from("1|1|2|2").unwrap())) - .set_rate_pack_result(Err(PersistentConfigError::TransactionError)); + .set_rate_pack_result(Err(TransactionError)); let _ = execute_process_combined_params_for_rate_pack(&multi_config, &mut persist_config); } @@ -2268,8 +2136,8 @@ mod tests { #[should_panic(expected = "rate-pack: database query failed due to NotPresent")] fn process_combined_params_panics_on_persistent_config_getter_method_with_cli_absent() { let multi_config = make_simplified_multi_config([]); - let mut persist_config = PersistentConfigurationMock::default() - .rate_pack_result(Err(PersistentConfigError::NotPresent)); + let mut persist_config = + PersistentConfigurationMock::default().rate_pack_result(Err(NotPresent)); let _ = execute_process_combined_params_for_rate_pack(&multi_config, &mut persist_config); } @@ -2294,7 +2162,7 @@ mod tests { let multi_config = make_simplified_multi_config([]); let mut persistent_config = PersistentConfigurationMock::new() .earning_wallet_address_result(Ok(None)) - .consuming_wallet_private_key_result(Err(PersistentConfigError::NotPresent)); + .consuming_wallet_private_key_result(Err(NotPresent)); let mut config = BootstrapperConfig::new(); config.db_password_opt = Some("password".to_string()); @@ -2302,7 +2170,7 @@ mod tests { assert_eq!( result, - Err(PersistentConfigError::NotPresent.into_configurator_error("consuming-private-key")) + Err(NotPresent.into_configurator_error("consuming-private-key")) ); } @@ -2511,8 +2379,8 @@ mod tests { init_test_logging(); let multi_config = make_simplified_multi_config([]); let logger = Logger::new("BAD_MP_READ"); - let mut persistent_config = configure_default_persistent_config(ZERO) - .mapping_protocol_result(Err(PersistentConfigError::NotPresent)); + let mut persistent_config = + configure_default_persistent_config(ZERO).mapping_protocol_result(Err(NotPresent)); let result = compute_mapping_protocol_opt(&multi_config, &mut persistent_config, &logger); @@ -2530,7 +2398,7 @@ mod tests { let logger = Logger::new("BAD_MP_WRITE"); let mut persistent_config = configure_default_persistent_config(ZERO) .mapping_protocol_result(Ok(Some(AutomapProtocol::Pcp))) - .set_mapping_protocol_result(Err(PersistentConfigError::NotPresent)); + .set_mapping_protocol_result(Err(NotPresent)); let result = compute_mapping_protocol_opt(&multi_config, &mut persistent_config, &logger); @@ -2642,7 +2510,7 @@ mod tests { (Some(past_neighbors), Some(_)) => Ok(Some( past_neighbors .split(",") - .map(|s| NodeDescriptor::try_from((main_cryptde(), s)).unwrap()) + .map(|s| NodeDescriptor::try_from((CRYPTDE_PAIR.main.as_ref(), s)).unwrap()) .collect::>(), )), _ => Ok(None), diff --git a/node/src/proxy_client/mod.rs b/node/src/proxy_client/mod.rs index d05cb505b4..aa0f330104 100644 --- a/node/src/proxy_client/mod.rs +++ b/node/src/proxy_client/mod.rs @@ -8,13 +8,13 @@ mod stream_handler_pool; mod stream_reader; mod stream_writer; +use crate::bootstrapper::CryptDEPair; use crate::proxy_client::resolver_wrapper::ResolverWrapperFactory; use crate::proxy_client::resolver_wrapper::ResolverWrapperFactoryReal; use crate::proxy_client::stream_handler_pool::StreamHandlerPool; use crate::proxy_client::stream_handler_pool::StreamHandlerPoolFactory; use crate::proxy_client::stream_handler_pool::StreamHandlerPoolFactoryReal; use crate::sub_lib::accountant::ReportExitServiceProvidedMessage; -use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::cryptde::PublicKey; use crate::sub_lib::hopper::MessageType; use crate::sub_lib::hopper::{ExpiredCoresPackage, IncipientCoresPackage}; @@ -52,7 +52,7 @@ pub struct ProxyClient { dns_servers: Vec, resolver_wrapper_factory: Box, stream_handler_pool_factory: Box, - cryptde: &'static dyn CryptDE, + cryptde_pair: CryptDEPair, to_hopper: Option>, to_accountant: Option>, pool: Option>, @@ -89,7 +89,7 @@ impl Handler for ProxyClient { let resolver = self.resolver_wrapper_factory.make(config, opts); self.pool = Some(self.stream_handler_pool_factory.make( resolver, - self.cryptde, + self.cryptde_pair.main.as_ref(), self.to_accountant.clone().expect("Accountant is unbound"), msg.peer_actors.proxy_client_opt.unwrap(), self.exit_service_rate, @@ -180,7 +180,7 @@ impl Handler for ProxyClient { match stream_context_opt { Some(stream_context) => { let package = IncipientCoresPackage::new( - self.cryptde, + self.cryptde_pair.main.as_ref(), stream_context.return_route.clone(), MessageType::DnsResolveFailed(VersionedData::new( &crate::sub_lib::migrations::dns_resolve_failure::MIGRATIONS, @@ -225,7 +225,7 @@ impl ProxyClient { dns_servers: config.dns_servers, resolver_wrapper_factory: Box::new(ResolverWrapperFactoryReal {}), stream_handler_pool_factory: Box::new(StreamHandlerPoolFactoryReal {}), - cryptde: config.cryptde, + cryptde_pair: config.cryptde_pair.clone(), to_hopper: None, to_accountant: None, pool: None, @@ -276,7 +276,7 @@ impl ProxyClient { msg_data_len ); let icp = match IncipientCoresPackage::new( - self.cryptde, + self.cryptde_pair.main.as_ref(), stream_context.return_route.clone(), payload, &stream_context.payload_destination_key, @@ -331,6 +331,7 @@ struct StreamContext { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::node_test_utils::check_timestamp; use crate::proxy_client::local_test_utils::ResolverWrapperFactoryMock; use crate::proxy_client::local_test_utils::ResolverWrapperMock; @@ -338,8 +339,8 @@ mod tests { use crate::proxy_client::stream_handler_pool::StreamHandlerPool; use crate::proxy_client::stream_handler_pool::StreamHandlerPoolFactory; use crate::sub_lib::accountant::ReportExitServiceProvidedMessage; - use crate::sub_lib::cryptde::CryptData; use crate::sub_lib::cryptde::PublicKey; + use crate::sub_lib::cryptde::{CryptDE, CryptData}; use crate::sub_lib::dispatcher::Component; use crate::sub_lib::hopper::MessageType; use crate::sub_lib::proxy_client::ClientResponsePayload_0v1; @@ -356,6 +357,7 @@ mod tests { use crate::test_utils::unshared_test_utils::prove_that_crash_request_handler_is_hooked_up; use crate::test_utils::*; use actix::System; + use lazy_static::lazy_static; use masq_lib::blockchains::chains::Chain; use masq_lib::test_utils::logging::{init_test_logging, TestLogHandler}; use std::cell::RefCell; @@ -367,6 +369,10 @@ mod tests { use std::thread; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!(CRASH_KEY, "PROXYCLIENT"); @@ -414,7 +420,7 @@ mod tests { Mutex< Vec<( Box, - &'static dyn CryptDE, + Box, Recipient, ProxyClientSubs, u64, @@ -429,7 +435,7 @@ mod tests { fn make( &self, resolver: Box, - cryptde: &'static dyn CryptDE, + cryptde: &dyn CryptDE, accountant_sub: Recipient, proxy_client_subs: ProxyClientSubs, exit_service_rate: u64, @@ -437,7 +443,7 @@ mod tests { ) -> Box { self.make_parameters.lock().unwrap().push(( resolver, - cryptde, + cryptde.dup(), accountant_sub, proxy_client_subs, exit_service_rate, @@ -461,7 +467,7 @@ mod tests { Mutex< Vec<( Box, - &'static dyn CryptDE, + Box, Recipient, ProxyClientSubs, u64, @@ -486,7 +492,7 @@ mod tests { #[test] fn is_decentralized_flag_is_passed_through_constructor() { let config_factory = |is_decentralized: bool| ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::V4( SocketAddrV4::from_str("1.2.3.4:4560").unwrap(), )], @@ -509,7 +515,7 @@ mod tests { )] fn proxy_client_can_be_crashed_properly_but_not_improperly() { let proxy_client = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::V4( SocketAddrV4::from_str("1.2.3.4:4560").unwrap(), )], @@ -528,7 +534,7 @@ mod tests { )] fn at_least_one_dns_server_must_be_provided() { ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![], exit_service_rate: 100, exit_byte_rate: 200, @@ -554,7 +560,7 @@ mod tests { .make_result(Box::new(pool)); let peer_actors = peer_actors_builder().build(); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![ SocketAddr::from_str("4.3.2.1:4321").unwrap(), SocketAddr::from_str("5.4.3.2:5432").unwrap(), @@ -612,7 +618,7 @@ mod tests { protocol: ProxyProtocol::HTTP, originator_public_key: PublicKey::new(&b"originator_public_key"[..]), }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), @@ -622,7 +628,7 @@ mod tests { ); let system = System::new("panics_if_hopper_is_unbound"); let subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: dnss(), exit_service_rate: 100, exit_byte_rate: 200, @@ -640,13 +646,12 @@ mod tests { #[test] fn logs_nonexistent_stream_key_during_dns_resolution_failure() { init_test_logging(); - let cryptde = main_cryptde(); let stream_key = StreamKey::make_meaningless_stream_key(); let stream_key_inner = stream_key.clone(); thread::spawn(move || { let system = System::new("logs_nonexistent_stream_key_during_dns_resolution_failure"); let subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("1.1.1.1:53").unwrap()], exit_service_rate: 0, exit_byte_rate: 0, @@ -675,11 +680,11 @@ mod tests { #[test] fn forwards_dns_resolve_failed_to_hopper() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (hopper, hopper_awaiter, hopper_recording_arc) = make_recorder(); let stream_key = StreamKey::make_meaningless_stream_key(); - let return_route = make_meaningless_route(); - let originator_key = make_meaningless_public_key(); + let return_route = make_meaningless_route(&CRYPTDE_PAIR); + let originator_key = make_meaningless_public_key(&CRYPTDE_PAIR); let stream_key_inner = stream_key.clone(); let return_route_inner = return_route.clone(); let originator_key_inner = originator_key.clone(); @@ -687,7 +692,7 @@ mod tests { let system = System::new("forwards_dns_resolve_failed_to_hopper"); let peer_actors = peer_actors_builder().hopper(hopper).build(); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("1.1.1.1:53").unwrap()], exit_service_rate: 0, exit_byte_rate: 0, @@ -742,7 +747,6 @@ mod tests { #[test] fn data_from_hopper_is_relayed_to_stream_handler_pool() { - let cryptde = main_cryptde(); let request = ClientRequestPayload_0v1 { stream_key: StreamKey::make_meaningless_stream_key(), sequenced_packet: SequencedPacket { @@ -755,9 +759,9 @@ mod tests { protocol: ProxyProtocol::HTTP, originator_public_key: PublicKey::new(&b"originator"[..]), }; - let key1 = make_meaningless_public_key(); - let key2 = make_meaningless_public_key(); - let route = make_one_way_route_to_proxy_client(vec![&key1, &key2]); + let key1 = make_meaningless_public_key(&CRYPTDE_PAIR); + let key2 = make_meaningless_public_key(&CRYPTDE_PAIR); + let route = make_one_way_route_to_proxy_client(vec![&key1, &key2], &CRYPTDE_PAIR); let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), @@ -779,7 +783,7 @@ mod tests { .lookup_ip_success(vec![IpAddr::from_str("4.3.2.1").unwrap()]); let resolver_factory = ResolverWrapperFactoryMock::new().new_result(Box::new(resolver)); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: dnss(), exit_service_rate: 100, exit_byte_rate: 200, @@ -802,7 +806,6 @@ mod tests { #[test] fn refuse_to_provide_exit_services_with_no_paying_wallet() { init_test_logging(); - let cryptde = main_cryptde(); let request = ClientRequestPayload_0v1 { stream_key: StreamKey::make_meaningless_stream_key(), sequenced_packet: SequencedPacket { @@ -818,7 +821,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), None, - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), request, 0, ); @@ -836,7 +839,7 @@ mod tests { .lookup_ip_success(vec![IpAddr::from_str("4.3.2.1").unwrap()]); let resolver_factory = ResolverWrapperFactoryMock::new().new_result(Box::new(resolver)); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: dnss(), exit_service_rate: rate_pack_exit(100), exit_byte_rate: rate_pack_exit_byte(100), @@ -853,13 +856,13 @@ mod tests { System::current().stop(); system.run(); assert_eq!(0, process_package_parameters.lock().unwrap().len()); - TestLogHandler::new().exists_log_containing(format!("WARN: ProxyClient: Refusing to provide exit services for CORES package with 12-byte payload without paying wallet").as_str()); + TestLogHandler::new().exists_log_containing("WARN: ProxyClient: Refusing to provide exit services for CORES package with 12-byte payload without paying wallet"); } #[test] fn does_provide_zero_hop_exit_services_with_no_paying_wallet() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let request = ClientRequestPayload_0v1 { stream_key: StreamKey::make_meaningless_stream_key(), sequenced_packet: SequencedPacket { @@ -903,7 +906,7 @@ mod tests { .lookup_ip_success(vec![IpAddr::from_str("4.3.2.1").unwrap()]); let resolver_factory = ResolverWrapperFactoryMock::new().new_result(Box::new(resolver)); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: dnss(), exit_service_rate: rate_pack_exit(100), exit_byte_rate: rate_pack_exit_byte(100), @@ -932,9 +935,9 @@ mod tests { let stream_key = StreamKey::make_meaningful_stream_key(test_name); let data: &[u8] = b"An honest politician is one who, when he is bought, will stay bought."; let system = System::new(test_name); - let route = make_meaningless_route(); + let route = make_meaningless_route(&CRYPTDE_PAIR); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("8.7.6.5:4321").unwrap()], exit_service_rate: 100, exit_byte_rate: 200, @@ -1002,7 +1005,7 @@ mod tests { assert_eq!( hopper_recording.get_record::(0), &IncipientCoresPackage::new( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), route.clone(), MessageType::ClientResponse(VersionedData::new( &crate::sub_lib::migrations::client_response_payload::MIGRATIONS, @@ -1022,7 +1025,7 @@ mod tests { assert_eq!( hopper_recording.get_record::(1), &IncipientCoresPackage::new( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), route.clone(), MessageType::ClientResponse(VersionedData::new( &crate::sub_lib::migrations::client_response_payload::MIGRATIONS, @@ -1083,7 +1086,7 @@ mod tests { let system = System::new("inbound_server_data_without_paying_wallet_does_not_report_exit_service"); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("8.7.6.5:4321").unwrap()], exit_service_rate: 100, exit_byte_rate: 200, @@ -1093,7 +1096,7 @@ mod tests { subject.stream_contexts.insert( stream_key.clone(), StreamContext { - return_route: make_meaningless_route(), + return_route: make_meaningless_route(&CRYPTDE_PAIR), payload_destination_key: PublicKey::new(&b"abcd"[..]), paying_wallet: None, }, @@ -1135,7 +1138,7 @@ mod tests { let data: &[u8] = b"An honest politician is one who, when he is bought, will stay bought."; let system = System::new("error_creating_incipient_cores_package_is_logged_and_dropped"); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde: main_cryptde(), + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("8.7.6.5:4321").unwrap()], exit_service_rate: 100, exit_byte_rate: 200, @@ -1145,7 +1148,7 @@ mod tests { subject.stream_contexts.insert( stream_key.clone(), StreamContext { - return_route: make_meaningless_route(), + return_route: make_meaningless_route(&CRYPTDE_PAIR), payload_destination_key: PublicKey::new(&[]), paying_wallet: Some(make_wallet("consuming")), }, @@ -1178,14 +1181,14 @@ mod tests { #[test] fn new_return_route_overwrites_existing_return_route() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (hopper, _, hopper_recording_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); let stream_key = StreamKey::make_meaningless_stream_key(); let data: &[u8] = b"An honest politician is one who, when he is bought, will stay bought."; let system = System::new("new_return_route_overwrites_existing_return_route"); let mut subject = ProxyClient::new(ProxyClientConfig { - cryptde, + cryptde_pair: CRYPTDE_PAIR.clone(), dns_servers: vec![SocketAddr::from_str("8.7.6.5:4321").unwrap()], exit_service_rate: 100, exit_byte_rate: 200, @@ -1199,7 +1202,7 @@ mod tests { let old_return_route = Route { hops: vec![CryptData::new(&[1, 2, 3, 4])], }; - let new_return_route = make_meaningless_route(); + let new_return_route = make_meaningless_route(&CRYPTDE_PAIR); let originator_public_key = PublicKey::new(&[4, 3, 2, 1]); subject.stream_contexts.insert( stream_key.clone(), diff --git a/node/src/proxy_client/stream_establisher.rs b/node/src/proxy_client/stream_establisher.rs index 4d6fdad24f..602b3c0c1c 100644 --- a/node/src/proxy_client/stream_establisher.rs +++ b/node/src/proxy_client/stream_establisher.rs @@ -22,7 +22,7 @@ use std::net::IpAddr; use std::net::SocketAddr; pub struct StreamEstablisher { - pub cryptde: &'static dyn CryptDE, + pub cryptde: Box, pub stream_adder_tx: Sender<(StreamKey, StreamSenders)>, pub stream_killer_tx: Sender<(StreamKey, u64)>, pub stream_connector: Box, @@ -34,7 +34,7 @@ pub struct StreamEstablisher { impl Clone for StreamEstablisher { fn clone(&self) -> Self { StreamEstablisher { - cryptde: self.cryptde, + cryptde: self.cryptde.dup(), stream_adder_tx: self.stream_adder_tx.clone(), stream_killer_tx: self.stream_killer_tx.clone(), stream_connector: Box::new(StreamConnectorReal {}), @@ -50,11 +50,11 @@ impl StreamEstablisher { &mut self, payload: &ClientRequestPayload_0v1, ip_addrs: Vec, - target_hostname: String, + target_hostname: &str, ) -> io::Result>> { let connection_info = self.stream_connector.connect_one( ip_addrs, - &target_hostname, + target_hostname, payload.target_port, &self.logger, )?; @@ -112,7 +112,7 @@ pub trait StreamEstablisherFactory: Send { } pub struct StreamEstablisherFactoryReal { - pub cryptde: &'static dyn CryptDE, + pub cryptde: Box, pub stream_adder_tx: Sender<(StreamKey, StreamSenders)>, pub stream_killer_tx: Sender<(StreamKey, u64)>, pub proxy_client_subs: ProxyClientSubs, @@ -122,7 +122,7 @@ pub struct StreamEstablisherFactoryReal { impl StreamEstablisherFactory for StreamEstablisherFactoryReal { fn make(&self) -> StreamEstablisher { StreamEstablisher { - cryptde: self.cryptde, + cryptde: self.cryptde.dup(), stream_adder_tx: self.stream_adder_tx.clone(), stream_killer_tx: self.stream_killer_tx.clone(), stream_connector: Box::new(StreamConnectorReal {}), @@ -136,8 +136,8 @@ impl StreamEstablisherFactory for StreamEstablisherFactoryReal { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::proxy_server::ProxyProtocol; - use crate::test_utils::main_cryptde; use crate::test_utils::recorder::make_recorder; use crate::test_utils::recorder::peer_actors_builder; use crate::test_utils::stream_connector_mock::StreamConnectorMock; @@ -145,12 +145,17 @@ mod tests { use actix::System; use crossbeam_channel::unbounded; use futures::future::lazy; + use lazy_static::lazy_static; use std::io::ErrorKind; use std::net::SocketAddr; use std::str::FromStr; use std::thread; use tokio::prelude::Async; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn spawn_stream_reader_handles_data() { let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); @@ -178,7 +183,7 @@ mod tests { ]; let subject = StreamEstablisher { - cryptde: main_cryptde(), + cryptde: CRYPTDE_PAIR.main.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new(StreamConnectorMock::new()), // only used in "establish_stream" diff --git a/node/src/proxy_client/stream_handler_pool.rs b/node/src/proxy_client/stream_handler_pool.rs index 5ecbe9794b..7fc6236176 100644 --- a/node/src/proxy_client/stream_handler_pool.rs +++ b/node/src/proxy_client/stream_handler_pool.rs @@ -75,7 +75,7 @@ type StreamEstablisherResult = impl StreamHandlerPoolReal { pub fn new( resolver: Box, - cryptde: &'static dyn CryptDE, + cryptde: &dyn CryptDE, accountant_sub: Recipient, proxy_client_subs: ProxyClientSubs, exit_service_rate: u64, @@ -86,7 +86,7 @@ impl StreamHandlerPoolReal { StreamHandlerPoolReal { inner: Arc::new(Mutex::new(StreamHandlerPoolRealInner { establisher_factory: Box::new(StreamEstablisherFactoryReal { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, proxy_client_subs: proxy_client_subs.clone(), @@ -112,6 +112,14 @@ impl StreamHandlerPoolReal { ) { let stream_key = payload.stream_key; let inner_arc_1 = inner_arc.clone(); + let logger = Self::make_logger_copy(&inner_arc); + let data_len = payload.sequenced_packet.data.len(); + let hostname = payload + .target_hostname + .as_ref() + .unwrap_or(&"".to_string()) + .to_string(); + let target_port = payload.target_port; match Self::find_stream_with_key(&stream_key, &inner_arc) { Some(sender_wrapper) => { let source = sender_wrapper.peer_addr(); @@ -120,6 +128,14 @@ impl StreamHandlerPoolReal { .map_err(move |error| { Self::clean_up_bad_stream(inner_arc_1, &stream_key, source, error) }); + debug!( + logger, + "Spawning future to write {} bytes over existing stream {:?} to {}:{}", + data_len, + stream_key, + hostname, + target_port + ); actix::spawn(future); } None => { @@ -150,6 +166,14 @@ impl StreamHandlerPoolReal { error, ); }); + debug!( + logger, + "Spawning future to write {} bytes over new stream {:?} to {}:{}", + data_len, + stream_key, + hostname, + target_port + ); actix::spawn(future); } } @@ -219,8 +243,17 @@ impl StreamHandlerPoolReal { let stream_key = payload.stream_key; let last_data = payload.sequenced_packet.last_data; let payload_size = payload.sequenced_packet.data.len(); + let logger = Self::make_logger_copy(&inner_arc); - Self::perform_write(payload.sequenced_packet, sender_wrapper.clone()).and_then(move |_| { + debug!( + logger, + "Queueing write of {} bytes{} to {} on stream {}", + payload_size, + if last_data { " (last data)" } else { "" }, + sender_wrapper.peer_addr(), + stream_key, + ); + Self::queue_write(payload.sequenced_packet, sender_wrapper.clone()).and_then(move |_| { let mut inner = inner_arc.lock().expect("Stream handler pool is poisoned"); if payload_size > 0 { match paying_wallet_opt { @@ -246,7 +279,7 @@ impl StreamHandlerPoolReal { Some(stream_senders) => { debug!( inner.logger, - "Removing StreamWriter and Shutting down StreamReader for {:?} to {}", + "Removing StreamWriter and shutting down StreamReader for {:?} to {}", stream_key, stream_senders.writer_data.peer_addr() ); @@ -331,7 +364,7 @@ impl StreamHandlerPoolReal { let mut stream_establisher = StreamHandlerPoolReal::make_establisher(inner_arc); Box::new( future::lazy(move || { - stream_establisher.establish_stream(&payload, vec![ip_addr], target_hostname) + stream_establisher.establish_stream(&payload, vec![ip_addr], &target_hostname) }) .map_err(|io_error| format!("Could not establish stream: {:?}", io_error)), ) @@ -419,7 +452,28 @@ impl StreamHandlerPoolReal { logger, "Found IP addresses for {}: {:?}", target_hostname, &filtered_ip_addrs ); - establisher.establish_stream(payload, filtered_ip_addrs, target_hostname) + let result = establisher.establish_stream(payload, filtered_ip_addrs, &target_hostname); + match result { + Ok(sender_wrapper) => { + debug!( + logger, + "Established stream with key {:?} to {}", + payload.stream_key, + sender_wrapper.peer_addr() + ); + Ok(sender_wrapper) + } + Err(e) => { + debug!( + logger, + "Failed to establish stream with key {:?} to {}: {}", + payload.stream_key, + target_hostname, + e + ); + Err(io::Error::new(io::ErrorKind::Other, e)) + } + } } fn make_fqdn(target_hostname: &str) -> String { @@ -441,7 +495,7 @@ impl StreamHandlerPoolReal { inner.logger.clone() } - fn perform_write( + fn queue_write( sequenced_packet: SequencedPacket, sender_wrapper: Box>, ) -> FutureResult<(), String> { @@ -535,7 +589,7 @@ pub trait StreamHandlerPoolFactory { fn make( &self, resolver: Box, - cryptde: &'static dyn CryptDE, + cryptde: &dyn CryptDE, accountant_sub: Recipient, proxy_client_subs: ProxyClientSubs, exit_service_rate: u64, @@ -549,7 +603,7 @@ impl StreamHandlerPoolFactory for StreamHandlerPoolFactoryReal { fn make( &self, resolver: Box, - cryptde: &'static dyn CryptDE, + cryptde: &dyn CryptDE, accountant_sub: Recipient, proxy_client_subs: ProxyClientSubs, exit_service_rate: u64, @@ -569,6 +623,7 @@ impl StreamHandlerPoolFactory for StreamHandlerPoolFactoryReal { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::node_test_utils::check_timestamp; use crate::proxy_client::local_test_utils::make_send_error; use crate::proxy_client::local_test_utils::ResolverWrapperMock; @@ -582,7 +637,6 @@ mod tests { use crate::test_utils::channel_wrapper_mocks::FuturesChannelFactoryMock; use crate::test_utils::channel_wrapper_mocks::ReceiverWrapperMock; use crate::test_utils::channel_wrapper_mocks::SenderWrapperMock; - use crate::test_utils::main_cryptde; use crate::test_utils::make_meaningless_route; use crate::test_utils::make_wallet; use crate::test_utils::recorder::make_recorder; @@ -591,6 +645,7 @@ mod tests { use crate::test_utils::tokio_wrapper_mocks::ReadHalfWrapperMock; use crate::test_utils::tokio_wrapper_mocks::WriteHalfWrapperMock; use actix::System; + use lazy_static::lazy_static; use masq_lib::constants::HTTP_PORT; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; @@ -607,6 +662,10 @@ mod tests { use tokio::prelude::Async; use trust_dns_resolver::error::ResolveErrorKind; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + struct StreamEstablisherFactoryMock { make_results: RefCell>, } @@ -641,12 +700,12 @@ mod tests { thread::spawn(move || { let system = System::new("dns_resolution_failure_sends_a_message_to_proxy_client"); let peer_actors = peer_actors_builder().proxy_client(proxy_client).build(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let resolver_mock = ResolverWrapperMock::new().lookup_ip_failure(ResolveErrorKind::Io.into()); let logger = Logger::new("dns_resolution_failure_sends_a_message_to_proxy_client"); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx: unbounded().0, stream_killer_tx: unbounded().0, stream_connector: Box::new(StreamConnectorMock::new()), @@ -697,7 +756,7 @@ mod tests { #[test] fn non_terminal_payload_can_be_sent_over_existing_connection() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let client_request_payload = ClientRequestPayload_0v1 { stream_key: stream_key.clone(), @@ -722,7 +781,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.clone().into(), 0, ); @@ -760,7 +819,7 @@ mod tests { fn write_failure_for_nonexistent_stream_generates_termination_message() { init_test_logging(); let test_name = "write_failure_for_nonexistent_stream_generates_termination_message"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); let originator_key = PublicKey::new(&b"men's souls"[..]); let (reader_shutdown_tx, reader_shutdown_rx) = unbounded(); @@ -780,7 +839,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.clone().into(), 0, ); @@ -835,7 +894,7 @@ mod tests { #[test] fn when_hostname_is_ip_establish_stream_without_dns_lookup() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let write_parameters = Arc::new(Mutex::new(vec![])); let expected_write_parameters = write_parameters.clone(); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); @@ -856,7 +915,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -890,7 +949,7 @@ mod tests { { let mut inner = subject.inner.lock().unwrap(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new(StreamConnectorMock::new().with_connection( @@ -952,7 +1011,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -960,7 +1019,7 @@ mod tests { let peer_actors = peer_actors_builder().build(); let subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided.clone(), peer_actors.proxy_client_opt.unwrap().clone(), 100, @@ -984,7 +1043,7 @@ mod tests { assert_eq!(received, Ok(())); TestLogHandler::new().await_log_containing( &format!( - "DEBUG: {test_name}: Removing StreamWriter and Shutting down StreamReader \ + "DEBUG: {test_name}: Removing StreamWriter and shutting down StreamReader \ for oUHoHuDKHjeWq+BJzBIqHpPFBQw to 3.4.5.6:80" ), 500, @@ -1013,7 +1072,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1021,7 +1080,7 @@ mod tests { let peer_actors = peer_actors_builder().build(); let subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided.clone(), peer_actors.proxy_client_opt.unwrap().clone(), 100, @@ -1052,7 +1111,7 @@ mod tests { #[test] fn ip_is_parsed_even_without_port() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let lookup_ip_parameters = Arc::new(Mutex::new(vec![])); let expected_lookup_ip_parameters = lookup_ip_parameters.clone(); let write_parameters = Arc::new(Mutex::new(vec![])); @@ -1075,7 +1134,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1115,7 +1174,7 @@ mod tests { { let mut inner = subject.inner.lock().unwrap(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new(StreamConnectorMock::new().with_connection( @@ -1164,7 +1223,7 @@ mod tests { init_test_logging(); let test_name = "missing_hostname_for_nonexistent_stream_generates_log_and_termination_message"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); let originator_key = PublicKey::new(&b"men's souls"[..]); let stream_key = StreamKey::make_meaningful_stream_key(test_name); @@ -1185,7 +1244,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1226,7 +1285,7 @@ mod tests { #[test] fn nonexistent_connection_springs_into_being_and_is_persisted_to_handle_transaction() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let lookup_ip_parameters = Arc::new(Mutex::new(vec![])); let expected_lookup_ip_parameters = lookup_ip_parameters.clone(); let write_parameters = Arc::new(Mutex::new(vec![])); @@ -1254,7 +1313,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1294,7 +1353,7 @@ mod tests { { let mut inner = subject.inner.lock().unwrap(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new(StreamConnectorMock::new().with_connection( @@ -1345,7 +1404,7 @@ mod tests { #[test] fn failing_to_make_a_connection_sends_an_error_response() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let lookup_ip_parameters = Arc::new(Mutex::new(vec![])); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); @@ -1367,7 +1426,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1394,7 +1453,7 @@ mod tests { subject.stream_killer_rx = stream_killer_rx; let (stream_adder_tx, _stream_adder_rx) = unbounded(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new( @@ -1467,7 +1526,7 @@ mod tests { fn wildcard_ip_resolves_in_dns_failure() { init_test_logging(); let test_name = "wildcard_ip_resolves_in_dns_failure"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let lookup_ip_parameters = Arc::new(Mutex::new(vec![])); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); @@ -1489,7 +1548,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1516,7 +1575,7 @@ mod tests { } let (stream_adder_tx, _stream_adder_rx) = unbounded(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new( @@ -1559,7 +1618,7 @@ mod tests { #[test] fn trying_to_write_to_disconnected_stream_writer_sends_an_error_response() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let lookup_ip_parameters = Arc::new(Mutex::new(vec![])); let write_parameters = Arc::new(Mutex::new(vec![])); @@ -1587,7 +1646,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1632,7 +1691,7 @@ mod tests { { let mut inner = subject.inner.lock().unwrap(); let establisher = StreamEstablisher { - cryptde, + cryptde: cryptde.dup(), stream_adder_tx, stream_killer_tx, stream_connector: Box::new( @@ -1679,7 +1738,7 @@ mod tests { #[test] fn bad_dns_lookup_produces_log_and_sends_error_response() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let (proxy_client, proxy_client_awaiter, proxy_client_recording_arc) = make_recorder(); let originator_key = PublicKey::new(&b"men's souls"[..]); @@ -1699,7 +1758,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1740,7 +1799,7 @@ mod tests { #[test] fn error_from_tx_to_writer_removes_stream() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let (proxy_client, _, _) = make_recorder(); let (hopper, _, _) = make_recorder(); @@ -1761,7 +1820,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1808,7 +1867,7 @@ mod tests { ) { init_test_logging(); let test_name = "process_package_does_not_create_new_connection_for_zero_length_data_with_unfamiliar_stream_key"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (hopper, _, hopper_recording_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); let stream_key = StreamKey::make_meaningful_stream_key(test_name); @@ -1832,7 +1891,7 @@ mod tests { let package = ExpiredCoresPackage::new( SocketAddr::from_str("1.2.3.4:1234").unwrap(), Some(make_wallet("consuming")), - make_meaningless_route(), + make_meaningless_route(&CRYPTDE_PAIR), client_request_payload.into(), 0, ); @@ -1875,7 +1934,7 @@ mod tests { let peer_actors = peer_actors_builder().proxy_client(proxy_client).build(); let mut subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided, peer_actors.proxy_client_opt.unwrap(), 0, @@ -1926,7 +1985,7 @@ mod tests { let peer_actors = peer_actors_builder().build(); let mut subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided, peer_actors.proxy_client_opt.unwrap(), 0, @@ -1968,7 +2027,7 @@ mod tests { let peer_actors = peer_actors_builder().proxy_client(proxy_client).build(); let mut subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided, peer_actors.proxy_client_opt.unwrap(), 0, @@ -1995,7 +2054,7 @@ mod tests { let peer_actors = peer_actors_builder().build(); let mut subject = StreamHandlerPoolReal::new( Box::new(ResolverWrapperMock::new()), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), peer_actors.accountant.report_exit_service_provided, peer_actors.proxy_client_opt.unwrap(), 0, diff --git a/node/src/proxy_client/stream_writer.rs b/node/src/proxy_client/stream_writer.rs index c9842741a9..9aea2d1a3c 100644 --- a/node/src/proxy_client/stream_writer.rs +++ b/node/src/proxy_client/stream_writer.rs @@ -90,16 +90,20 @@ impl StreamWriter { Some(packet) => { debug!( self.logger, - "Writing {} bytes over existing stream", - packet.data.len() + "Writing {} bytes from packet {}{} over existing stream", + packet.data.len(), + packet.sequence_number, + if packet.last_data { " (last data)" } else { "" } ); match self.stream.poll_write(&packet.data) { Err(e) => { if indicates_dead_stream(e.kind()) { error!( self.logger, - "Error writing {} bytes: {}", + "Error writing {} bytes from packet {}{}: {}", packet.data.len(), + packet.sequence_number, + if packet.last_data { " (last data)" } else { "" }, e ); return Err(()); @@ -162,6 +166,13 @@ mod tests { use std::io::ErrorKind; use std::str::FromStr; use std::sync::{Arc, Mutex}; + use std::thread; + + fn thread_id_string() -> String { + let thread_id_str = format!("{:?}", thread::current().id()); + let thread_id = &thread_id_str[9..(thread_id_str.len() - 1)]; + format!("Thd{}", thread_id) + } #[test] fn stream_writer_writes_packets_in_sequenced_order() { @@ -219,44 +230,53 @@ mod tests { assert_eq!(write_params[3], empty_packet); let tlh = TestLogHandler::new(); + let thread_id = thread_id_string(); tlh.assert_logs_contain_in_order(vec![ format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes over existing stream", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes from packet 0 over existing stream", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 5/5 bytes of clear data", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 5/5 bytes of clear data", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 6 bytes over existing stream", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 6 bytes from packet 1 over existing stream", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 6/6 bytes of clear data", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 6/6 bytes of clear data", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 4 bytes over existing stream", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 4 bytes from packet 2 over existing stream", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 4/4 bytes of clear data", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 4/4 bytes of clear data", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 0 bytes over existing stream", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 0 bytes from packet 3 over existing stream", + thread_id, stream_key ) .as_str(), format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 0/0 bytes of clear data", + "{}: DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Wrote 0/0 bytes of clear data", + thread_id, stream_key ) .as_str(), @@ -341,7 +361,7 @@ mod tests { assert_eq!(write_params.lock().unwrap().len(), 2); let tlh = TestLogHandler::new(); tlh.assert_logs_contain_in_order(vec!( - format!("DEBUG: StreamWriter for {:?}/1.3.3.4:5678: Writing 19 bytes over existing stream", stream_key).as_str (), + format!("DEBUG: StreamWriter for {:?}/1.3.3.4:5678: Writing 19 bytes from packet 0 over existing stream", stream_key).as_str (), format!("WARN: StreamWriter for {:?}/1.3.3.4:5678: Continuing after write error: other error", stream_key).as_str (), format!("DEBUG: StreamWriter for {:?}/1.3.3.4:5678: Wrote 19/19 bytes of clear data", stream_key).as_str ())); } @@ -455,7 +475,7 @@ mod tests { TestLogHandler::new().exists_log_containing( format!( - "ERROR: StreamWriter for {:?}/2.3.4.5:80: Error writing 19 bytes: broken pipe", + "ERROR: StreamWriter for {:?}/2.3.4.5:80: Error writing 19 bytes from packet 0: broken pipe", stream_key ) .as_str(), @@ -573,7 +593,7 @@ mod tests { let tlh = TestLogHandler::new(); tlh.assert_logs_contain_in_order(vec![ format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes over existing stream", + "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes from packet 0 (last data) over existing stream", stream_key ) .as_str(), @@ -626,7 +646,7 @@ mod tests { let tlh = TestLogHandler::new(); tlh.assert_logs_contain_in_order(vec![ format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes over existing stream", + "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes from packet 0 (last data) over existing stream", stream_key ) .as_str(), @@ -680,7 +700,7 @@ mod tests { let tlh = TestLogHandler::new(); tlh.assert_logs_contain_in_order(vec![ format!( - "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes over existing stream", + "DEBUG: StreamWriter for {:?}/2.2.3.4:5678: Writing 5 bytes from packet 0 (last data) over existing stream", stream_key ) .as_str(), diff --git a/node/src/proxy_server/client_request_payload_factory.rs b/node/src/proxy_server/client_request_payload_factory.rs index e146501e20..75a484a37b 100644 --- a/node/src/proxy_server/client_request_payload_factory.rs +++ b/node/src/proxy_server/client_request_payload_factory.rs @@ -71,8 +71,9 @@ impl ClientRequestPayloadFactoryReal { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::proxy_server::ProxyProtocol; - use crate::test_utils::main_cryptde; + use lazy_static::lazy_static; use masq_lib::constants::HTTP_PORT; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; @@ -80,6 +81,10 @@ mod tests { use std::str::FromStr; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn handles_http_with_a_port() { let data = PlainData::new(&b"GET http://borkoed.com:2345/fleebs.html HTTP/1.1\r\n\r\n"[..]); @@ -92,7 +97,7 @@ mod tests { is_clandestine: false, data: data.clone().into(), }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let logger = Logger::new("test"); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -129,7 +134,7 @@ mod tests { is_clandestine: false, data: data.clone().into(), }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new(test_name); let stream_key = StreamKey::make_meaningful_stream_key(test_name); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -185,7 +190,7 @@ mod tests { data: data.clone().into(), }; let stream_key = StreamKey::make_meaningless_stream_key(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new("test"); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -234,7 +239,7 @@ mod tests { sequence_number: Some(0), data: data.clone().into(), }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new(test_name); let stream_key = StreamKey::make_meaningful_stream_key(test_name); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -271,7 +276,7 @@ mod tests { is_clandestine: false, data: vec![0x10, 0x11, 0x12], }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new(test_name); let stream_key = StreamKey::make_meaningful_stream_key(test_name); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -297,7 +302,7 @@ mod tests { is_clandestine: true, data: vec![0x10, 0x11, 0x12], }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new(test_name); let stream_key = StreamKey::make_meaningful_stream_key(test_name); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -319,7 +324,7 @@ mod tests { data: vec![0x10, 0x11, 0x12], is_clandestine: false, }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new("test"); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); @@ -348,7 +353,7 @@ mod tests { sequence_number: None, data: vec![1, 3, 5, 7], }; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let logger = Logger::new(test_name); let stream_key = StreamKey::make_meaningful_stream_key(test_name); let subject = Box::new(ClientRequestPayloadFactoryReal::new()); diff --git a/node/src/proxy_server/mod.rs b/node/src/proxy_server/mod.rs index fc03348349..459acf668c 100644 --- a/node/src/proxy_server/mod.rs +++ b/node/src/proxy_server/mod.rs @@ -7,6 +7,7 @@ pub mod server_impersonator_http; pub mod server_impersonator_tls; pub mod tls_protocol_pack; +use crate::bootstrapper::CryptDEPair; use crate::proxy_server::client_request_payload_factory::{ ClientRequestPayloadFactory, ClientRequestPayloadFactoryReal, }; @@ -85,8 +86,7 @@ pub struct ProxyServer { stream_key_ttl: HashMap, is_decentralized: bool, consuming_wallet_balance: Option, - main_cryptde: &'static dyn CryptDE, - alias_cryptde: &'static dyn CryptDE, + cryptde_pair: CryptDEPair, crashable: bool, logger: Logger, route_ids_to_return_routes: TtlHashMap, @@ -250,8 +250,7 @@ where impl ProxyServer { pub fn new( - main_cryptde: &'static dyn CryptDE, - alias_cryptde: &'static dyn CryptDE, + cryptde_pair: CryptDEPair, is_decentralized: bool, consuming_wallet_balance: Option, crashable: bool, @@ -268,8 +267,7 @@ impl ProxyServer { stream_key_ttl: HashMap::new(), is_decentralized, consuming_wallet_balance, - main_cryptde, - alias_cryptde, + cryptde_pair, crashable, logger: Logger::new("ProxyServer"), route_ids_to_return_routes: TtlHashMap::new(RETURN_ROUTE_TTL), @@ -369,7 +367,7 @@ impl ProxyServer { }; let exit_public_key = { // ugly, ugly - let self_public_key = self.main_cryptde.public_key(); + let self_public_key = self.cryptde_pair.main.as_ref().public_key(); return_route_info .find_exit_node_key() .unwrap_or_else(|| { @@ -493,8 +491,10 @@ impl ProxyServer { debug!( self.logger, "ExpiredCoresPackage remaining_route: {}", - msg.remaining_route - .to_string(vec![self.main_cryptde, self.main_cryptde]) + msg.remaining_route.to_string(vec![ + self.cryptde_pair.main.as_ref(), + self.cryptde_pair.main.as_ref() + ]) ); let payload_data_len = msg.payload_len; let response = msg.payload; @@ -662,9 +662,10 @@ impl ProxyServer { stream_key } None => { - let stream_key = self - .stream_key_factory - .make(self.main_cryptde.public_key(), ibcd.client_addr); + let stream_key = self.stream_key_factory.make( + self.cryptde_pair.main.as_ref().public_key(), + ibcd.client_addr, + ); self.keys_and_addrs.insert(stream_key, ibcd.client_addr); debug!( self.logger, @@ -704,7 +705,7 @@ impl ProxyServer { match self.client_request_payload_factory.make( &new_ibcd, *stream_key, - self.alias_cryptde, + self.cryptde_pair.alias.as_ref(), &self.logger, ) { None => Err("Couldn't create ClientRequestPayload".to_string()), @@ -840,7 +841,7 @@ impl ProxyServer { let payload_size = payload.sequenced_packet.data.len(); let stream_key = payload.stream_key; let pkg = IncipientCoresPackage::new( - args.main_cryptde, + args.main_cryptde.as_ref(), route, payload.into(), &payload_destination_key, @@ -930,9 +931,9 @@ impl ProxyServer { ) -> Option> { let mut mut_remaining_route = remaining_route.clone(); mut_remaining_route - .shift(self.main_cryptde) + .shift(self.cryptde_pair.main.as_ref()) .expect("Internal error: remaining route in ProxyServer with no hops"); - let return_route_id = match mut_remaining_route.id(self.main_cryptde) { + let return_route_id = match mut_remaining_route.id(self.cryptde_pair.main.as_ref()) { Ok(rri) => rri, Err(e) => { error!(self.logger, "Can't report services consumed: {}", e); @@ -1222,7 +1223,7 @@ impl IBCDHelper for IBCDHelperReal { } pub struct TransmitToHopperArgs { - pub main_cryptde: &'static dyn CryptDE, + pub main_cryptde: Box, pub payload: ClientRequestPayload_0v1, pub client_addr: SocketAddr, pub timestamp: SystemTime, @@ -1253,7 +1254,7 @@ impl TransmitToHopperArgs { None }; Self { - main_cryptde: proxy_server.main_cryptde, + main_cryptde: proxy_server.cryptde_pair.main.dup(), payload, client_addr, timestamp, @@ -1353,6 +1354,7 @@ impl Hostname { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::match_every_type_id; use crate::proxy_server::protocol_pack::ServerImpersonator; use crate::proxy_server::server_impersonator_http::ServerImpersonatorHttp; @@ -1375,8 +1377,10 @@ mod tests { use crate::sub_lib::sequence_buffer::SequencedPacket; use crate::sub_lib::ttl_hashmap::TtlHashMap; use crate::sub_lib::versioned_data::VersionedData; + use crate::test_utils::make_meaningless_route; use crate::test_utils::make_paying_wallet; use crate::test_utils::make_wallet; + use crate::test_utils::rate_pack; use crate::test_utils::recorder::make_recorder; use crate::test_utils::recorder::peer_actors_builder; use crate::test_utils::recorder::Recorder; @@ -1385,10 +1389,9 @@ mod tests { make_request_payload, prove_that_crash_request_handler_is_hooked_up, AssertionsMessage, }; use crate::test_utils::zero_hop_route_response; - use crate::test_utils::{alias_cryptde, rate_pack}; - use crate::test_utils::{main_cryptde, make_meaningless_route}; use actix::System; use crossbeam_channel::unbounded; + use lazy_static::lazy_static; use masq_lib::constants::{HTTP_PORT, TLS_PORT}; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; @@ -1401,6 +1404,10 @@ mod tests { use std::thread; use std::time::SystemTime; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + impl Handler> for ProxyServer { type Result = (); @@ -1622,8 +1629,8 @@ mod tests { ) { init_test_logging(); let test_name = "proxy_server_receives_http_request_with_new_stream_key_from_dispatcher_then_sends_cores_package_to_hopper"; - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (hopper_mock, hopper_awaiter, hopper_log_arc) = make_recorder(); let (neighborhood_mock, _, neighborhood_recording_arc) = make_recorder(); @@ -1678,8 +1685,7 @@ mod tests { .make_result(stream_key); let system = System::new(test_name); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -1726,8 +1732,8 @@ mod tests { #[test] fn proxy_server_receives_connect_responds_with_ok_and_stores_stream_key_and_hostname() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let http_request = b"CONNECT https://realdomain.nu:443 HTTP/1.1\r\nHost: https://bunkjunk.wrong:443\r\n\r\n"; let (hopper_mock, hopper_awaiter, hopper_recording_arc) = make_recorder(); let (neighborhood_mock, _, neighborhood_recording_arc) = make_recorder(); @@ -1799,8 +1805,7 @@ mod tests { "proxy_server_receives_connect_responds_with_ok_and_stores_stream_key_and_hostname", ); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -1850,10 +1855,9 @@ mod tests { ) { let system = System::new("handle_client_response_payload_increments_sequence_number_when_browser_proxy_sequence_offset_is_true"); let (dispatcher_mock, _, dispatcher_log_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -1924,7 +1928,7 @@ mod tests { #[test] fn proxy_server_sends_route_failure_for_connect_requests_to_ports_other_than_443() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let http_request = b"CONNECT https://realdomain.nu:8443 HTTP/1.1\r\nHost: https://bunkjunk.wrong:443\r\n\r\n"; let (hopper_mock, _hopper_awaiter, _hopper_recording_arc) = make_recorder(); @@ -1959,8 +1963,7 @@ mod tests { "proxy_server_receives_connect_responds_with_ok_and_stores_stream_key_and_hostname", ); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -1996,7 +1999,7 @@ mod tests { #[test] fn proxy_server_sends_error_and_shuts_down_stream_when_connect_host_unparseable() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let http_request = "CONNECT λ:🥓:λ HTTP/1.1\r\nHost: 🥓:🥔:🥔\r\n\r\n".as_bytes(); let (hopper_mock, _hopper_awaiter, _hopper_recording_arc) = make_recorder(); @@ -2031,8 +2034,7 @@ mod tests { "proxy_server_receives_connect_responds_with_ok_and_stores_stream_key_and_hostname", ); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2070,7 +2072,6 @@ mod tests { fn proxy_server_receives_http_request_with_no_consuming_wallet_and_sends_impersonated_response() { init_test_logging(); - let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (hopper, _, hopper_log_arc) = make_recorder(); let (neighborhood, _, neighborhood_log_arc) = make_recorder(); @@ -2089,7 +2090,7 @@ mod tests { }; let stream_key_factory = StreamKeyFactoryMock::new(); // can't make any stream keys; shouldn't have to let system = System::new("proxy_server_receives_http_request_with_no_consuming_wallet_and_sends_impersonated_response"); - let mut subject = ProxyServer::new(cryptde, alias_cryptde(), true, None, false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); subject.stream_key_factory = Box::new(stream_key_factory); subject.keys_and_addrs.insert(stream_key, socket_addr); let subject_addr: Addr = subject.start(); @@ -2129,7 +2130,6 @@ mod tests { fn proxy_server_receives_tls_request_with_no_consuming_wallet_and_sends_impersonated_response() { init_test_logging(); - let cryptde = main_cryptde(); let tls_request = b"Fake TLS request"; let (hopper, _, hopper_log_arc) = make_recorder(); let (neighborhood, _, neighborhood_log_arc) = make_recorder(); @@ -2148,7 +2148,7 @@ mod tests { }; let stream_key_factory = StreamKeyFactoryMock::new(); // can't make any stream keys; shouldn't have to let system = System::new("proxy_server_receives_tls_request_with_no_consuming_wallet_and_sends_impersonated_response"); - let mut subject = ProxyServer::new(cryptde, alias_cryptde(), true, None, false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); subject.stream_key_factory = Box::new(stream_key_factory); subject.keys_and_addrs.insert(stream_key, socket_addr); let subject_addr: Addr = subject.start(); @@ -2188,8 +2188,8 @@ mod tests { fn proxy_server_receives_http_request_with_no_consuming_wallet_in_zero_hop_mode_and_handles_normally( ) { init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let expected_data = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n".to_vec(); let expected_data_inner = expected_data.clone(); let expected_route = zero_hop_route_response(main_cryptde.public_key(), main_cryptde); @@ -2211,8 +2211,7 @@ mod tests { }; let stream_key_factory = StreamKeyFactoryMock::new(); // can't make any stream keys; shouldn't have to let system = System::new("proxy_server_receives_http_request_with_no_consuming_wallet_in_zero_hop_mode_and_handles_normally"); - let mut subject = - ProxyServer::new(main_cryptde, alias_cryptde, false, None, false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), false, None, false, false); subject.stream_key_factory = Box::new(stream_key_factory); subject.keys_and_addrs.insert(stream_key, socket_addr); let subject_addr: Addr = subject.start(); @@ -2268,8 +2267,8 @@ mod tests { fn proxy_server_receives_tls_request_with_no_consuming_wallet_in_zero_hop_mode_and_handles_normally( ) { init_test_logging(); - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let expected_data = b"Fake TLS request".to_vec(); let expected_data_inner = expected_data.clone(); let expected_route = zero_hop_route_response(main_cryptde.public_key(), main_cryptde); @@ -2291,8 +2290,7 @@ mod tests { }; let stream_key_factory = StreamKeyFactoryMock::new(); // can't make any stream keys; shouldn't have to let system = System::new("proxy_server_receives_tls_request_with_no_consuming_wallet_in_zero_hop_mode_and_handles_normally"); - let mut subject = - ProxyServer::new(main_cryptde, alias_cryptde, false, None, false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), false, None, false, false); subject.stream_key_factory = Box::new(stream_key_factory); subject.keys_and_addrs.insert(stream_key, socket_addr); let subject_addr: Addr = subject.start(); @@ -2347,8 +2345,8 @@ mod tests { #[test] fn proxy_server_receives_http_request_with_existing_stream_key_from_dispatcher_then_sends_cores_package_to_hopper( ) { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let hopper_mock = Recorder::new(); let hopper_log_arc = hopper_mock.get_recording(); @@ -2399,8 +2397,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new(); // can't make any stream keys; shouldn't have to let system = System::new("proxy_server_receives_http_request_from_dispatcher_then_sends_cores_package_to_hopper"); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2429,8 +2426,8 @@ mod tests { #[test] fn proxy_server_receives_http_request_from_dispatcher_then_sends_multihop_cores_package_to_hopper( ) { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let consuming_wallet = make_paying_wallet(b"paying wallet"); let earning_wallet = make_wallet("earning wallet"); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; @@ -2518,8 +2515,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); let system = System::new("proxy_server_receives_http_request_from_dispatcher_then_sends_multihop_cores_package_to_hopper"); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2552,11 +2548,10 @@ mod tests { #[test] fn proxy_server_sends_a_message_when_dns_retry_found_a_route() { - let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (proxy_server_mock, proxy_server_awaiter, proxy_server_recording_arc) = make_recorder(); let expected_service = ExpectedService::Exit( - main_cryptde().public_key().clone(), + CRYPTDE_PAIR.main.as_ref().public_key().clone(), make_wallet("walletAddress"), DEFAULT_RATE_PACK, ); @@ -2588,8 +2583,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); let system = System::new("proxy_server_sends_a_message_when_dns_retry_found_a_route"); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2624,7 +2618,6 @@ mod tests { #[test] fn proxy_server_sends_a_message_when_dns_retry_cannot_find_a_route() { let test_name = "proxy_server_sends_a_message_when_dns_retry_cannot_find_a_route"; - let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (proxy_server_mock, _, proxy_server_recording_arc) = make_recorder(); let proxy_server_mock = @@ -2648,8 +2641,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); let system = System::new(test_name); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2685,7 +2677,6 @@ mod tests { fn proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected() { init_test_logging(); let test_name = "proxy_server_sends_a_message_with_error_when_quad_zeros_are_detected"; - let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: 0.0.0.0\r\n\r\n"; let socket_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); let stream_key = StreamKey::make_meaningless_stream_key(); @@ -2702,8 +2693,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); let system = System::new(test_name); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2725,8 +2715,8 @@ mod tests { #[test] fn proxy_server_uses_existing_route() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let destination_key = PublicKey::from(&b"our destination"[..]); let route_query_response = RouteQueryResponse { @@ -2774,8 +2764,7 @@ mod tests { let stream_key_factory = StreamKeyFactoryMock::new().make_result(stream_key); let system = System::new("proxy_server_uses_existing_route"); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -2802,7 +2791,7 @@ mod tests { #[test] fn proxy_server_sends_message_to_accountant_about_all_services_consumed_on_the_route_over() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let now = SystemTime::now(); let exit_earning_wallet = make_wallet("exit earning wallet"); let route_1_earning_wallet = make_wallet("route 1 earning wallet"); @@ -2815,7 +2804,7 @@ mod tests { let routing_node_2_rate_pack = rate_pack(102); let exit_node_rate_pack = rate_pack(103); let route_query_response = RouteQueryResponse { - route: make_meaningless_route(), + route: make_meaningless_route(&CRYPTDE_PAIR), expected_services: ExpectedServices::RoundTrip( vec![ ExpectedService::Nothing, @@ -2877,7 +2866,7 @@ mod tests { }; let logger = Logger::new("test"); let args = TransmitToHopperArgs { - main_cryptde: cryptde, + main_cryptde: cryptde.dup(), payload, client_addr: source_addr, timestamp: now, @@ -2936,11 +2925,11 @@ mod tests { #[test] fn try_transmit_to_hopper_orders_stream_shutdown_if_directed_to_do_so() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (proxy_server_mock, _, proxy_server_recording_arc) = make_recorder(); let route_query_response = RouteQueryResponse { - route: make_meaningless_route(), + route: make_meaningless_route(&CRYPTDE_PAIR), expected_services: ExpectedServices::RoundTrip( vec![ExpectedService::Nothing], vec![ExpectedService::Nothing], @@ -2965,7 +2954,7 @@ mod tests { }; let logger = Logger::new("test"); let args = TransmitToHopperArgs { - main_cryptde: cryptde, + main_cryptde: cryptde.dup(), payload, client_addr: source_addr, timestamp: SystemTime::now(), @@ -3014,7 +3003,7 @@ mod tests { #[test] fn proxy_server_logs_messages_when_routing_services_are_not_requested() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (accountant_mock, accountant_awaiter, _) = make_recorder(); let (neighborhood_mock, _, _) = make_recorder(); @@ -3047,8 +3036,7 @@ mod tests { let system = System::new("proxy_server_logs_messages_when_routing_services_are_not_requested"); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3078,8 +3066,7 @@ mod tests { fn route_result_message_handler_panics_when_dns_retries_hashmap_doesnt_contain_a_stream_key() { let system = System::new("route_result_message_handler_panics_when_dns_retries_hashmap_doesnt_contain_a_stream_key"); let subject = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3145,7 +3132,6 @@ mod tests { init_test_logging(); let test_name = "proxy_server_receives_http_request_from_dispatcher_but_neighborhood_cant_make_route"; - let cryptde = main_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (neighborhood_mock, _, neighborhood_recording_arc) = make_recorder(); let neighborhood_mock = neighborhood_mock.route_query_response(None); @@ -3167,8 +3153,7 @@ mod tests { thread::spawn(move || { let system = System::new(test_name); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3217,9 +3202,9 @@ mod tests { let _system = System::new("proxy_server_panics_if_it_receives_a_one_way_route_from_a_request_for_a_round_trip_route"); let peer_actors = peer_actors_builder().build(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let route_result = RouteQueryResponse { - route: make_meaningless_route(), + route: make_meaningless_route(&CRYPTDE_PAIR), expected_services: ExpectedServices::OneWay(vec![ ExpectedService::Nothing, ExpectedService::Routing( @@ -3254,7 +3239,7 @@ mod tests { let logger = Logger::new("ProxyServer"); let source_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); let args = TransmitToHopperArgs { - main_cryptde: cryptde, + main_cryptde: cryptde.dup(), payload, client_addr: source_addr, timestamp: SystemTime::now(), @@ -3277,11 +3262,8 @@ mod tests { #[should_panic(expected = "Return route has to begin with an exit service if not zero hop")] fn report_response_services_consumed_does_not_allow_for_other_order_than_started_at_exit_service( ) { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); let subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3313,7 +3295,7 @@ mod tests { ) { init_test_logging(); let test_name = "proxy_server_receives_http_request_from_dispatcher_but_neighborhood_cant_make_route_with_no_expected_services"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let public_key = &cryptde.public_key(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (neighborhood_mock, _, neighborhood_recording_arc) = make_recorder(); @@ -3348,8 +3330,7 @@ mod tests { thread::spawn(move || { let system = System::new(test_name); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3414,8 +3395,8 @@ mod tests { 0x00, 0x0A, // server_name_length b's', b'e', b'r', b'v', b'e', b'r', b'.', b'c', b'o', b'm', // server_name ]; - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let hopper_mock = Recorder::new(); let hopper_log_arc = hopper_mock.get_recording(); let hopper_awaiter = hopper_mock.get_awaiter(); @@ -3463,8 +3444,7 @@ mod tests { .unwrap(); thread::spawn(move || { let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3500,8 +3480,8 @@ mod tests { 0x10, // handshake_type: ClientKeyExchange (not important--just not ClientHello) 0x00, 0x00, 0x00, // length: 0 ]; - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let hopper_mock = Recorder::new(); let hopper_log_arc = hopper_mock.get_recording(); let hopper_awaiter = hopper_mock.get_awaiter(); @@ -3549,8 +3529,7 @@ mod tests { .unwrap(); thread::spawn(move || { let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3585,8 +3564,8 @@ mod tests { 0xFF, // content_type: don't care, just not Handshake 0x00, 0x00, 0x00, 0x00, // version, length: don't care ]; - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let main_cryptde = CRYPTDE_PAIR.main.as_ref(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let hopper_mock = Recorder::new(); let hopper_log_arc = hopper_mock.get_recording(); let hopper_awaiter = hopper_mock.get_awaiter(); @@ -3604,7 +3583,7 @@ mod tests { let expected_data = tls_request.to_vec(); let msg_from_dispatcher = InboundClientData { timestamp: SystemTime::now(), - client_addr: client_addr, + client_addr, reception_port: Some(TLS_PORT), sequence_number: Some(0), last_data: true, @@ -3634,8 +3613,7 @@ mod tests { .unwrap(); thread::spawn(move || { let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3664,7 +3642,6 @@ mod tests { #[test] fn proxy_server_receives_tls_client_hello_from_dispatcher_but_neighborhood_cant_make_route() { init_test_logging(); - let cryptde = main_cryptde(); let tls_request = [ 0x16, // content_type: Handshake 0x00, 0x00, 0x00, 0x00, // version, length: don't care @@ -3705,8 +3682,7 @@ mod tests { thread::spawn(move || { let system = System::new(test_name); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3744,10 +3720,9 @@ mod tests { let test_name = "proxy_server_receives_terminal_response_from_hopper"; let system = System::new(test_name); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3814,8 +3789,7 @@ mod tests { #[should_panic(expected = "time calculation error")] fn log_straggling_packet_panics_if_timestamp_is_wrong() { let subject = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3830,10 +3804,9 @@ mod tests { #[test] fn handle_client_response_payload_purges_stream_keys_for_terminal_response() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -3937,12 +3910,10 @@ mod tests { init_test_logging(); let test_name = "proxy_server_schedules_stream_key_purge_once_shutdown_order_is_received_for_stream"; - let cryptde = main_cryptde(); let stream_key_purge_delay_in_millis = 500; let offset_in_millis = 100; let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4042,10 +4013,9 @@ mod tests { fn straggling_packets_are_charged_and_dropped_as_the_browser_stopped_awaiting_them_anyway() { init_test_logging(); let test_name = "straggling_packets_are_charged_and_dropped_as_the_browser_stopped_awaiting_them_anyway"; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4147,10 +4117,9 @@ mod tests { let system = System::new("proxy_server_receives_nonterminal_response_from_hopper"); let (dispatcher_mock, _, dispatcher_log_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4354,10 +4323,9 @@ mod tests { init_test_logging(); let test_name = "dns_retry_entry_is_removed_after_a_successful_client_response"; let system = System::new(test_name); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4455,10 +4423,9 @@ mod tests { System::new("proxy_server_records_services_consumed_even_after_browser_stream_is_gone"); let (dispatcher_mock, _, dispatcher_log_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4556,10 +4523,9 @@ mod tests { fn handle_dns_resolve_failure_sends_message_to_dispatcher() { let system = System::new("proxy_server_receives_response_from_routing_services"); let (dispatcher_mock, _, dispatcher_log_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4631,10 +4597,9 @@ mod tests { fn handle_dns_resolve_failure_reports_services_consumed() { let system = System::new("proxy_server_records_accounting"); let (accountant, _, accountant_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4749,10 +4714,9 @@ mod tests { let test_name = "handle_dns_resolve_failure_sends_message_to_neighborhood"; let system = System::new(test_name); let (neighborhood_mock, _, neighborhood_log_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4831,10 +4795,9 @@ mod tests { let test_name = "handle_dns_resolve_failure_does_not_send_message_to_neighborhood_when_server_is_not_specified"; let system = System::new(test_name); let (neighborhood, _, neighborhood_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4902,10 +4865,9 @@ mod tests { init_test_logging(); let system = System::new("test"); let (neighborhood_mock, _, _) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -4979,10 +4941,9 @@ mod tests { init_test_logging(); let system = System::new("test"); let (neighborhood_mock, _, _) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5052,12 +5013,11 @@ mod tests { #[test] fn handle_dns_resolve_failure_purges_stream_keys() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (neighborhood_mock, _, _) = make_recorder(); let (dispatcher_mock, _, _) = make_recorder(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5130,11 +5090,10 @@ mod tests { let system = System::new("handle_dns_resolve_failure_zero_hop"); let (dispatcher_mock, _, dispatcher_recording_arc) = make_recorder(); let (neighborhood_mock, _, neighborhood_recording_arc) = make_recorder(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let this_node_public_key = cryptde.public_key(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), false, //meaning ZeroHop Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5222,7 +5181,7 @@ mod tests { rate_pack(10), )]; let route_query_response_expected = RouteQueryResponse { - route: make_meaningless_route(), + route: make_meaningless_route(&CRYPTDE_PAIR), expected_services: ExpectedServices::RoundTrip( expected_services.clone(), expected_services.clone(), @@ -5232,10 +5191,9 @@ mod tests { let neighborhood_mock = neighborhood_mock .system_stop_conditions(match_every_type_id!(RouteQueryMessage)) .route_query_response(Some(route_query_response_expected.clone())); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5329,10 +5287,9 @@ mod tests { exit_wallet, rate_pack(10), )]; - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5392,7 +5349,7 @@ mod tests { rate_pack(10), )]; let route_query_response_expected = RouteQueryResponse { - route: make_meaningless_route(), + route: make_meaningless_route(&CRYPTDE_PAIR), expected_services: ExpectedServices::RoundTrip( expected_services.clone(), expected_services.clone(), @@ -5406,10 +5363,9 @@ mod tests { RouteQueryMessage )) .route_query_response(Some(route_query_response_expected.clone())); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5498,12 +5454,11 @@ mod tests { #[should_panic(expected = "Dispatcher unbound in ProxyServer")] fn panics_if_dispatcher_is_unbound() { let system = System::new("panics_if_dispatcher_is_unbound"); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let socket_addr = SocketAddr::from_str("1.2.3.4:5678").unwrap(); let stream_key = StreamKey::make_meaningless_stream_key(); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5552,8 +5507,7 @@ mod tests { let system = System::new("panics_if_hopper_is_unbound"); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let subject = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5582,13 +5536,12 @@ mod tests { fn report_response_services_consumed_complains_and_drops_package_if_return_route_id_is_unrecognized( ) { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); let system = System::new("report_response_services_consumed_complains_and_drops_package_if_return_route_id_is_unrecognized"); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5633,13 +5586,12 @@ mod tests { fn report_response_services_consumed_complains_and_drops_package_if_return_route_id_is_unreadable( ) { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let (dispatcher, _, dispatcher_recording_arc) = make_recorder(); let (accountant, _, accountant_recording_arc) = make_recorder(); let system = System::new("report_response_services_consumed_complains_and_drops_package_if_return_route_id_is_unreadable"); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5687,15 +5639,14 @@ mod tests { #[test] fn return_route_ids_expire_when_instructed() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let stream_key = StreamKey::make_meaningless_stream_key(); let (tx, rx) = unbounded(); thread::spawn(move || { let system = System::new("report_response_services_consumed_complains_and_drops_package_if_return_route_id_does_not_exist"); let mut subject = ProxyServer::new( - cryptde, - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5748,8 +5699,7 @@ mod tests { #[test] fn handle_stream_shutdown_msg_handles_unknown_peer_addr() { - let mut subject = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); let unaffected_socket_addr = SocketAddr::from_str("2.3.4.5:6789").unwrap(); let unaffected_stream_key = StreamKey::make_meaningful_stream_key("unaffected"); subject @@ -5790,8 +5740,7 @@ mod tests { fn handle_stream_shutdown_msg_reports_to_counterpart_through_tunnel_when_necessary() { let system = System::new("test"); let mut subject = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5817,14 +5766,20 @@ mod tests { ); let affected_route = Route::round_trip( RouteSegment::new( - vec![main_cryptde().public_key(), affected_cryptde.public_key()], + vec![ + CRYPTDE_PAIR.main.as_ref().public_key(), + affected_cryptde.public_key(), + ], Component::ProxyClient, ), RouteSegment::new( - vec![affected_cryptde.public_key(), main_cryptde().public_key()], + vec![ + affected_cryptde.public_key(), + CRYPTDE_PAIR.main.as_ref().public_key(), + ], Component::ProxyServer, ), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), Some(make_paying_wallet(b"consuming")), 1234, Some(TEST_DEFAULT_CHAIN.rec().contract), @@ -5888,7 +5843,7 @@ mod tests { target_hostname: Some(String::from("tunneled.com")), target_port: 443, protocol: ProxyProtocol::TLS, - originator_public_key: alias_cryptde().public_key().clone(), + originator_public_key: CRYPTDE_PAIR.alias.as_ref().public_key().clone(), } ), other => panic!("Wrong payload type: {:?}", other), @@ -5915,8 +5870,7 @@ mod tests { "handle_stream_shutdown_msg_reports_to_counterpart_without_tunnel_when_necessary"; let system = System::new(test_name); let mut subject = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -5942,14 +5896,20 @@ mod tests { ); let affected_route = Route::round_trip( RouteSegment::new( - vec![main_cryptde().public_key(), affected_cryptde.public_key()], + vec![ + CRYPTDE_PAIR.main.as_ref().public_key(), + affected_cryptde.public_key(), + ], Component::ProxyClient, ), RouteSegment::new( - vec![affected_cryptde.public_key(), main_cryptde().public_key()], + vec![ + affected_cryptde.public_key(), + CRYPTDE_PAIR.main.as_ref().public_key(), + ], Component::ProxyServer, ), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), Some(make_paying_wallet(b"consuming")), 1234, Some(TEST_DEFAULT_CHAIN.rec().contract), @@ -6008,7 +5968,7 @@ mod tests { target_hostname: None, target_port: HTTP_PORT, protocol: ProxyProtocol::HTTP, - originator_public_key: alias_cryptde().public_key().clone(), + originator_public_key: CRYPTDE_PAIR.alias.as_ref().public_key().clone(), } ), other => panic!("Wrong payload type: {:?}", other), @@ -6036,8 +5996,7 @@ mod tests { #[test] fn handle_stream_shutdown_msg_logs_errors_from_handling_normal_client_data() { init_test_logging(); - let mut subject = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, Some(0), false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, Some(0), false, false); subject.subs = Some(make_proxy_server_out_subs()); let helper = IBCDHelperMock::default() .handle_normal_client_data_result(Err("Our help is not welcome".to_string())); @@ -6062,8 +6021,7 @@ mod tests { #[test] fn stream_shutdown_msg_populates_correct_inbound_client_data_msg() { let help_to_handle_normal_client_data_params_arc = Arc::new(Mutex::new(vec![])); - let mut subject = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, Some(0), false, false); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, Some(0), false, false); subject.subs = Some(make_proxy_server_out_subs()); let icd_helper = IBCDHelperMock::default() .handle_normal_client_data_params(&help_to_handle_normal_client_data_params_arc) @@ -6109,8 +6067,7 @@ mod tests { #[test] fn help_to_handle_normal_client_data_missing_consuming_wallet_and_protocol_pack_not_found() { - let mut proxy_server = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, false, false); + let mut proxy_server = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); proxy_server.subs = Some(make_proxy_server_out_subs()); let inbound_client_data_msg = InboundClientData { timestamp: SystemTime::now(), @@ -6136,14 +6093,14 @@ mod tests { #[test] fn resolve_message_handles_mailbox_error_from_neighborhood() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let payload = make_request_payload(111, cryptde); let stream_key = payload.stream_key; let (proxy_server, _, proxy_server_recording_arc) = make_recorder(); let addr = proxy_server.start(); let proxy_server_sub = recipient!(&addr, AddRouteResultMessage); let args = TransmitToHopperArgs { - main_cryptde: cryptde, + main_cryptde: cryptde.dup(), payload, client_addr: SocketAddr::from_str("1.2.3.4:1234").unwrap(), timestamp: SystemTime::now(), @@ -6206,8 +6163,7 @@ mod tests { #[test] fn help_to_handle_normal_client_data_make_payload_failed() { let mut proxy_server = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -6240,8 +6196,7 @@ mod tests { #[test] fn new_http_request_creates_new_entry_inside_dns_retries_hashmap() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); + let alias_cryptde = CRYPTDE_PAIR.alias.as_ref(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (neighborhood_mock, _, _) = make_recorder(); let destination_key = PublicKey::from(&b"our destination"[..]); @@ -6278,8 +6233,7 @@ mod tests { "proxy_server_receives_http_request_from_dispatcher_then_sends_cores_package_to_hopper", ); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), true, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -6309,8 +6263,6 @@ mod tests { #[test] fn new_http_request_creates_new_exhausted_entry_inside_dns_retries_hashmap_zero_hop() { - let main_cryptde = main_cryptde(); - let alias_cryptde = alias_cryptde(); let http_request = b"GET /index.html HTTP/1.1\r\nHost: nowhere.com\r\n\r\n"; let (neighborhood_mock, _, _) = make_recorder(); let destination_key = PublicKey::from(&b"our destination"[..]); @@ -6338,7 +6290,7 @@ mod tests { .make( &msg_from_dispatcher, stream_key.clone(), - alias_cryptde, + CRYPTDE_PAIR.alias.as_ref(), &Logger::new("test"), ) .unwrap(); @@ -6347,8 +6299,7 @@ mod tests { "new_http_request_creates_new_exhausted_entry_inside_dns_retries_hashmap_zero_hop", ); let mut subject = ProxyServer::new( - main_cryptde, - alias_cryptde, + CRYPTDE_PAIR.clone(), false, Some(STANDARD_CONSUMING_WALLET_BALANCE), false, @@ -6378,15 +6329,18 @@ mod tests { #[test] fn hostname_works() { - assert_on_hostname("https://example.com/folder/file.html", "example.com"); - assert_on_hostname("example.com/index.php?arg=test", "example.com"); + assert_on_hostname( + "https://www.example.com/folder/file.html", + "www.example.com", + ); + assert_on_hostname("www.example.com/index.php?arg=test", "www.example.com"); assert_on_hostname("sub.example.com/index.php?arg=test", "sub.example.com"); assert_on_hostname("1.1.1.1", "1.1.1.1"); assert_on_hostname("", ""); assert_on_hostname("example", "example"); assert_on_hostname( - "htttttps://example.com/folder/file.html", - "htttttps://example.com/folder/file.html", + "htttttps://www.example.com/folder/file.html", + "htttttps://www.example.com/folder/file.html", ); } @@ -6428,11 +6382,11 @@ mod tests { Err("localhost".to_string()) ); assert_eq!( - Hostname::new("example.com").validate_non_loopback_host(), + Hostname::new("www.example.com").validate_non_loopback_host(), Ok(()) ); assert_eq!( - Hostname::new("https://example.com").validate_non_loopback_host(), + Hostname::new("https://www.example.com").validate_non_loopback_host(), Ok(()) ); } @@ -6443,8 +6397,7 @@ mod tests { let http_request = b"GET /index.html HTTP/1.1\r\nHost: localhost\r\n\r\n"; let expected_data = http_request.to_vec(); let mut proxy_server = ProxyServer::new( - main_cryptde(), - alias_cryptde(), + CRYPTDE_PAIR.clone(), true, Some(58), false, @@ -6479,7 +6432,7 @@ mod tests { )] fn handle_stream_shutdown_complains_about_clandestine_message() { let system = System::new("test"); - let subject = ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, false, false); + let subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); let subject_addr = subject.start(); subject_addr @@ -6499,8 +6452,7 @@ mod tests { expected = "panic message (processed with: node_lib::sub_lib::utils::crash_request_analyzer)" )] fn proxy_server_can_be_crashed_properly_but_not_improperly() { - let proxy_server = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, true, false); + let proxy_server = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, true, false); prove_that_crash_request_handler_is_hooked_up(proxy_server, CRASH_KEY); } @@ -6508,9 +6460,8 @@ mod tests { #[test] fn find_or_generate_stream_key_prioritizes_existing_stream_key_first() { let socket_addr = SocketAddr::from_str("1.2.3.4:4321").unwrap(); - let stream_key = StreamKey::new(main_cryptde().public_key(), socket_addr); - let mut subject = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, false, false); + let stream_key = StreamKey::new(CRYPTDE_PAIR.main.as_ref().public_key(), socket_addr); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); subject.keys_and_addrs.insert(stream_key, socket_addr); let ibcd = InboundClientData { timestamp: SystemTime::now(), @@ -6534,9 +6485,8 @@ mod tests { #[test] fn find_or_generate_stream_key_creates_stream_key_if_necessary() { let socket_addr = SocketAddr::from_str("1.2.3.4:4321").unwrap(); - let stream_key = StreamKey::new(main_cryptde().public_key(), socket_addr); - let mut subject = - ProxyServer::new(main_cryptde(), alias_cryptde(), true, None, false, false); + let stream_key = StreamKey::new(CRYPTDE_PAIR.main.as_ref().public_key(), socket_addr); + let mut subject = ProxyServer::new(CRYPTDE_PAIR.clone(), true, None, false, false); let ibcd = InboundClientData { timestamp: SystemTime::now(), client_addr: socket_addr, diff --git a/node/src/server_initializer.rs b/node/src/server_initializer.rs index 54e8b0b368..8326e0157e 100644 --- a/node/src/server_initializer.rs +++ b/node/src/server_initializer.rs @@ -387,7 +387,6 @@ pub mod test_utils { #[cfg(test)] pub mod tests { use super::*; - use crate::bootstrapper::BootstrapperConfig; use crate::crash_test_dummy::CrashTestDummy; use crate::node_test_utils::DirsWrapperMock; use crate::server_initializer::test_utils::PrivilegeDropperMock; @@ -405,7 +404,7 @@ pub mod tests { use std::sync::{Arc, Mutex}; use test_utilities::byte_array_reader_writer::{ByteArrayReader, ByteArrayWriter}; - impl ConfiguredByPrivilege for CrashTestDummy { + impl ConfiguredByPrivilege for CrashTestDummy { fn initialize_as_privileged( &mut self, _multi_config: &MultiConfig, @@ -683,8 +682,8 @@ pub mod tests { #[test] fn exits_after_all_socket_servers_exit() { let _ = LogfileNameGuard::new(&PathBuf::from("uninitialized")); - let dns_socket_server = CrashTestDummy::new(CrashPoint::Error, ()); - let bootstrapper = CrashTestDummy::new(CrashPoint::Error, BootstrapperConfig::new()); + let dns_socket_server = CrashTestDummy::new(CrashPoint::Error); + let bootstrapper = CrashTestDummy::new(CrashPoint::Error); let dirs_wrapper = make_pre_populated_mocked_directory_wrapper(); let privilege_dropper = PrivilegeDropperMock::new(); let mut subject = ServerInitializerReal { @@ -711,8 +710,8 @@ pub mod tests { #[test] fn server_initializer_as_a_future() { - let dns_socket_server = CrashTestDummy::new(CrashPoint::None, ()); - let bootstrapper = CrashTestDummy::new(CrashPoint::None, BootstrapperConfig::new()); + let dns_socket_server = CrashTestDummy::new(CrashPoint::None); + let bootstrapper = CrashTestDummy::new(CrashPoint::None); let privilege_dropper = PrivilegeDropperMock::new(); let dirs_wrapper = DirsWrapperMock::new(); @@ -731,14 +730,13 @@ pub mod tests { // TODO: GH-525: It should panic // #[should_panic(expected = "EntryDnsServerMock was instructed to panic")] fn server_initializer_dns_socket_server_panics() { - let bootstrapper = CrashTestDummy::new(CrashPoint::None, BootstrapperConfig::new()); + let bootstrapper = CrashTestDummy::new(CrashPoint::None); let privilege_dropper = PrivilegeDropperMock::new(); let dirs_wrapper = DirsWrapperMock::new(); let mut subject = ServerInitializerReal { dns_socket_server: Box::new(CrashTestDummy::panic( "EntryDnsServerMock was instructed to panic".to_string(), - (), )), bootstrapper: Box::new(bootstrapper), privilege_dropper: Box::new(privilege_dropper), @@ -751,14 +749,13 @@ pub mod tests { #[test] #[should_panic(expected = "BootstrapperMock was instructed to panic")] fn server_initializer_bootstrapper_panics() { - let dns_socket_server = CrashTestDummy::new(CrashPoint::None, ()); + let dns_socket_server = CrashTestDummy::new(CrashPoint::None); let privilege_dropper = PrivilegeDropperMock::new(); let dirs_wrapper = DirsWrapperMock::new(); let mut subject = ServerInitializerReal { dns_socket_server: Box::new(dns_socket_server), bootstrapper: Box::new(CrashTestDummy::panic( "BootstrapperMock was instructed to panic".to_string(), - BootstrapperConfig::new(), )), privilege_dropper: Box::new(privilege_dropper), dirs_wrapper: Box::new(dirs_wrapper), diff --git a/node/src/stream_handler_pool.rs b/node/src/stream_handler_pool.rs index 470f0c44f6..7aa6d0ff6c 100644 --- a/node/src/stream_handler_pool.rs +++ b/node/src/stream_handler_pool.rs @@ -783,6 +783,7 @@ impl TrafficAnalyzerReal {} #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::http_request_start_finder::HttpRequestDiscriminatorFactory; use crate::json_discriminator_factory::JsonDiscriminatorFactory; use crate::json_masquerader::JsonMasquerader; @@ -794,7 +795,6 @@ mod tests { }; use crate::sub_lib::stream_connector::ConnectionInfo; use crate::test_utils::channel_wrapper_mocks::SenderWrapperMock; - use crate::test_utils::main_cryptde; use crate::test_utils::rate_pack; use crate::test_utils::recorder::make_recorder; use crate::test_utils::recorder::peer_actors_builder; @@ -809,6 +809,7 @@ mod tests { use actix::Addr; use actix::System; use crossbeam_channel::unbounded; + use lazy_static::lazy_static; use masq_lib::constants::HTTP_PORT; use masq_lib::test_utils::logging::init_test_logging; use masq_lib::test_utils::logging::TestLogHandler; @@ -824,6 +825,10 @@ mod tests { use std::time::SystemTime; use tokio::prelude::Async; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!(CRASH_KEY, "STREAMHANDLERPOOL"); @@ -1615,7 +1620,7 @@ mod tests { #[test] fn node_query_response_handler_does_not_try_to_write_when_neighbor_is_not_found() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); thread::spawn(move || { @@ -1663,7 +1668,7 @@ mod tests { #[test] fn node_query_response_handler_does_not_try_to_write_when_neighbor_ip_is_not_known() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); thread::spawn(move || { @@ -1715,7 +1720,7 @@ mod tests { #[test] fn node_query_response_handler_resends_transmit_data_msg_when_connection_is_in_progress() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); let peer_addr = SocketAddr::from_str("5.4.3.1:8000").unwrap(); @@ -1813,7 +1818,7 @@ mod tests { #[test] fn log_an_error_when_it_fails_to_send_a_packet() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); let peer_addr = SocketAddr::new(localhost(), find_free_port()); let sw_key = StreamWriterKey::from(peer_addr); @@ -1856,7 +1861,7 @@ mod tests { fn when_a_new_connection_fails_the_stream_writer_flag_is_removed_and_another_connection_is_attempted_for_the_next_message_with_the_same_stream_key( ) { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); let key_bg = key.clone(); let peer_addr = SocketAddr::from_str("5.4.3.1:8000").unwrap(); @@ -1968,7 +1973,7 @@ mod tests { fn node_query_response_handler_sets_counterpart_flag_and_removes_stream_writer_if_last_data_is_true( ) { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key().clone(); let peer_addr = SocketAddr::from_str("127.0.0.1:8005").unwrap(); let sender_wrapper_unbounded_send_params_arc = Arc::new(Mutex::new(vec![])); @@ -2023,7 +2028,7 @@ mod tests { )] fn when_node_query_response_node_addr_contains_no_ports_then_stream_handler_pool_panics() { init_test_logging(); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key(); let peer_addr = SocketAddr::from_str("5.4.3.1:8000").unwrap(); diff --git a/node/src/stream_reader.rs b/node/src/stream_reader.rs index 34a7b62bdf..cac9211a67 100644 --- a/node/src/stream_reader.rs +++ b/node/src/stream_reader.rs @@ -538,7 +538,8 @@ mod tests { Box::new(TlsDiscriminatorFactory::new()), Box::new(HttpRequestDiscriminatorFactory::new()), ]; - let http_connect_request = Vec::from("CONNECT example.com:443 HTTP/1.1\r\n\r\n".as_bytes()); + let http_connect_request = + Vec::from("CONNECT www.example.com:443 HTTP/1.1\r\n\r\n".as_bytes()); // Magic TLS Sauce stolen from Configuration let tls_request = Vec::from(&[0x16, 0x03, 0x01, 0x00, 0x03, 0x01, 0x02, 0x03][..]); let reader = ReadHalfWrapperMock { @@ -594,7 +595,7 @@ mod tests { let discriminator_factories: Vec> = vec![Box::new(HttpRequestDiscriminatorFactory::new())]; let request1 = Vec::from("GET http://here.com HTTP/1.1\r\n\r\n".as_bytes()); - let request2 = Vec::from("GET http://example.com HTTP/1.1\r\n\r\n".as_bytes()); + let request2 = Vec::from("GET http://www.example.com HTTP/1.1\r\n\r\n".as_bytes()); let reader = ReadHalfWrapperMock { poll_read_results: vec![ (request1.clone(), Ok(Async::Ready(request1.len()))), @@ -651,7 +652,7 @@ mod tests { last_data: false, is_clandestine: false, sequence_number: Some(1), - data: Vec::from("GET http://example.com HTTP/1.1\r\n\r\n".as_bytes()), + data: Vec::from("GET http://www.example.com HTTP/1.1\r\n\r\n".as_bytes()), } ); } diff --git a/node/src/sub_lib/cryptde.rs b/node/src/sub_lib/cryptde.rs index 3e37449d06..d2885c6d5f 100644 --- a/node/src/sub_lib/cryptde.rs +++ b/node/src/sub_lib/cryptde.rs @@ -1,6 +1,7 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. use crate::sub_lib::route::RouteError; use ethsign_crypto::Keccak256; +use masq_lib::blockchains::chains::Chain; use rustc_hex::{FromHex, ToHex}; use serde::de::Visitor; use serde::Deserialize; @@ -555,6 +556,8 @@ pub trait CryptDE: Send + Sync { descriptor_fragment: &str, ) -> Result; fn digest(&self) -> [u8; 32]; + fn make_from_str(&self, value: &str, chain: Chain) -> Result, String>; + fn to_string(&self) -> String; fn as_any(&self) -> &dyn Any; } @@ -628,8 +631,9 @@ pub fn create_digest(msg: &dyn AsRef<[u8]>, address: &dyn AsRef<[u8]>) -> [u8; 3 #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::cryptde_null::CryptDENull; - use crate::test_utils::main_cryptde; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use rustc_hex::{FromHex, FromHexError}; use serde::de; @@ -637,6 +641,10 @@ mod tests { use serde_cbor; use serde_derive::{Deserialize, Serialize}; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn private_key_constructor_works_as_expected() { let subject = PrivateKey::new(&[1, 2, 3, 4]); @@ -1008,7 +1016,7 @@ mod tests { #[test] fn encodex_and_decodex_communicate() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let start = TestStruct::make(); let intermediate = encodex(cryptde, &cryptde.public_key(), &start).unwrap(); @@ -1019,7 +1027,7 @@ mod tests { #[test] fn encodex_produces_expected_data() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let start = TestStruct::make(); let intermediate = super::encodex(cryptde, &cryptde.public_key(), &start).unwrap(); @@ -1032,7 +1040,7 @@ mod tests { #[test] fn decodex_produces_expected_structure() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let serialized = serde_cbor::ser::to_vec(&TestStruct::make()).unwrap(); let encrypted = cryptde .encode(&cryptde.public_key(), &PlainData::from(serialized)) @@ -1045,7 +1053,7 @@ mod tests { #[test] fn encodex_handles_encryption_error() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let item = TestStruct::make(); let result = encodex(cryptde, &PublicKey::new(&[]), &item); @@ -1093,7 +1101,7 @@ mod tests { #[test] fn encodex_handles_serialization_error() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let item = BadSerStruct { flag: true }; let result = encodex(cryptde, &cryptde.public_key(), &item); @@ -1107,7 +1115,7 @@ mod tests { #[test] fn decodex_handles_deserialization_error() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let data = cryptde .encode(&cryptde.public_key(), &PlainData::new(b"whompem")) .unwrap(); diff --git a/node/src/sub_lib/cryptde_null.rs b/node/src/sub_lib/cryptde_null.rs index 4b724ca77c..bb10b35622 100644 --- a/node/src/sub_lib/cryptde_null.rs +++ b/node/src/sub_lib/cryptde_null.rs @@ -148,6 +148,33 @@ impl CryptDE for CryptDENull { fn digest(&self) -> [u8; 32] { self.digest } + + fn make_from_str(&self, value: &str, chain: Chain) -> Result, String> { + let decoded = match base64::decode_config(value, base64::URL_SAFE_NO_PAD) { + Ok(d) => d, + Err(_) => { + return Err(format!( + "Serialized CryptDE must have valid Base64, not '{}'", + value + )) + } + }; + let private_key = PrivateKey::new(decoded.as_slice()); + let public_key = Self::public_from_private(&private_key); + let digest = cryptde::create_digest(&public_key, &chain.rec().contract); + let next_symmetric_key_seed = self.next_symmetric_key_seed.clone(); + Ok(Box::new(Self { + private_key, + public_key, + digest, + next_symmetric_key_seed, + })) + } + + fn to_string(&self) -> String { + base64::encode_config(self.private_key.as_slice(), base64::URL_SAFE_NO_PAD) + } + fn as_any(&self) -> &dyn Any { self } @@ -263,14 +290,76 @@ impl CryptDENull { #[cfg(test)] mod tests { use super::*; - use crate::test_utils::main_cryptde; + use crate::bootstrapper::CryptDEPair; use ethsign_crypto::Keccak256; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::panic::{catch_unwind, AssertUnwindSafe}; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + + #[test] + fn to_string_works() { + let subject = CryptDENull::new(Chain::Dev); + let private_key_data = subject.private_key.as_slice().to_vec(); + + let actual_string: String = subject.to_string(); + + let expected_string = format!( + "{}", + base64::encode_config(&private_key_data, base64::URL_SAFE_NO_PAD) + ); + assert_eq!(actual_string, expected_string); + } + + #[test] + fn make_from_str_can_fail_on_base64_syntax() { + let subject = CryptDENull::new(Chain::Dev); + let string = "/ / / /"; // invalid + + let result = subject.make_from_str(string, Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have valid Base64, not '/ / / /'".to_string() + ); + } + + #[test] + fn make_from_str_can_succeed() { + let subject = CryptDENull::new(Chain::BaseSepolia); + let private_key_data = subject.private_key.as_slice().to_vec(); + let string = format!( + "{}", + base64::encode_config(private_key_data, base64::URL_SAFE_NO_PAD) + ); + + let boxed_result = subject + .make_from_str(string.as_str(), Chain::BaseSepolia) + .unwrap(); + + let result = boxed_result + .as_ref() + .as_any() + .downcast_ref::() + .unwrap(); + assert_eq!(result.public_key, subject.public_key); + assert_eq!(result.private_key, subject.private_key); + assert_eq!(result.digest, subject.digest); + let subject_next_seed_lock = subject.next_symmetric_key_seed.lock().unwrap(); + let subject_next_seed = *subject_next_seed_lock.deref(); + drop(subject_next_seed_lock); + let result_next_seed_lock = result.next_symmetric_key_seed.lock().unwrap(); + let result_next_seed = *result_next_seed_lock.deref(); + drop(result_next_seed_lock); + assert_eq!(result_next_seed, subject_next_seed); + } + #[test] fn encode_with_empty_key() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let result = subject.encode(&PublicKey::new(b""), &PlainData::new(b"data")); @@ -279,7 +368,7 @@ mod tests { #[test] fn encode_with_empty_data() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let result = subject.encode(&PublicKey::new(b"key"), &PlainData::new(b"")); @@ -288,7 +377,7 @@ mod tests { #[test] fn encode_with_key_and_data() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let result = subject.encode(&PublicKey::new(b"key"), &PlainData::new(b"data")); @@ -355,7 +444,7 @@ mod tests { #[test] fn gen_key_sym_produces_different_keys_on_successive_calls() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let one_key = subject.gen_key_sym(); let another_key = subject.gen_key_sym(); @@ -386,7 +475,7 @@ mod tests { #[test] fn encode_sym_with_empty_key() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let key = SymmetricKey::new(b""); let result = subject.encode_sym(&key, &PlainData::new(b"data")); @@ -396,7 +485,7 @@ mod tests { #[test] fn encode_sym_with_empty_data() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let key = subject.gen_key_sym(); let result = subject.encode_sym(&key, &PlainData::new(b"")); @@ -406,7 +495,7 @@ mod tests { #[test] fn encode_sym_with_key_and_data() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let key = SymmetricKey::new(b"key"); let result = subject.encode_sym(&key, &PlainData::new(b"data")); @@ -418,7 +507,7 @@ mod tests { #[test] fn decode_sym_with_empty_key() { - let subject = main_cryptde().clone(); + let subject = CRYPTDE_PAIR.main.as_ref().clone(); let key = SymmetricKey::new(b""); let result = subject.decode_sym(&key, &CryptData::new(b"keydata")); @@ -428,7 +517,7 @@ mod tests { #[test] fn decode_sym_with_empty_data() { - let subject = main_cryptde().clone(); + let subject = CRYPTDE_PAIR.main.as_ref().clone(); let key = subject.gen_key_sym(); let result = subject.decode_sym(&key, &CryptData::new(b"")); @@ -438,7 +527,7 @@ mod tests { #[test] fn decode_sym_with_key_and_data() { - let subject = main_cryptde().clone(); + let subject = CRYPTDE_PAIR.main.as_ref().clone(); let key = SymmetricKey::new(b"key"); let result = subject.decode_sym(&key, &CryptData::new(b"keydata")); @@ -451,7 +540,7 @@ mod tests { expected = "Could not decrypt with 6261644b6579 data beginning with 6b6579646174" )] fn decode_sym_with_wrong_key() { - let subject = main_cryptde().clone(); + let subject = CRYPTDE_PAIR.main.as_ref().clone(); let key = SymmetricKey::new(b"badKey"); let _ = subject.decode_sym(&key, &CryptData::new(b"keydataxyz")); @@ -459,7 +548,7 @@ mod tests { #[test] fn decode_sym_with_key_exceeding_data_length() { - let subject = main_cryptde().clone(); + let subject = CRYPTDE_PAIR.main.as_ref().clone(); let key = SymmetricKey::new(b"invalidkey"); let result = subject.decode_sym(&key, &CryptData::new(b"keydata")); @@ -474,7 +563,7 @@ mod tests { #[test] fn random_is_pretty_predictable() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let mut dest: [u8; 11] = [0; 11]; subject.random(&mut dest[..]); @@ -499,7 +588,7 @@ mod tests { #[test] fn generated_keys_work_with_each_other() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let expected_data = PlainData::new(&b"These are the times that try men's souls"[..]); let encrypted_data = subject @@ -511,7 +600,7 @@ mod tests { #[test] fn symmetric_encryption_works_with_same_key() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let key = subject.gen_key_sym(); let expected_data = PlainData::new(&b"These are the times that try men's souls"[..]); @@ -522,7 +611,7 @@ mod tests { #[test] fn symmetric_encryption_fails_with_different_keys() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let key1 = subject.gen_key_sym(); let key2 = subject.gen_key_sym(); @@ -576,7 +665,7 @@ mod tests { #[test] fn dup_works() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let result = subject.dup(); @@ -586,7 +675,7 @@ mod tests { #[test] fn stringifies_public_key_properly() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[1, 2, 3, 4]); let result = subject.public_key_to_descriptor_fragment(&public_key); @@ -596,7 +685,7 @@ mod tests { #[test] fn destringifies_public_key_properly() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let half_key = "AQIDBA"; let result = subject.descriptor_fragment_to_first_contact_public_key(half_key); @@ -606,7 +695,7 @@ mod tests { #[test] fn fails_to_destringify_public_key_properly() { - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let half_key = "((]--$"; let result = subject.descriptor_fragment_to_first_contact_public_key(half_key); @@ -662,7 +751,7 @@ mod tests { #[test] fn verifying_a_good_signature_works() { let data = PlainData::new(HASHABLE_DATA.as_bytes()); - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let signature = subject.sign(&data).unwrap(); let result = subject.verify_signature(&data, &signature, &subject.public_key()); @@ -673,7 +762,7 @@ mod tests { #[test] fn verifying_a_bad_signature_fails() { let data = PlainData::new(HASHABLE_DATA.as_bytes()); - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let mut modified = Vec::from(HASHABLE_DATA.as_bytes()); modified[0] = modified[0] + 1; let different_data = PlainData::from(modified); @@ -688,7 +777,7 @@ mod tests { fn hashing_produces_the_same_value_for_the_same_data() { let some_data = PlainData::new(HASHABLE_DATA.as_bytes()); let more_data = some_data.clone(); - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let some_result = subject.hash(&some_data); let more_result = subject.hash(&more_data); @@ -702,7 +791,7 @@ mod tests { let mut modified = Vec::from(HASHABLE_DATA.as_bytes()); modified[0] = modified[0] + 1; let different_data = PlainData::from(modified); - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let some_result = subject.hash(&some_data); let different_result = subject.hash(&different_data); @@ -714,7 +803,7 @@ mod tests { fn hashing_produces_the_same_length_for_long_and_short_data() { let long_data = PlainData::new(HASHABLE_DATA.as_bytes()); let short_data = PlainData::new(&[1, 2, 3, 4]); - let subject = main_cryptde(); + let subject = CRYPTDE_PAIR.main.as_ref(); let long_result = subject.hash(&long_data); let short_result = subject.hash(&short_data); @@ -724,7 +813,7 @@ mod tests { #[test] fn hashing_produces_a_digest_with_the_smart_contract_address() { - let subject = &main_cryptde(); + let subject = &CRYPTDE_PAIR.main.as_ref(); let merged = [ subject.public_key().as_ref(), TEST_DEFAULT_CHAIN.rec().contract.as_ref(), diff --git a/node/src/sub_lib/cryptde_real.rs b/node/src/sub_lib/cryptde_real.rs index dd299a6bbb..d3905a9629 100644 --- a/node/src/sub_lib/cryptde_real.rs +++ b/node/src/sub_lib/cryptde_real.rs @@ -182,10 +182,76 @@ impl CryptDE for CryptDEReal { self.digest } + fn make_from_str(&self, value: &str, chain: Chain) -> Result, String> { + let parts = value.split(',').collect::>(); + if parts.len() != 2 { + return Err(format!( + "Serialized CryptDE must have 2 comma-separated parts, not {}", + parts.len() + )); + } + let convert = |s: &str| -> Result, String> { + match base64::decode_config(s, base64::URL_SAFE_NO_PAD) { + Ok(v) => Ok(v), + Err(_) => Err(format!( + "Serialized CryptDE must have valid Base64, not '{}'", + s + )), + } + }; + let encryption_secret_key = match convert(parts[0]) { + Ok(v) => encryption::SecretKey(match v.clone().try_into() { + Ok(vi) => vi, + Err(_) => { + return Err(format!( + "Serialized CryptDE must have {}-byte encryption key, not {}", + cxsp::SECRETKEYBYTES, + v.len() + )) + } + }), + Err(e) => return Err(e), + }; + let signing_secret_key = match convert(parts[1]) { + Ok(v) => signing::SecretKey(match v.clone().try_into() { + Ok(vi) => vi, + Err(_) => { + return Err(format!( + "Serialized CryptDE must have {}-byte signing key, not {}", + signing::SECRETKEYBYTES, + v.len() + )) + } + }), + Err(e) => return Err(e), + }; + let public_key = Self::local_public_key_from( + &encryption_secret_key.public_key(), + &signing_secret_key.public_key(), + ); + let digest = cryptde::create_digest(&public_key, &chain.rec().contract); + let pre_shared_data = chain.rec().contract.0; + Ok(Box::new(CryptDEReal { + public_key, + encryption_secret_key, + signing_secret_key, + digest, + pre_shared_data, + })) + } + + fn to_string(&self) -> String { + let encryption_secret_data = self.encryption_secret_key.as_ref().to_vec(); + let signing_secret_data = self.signing_secret_key.as_ref().to_vec(); + format!( + "{},{}", + base64::encode_config(&encryption_secret_data, base64::URL_SAFE_NO_PAD), + base64::encode_config(&signing_secret_data, base64::URL_SAFE_NO_PAD) + ) + } + fn as_any(&self) -> &dyn Any { - //I don't know about a use of this for cryptDEReal anywhere; - //created for a special case of manipulation with cryptDENull where I know I'm not going to meet cryptDEReal there - unimplemented!() + self } } @@ -206,6 +272,16 @@ impl CryptDEReal { } } + pub fn disabled() -> Self { + Self { + public_key: PublicKey::new(&[0u8; cxsp::PUBLICKEYBYTES + signing::PUBLICKEYBYTES]), + encryption_secret_key: encryption::SecretKey([0u8; cxsp::SECRETKEYBYTES]), + signing_secret_key: signing::SecretKey([0u8; signing::SECRETKEYBYTES]), + digest: [0u8; 32], + pre_shared_data: [0u8; 20], + } + } + fn local_public_key_from( encryption_public_key: &encryption::PublicKey, signing_public_key: &signing::PublicKey, @@ -244,6 +320,162 @@ mod tests { } } + #[test] + fn disabled_works() { + let subject = CryptDEReal::disabled(); + + assert_eq!( + subject.public_key().as_slice(), + &[0u8; cxsp::PUBLICKEYBYTES + signing::PUBLICKEYBYTES] + ); + assert_eq!( + subject.encryption_secret_key.as_ref(), + &[0u8; cxsp::SECRETKEYBYTES] + ); + assert_eq!( + subject.signing_secret_key.as_ref(), + &[0u8; signing::SECRETKEYBYTES] + ); + assert_eq!(subject.digest, [0u8; 32]); + assert_eq!(subject.pre_shared_data, [0u8; 20]); + } + + #[test] + fn to_string_works() { + let subject = CryptDEReal::default(); + let encryption_secret_data = subject.encryption_secret_key.as_ref().to_vec(); + let signing_secret_data = subject.signing_secret_key.as_ref().to_vec(); + + let actual_string: String = subject.to_string(); + + let expected_string = format!( + "{},{}", + base64::encode_config(&encryption_secret_data, base64::URL_SAFE_NO_PAD), + base64::encode_config(&signing_secret_data, base64::URL_SAFE_NO_PAD) + ); + assert_eq!(actual_string, expected_string); + } + + #[test] + fn make_from_str_can_fail_on_delimiters() { + let subject = CryptDEReal::default(); + let string = ",,,,,"; // invalid + + let result = subject.make_from_str(string, Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have 2 comma-separated parts, not 6".to_string() + ); + } + + const ENCRYPTION_SECRET_KEY_DATA: [u8; 32] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, + ]; + const SIGNING_SECRET_KEY_DATA: [u8; 64] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + ]; + + #[test] + fn make_from_str_can_fail_on_key_length_for_encryption() { + let subject = CryptDEReal::default(); + let encryption_string = "AgMEBQ"; // invalid + let signing_string = + base64::encode_config(&SIGNING_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let string = format!("{},{}", encryption_string, signing_string); + + let result = subject.make_from_str(string.as_str(), Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have 32-byte encryption key, not 4".to_string() + ); + } + + #[test] + fn make_from_str_can_fail_on_key_length_for_signing() { + let subject = CryptDEReal::default(); + let encryption_string = + base64::encode_config(&ENCRYPTION_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let signing_string = "AgMEBQ"; // invalid + let string = format!("{},{}", encryption_string, signing_string); + + let result = subject.make_from_str(string.as_str(), Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have 64-byte signing key, not 4".to_string() + ); + } + + #[test] + fn make_from_str_can_fail_on_base64_syntax_for_encryption() { + let subject = CryptDEReal::default(); + let signing_string = + base64::encode_config(&SIGNING_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let string = format!("{},{}", "/ / / /", signing_string); // invalid + + let result = subject.make_from_str(string.as_str(), Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have valid Base64, not '/ / / /'".to_string() + ); + } + + #[test] + fn make_from_str_can_fail_on_base64_syntax_for_signing() { + let subject = CryptDEReal::default(); + let encryption_string = + base64::encode_config(&ENCRYPTION_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let string = format!("{},{}", encryption_string, "/ / / /"); // invalid + + let result = subject.make_from_str(string.as_str(), Chain::Dev); + + assert_eq!( + result.err().unwrap(), + "Serialized CryptDE must have valid Base64, not '/ / / /'".to_string() + ); + } + + #[test] + fn make_from_str_can_succeed() { + let subject = CryptDEReal::default(); + let encryption_string = + base64::encode_config(&ENCRYPTION_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let signing_string = + base64::encode_config(&SIGNING_SECRET_KEY_DATA, base64::URL_SAFE_NO_PAD); + let string = format!("{},{}", encryption_string, signing_string); + + let boxed_result = subject + .make_from_str(string.as_str(), Chain::BaseSepolia) + .unwrap(); + + let result = boxed_result + .as_ref() + .as_any() + .downcast_ref::() + .unwrap(); + let expected_encryption_secret_key = encryption::SecretKey(ENCRYPTION_SECRET_KEY_DATA); + let expected_signing_secret_key = signing::SecretKey(SIGNING_SECRET_KEY_DATA); + let expected_public_key = CryptDEReal::local_public_key_from( + &expected_encryption_secret_key.public_key(), + &expected_signing_secret_key.public_key(), + ); + let expected_digest = + cryptde::create_digest(&expected_public_key, &Chain::BaseSepolia.rec().contract); + let expected_pre_shared_data = Chain::BaseSepolia.rec().contract.0; + + assert_eq!(result.encryption_secret_key, expected_encryption_secret_key); + assert_eq!(result.signing_secret_key, expected_signing_secret_key); + assert_eq!(result.public_key, expected_public_key); + assert_eq!(result.digest, expected_digest); + assert_eq!(result.pre_shared_data, expected_pre_shared_data); + } + #[test] fn construction_generates_different_keys() { let first_subject = CryptDEReal::default(); diff --git a/node/src/sub_lib/hop.rs b/node/src/sub_lib/hop.rs index 841d54198c..ef5d0a87c8 100644 --- a/node/src/sub_lib/hop.rs +++ b/node/src/sub_lib/hop.rs @@ -50,9 +50,15 @@ impl LiveHop { #[cfg(test)] mod tests { use super::*; - use crate::test_utils::{main_cryptde, make_paying_wallet}; + use crate::bootstrapper::CryptDEPair; + use crate::test_utils::make_paying_wallet; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn can_construct_hop() { let key = PublicKey::new(b"key"); @@ -70,7 +76,7 @@ mod tests { #[test] fn decode_can_handle_errors() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let encrypted = CryptData::new(&[0]); let result = LiveHop::decode(cryptde, &encrypted); @@ -85,7 +91,7 @@ mod tests { #[test] fn encode_decode() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let encode_key = cryptde.public_key(); let contract_address = &TEST_DEFAULT_CHAIN.rec().contract.clone(); diff --git a/node/src/sub_lib/hopper.rs b/node/src/sub_lib/hopper.rs index 5c1c000a73..96d756ef20 100644 --- a/node/src/sub_lib/hopper.rs +++ b/node/src/sub_lib/hopper.rs @@ -145,7 +145,7 @@ impl ExpiredCoresPackage { #[derive(Clone)] pub struct HopperConfig { - pub cryptdes: CryptDEPair, + pub cryptde_pair: CryptDEPair, pub per_routing_service: u64, pub per_routing_byte: u64, pub is_decentralized: bool, @@ -174,12 +174,17 @@ mod tests { use crate::sub_lib::dispatcher::Component; use crate::sub_lib::route::RouteSegment; use crate::test_utils::recorder::Recorder; - use crate::test_utils::{main_cryptde, make_meaningless_message_type, make_paying_wallet}; + use crate::test_utils::{make_meaningless_message_type, make_paying_wallet}; use actix::Actor; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use std::net::IpAddr; use std::str::FromStr; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn hopper_subs_debug() { let recorder = Recorder::new().start(); @@ -197,7 +202,7 @@ mod tests { #[test] fn no_lookup_incipient_cores_package_is_created_correctly() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[1, 2]); let node_addr = NodeAddr::new(&IpAddr::from_str("1.2.3.4").unwrap(), &[1, 2, 3, 4]); let payload = make_meaningless_message_type(); @@ -221,7 +226,7 @@ mod tests { #[test] fn no_lookup_incipient_cores_package_new_complains_about_problems_encrypting_payload() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let result = NoLookupIncipientCoresPackage::new( cryptde, &PublicKey::new(&[]), @@ -238,7 +243,7 @@ mod tests { #[test] fn incipient_cores_package_is_created_correctly() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let key12 = cryptde.public_key(); let key34 = PublicKey::new(&[3, 4]); @@ -269,7 +274,7 @@ mod tests { #[test] fn incipient_cores_package_new_complains_about_problems_encrypting_payload() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let result = IncipientCoresPackage::new( cryptde, Route { hops: vec![] }, @@ -290,7 +295,7 @@ mod tests { let immediate_neighbor = SocketAddr::from_str("1.2.3.4:1234").unwrap(); let a_key = PublicKey::new(&[65, 65, 65]); let b_key = PublicKey::new(&[66, 66, 66]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let route = Route::one_way( RouteSegment::new(vec![&a_key, &b_key], Component::Neighborhood), diff --git a/node/src/sub_lib/neighborhood.rs b/node/src/sub_lib/neighborhood.rs index 79623cda3b..ba8ba7c6c9 100644 --- a/node/src/sub_lib/neighborhood.rs +++ b/node/src/sub_lib/neighborhood.rs @@ -75,7 +75,7 @@ pub enum NeighborhoodMode { } impl Display for NeighborhoodMode { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { NeighborhoodMode::Standard(_, _, _) => write!(f, "Standard"), NeighborhoodMode::ZeroHop => write!(f, "ZeroHop"), @@ -340,7 +340,7 @@ enum DescriptorParsingError<'a> { } impl Display for DescriptorParsingError<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn only_user_intended() -> String { CHAINS .iter() @@ -395,7 +395,7 @@ impl FromStr for Hops { } impl Display for Hops { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", *self as usize) } } @@ -428,7 +428,7 @@ pub struct NeighborhoodSubs { } impl Debug for NeighborhoodSubs { - fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { + fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { write!(f, "NeighborhoodSubs") } } @@ -619,9 +619,9 @@ impl Default for NeighborhoodTools { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::cryptde_real::CryptDEReal; use crate::sub_lib::utils::NotifyLaterHandleReal; - use crate::test_utils::main_cryptde; use crate::test_utils::recorder::Recorder; use actix::Actor; use masq_lib::constants::DEFAULT_CHAIN; @@ -629,6 +629,10 @@ mod tests { use masq_lib::utils::{localhost, NeighborhoodModeLight}; use std::str::FromStr; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn constants_have_correct_values() { assert_eq!( @@ -858,7 +862,7 @@ mod tests { #[test] fn from_str_complains_about_bad_base_64() { let result = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:bad_key@1.2.3.4:1234;2345", )); @@ -900,7 +904,8 @@ mod tests { #[test] fn from_str_complains_about_blank_public_key() { - let result = NodeDescriptor::try_from((main_cryptde(), "masq://dev:@1.2.3.4:1234/2345")); + let result = + NodeDescriptor::try_from((CRYPTDE_PAIR.main.as_ref(), "masq://dev:@1.2.3.4:1234/2345")); assert_eq!(result, Err(String::from("Public key cannot be empty"))); } @@ -908,7 +913,7 @@ mod tests { #[test] fn from_str_complains_about_bad_node_addr() { let result = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-mainnet:R29vZEtleQ==@BadNodeAddr", )); @@ -918,7 +923,7 @@ mod tests { #[test] fn from_str_handles_the_happy_path_with_node_addr() { let result = NodeDescriptor::try_from(( - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), "masq://eth-ropsten:R29vZEtleQ@1.2.3.4:1234/2345/3456", )); @@ -937,7 +942,10 @@ mod tests { #[test] fn from_str_handles_the_happy_path_without_node_addr() { - let result = NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:R29vZEtleQ@:")); + let result = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:R29vZEtleQ@:", + )); assert_eq!( result.unwrap(), @@ -979,7 +987,7 @@ mod tests { #[test] fn node_descriptor_from_key_node_addr_and_mainnet_flag_works() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[1, 2, 3, 4, 5, 6, 7, 8]); let node_addr = NodeAddr::new(&IpAddr::from_str("123.45.67.89").unwrap(), &[2345, 3456]); @@ -997,7 +1005,7 @@ mod tests { #[test] fn node_descriptor_to_string_works_for_mainnet() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[1, 2, 3, 4, 5, 6, 7, 8]); let node_addr = NodeAddr::new(&IpAddr::from_str("123.45.67.89").unwrap(), &[2345, 3456]); let subject = NodeDescriptor::from((&public_key, &node_addr, Chain::EthMainnet, cryptde)); @@ -1012,7 +1020,7 @@ mod tests { #[test] fn node_descriptor_to_string_works_for_not_mainnet() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[1, 2, 3, 4, 5, 6, 7, 8]); let node_addr = NodeAddr::new(&IpAddr::from_str("123.45.67.89").unwrap(), &[2345, 3456]); let subject = NodeDescriptor::from((&public_key, &node_addr, Chain::EthRopsten, cryptde)); @@ -1027,7 +1035,7 @@ mod tests { #[test] fn first_part_of_node_descriptor_must_not_be_longer_than_required() { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = CRYPTDE_PAIR.main.as_ref(); let public_key = PublicKey::new(&[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, @@ -1068,12 +1076,16 @@ mod tests { #[test] fn standard_mode_results() { - let one_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AQIDBA@1.2.3.4:1234")) - .unwrap(); - let another_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AgMEBQ@2.3.4.5:2345")) - .unwrap(); + let one_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", + )) + .unwrap(); + let another_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AgMEBQ@2.3.4.5:2345", + )) + .unwrap(); let subject = NeighborhoodMode::Standard( NodeAddr::new(&localhost(), &[1234, 2345]), vec![one_neighbor.clone(), another_neighbor.clone()], @@ -1099,12 +1111,16 @@ mod tests { #[test] fn originate_only_mode_results() { - let one_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-ropsten:AQIDBA@1.2.3.4:1234")) - .unwrap(); - let another_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345")) - .unwrap(); + let one_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-ropsten:AQIDBA@1.2.3.4:1234", + )) + .unwrap(); + let another_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-ropsten:AgMEBQ@2.3.4.5:2345", + )) + .unwrap(); let subject = NeighborhoodMode::OriginateOnly( vec![one_neighbor.clone(), another_neighbor.clone()], rate_pack(100), @@ -1126,12 +1142,16 @@ mod tests { #[test] fn consume_only_mode_results() { - let one_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AQIDBA@1.2.3.4:1234")) - .unwrap(); - let another_neighbor = - NodeDescriptor::try_from((main_cryptde(), "masq://eth-mainnet:AgMEBQ@2.3.4.5:2345")) - .unwrap(); + let one_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AQIDBA@1.2.3.4:1234", + )) + .unwrap(); + let another_neighbor = NodeDescriptor::try_from(( + CRYPTDE_PAIR.main.as_ref(), + "masq://eth-mainnet:AgMEBQ@2.3.4.5:2345", + )) + .unwrap(); let subject = NeighborhoodMode::ConsumeOnly(vec![one_neighbor.clone(), another_neighbor.clone()]); diff --git a/node/src/sub_lib/proxy_client.rs b/node/src/sub_lib/proxy_client.rs index 36fc312204..ac23184abe 100644 --- a/node/src/sub_lib/proxy_client.rs +++ b/node/src/sub_lib/proxy_client.rs @@ -1,5 +1,5 @@ // Copyright (c) 2019, MASQ (https://masq.ai) and/or its affiliates. All rights reserved. -use crate::sub_lib::cryptde::CryptDE; +use crate::bootstrapper::CryptDEPair; use crate::sub_lib::hopper::{ExpiredCoresPackage, MessageType}; use crate::sub_lib::peer_actors::BindMessage; use crate::sub_lib::proxy_server::ClientRequestPayload_0v1; @@ -21,7 +21,7 @@ pub fn error_socket_addr() -> SocketAddr { #[derive(Clone)] pub struct ProxyClientConfig { - pub cryptde: &'static dyn CryptDE, + pub cryptde_pair: CryptDEPair, pub dns_servers: Vec, pub exit_service_rate: u64, pub exit_byte_rate: u64, diff --git a/node/src/sub_lib/route.rs b/node/src/sub_lib/route.rs index ecbd0261ed..6d9b526040 100644 --- a/node/src/sub_lib/route.rs +++ b/node/src/sub_lib/route.rs @@ -11,6 +11,7 @@ use ethereum_types::Address; use itertools::Itertools; use serde_derive::{Deserialize, Serialize}; use std::cmp::min; +use std::fmt::Debug; use std::iter; #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] @@ -320,12 +321,18 @@ impl Route { } } -#[derive(Debug)] pub struct RouteSegment { pub keys: Vec, pub recipient: Component, } +impl Debug for RouteSegment { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let keys_base64: Vec = self.keys.iter().map(|k| k.to_string()).collect(); + write!(f, "{} : {:?}", keys_base64.join(" -> "), self.recipient) + } +} + impl RouteSegment { pub fn new(keys: Vec<&PublicKey>, recipient: Component) -> RouteSegment { RouteSegment { @@ -346,15 +353,21 @@ pub enum RouteError { #[cfg(test)] mod tests { use super::*; + use crate::bootstrapper::CryptDEPair; use crate::sub_lib::cryptde_null::CryptDENull; + use crate::test_utils::make_paying_wallet; use crate::test_utils::make_wallet; - use crate::test_utils::{main_cryptde, make_paying_wallet}; + use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use serde_cbor; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn id_decodes_return_route_id() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let subject = Route { hops: vec![Route::encrypt_return_route_id(42, cryptde)], @@ -365,7 +378,7 @@ mod tests { #[test] fn id_returns_empty_route_error_when_the_route_is_empty() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let subject = Route { hops: vec![] }; @@ -387,9 +400,34 @@ mod tests { let _ = subject.id(&cryptde2); } + #[test] + fn route_segments_are_represented_in_base64_by_debug() { + let public_key_data_1: Vec = vec![12, 34, 56, 78, 90]; + let public_key_data_2: Vec = vec![34, 56, 78, 90, 12]; + let public_key_data_3: Vec = vec![56, 78, 90, 12, 34]; + let subject = RouteSegment::new( + vec![ + &PublicKey::new(public_key_data_1.as_slice()), + &PublicKey::new(public_key_data_2.as_slice()), + &PublicKey::new(public_key_data_3.as_slice()), + ], + Component::ProxyClient, + ); + + let result = format!("{:?}", subject); + + let base64_1 = base64::encode_config(&public_key_data_1, base64::STANDARD_NO_PAD); + let base64_2 = base64::encode_config(&public_key_data_2, base64::STANDARD_NO_PAD); + let base64_3 = base64::encode_config(&public_key_data_3, base64::STANDARD_NO_PAD); + assert_eq!( + result, + format!("{} -> {} -> {} : ProxyClient", base64_1, base64_2, base64_3) + ); + } + #[test] fn construct_does_not_like_route_segments_with_too_few_keys() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_wallet("wallet"); let result = Route::one_way( RouteSegment::new(vec![], Component::ProxyClient), @@ -412,7 +450,7 @@ mod tests { let b_key = PublicKey::new(&[66, 66, 66]); let c_key = PublicKey::new(&[67, 67, 67]); let d_key = PublicKey::new(&[68, 68, 68]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let result = Route::round_trip( @@ -435,7 +473,7 @@ mod tests { #[test] fn construct_can_make_single_hop_route() { let target_key = PublicKey::new(&[65, 65, 65]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let subject = Route::single_hop(&target_key, cryptde).unwrap(); @@ -462,7 +500,7 @@ mod tests { let d_key = PublicKey::new(&[68, 68, 68]); let e_key = PublicKey::new(&[69, 69, 69]); let f_key = PublicKey::new(&[70, 70, 70]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let return_route_id = 4321; let contract_address = TEST_DEFAULT_CHAIN.rec().contract; @@ -573,7 +611,7 @@ mod tests { fn construct_can_make_short_single_stop_route() { let a_key = PublicKey::new(&[65, 65, 65]); let b_key = PublicKey::new(&[66, 66, 66]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let contract_address = TEST_DEFAULT_CHAIN.rec().contract; @@ -609,7 +647,7 @@ mod tests { #[test] fn next_hop_decodes_top_hop() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let key12 = cryptde.public_key(); let key34 = PublicKey::new(&[3, 4]); @@ -664,7 +702,7 @@ mod tests { #[test] fn shift_returns_next_hop_and_adds_garbage_at_the_bottom() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let key12 = cryptde.public_key(); let key34 = PublicKey::new(&[3, 4]); @@ -716,7 +754,7 @@ mod tests { #[test] fn empty_route_says_none_when_asked_for_next_hop() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let subject = Route { hops: Vec::new() }; let result = subject.next_hop(cryptde).err().unwrap(); @@ -726,7 +764,7 @@ mod tests { #[test] fn shift_says_none_when_asked_for_next_hop_on_empty_route() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let mut subject = Route { hops: Vec::new() }; let result = subject.shift(cryptde).err().unwrap(); @@ -738,7 +776,7 @@ mod tests { fn route_serialization_deserialization() { let key1 = PublicKey::new(&[1, 2, 3, 4]); let key2 = PublicKey::new(&[4, 3, 2, 1]); - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let paying_wallet = make_paying_wallet(b"wallet"); let original = Route::round_trip( RouteSegment::new(vec![&key1, &key2], Component::ProxyClient), @@ -765,7 +803,7 @@ mod tests { let paying_wallet = make_paying_wallet(b"wallet"); let subject = Route::one_way( RouteSegment::new(vec![&key1, &key2, &key3], Component::Neighborhood), - main_cryptde(), + CRYPTDE_PAIR.main.as_ref(), Some(paying_wallet), Some(TEST_DEFAULT_CHAIN.rec().contract), ) diff --git a/node/src/sub_lib/stream_key.rs b/node/src/sub_lib/stream_key.rs index 7c3110ee1e..bca70efe43 100644 --- a/node/src/sub_lib/stream_key.rs +++ b/node/src/sub_lib/stream_key.rs @@ -130,14 +130,18 @@ fn add_socket_addr_to_hash(mut hash: sha1::Sha1, client_addr: SocketAddr) -> sha #[cfg(test)] mod tests { use super::*; - use crate::test_utils::main_cryptde; + use crate::bootstrapper::CryptDEPair; use itertools::Itertools; use std::net::IpAddr; use std::str::FromStr; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } + #[test] fn stream_keys_with_different_host_names_are_different() { - let public_key = main_cryptde().public_key(); + let public_key = CRYPTDE_PAIR.main.public_key(); let stream_key_count = 100; let ip_addr = IpAddr::from_str("1.2.3.4").unwrap(); let client_addrs = (0..stream_key_count).map(|i| SocketAddr::new(ip_addr, 1024 + i as u16)); @@ -167,7 +171,7 @@ mod tests { #[test] fn stream_keys_are_salted() { - let public_key = main_cryptde().public_key(); + let public_key = CRYPTDE_PAIR.main.public_key(); let client_addr = SocketAddr::new(IpAddr::from_str("1.2.3.4").unwrap(), 1024); let result = StreamKey::new(&public_key, client_addr); diff --git a/node/src/test_utils/mod.rs b/node/src/test_utils/mod.rs index 1bf32b4b54..351b27711c 100644 --- a/node/src/test_utils/mod.rs +++ b/node/src/test_utils/mod.rs @@ -24,7 +24,6 @@ use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::cryptde::CryptData; use crate::sub_lib::cryptde::PlainData; use crate::sub_lib::cryptde::PublicKey; -use crate::sub_lib::cryptde_null::CryptDENull; use crate::sub_lib::dispatcher::Component; use crate::sub_lib::neighborhood::ExpectedServices; use crate::sub_lib::neighborhood::RouteQueryResponse; @@ -36,7 +35,6 @@ use crate::sub_lib::wallet::Wallet; use crossbeam_channel::{unbounded, Receiver, Sender}; use ethsign_crypto::Keccak256; use futures::sync::mpsc::SendError; -use lazy_static::lazy_static; use masq_lib::test_utils::utils::TEST_DEFAULT_CHAIN; use rand::RngCore; use regex::Regex; @@ -63,28 +61,6 @@ use std::time::Duration; use std::time::Instant; use web3::types::{Address, U256}; -lazy_static! { - static ref MAIN_CRYPTDE_NULL: Box = - Box::new(CryptDENull::new(TEST_DEFAULT_CHAIN)); - static ref ALIAS_CRYPTDE_NULL: Box = - Box::new(CryptDENull::new(TEST_DEFAULT_CHAIN)); -} - -pub fn main_cryptde() -> &'static dyn CryptDE { - MAIN_CRYPTDE_NULL.as_ref() -} - -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, } @@ -174,34 +150,39 @@ impl Waiter { } } -pub fn make_one_way_route_to_proxy_client(public_keys: Vec<&PublicKey>) -> Route { +pub fn make_one_way_route_to_proxy_client( + public_keys: Vec<&PublicKey>, + cryptde_pair: &CryptDEPair, +) -> Route { Route::one_way( RouteSegment::new(public_keys, Component::ProxyClient), - main_cryptde(), + cryptde_pair.main.as_ref(), Some(make_paying_wallet(b"irrelevant")), Some(TEST_DEFAULT_CHAIN.rec().contract), ) .unwrap() } -pub fn make_meaningless_route() -> Route { +pub fn make_meaningless_route(cryptde_pair: &CryptDEPair) -> Route { Route::one_way( RouteSegment::new( vec![ - &make_meaningless_public_key(), - &make_meaningless_public_key(), + &make_meaningless_public_key(cryptde_pair), + &make_meaningless_public_key(cryptde_pair), ], Component::ProxyClient, ), - main_cryptde(), + cryptde_pair.main.as_ref(), Some(make_paying_wallet(b"irrelevant")), Some(TEST_DEFAULT_CHAIN.rec().contract), ) .unwrap() } -pub fn make_meaningless_public_key() -> PublicKey { - PublicKey::new(&make_garbage_data(main_cryptde().public_key().len())) +pub fn make_meaningless_public_key(cryptde_pair: &CryptDEPair) -> PublicKey { + PublicKey::new(&make_garbage_data( + cryptde_pair.main.as_ref().public_key().len(), + )) } pub fn make_meaningless_wallet_private_key() -> PlainData { @@ -713,7 +694,7 @@ pub mod unshared_test_utils { ClientRequestPayload_0v1 { stream_key: StreamKey::make_meaningful_stream_key("request"), sequenced_packet: SequencedPacket::new(make_garbage_data(bytes), 0, true), - target_hostname: Some("example.com".to_string()), + target_hostname: Some("www.example.com".to_string()), target_port: HTTP_PORT, protocol: ProxyProtocol::HTTP, originator_public_key: cryptde.public_key().clone(), @@ -1227,23 +1208,27 @@ pub mod unshared_test_utils { #[cfg(test)] mod tests { + use super::*; use crate::sub_lib::cryptde::CryptData; use crate::sub_lib::hop::LiveHop; use crate::sub_lib::neighborhood::ExpectedService; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::{ ArbitraryIdStamp, FirstTraitMock, SecondTraitMock, TestSubject, }; + use lazy_static::lazy_static; use std::borrow::BorrowMut; use std::iter; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; - use super::*; + lazy_static! { + static ref CRYPTDE_PAIR: CryptDEPair = CryptDEPair::null(); + } #[test] fn characterize_zero_hop_route() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key(); let subject = zero_hop_route_response(&key, cryptde); @@ -1275,7 +1260,7 @@ mod tests { #[test] fn characterize_route_to_proxy_client() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key(); let subject = route_to_proxy_client(&key, cryptde); @@ -1299,7 +1284,7 @@ mod tests { #[test] fn characterize_route_from_proxy_client() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key(); let subject = route_from_proxy_client(&key, cryptde); @@ -1323,7 +1308,7 @@ mod tests { #[test] fn characterize_route_to_proxy_server() { - let cryptde = main_cryptde(); + let cryptde = CRYPTDE_PAIR.main.as_ref(); let key = cryptde.public_key(); let subject = route_to_proxy_server(&key, cryptde); diff --git a/node/src/test_utils/neighborhood_test_utils.rs b/node/src/test_utils/neighborhood_test_utils.rs index 34dd1eb9c2..827393cbde 100644 --- a/node/src/test_utils/neighborhood_test_utils.rs +++ b/node/src/test_utils/neighborhood_test_utils.rs @@ -87,9 +87,20 @@ pub fn make_node_record_f( result } -pub fn make_global_cryptde_node_record(n: u16, has_ip: bool) -> NodeRecord { +pub fn make_global_cryptde_node_record( + n: u16, + has_ip: bool, + cryptde_pair: &CryptDEPair, +) -> NodeRecord { + let mut node_record = make_node_record(n, has_ip); + node_record.inner.public_key = cryptde_pair.main.public_key().clone(); + node_record.resign(); + node_record +} + +pub fn make_cryptde_node_record(n: u16, has_ip: bool, cryptde_pair: &CryptDEPair) -> NodeRecord { let mut node_record = make_node_record(n, has_ip); - node_record.inner.public_key = main_cryptde().public_key().clone(); + node_record.inner.public_key = cryptde_pair.main.public_key().clone(); node_record.resign(); node_record } @@ -101,7 +112,6 @@ pub fn make_meaningless_db() -> NeighborhoodDatabase { pub fn db_from_node(node: &NodeRecord) -> NeighborhoodDatabase { let mut db = NeighborhoodDatabase::new( - node.public_key(), node.into(), node.earning_wallet(), &CryptDENull::from(node.public_key(), TEST_DEFAULT_CHAIN), @@ -116,8 +126,9 @@ pub fn db_from_node(node: &NodeRecord) -> NeighborhoodDatabase { pub fn neighborhood_from_nodes( root: &NodeRecord, neighbor_opt: Option<&NodeRecord>, + cryptde_pair: &CryptDEPair, ) -> Neighborhood { - let cryptde: &dyn CryptDE = main_cryptde(); + let cryptde: &dyn CryptDE = cryptde_pair.main.as_ref(); if root.public_key() != cryptde.public_key() { panic!("Neighborhood must be built on root node with public key from cryptde()"); } @@ -139,7 +150,7 @@ pub fn neighborhood_from_nodes( config.earning_wallet = root.earning_wallet(); config.consuming_wallet_opt = Some(make_paying_wallet(b"consuming")); config.db_password_opt = Some("password".to_string()); - Neighborhood::new(cryptde, &config) + Neighborhood::new(cryptde_pair.clone(), &config) } impl From<&NodeRecord> for NeighborhoodMode { diff --git a/node/src/test_utils/persistent_configuration_mock.rs b/node/src/test_utils/persistent_configuration_mock.rs index 4906c835cd..138a1deb65 100644 --- a/node/src/test_utils/persistent_configuration_mock.rs +++ b/node/src/test_utils/persistent_configuration_mock.rs @@ -5,6 +5,7 @@ use crate::database::rusqlite_wrappers::TransactionSafeWrapper; use crate::db_config::persistent_configuration::{PersistentConfigError, PersistentConfiguration}; use crate::sub_lib::accountant::{PaymentThresholds, ScanIntervals}; +use crate::sub_lib::cryptde::CryptDE; use crate::sub_lib::neighborhood::{Hops, NodeDescriptor, RatePack}; use crate::sub_lib::wallet::Wallet; use crate::test_utils::unshared_test_utils::arbitrary_id_stamp::ArbitraryIdStamp; @@ -16,7 +17,7 @@ use std::sync::{Arc, Mutex}; use std::u64; #[allow(clippy::type_complexity)] -#[derive(Clone, Default)] +#[derive(Default)] pub struct PersistentConfigurationMock { blockchain_service_url_results: RefCell, PersistentConfigError>>>, set_blockchain_service_url_params: Arc>>, @@ -31,6 +32,10 @@ pub struct PersistentConfigurationMock { clandestine_port_results: RefCell>>, set_clandestine_port_params: Arc>>, set_clandestine_port_results: RefCell>>, + cryptde_params: Arc>>, + cryptde_results: RefCell>, PersistentConfigError>>>, + set_cryptde_params: Arc, String)>>>, + set_cryptde_results: RefCell>>, gas_price_results: RefCell>>, set_gas_price_params: Arc>>, set_gas_price_results: RefCell>>, @@ -79,6 +84,84 @@ pub struct PersistentConfigurationMock { arbitrary_id_stamp_opt: Option, } +impl Clone for PersistentConfigurationMock { + fn clone(&self) -> Self { + Self { + blockchain_service_url_results: self.blockchain_service_url_results.clone(), + set_blockchain_service_url_params: self.set_blockchain_service_url_params.clone(), + set_blockchain_service_url_results: self.set_blockchain_service_url_results.clone(), + current_schema_version_results: self.current_schema_version_results.clone(), + chain_name_params: self.chain_name_params.clone(), + chain_name_results: self.chain_name_results.clone(), + check_password_params: self.check_password_params.clone(), + check_password_results: self.check_password_results.clone(), + change_password_params: self.change_password_params.clone(), + change_password_results: self.change_password_results.clone(), + clandestine_port_results: self.clandestine_port_results.clone(), + set_clandestine_port_params: self.set_clandestine_port_params.clone(), + set_clandestine_port_results: self.set_clandestine_port_results.clone(), + cryptde_params: self.cryptde_params.clone(), + cryptde_results: RefCell::new( + self.cryptde_results + .borrow() + .iter() + .map(|x| { + x.as_ref() + .map(|cryptde_opt| cryptde_opt.as_ref().map(|cryptde| cryptde.dup())) + .map_err(|e| e.clone()) + }) + .collect(), + ), + set_cryptde_params: self.set_cryptde_params.clone(), + set_cryptde_results: self.set_cryptde_results.clone(), + gas_price_results: self.gas_price_results.clone(), + set_gas_price_params: self.set_gas_price_params.clone(), + set_gas_price_results: self.set_gas_price_results.clone(), + consuming_wallet_params: self.consuming_wallet_params.clone(), + consuming_wallet_results: self.consuming_wallet_results.clone(), + consuming_wallet_private_key_params: self.consuming_wallet_private_key_params.clone(), + consuming_wallet_private_key_results: self.consuming_wallet_private_key_results.clone(), + earning_wallet_results: self.earning_wallet_results.clone(), + earning_wallet_address_results: self.earning_wallet_address_results.clone(), + set_wallet_info_params: self.set_wallet_info_params.clone(), + set_wallet_info_results: self.set_wallet_info_results.clone(), + mapping_protocol_results: self.mapping_protocol_results.clone(), + set_mapping_protocol_params: self.set_mapping_protocol_params.clone(), + set_mapping_protocol_results: self.set_mapping_protocol_results.clone(), + min_hops_results: self.min_hops_results.clone(), + set_min_hops_params: self.set_min_hops_params.clone(), + set_min_hops_results: self.set_min_hops_results.clone(), + neighborhood_mode_results: self.neighborhood_mode_results.clone(), + set_neighborhood_mode_params: self.set_neighborhood_mode_params.clone(), + set_neighborhood_mode_results: self.set_neighborhood_mode_results.clone(), + past_neighbors_params: self.past_neighbors_params.clone(), + past_neighbors_results: self.past_neighbors_results.clone(), + set_past_neighbors_params: self.set_past_neighbors_params.clone(), + set_past_neighbors_results: self.set_past_neighbors_results.clone(), + start_block_params: self.start_block_params.clone(), + start_block_results: self.start_block_results.clone(), + set_start_block_params: self.set_start_block_params.clone(), + set_start_block_results: self.set_start_block_results.clone(), + max_block_count_params: self.max_block_count_params.clone(), + max_block_count_results: self.max_block_count_results.clone(), + set_max_block_count_params: self.set_max_block_count_params.clone(), + set_max_block_count_results: self.set_max_block_count_results.clone(), + set_start_block_from_txn_params: self.set_start_block_from_txn_params.clone(), + set_start_block_from_txn_results: self.set_start_block_from_txn_results.clone(), + payment_thresholds_results: self.payment_thresholds_results.clone(), + set_payment_thresholds_params: self.set_payment_thresholds_params.clone(), + set_payment_thresholds_results: self.set_payment_thresholds_results.clone(), + rate_pack_results: self.rate_pack_results.clone(), + set_rate_pack_params: self.set_rate_pack_params.clone(), + set_rate_pack_results: self.set_rate_pack_results.clone(), + scan_intervals_results: self.scan_intervals_results.clone(), + set_scan_intervals_params: self.set_scan_intervals_params.clone(), + set_scan_intervals_results: self.set_scan_intervals_results.clone(), + arbitrary_id_stamp_opt: self.arbitrary_id_stamp_opt.clone(), + } + } +} + impl PersistentConfiguration for PersistentConfigurationMock { fn blockchain_service_url(&self) -> Result, PersistentConfigError> { self.blockchain_service_url_results.borrow_mut().remove(0) @@ -154,6 +237,29 @@ impl PersistentConfiguration for PersistentConfigurationMock { self.set_clandestine_port_results.borrow_mut().remove(0) } + fn cryptde( + &self, + db_password: &str, + ) -> Result>, PersistentConfigError> { + self.cryptde_params + .lock() + .unwrap() + .push(db_password.to_string()); + self.cryptde_results.borrow_mut().remove(0) + } + + fn set_cryptde( + &mut self, + cryptde: &dyn CryptDE, + db_password: &str, + ) -> Result<(), PersistentConfigError> { + self.set_cryptde_params + .lock() + .unwrap() + .push((cryptde.dup(), db_password.to_string())); + self.set_cryptde_results.borrow_mut().remove(0) + } + fn earning_wallet(&self) -> Result, PersistentConfigError> { Self::result_from(&self.earning_wallet_results) } @@ -481,6 +587,32 @@ impl PersistentConfigurationMock { self } + pub fn cryptde_params(mut self, params: &Arc>>) -> Self { + self.cryptde_params = params.clone(); + self + } + + pub fn cryptde_result( + self, + result: Result>, PersistentConfigError>, + ) -> Self { + self.cryptde_results.borrow_mut().push(result); + self + } + + pub fn set_cryptde_params( + mut self, + params: &Arc, String)>>>, + ) -> Self { + self.set_cryptde_params = params.clone(); + self + } + + pub fn set_cryptde_result(self, result: Result<(), PersistentConfigError>) -> Self { + self.set_cryptde_results.borrow_mut().push(result); + self + } + pub fn gas_price_result(self, result: Result) -> Self { self.gas_price_results.borrow_mut().push(result); self diff --git a/node/tests/http_through_node_test.rs b/node/tests/http_through_node_test.rs index f49cb25b9f..eac50603b7 100644 --- a/node/tests/http_through_node_test.rs +++ b/node/tests/http_through_node_test.rs @@ -24,7 +24,7 @@ fn http_through_node_integration() { stream .set_read_timeout(Some(Duration::from_millis(1000))) .unwrap(); - let request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".as_bytes(); + let request = "GET /index.html HTTP/1.1\r\nHost: www.testingmcafeesites.com\r\n\r\n".as_bytes(); stream.write(request.clone()).unwrap(); let buf = read_until_timeout(&mut stream); @@ -32,7 +32,7 @@ fn http_through_node_integration() { let response = String::from_utf8(buf).expect("Response is not UTF-8"); assert_eq!(&response[9..15], &"200 OK"[..]); assert_eq!( - response.contains("

Example Domain

"), + response.contains("URL for testing."), true, "{}", response diff --git a/node/tests/initialization_test.rs b/node/tests/initialization_test.rs index 5b57d5b969..0a5e46ba8d 100644 --- a/node/tests/initialization_test.rs +++ b/node/tests/initialization_test.rs @@ -15,7 +15,9 @@ use node_lib::daemon::launch_verifier::{VerifierTools, VerifierToolsReal}; use node_lib::database::db_initializer::DATABASE_FILE; #[cfg(not(target_os = "windows"))] use node_lib::privilege_drop::{PrivilegeDropper, PrivilegeDropperReal}; +use regex::Regex; use rusqlite::{Connection, OpenFlags}; +use std::io::Read; use std::ops::Add; use std::time::{Duration, SystemTime}; use utils::CommandConfig; @@ -76,7 +78,7 @@ fn initialization_sequence_integration() { ("neighborhood-mode", Some("zero-hop")), ("log-level", Some("trace")), ("data-directory", Some(&data_directory.to_str().unwrap())), - ("blockchain-service-url", Some("https://example.com")), + ("blockchain-service-url", Some("https://www.example.com")), ])) .unwrap(); let financials_request = UiFinancialsRequest { @@ -305,3 +307,40 @@ fn node_creates_log_file_with_heading_integration() { node.wait_for_log(&expected_heading_regex, Some(5000)); //Node is dropped and killed } + +fn descriptor_from_logfile(test_name: &str, sterile_database: bool) -> String { + let descriptor_log_pattern = r"INFO: Bootstrapper: MASQ Node local descriptor: (masq://.*@:)"; + let mut log_data = Vec::new(); + let mut node = utils::MASQNode::start_standard( + test_name, + Some(CommandConfig::new().pair("--db-password", "test-password")), + sterile_database, + true, + false, + true, + ); + node.wait_for_log(descriptor_log_pattern, Some(5000)); + let path_to_logfile = MASQNode::path_to_logfile(&node.data_dir); + let mut logfile = std::fs::File::open(path_to_logfile).unwrap(); + logfile.read_to_end(&mut log_data).unwrap(); + let log_string = String::from_utf8(log_data).unwrap(); + let regex = Regex::new(descriptor_log_pattern).unwrap(); + let descriptor = regex + .captures(&log_string) + .unwrap() + .get(1) + .unwrap() + .as_str(); + node.kill().unwrap(); + descriptor.to_string() +} + +#[test] +fn second_run_node_uses_same_public_key_as_first_run_node_integration() { + let test_name = "second_run_node_uses_same_public_key_as_first_run_node"; + let first_descriptor = descriptor_from_logfile(test_name, true); + + let second_descriptor = descriptor_from_logfile(test_name, false); + + assert_eq!(second_descriptor, first_descriptor); +} diff --git a/node/tests/tls_through_node_test.rs b/node/tests/tls_through_node_test.rs index 1509e38c7a..6cb04cc912 100644 --- a/node/tests/tls_through_node_test.rs +++ b/node/tests/tls_through_node_test.rs @@ -2,9 +2,8 @@ pub mod utils; -use native_tls::HandshakeError; use native_tls::TlsConnector; -use native_tls::TlsStream; +use native_tls::{HandshakeError, MidHandshakeTlsStream, TlsStream}; use node_lib::test_utils::*; use std::io::Write; use std::net::SocketAddr; @@ -25,7 +24,6 @@ fn tls_through_node_integration() { ); let mut tls_stream = { - let mut tls_stream: Option> = None; let stream = TcpStream::connect(SocketAddr::from_str("127.0.0.1:443").unwrap()) .expect("Could not connect to 127.0.0.1:443"); stream @@ -33,31 +31,27 @@ fn tls_through_node_integration() { .expect("Could not set read timeout to 1000ms"); let connector = TlsConnector::new().expect("Could not build TlsConnector"); match connector.connect( - "example.com", + "www.example.com", stream.try_clone().expect("Couldn't clone TcpStream"), ) { - Ok(s) => { - tls_stream = Some(s); - } + Ok(s) => s, Err(HandshakeError::WouldBlock(interrupted_stream)) => { - thread::sleep(Duration::from_millis(100)); - match interrupted_stream.handshake() { - Ok(stream) => tls_stream = Some(stream), + match handle_wouldblock(interrupted_stream) { + Ok(stream) => stream, Err(e) => { - println!("connection error after interruption retry: {:?}", e); handle_connection_error(stream); + panic!("connection error after WouldBlock: {:?}", e); } } } Err(e) => { - println!("connection error: {:?}", e); handle_connection_error(stream); + panic!("connection error: {:?}", e); } } - - tls_stream.expect("Couldn't handshake") }; - let request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".as_bytes(); + + let request = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n".as_bytes(); tls_stream .write(request.clone()) .expect("Could not write request to TLS stream"); @@ -65,6 +59,7 @@ fn tls_through_node_integration() { let _ = tls_stream.shutdown(); // Can't do anything about an error here let response = String::from_utf8(Vec::from(&buf[..])).expect("Response is not UTF-8"); + assert_eq!(&response[9..15], &"200 OK"[..]); assert_eq!( response.contains("

Example Domain

"), @@ -73,3 +68,28 @@ fn tls_through_node_integration() { response ); } + +fn handle_wouldblock( + interrupted_stream: MidHandshakeTlsStream, +) -> Result, HandshakeError> { + let mut retries_left = 10; + let mut retry_stream = interrupted_stream; + while retries_left > 0 { + retries_left -= 1; + eprintln!( + "Handshake interrupted, retrying... ({} retries left)", + retries_left + ); + thread::sleep(Duration::from_millis(100)); + match retry_stream.handshake() { + Ok(stream) => return Ok(stream), + Err(HandshakeError::WouldBlock(interrupted_stream)) => { + retry_stream = interrupted_stream; + } + Err(e) => { + return Err(e); + } + } + } + panic!("Handshake never completed after retries"); +} diff --git a/node/tests/ui_gateway_test.rs b/node/tests/ui_gateway_test.rs index fc68020751..07b603bff6 100644 --- a/node/tests/ui_gateway_test.rs +++ b/node/tests/ui_gateway_test.rs @@ -142,7 +142,7 @@ fn daemon_does_not_allow_node_to_keep_his_client_alive_integration() { ("chain", Some("polygon-mainnet")), ("neighborhood-mode", Some("standard")), ("log-level", Some("trace")), - ("blockchain-service-url", Some("https://example.com")), + ("blockchain-service-url", Some("https://www.example.com")), ("data-directory", Some(&data_directory.to_str().unwrap())), ])) .unwrap();