summaryrefslogtreecommitdiffstats
path: root/src/simtest/identity.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/simtest/identity.rs')
-rw-r--r--src/simtest/identity.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/simtest/identity.rs b/src/simtest/identity.rs
index 9859d0e..6f468a3 100644
--- a/src/simtest/identity.rs
+++ b/src/simtest/identity.rs
@@ -170,3 +170,74 @@ async fn nodes_on_both_transports_carry_the_others() {
assert!(a.transport.can_reach(b.local_id()));
assert!(c.transport.can_reach(b.local_id()));
}
+
+/// Whole nodes over libp2p's in-memory transport, under the identity layer: seeds are
+/// multiaddrs, and members find each other's listen addresses in the member list.
+#[cfg(feature = "libp2p")]
+#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
+async fn nodes_over_libp2p() {
+ use crate::transport::p2p::{Libp2pConfig, Libp2pTransport};
+ use ::libp2p::identity::Keypair;
+ use sha2::Digest;
+
+ fn key(id: &str) -> Keypair {
+ let mut seed: [u8; 32] = sha2::Sha256::digest(format!("libp2p {id}").as_bytes()).into();
+ Keypair::ed25519_from_bytes(&mut seed).unwrap()
+ }
+ // Memory ports are process-wide; these are this test's.
+ let address = |id: &str| -> ::libp2p::Multiaddr {
+ let port = 50_000 + u64::from(id.as_bytes()[0]);
+ format!("/memory/{port}").parse().unwrap()
+ };
+ let on_libp2p = |id: &'static str| {
+ move |config: &mut crate::node::NodeConfig| {
+ let transport = Libp2pTransport::start(Libp2pConfig {
+ key: key(id),
+ listen: vec![address(id)],
+ memory: true,
+ })
+ .unwrap();
+ config.transport = Arc::new(transport);
+ config.identity.as_mut().unwrap().scheme = "libp2p";
+ }
+ };
+ let a_peer = key("a").public().to_peer_id();
+ let seed = format!("libp2p:{}", address("a").with_p2p(a_peer).unwrap());
+
+ let sim = Sim::with_identity(56);
+ let a = sim.start_with("a", &[], Start::Genesis, on_libp2p("a"));
+ let others: Vec<AppState> = ["b", "c", "d"]
+ .into_iter()
+ .map(|id| sim.start_with(id, &[seed.as_str()], Start::Join, on_libp2p(id)))
+ .collect();
+ let mut all: Vec<&AppState> = vec![&a];
+ all.extend(others.iter());
+ sim.wait_ready(&all, SOON).await;
+
+ write(&others[2], "from/d", json!("d")).await;
+ sim.wait_converged(&all, SOON).await;
+ for node in &all {
+ assert_eq!(read(node, "from/d").await, Some(json!("d")));
+ peers_are_node_ids(node).await;
+ }
+ let d_id = others[2].local_id().to_owned();
+ let expected = format!(
+ "libp2p:{}",
+ address("d")
+ .with_p2p(key("d").public().to_peer_id())
+ .unwrap()
+ );
+ let a = &a;
+ sim.wait_until(
+ "d's listen address is in the member list",
+ SOON,
+ move || {
+ let (d_id, expected) = (d_id.clone(), expected.clone());
+ async move {
+ let replica = a.doc.read().await;
+ members::addresses(&replica.doc, &d_id) == [expected]
+ }
+ },
+ )
+ .await;
+}