Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8aa7bed
PersistentConfiguration now handles CryptDEs
dnwiebe Apr 29, 2025
02e059c
Temporary commit
dnwiebe May 21, 2025
b49606b
All tests apparently passing
dnwiebe May 29, 2025
c3d18a3
Starting to deal with the consequences of removing CryptDE as a static
dnwiebe Jun 27, 2025
c6887b9
About two-thirds done.
dnwiebe Jun 27, 2025
0b5a864
All unit tests passing
dnwiebe Jun 30, 2025
c66e762
New integration test is passing
dnwiebe Jul 1, 2025
a42c445
Merged in master
dnwiebe Jul 1, 2025
7295793
Unit, integration, and multinode tests passing
dnwiebe Jul 2, 2025
e3d2126
Review issues
dnwiebe Jul 3, 2025
b89a378
Removed two fields from BootstrapperConfig
dnwiebe Jul 3, 2025
2468554
Formatting
dnwiebe Jul 3, 2025
4437d36
Review issues
dnwiebe Jul 4, 2025
1bba5fe
Removed unused second parameter to CrashTestDummy constructor
dnwiebe Jul 4, 2025
828a354
Formatting
dnwiebe Jul 4, 2025
55334db
Changing the way database passwords are established
dnwiebe Jul 10, 2025
04c0365
Formatting
dnwiebe Jul 10, 2025
2f16112
Trying to find issue with --fake-public-key and chain
dnwiebe Jul 16, 2025
e6707e3
Multinode tests and unit tests are working.
dnwiebe Jul 16, 2025
4dfb97f
Formatting and removing debug logs
dnwiebe Jul 16, 2025
4671266
Removed unused import
dnwiebe Jul 16, 2025
09f953e
Clippy appeasement
dnwiebe Jul 17, 2025
c76a5bb
Review issues
dnwiebe Jul 18, 2025
ccd602d
Formatting
dnwiebe Jul 18, 2025
e52c338
Switched test from example.com to testingmcafeesites.com
dnwiebe Jul 19, 2025
83e37fa
Made running single integration tests easier; added TLS retries to in…
dnwiebe Jul 21, 2025
8d060fe
Formatting
dnwiebe Jul 21, 2025
7cf6856
Race in setup_reporter removed
dnwiebe Jul 29, 2025
843570b
Increased a timeout
dnwiebe Jul 30, 2025
c5c94db
Formatting
dnwiebe Jul 30, 2025
2fc19f1
example.com -> www.example.com
dnwiebe Jul 30, 2025
45f2e17
Review issues
dnwiebe Jul 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions masq_lib/src/blockchains/chains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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::<Vec<_>>();

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()
Expand Down
2 changes: 1 addition & 1 deletion masq_lib/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
49 changes: 42 additions & 7 deletions masq_lib/src/test_utils/environment_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<ThreadId>> = Mutex::new(None);
static ref CLAP_GUARD_MUTEX: Mutex<()> = Mutex::new(());
static ref LOGFILE_NAME_GUARD_MUTEX: Mutex<()> = Mutex::new(());
}
Expand All @@ -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()),
}
}
}
Expand All @@ -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<ThreadId>> {
ENVIRONMENT_GUARD_THREAD_ID
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
}

impl<'a> Default for EnvironmentGuard<'a> {
Expand Down
28 changes: 18 additions & 10 deletions multinode_integration_tests/src/masq_node_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DockerHostSocketAddr>,
local_addr: SocketAddr,
listener: TcpListener,
stream_opt: Option<TcpStream>,
}

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,
}
}
Expand All @@ -37,10 +38,17 @@ impl MASQNodeServer {
pub fn wait_for_chunk(&mut self, duration: Duration) -> Result<Vec<u8>, 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<TcpStream>, Receiver<TcpStream>) = 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)
}
Expand Down
5 changes: 3 additions & 2 deletions multinode_integration_tests/tests/bookkeeping_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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("<h1>Example Domain</h1>"),
"Not from example.com:\n{}",
"Not from www.example.com:\n{}",
response
);

Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(),
Expand All @@ -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(),
Expand Down Expand Up @@ -280,13 +282,15 @@ 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])
.build(),
);
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)
Expand Down Expand Up @@ -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(
Expand Down
11 changes: 9 additions & 2 deletions multinode_integration_tests/tests/connection_progress_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(),
);
Expand All @@ -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(),
)
})
Expand Down
4 changes: 2 additions & 2 deletions multinode_integration_tests/tests/data_routing_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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");
Expand Down
10 changes: 6 additions & 4 deletions multinode_integration_tests/tests/self_test.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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![
Expand All @@ -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(),
Expand Down
Loading
Loading