diff options
| author | tv <tv@krebsco.de> | 2026-11-01 19:48:07 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-01 19:48:07 +0100 |
| commit | d5bac903cf181b2f1ace38ae330bb0a286d26da3 (patch) | |
| tree | f6534d3ad3505e117660e3da2e93dc522aa02ada | |
| parent | 78f67ee4dba0fdcd2ad6d91b5d46844284cf2d87 (diff) | |
alive stamps too much in the future are ignored
| -rw-r--r-- | src/swarm/members.rs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/swarm/members.rs b/src/swarm/members.rs index 59c7571..05c6501 100644 --- a/src/swarm/members.rs +++ b/src/swarm/members.rs @@ -216,12 +216,15 @@ pub(crate) fn alive_at(doc: &impl ReadDoc, pk: &str) -> Option<u64> { } /// The members that said they are alive within `window` before `now_ms` (sorted): the -/// electorate of a remake (`remake::coordinator`). +/// electorate of a remake (`remake::coordinator`). A stamp further in the future than a +/// renewal interval (`alive_renewal`) doesn't count: its node's clock is that far ahead +/// (it warns about it, `swarm::skew`), and the stamp would never age out. pub(crate) fn electorate(doc: &impl ReadDoc, now_ms: u64, window: Duration) -> Vec<String> { let oldest = now_ms.saturating_sub(window.as_millis() as u64); + let newest = now_ms.saturating_add(alive_renewal(window).as_millis() as u64); members(doc) .into_iter() - .filter(|pk| alive_at(doc, pk).is_some_and(|at| at >= oldest)) + .filter(|pk| alive_at(doc, pk).is_some_and(|at| (oldest..=newest).contains(&at))) .collect() } @@ -389,6 +392,9 @@ mod tests { ("stale", json!({ "since": 1, "alive": now - 8 * day })), ("new", json!({ "since": now - day })), ("old", json!({ "since": 1 })), + // A clock a day ahead is tolerated (one renewal interval); a week isn't. + ("ahead", json!({ "since": 1, "alive": now + day })), + ("future", json!({ "since": 1, "alive": now + 7 * day })), ]; change(&mut doc, |doc| { for (pk, entry) in entries { @@ -397,7 +403,7 @@ mod tests { }); assert_eq!( electorate(&doc, now, Duration::from_secs(7 * 24 * 3600)), - ["fresh", "new"] + ["ahead", "fresh", "new"] ); } |
