From a0dcc0ad89565985ee5b95741ca418db02fcce3b Mon Sep 17 00:00:00 2001 From: "K. Isom" Date: Wed, 21 Oct 2026 23:01:56 -0700 Subject: [PATCH] test(fuzz): measure the recovery probe from the latest tick Fuzz steps can move the clock backwards, while a peer's idle time counts from its last frame, so advancing from the current tick could stay short of the idle window. Track the latest tick and probe from it; skip the probe when the tick is too close to u64::MAX to advance. A 5-minute nightly run (84k inputs) is clean after the fix. Co-Authored-By: Claude Opus 5.5 --- fuzz/src/lib.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index f570df1b..d4c181d2 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -318,6 +318,9 @@ pub struct Harness { mtu: usize, q: Rc, now: Tick, + /// The latest tick the node has been given. Steps can move `now` + /// backwards, but the node's idle clock counts from the latest tick. + max_now: Tick, peers: BTreeMap, /// Drops counted in the overflow slot (`addr: None`). overflow_drops: u64, @@ -350,6 +353,7 @@ impl Harness { mtu, q, now: 0, + max_now: 0, peers: BTreeMap::new(), overflow_drops: 0, stored: BTreeMap::new(), @@ -511,6 +515,7 @@ impl Harness { } else { self.now.saturating_sub(delta.unsigned_abs()) }; + self.max_now = self.max_now.max(self.now); } Step::Ourselves { size } => { let payload = vec![0x5A; *size as usize % (MAX_PAYLOAD + 1)]; @@ -773,7 +778,16 @@ impl Harness { /// every peer, a frame from a never-seen address still gets a slot, so /// the node stores the observation it carries. pub fn check_peer_table_recovers(&mut self) { - self.now = self.now.saturating_add(conformance::PEER_IDLE_MS + 1); + // Idle time counts from each peer's last frame, so measure from the + // latest tick, not the current one (a step may have moved `now` + // backwards; ages saturate rather than go negative). Ticks this close + // to u64::MAX can't advance by PEER_IDLE_MS, so there's nothing to + // probe. + let Some(now) = self.max_now.checked_add(conformance::PEER_IDLE_MS + 1) else { + return; + }; + self.now = now; + self.max_now = now; self.pump(); let addr = Addr::MAX; let obs = Observation::broadcast([0xEE; 16], u64::MAX, b"recovery", b"probe");