diff options
| author | tv <tv@krebsco.de> | 2026-10-26 05:54:53 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-26 05:54:53 +0100 |
| commit | 0b13e180c4dcd38e3ea8ffeecc9e5ebefa023212 (patch) | |
| tree | 7ab995f1a8d6aed9365bd6eed5fe2625fd56324e /src/simtest/timing.rs | |
| parent | f00378e8609e0117132d7aab3f4468a1721f52fa (diff) | |
number handshakes
This prevents late hellos from resetting the session.
Diffstat (limited to 'src/simtest/timing.rs')
| -rw-r--r-- | src/simtest/timing.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/simtest/timing.rs b/src/simtest/timing.rs index e4981dd..4247090 100644 --- a/src/simtest/timing.rs +++ b/src/simtest/timing.rs @@ -239,6 +239,53 @@ async fn is_dormant(node: &AppState, other: &str) -> bool { == Some(true) } +/// R27: a resent HELLO (its reply was lost) or a late copy of one doesn't reset the +/// session it opened; only a new handshake does. +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn resent_hello_keeps_the_session() { + let sim = Sim::new(8); + let a = sim.start("a", &[], Start::Genesis); + let b = sim.start("b", &["a"], Start::Join); + let (a, b) = (&a, &b); + sim.wait_ready(&[a, b], SOON).await; + write(a, "data", json!(1)).await; + sim.wait_converged(&[a, b], SOON).await; + let opened = move || async move { peer(a, "b", |p| p.sync.has_opened()).await == Some(true) }; + sim.wait_until("a has heard b's heads", SOON, opened).await; + + let (run, handshake) = peer(a, "b", |p| p.last_hello).await.unwrap().unwrap(); + assert_eq!(run, b.run_id); + let (epoch, epoch_seq) = b.epoch_stamp().await; + let swarm_id = b.swarm_id().await; + let hello = |handshake| { + ParsedMessage::Hello(HelloRequest { + swarm_id: swarm_id.clone(), + epoch, + epoch_seq, + auth: Vec::new(), + ready: true, + run_id: run, + handshake, + }) + }; + for repeated in [handshake, handshake.saturating_sub(1)] { + sim.net.inject("b", "a", &hello(repeated)).await.unwrap(); + assert!(opened().await, "HELLO {repeated} reset the session"); + assert_eq!( + peer(a, "b", |p| p.last_hello).await.unwrap(), + Some((run, handshake)) + ); + } + sim.net + .inject("b", "a", &hello(handshake + 1)) + .await + .unwrap(); + assert_eq!( + peer(a, "b", |p| p.last_hello).await.unwrap(), + Some((run, handshake + 1)) + ); +} + /// R17: a message sent before the peer's last epoch change and delivered late doesn't /// flip the epoch we recorded for it back; a new run of the peer starts its count over. /// The peer is a "ghost" whose messages are injected, so their order is the test's. @@ -261,6 +308,7 @@ async fn late_epoch_does_not_flip_a_peers_epoch() { auth: Vec::new(), ready: true, run_id: run, + handshake: 1, }) }; let ping = |epoch: Epoch, epoch_seq: u32| { |
