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.
This commit is contained in:
Johnathan Corgan
2026-08-15 13:49:38 +00:00
parent 40f4b8e5ac
commit efd3c208c5
+19
View File
@@ -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();