From efd3c208c5e77e7a70e4d26d4cc634b59489e6a3 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Sat, 15 Aug 2026 13:49:38 +0000 Subject: [PATCH] Pin the rekey expiry condition against the pending flag in the core The abandon arm keys on an in-flight handshake, and a completed pending epoch beside an aged peer stamp must not be read as one: widening the condition to either flag discards the epoch the peer has already moved to. Widening it left every test in the sans-IO core green, so the property had no core-level pin. The behaviour was already caught one layer up, at the tick loop, but only through the node harness. Named and shaped to match the equivalent test the next branch already carries, so the two merge as a no-op rather than as an add/add conflict. --- src/proto/fsp/tests/core.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/proto/fsp/tests/core.rs b/src/proto/fsp/tests/core.rs index 6fee745e..f23d8ea7 100644 --- a/src/proto/fsp/tests/core.rs +++ b/src/proto/fsp/tests/core.rs @@ -276,6 +276,25 @@ fn poll_rekey_does_not_abandon_a_fresh_or_locally_initiated_handshake() { assert!(fsp.poll_rekey(vec![none], &cfg(100, 1000)).is_empty()); } +#[test] +fn poll_rekey_expiry_reads_the_handshake_flag_and_never_the_pending_flag() { + let fsp = Fsp::new(); + // A completed rekey waiting for its cutover, with an expired peer stamp + // and no handshake beside it. `has_pending` must not stand in for + // `rekey_in_progress` here: widening the condition to either flag would + // discard the epoch the peer has already moved to. The other two arms of + // this snapshot are quiet, so an empty result can only mean the abandon + // arm declined. + let mut s = session_snapshot(11); + s.has_pending = true; + s.rekey_in_progress = false; + s.armed_handshake_expired = true; + assert!( + fsp.poll_rekey(vec![s], &cfg(100, 1000)).is_empty(), + "a pending session with no armed handshake is not an expiring handshake" + ); +} + #[test] fn poll_rekey_groups_abandons_between_the_drains_and_the_rekeys() { let fsp = Fsp::new();