mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 19:49:28 +00:00
Add a test for an inbound handshake from monerod (#75)
* monerod: set a random DB and remove dir when done * add a test for an inbound monerod handshake * don't fail if can't remove dir on windows * Update test-utils/src/monerod.rs Co-authored-by: hinto-janai <hinto.janai@protonmail.com> * use `temp_dir` * use `tempfile` --------- Co-authored-by: hinto-janai <hinto.janai@protonmail.com>
This commit is contained in:
parent
34bfe37673
commit
e560ecc2ee
7 changed files with 86 additions and 13 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -613,6 +613,7 @@ dependencies = [
|
||||||
"monero-wire",
|
"monero-wire",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"tar",
|
"tar",
|
||||||
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
|
@ -70,6 +70,7 @@ tracing-subscriber = { version = "0.3.17", default-features = false }
|
||||||
tracing = { version = "0.1.40", default-features = false }
|
tracing = { version = "0.1.40", default-features = false }
|
||||||
|
|
||||||
## workspace.dev-dependencies
|
## workspace.dev-dependencies
|
||||||
|
tempfile = { version = "3" }
|
||||||
reqwest = { version = "0.11.24" }
|
reqwest = { version = "0.11.24" }
|
||||||
proptest = { version = "1" }
|
proptest = { version = "1" }
|
||||||
proptest-derive = { version = "0.4.0" }
|
proptest-derive = { version = "0.4.0" }
|
||||||
|
|
|
@ -29,6 +29,6 @@ borsh = { workspace = true, default-features = false, features = ["derive", "std
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cuprate-test-utils = {path = "../../test-utils"}
|
cuprate-test-utils = {path = "../../test-utils"}
|
||||||
|
|
||||||
hex = { workspace = true }
|
hex = { workspace = true, features = ["std"] }
|
||||||
tokio = { workspace = true, features = ["net", "rt-multi-thread", "rt", "macros"]}
|
tokio = { workspace = true, features = ["net", "rt-multi-thread", "rt", "macros"]}
|
||||||
tracing-subscriber = { workspace = true }
|
tracing-subscriber = { workspace = true }
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl NetZoneAddress for SocketAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClearNetServerCfg {
|
pub struct ClearNetServerCfg {
|
||||||
addr: SocketAddr,
|
pub addr: SocketAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
|
@ -1,23 +1,25 @@
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
use futures::{channel::mpsc, StreamExt};
|
use futures::{channel::mpsc, StreamExt};
|
||||||
use tokio::sync::{broadcast, Semaphore};
|
use tokio::{
|
||||||
|
sync::{broadcast, Semaphore},
|
||||||
|
time::timeout,
|
||||||
|
};
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
use cuprate_helper::network::Network;
|
use cuprate_helper::network::Network;
|
||||||
use monero_wire::{common::PeerSupportFlags, BasicNodeData};
|
use monero_wire::{common::PeerSupportFlags, BasicNodeData};
|
||||||
|
|
||||||
use monero_p2p::{
|
use monero_p2p::{
|
||||||
client::{ConnectRequest, Connector, DoHandshakeRequest, HandShaker},
|
client::{ConnectRequest, Connector, DoHandshakeRequest, HandShaker, InternalPeerID},
|
||||||
network_zones::ClearNet,
|
network_zones::{ClearNet, ClearNetServerCfg},
|
||||||
ConnectionDirection,
|
ConnectionDirection, NetworkZone,
|
||||||
};
|
};
|
||||||
|
|
||||||
use cuprate_test_utils::{
|
use cuprate_test_utils::{
|
||||||
monerod::monerod,
|
monerod::monerod,
|
||||||
test_netzone::{TestNetZone, TestNetZoneAddr},
|
test_netzone::{TestNetZone, TestNetZoneAddr},
|
||||||
};
|
};
|
||||||
use monero_p2p::client::InternalPeerID;
|
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::*;
|
use utils::*;
|
||||||
|
@ -143,3 +145,56 @@ async fn handshake_cuprate_to_monerod() {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn handshake_monerod_to_cuprate() {
|
||||||
|
let (broadcast_tx, _) = broadcast::channel(1); // this isn't actually used in this test.
|
||||||
|
let semaphore = Arc::new(Semaphore::new(10));
|
||||||
|
let permit = semaphore.acquire_owned().await.unwrap();
|
||||||
|
|
||||||
|
let our_basic_node_data = BasicNodeData {
|
||||||
|
my_port: 18081,
|
||||||
|
network_id: Network::Mainnet.network_id().into(),
|
||||||
|
peer_id: 87980,
|
||||||
|
support_flags: PeerSupportFlags::from(1_u32),
|
||||||
|
rpc_port: 0,
|
||||||
|
rpc_credits_per_hash: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut handshaker = HandShaker::<ClearNet, _, _, _>::new(
|
||||||
|
DummyAddressBook,
|
||||||
|
DummyCoreSyncSvc,
|
||||||
|
DummyPeerRequestHandlerSvc,
|
||||||
|
broadcast_tx,
|
||||||
|
our_basic_node_data,
|
||||||
|
);
|
||||||
|
|
||||||
|
let addr = "127.0.0.1:18081".parse().unwrap();
|
||||||
|
|
||||||
|
let mut listener = ClearNet::incoming_connection_listener(ClearNetServerCfg { addr })
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let _monerod = monerod(["--add-exclusive-node=127.0.0.1:18081"]).await;
|
||||||
|
|
||||||
|
// Put a timeout on this just in case monerod doesn't make the connection to us.
|
||||||
|
let next_connection_fut = timeout(Duration::from_secs(30), listener.next());
|
||||||
|
|
||||||
|
if let Some(Ok((addr, stream, sink))) = next_connection_fut.await.unwrap() {
|
||||||
|
let _ = handshaker
|
||||||
|
.ready()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.call(DoHandshakeRequest {
|
||||||
|
addr: InternalPeerID::KnownAddr(addr.unwrap()), // This is clear net all addresses are known.
|
||||||
|
peer_stream: stream,
|
||||||
|
peer_sink: sink,
|
||||||
|
direction: ConnectionDirection::InBound,
|
||||||
|
permit,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
panic!("Failed to receive connection from monerod.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ async-trait = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["full"] }
|
tokio = { workspace = true, features = ["full"] }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
bytes = { workspace = true, features = ["std"] }
|
bytes = { workspace = true, features = ["std"] }
|
||||||
|
tempfile = { workspace = true }
|
||||||
|
|
||||||
borsh = { workspace = true, features = ["derive"]}
|
borsh = { workspace = true, features = ["derive"]}
|
||||||
|
|
||||||
|
|
|
@ -34,16 +34,18 @@ pub async fn monerod<T: AsRef<OsStr>>(flags: impl IntoIterator<Item = T>) -> Spa
|
||||||
let p2p_port = get_available_port(&[rpc_port]);
|
let p2p_port = get_available_port(&[rpc_port]);
|
||||||
let zmq_port = get_available_port(&[rpc_port, p2p_port]);
|
let zmq_port = get_available_port(&[rpc_port, p2p_port]);
|
||||||
|
|
||||||
// TODO: set a random DB location
|
let data_dir = tempfile::tempdir().unwrap();
|
||||||
|
|
||||||
let mut monerod = Command::new(path_to_monerod)
|
let mut monerod = Command::new(path_to_monerod)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.args(flags)
|
.args(flags)
|
||||||
.arg("--regtest")
|
.arg("--regtest")
|
||||||
.arg("--log-level=2")
|
.arg("--log-level=2")
|
||||||
.arg(format!("--p2p-bind-port={}", p2p_port))
|
.arg(format!("--p2p-bind-port={p2p_port}"))
|
||||||
.arg(format!("--rpc-bind-port={}", rpc_port))
|
.arg(format!("--rpc-bind-port={rpc_port}"))
|
||||||
.arg(format!("--zmq-rpc-bind-port={}", zmq_port))
|
.arg(format!("--zmq-rpc-bind-port={zmq_port}"))
|
||||||
|
.arg(format!("--data-dir={}", data_dir.path().display()))
|
||||||
.arg("--non-interactive")
|
.arg("--non-interactive")
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -81,6 +83,7 @@ pub async fn monerod<T: AsRef<OsStr>>(flags: impl IntoIterator<Item = T>) -> Spa
|
||||||
process: monerod,
|
process: monerod,
|
||||||
rpc_port,
|
rpc_port,
|
||||||
p2p_port,
|
p2p_port,
|
||||||
|
_data_dir: data_dir,
|
||||||
start_up_logs: logs,
|
start_up_logs: logs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +111,9 @@ pub struct SpawnedMoneroD {
|
||||||
rpc_port: u16,
|
rpc_port: u16,
|
||||||
/// The P2P port of the monerod instance.
|
/// The P2P port of the monerod instance.
|
||||||
p2p_port: u16,
|
p2p_port: u16,
|
||||||
|
/// The data dir for monerod - when this is dropped the dir will be deleted.
|
||||||
|
_data_dir: tempfile::TempDir,
|
||||||
|
/// The logs upto [`MONEROD_STARTUP_TEXT`].
|
||||||
start_up_logs: String,
|
start_up_logs: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +131,10 @@ impl SpawnedMoneroD {
|
||||||
|
|
||||||
impl Drop for SpawnedMoneroD {
|
impl Drop for SpawnedMoneroD {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
let mut error = false;
|
||||||
|
|
||||||
if self.process.kill().is_err() {
|
if self.process.kill().is_err() {
|
||||||
|
error = true;
|
||||||
println!("Failed to kill monerod, process id: {}", self.process.id())
|
println!("Failed to kill monerod, process id: {}", self.process.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,5 +158,12 @@ impl Drop for SpawnedMoneroD {
|
||||||
println!("{}{out}", self.start_up_logs);
|
println!("{}{out}", self.start_up_logs);
|
||||||
println!("------END-MONEROD-LOGS------");
|
println!("------END-MONEROD-LOGS------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if error && !panicking() {
|
||||||
|
// `println` only outputs in a test when panicking so if there is an error while
|
||||||
|
// dropping monerod but not an error in the test then we need to panic to make sure
|
||||||
|
// the println!s are output.
|
||||||
|
panic!("Error while dropping monerod");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue