From 0039ffe04d290935936d33e681c2a0f2575c4264 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 25 Oct 2026 23:50:29 +0100 Subject: refresh peers after stall --- src/simtest/timing.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/simtest') diff --git a/src/simtest/timing.rs b/src/simtest/timing.rs index 25ecf89..e4981dd 100644 --- a/src/simtest/timing.rs +++ b/src/simtest/timing.rs @@ -146,6 +146,44 @@ async fn stalled_catch_up_source_is_replaced() { assert!(sources >= 2, "{sources} catch-up sources"); } +/// A joining node whose only known peer stalls as its catch-up source asks it again +/// (a fresh HELLO): the reply lists the peers that joined meanwhile, and one of them +/// takes over. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn stalled_source_refreshes_the_peer_list() { + let sim = Sim::new(7); + let a = sim.start("a", &[], Start::Genesis); + let a = &a; + sim.wait_ready(&[a], SOON).await; + write(a, "data", json!("x")).await; + + // c knows only a, which lists nobody: there is nobody else yet. + sim.net.set_link( + "a", + "c", + LinkParams { + drop: vec![MessageKind::Sync], + ..LinkParams::default() + }, + ); + let c = sim.start("c", &["a"], Start::Join); + let c = &c; + sim.wait_until("c knows a", SOON, move || async move { + c.get_peer_state("a").await.is_some() + }) + .await; + + // b joins meanwhile; c hears of it only by asking a again (after giving it up, or + // earlier if the keepalive heal re-handshakes first). + let b = sim.start("b", &["a"], Start::Join); + let b = &b; + sim.wait_ready(&[b], SOON).await; + + sim.wait_ready(&[c], LOSSY).await; + assert_eq!(read(c, "data").await, Some(json!("x"))); + assert!(c.get_peer_state("b").await.is_some()); +} + /// A peer that hears nothing for `dormant_after` is dormant; once messages flow again /// it is active, re-handshakes, and syncs what it missed. #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -- cgit v1.3.1