From c12ce1a67e387474d17419bb252211bf04b2e443 Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 3 Nov 2026 01:19:05 +0100 Subject: always announce new heads --- src/simtest/relay.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src/simtest') diff --git a/src/simtest/relay.rs b/src/simtest/relay.rs index 9b016b8..dadeed3 100644 --- a/src/simtest/relay.rs +++ b/src/simtest/relay.rs @@ -64,3 +64,56 @@ async fn changes_reach_members_the_writer_cant_reach_at_once() { .await; } } + +/// One transport, a full mesh by the member list, but the writer x reaches b alone (as +/// one behind NAT may): what x writes reaches c through b, at once, though the member +/// list makes c x's neighbour too. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn changes_reach_members_the_writer_fails_to_reach_at_once() { + let keepalive = Duration::from_secs(5); + let slow = move |config: &mut crate::node::NodeConfig| { + config.timing = Timing::new(keepalive, SYNC_REPLY_TIMEOUT, DELIVERY_LIMIT); + }; + let sim = Sim::with_identity(63); + // Nothing between x and c, either way. + let cut = crate::transport::sim::LinkParams { + loss: 1.0, + ..Default::default() + }; + sim.net.set_link("x", "c", cut.clone()); + sim.net.set_link("c", "x", cut); + let b = sim.start_on_with("b", &["sim"], &[], Start::Genesis, slow); + let c = sim.start_on_with("c", &["sim"], &["b"], Start::Join, slow); + let x = sim.start_on_with("x", &["sim"], &["b"], Start::Join, slow); + sim.wait_ready(&[&b, &c, &x], SOON).await; + let (c_id, x_id) = (c.local_id().to_owned(), x.local_id().to_owned()); + { + let (b, c_id, x_id) = (&b, c_id.clone(), x_id.clone()); + sim.wait_until( + "b knows its neighbours, a full mesh, x and c among them", + SOON, + move || { + let (c_id, x_id) = (c_id.clone(), x_id.clone()); + async move { + topology::view_known(b) + && topology::is_full_mesh(b) + && topology::is_neighbour(b, &c_id) + && topology::is_neighbour(b, &x_id) + } + }, + ) + .await; + } + sim.wait_converged(&[&b, &c, &x], SOON).await; + + write(&x, "y", json!(1)).await; + { + let c = &c; + sim.wait_until( + "c has x's write within a second", + Duration::from_secs(1), + move || async move { read(c, "y").await == Some(json!(1)) }, + ) + .await; + } +} -- cgit v1.3.1