fix(store): peer estimates outside a plausible wall range don't count

Spec §9 decision J: an estimate outside the plausibility bounds doesn't
count. A max-based peer_time_estimate always returned a forged
observed_at = u64::MAX, which the host then rejected, so it never saw
the honest estimates and stayed quarantined.

LogStoreBuilder::plausible_wall_ms(floor..=ceiling) sets the range
(default unbounded, so behaviour is unchanged when unset), and
peer_time_estimate filters candidates against it before taking the
max. The WallClockStore signature is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 08:44:09 -07:00
co-authored by Claude Opus 5.5
parent 01db6c0b71
commit 15bbdbd4a0
2 changed files with 66 additions and 4 deletions
+35
View File
@@ -1298,6 +1298,41 @@ mod snapshots_and_flush {
assert_eq!(s.peer_time_estimate(200), Some(u64::MAX));
}
/// Decision J / B3: an estimate outside the plausible range doesn't count,
/// so a forged `observed_at = u64::MAX` can't hide the honest estimates.
#[test]
fn implausible_peer_time_does_not_count() {
const FLOOR: u64 = 1_767_225_600_000; // 2026-01-01Z
const CEILING: u64 = FLOOR + 36_525 * 86_400_000;
let path = store_path("j_plausible");
let mut s = LogStore::builder(&path)
.plausible_wall_ms(FLOOR..=CEILING)
.open(0)
.unwrap();
s.insert(obs([1; 16], 1, 0, Some(u64::MAX)), 0).unwrap();
assert_eq!(
s.peer_time_estimate(0),
None,
"the forgery alone counts for nothing"
);
s.insert(obs([2; 16], 1, 0, Some(FLOOR - 1)), 0).unwrap();
assert_eq!(
s.peer_time_estimate(0),
None,
"below the floor doesn't count"
);
s.insert(obs([3; 16], 1, 100, Some(FLOOR + 5_000)), 0)
.unwrap();
assert_eq!(s.peer_time_estimate(50), Some(FLOOR + 5_150));
drop(s);
// Unset, the range is unbounded: the forgery wins, saturated.
let path = store_path("j_unbounded");
let mut s = LogStore::builder(&path).open(0).unwrap();
s.insert(obs([1; 16], 1, 0, Some(u64::MAX)), 0).unwrap();
assert_eq!(s.peer_time_estimate(0), Some(u64::MAX));
}
/// Decision L: quarantined entries are exempt from every trim rule, not
/// just the age trim.
#[test]