From 06179a9df971636dd6c5e9f438baa9f133854830 Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 27 Oct 2026 02:02:15 +0100 Subject: add support for several transports --- src/simtest/identity.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'src/simtest/identity.rs') diff --git a/src/simtest/identity.rs b/src/simtest/identity.rs index a33783f..9859d0e 100644 --- a/src/simtest/identity.rs +++ b/src/simtest/identity.rs @@ -2,6 +2,7 @@ //! through addresses (seeds, HELLO_REPLYs, the member list), and believed only once a //! node proved itself at an address. +use std::sync::Arc; use std::time::Duration; use serde_json::json; @@ -12,7 +13,8 @@ use crate::state::AppState; use crate::swarm::bootstrap::Start; use crate::swarm::members; use crate::transport::identity::{WHO_LABEL, signed}; -use crate::transport::{HeadsSummary, IdentityProof, Keepalive, ParsedMessage}; +use crate::transport::sim::SimNet; +use crate::transport::{HeadsSummary, IdentityProof, Keepalive, ParsedMessage, Transport}; const SOON: Duration = Duration::from_secs(20); @@ -126,3 +128,45 @@ async fn a_proof_holds_only_at_its_address() { // Known by its node ID, not by its address. assert!(a.get_peer_state("ghost").await.is_none()); } + +/// A swarm across two transports: a only on the first, c only on the second, b on both. +/// a and c never reach each other, and still share everything through b. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn nodes_on_both_transports_carry_the_others() { + let sim = Sim::with_identity(54); + let second = SimNet::new(55); + let a = sim.start("a", &[], Start::Genesis); + let b = sim.start_with("b", &["a"], Start::Join, |config| { + let identity = config.identity.as_mut().unwrap(); + let transport: Arc = second.transport("b"); + identity.more.push(("other", transport)); + }); + let c = sim.start_with("c", &["other:b"], Start::Join, |config| { + config.transport = second.transport("c"); + config.identity.as_mut().unwrap().scheme = "other"; + }); + sim.wait_ready(&[&a, &b, &c], SOON).await; + assert_eq!(b.transport.local_addresses(), ["sim:b", "other:b"]); + + write(&c, "from/c", json!("c")).await; + write(&a, "from/a", json!("a")).await; + sim.wait_converged(&[&a, &b, &c], SOON).await; + assert_eq!(read(&a, "from/c").await, Some(json!("c"))); + assert_eq!(read(&c, "from/a").await, Some(json!("a"))); + + // The member list says where c is, on a transport a doesn't have. + let c_id = c.local_id().to_owned(); + let a_ref = &a; + sim.wait_until("a knows c's entry", SOON, move || { + let c_id = c_id.clone(); + async move { + let replica = a_ref.doc.read().await; + members::addresses(&replica.doc, &c_id) == ["other:c"] + } + }) + .await; + assert!(!a.transport.can_reach(c.local_id())); + assert!(!c.transport.can_reach(a.local_id())); + assert!(a.transport.can_reach(b.local_id())); + assert!(c.transport.can_reach(b.local_id())); +} -- cgit v1.3.1