refactor(core): WallClockStore trait replaces the store_mut backdoor
Task 10b reached LogStore::set_wall_clock through a general Node::store_mut. Kyle: replace it with a narrower accessor. A WallClockStore trait (set_wall_clock + peer_time_estimate, implemented only by LogStore) now backs Node::set_wall_clock and Node::peer_time_estimate, so no &mut Store escapes the facade.
This commit is contained in:
@@ -25,7 +25,7 @@ pub use node::{Node, ObserveError};
|
||||
pub use observation::{
|
||||
Dest, NodeId, Observation, ObservationId, Payload, SigAlgo, Signature, Tick, Topic,
|
||||
};
|
||||
pub use store::{Store, StoreError, TrimPolicy};
|
||||
pub use store::{Store, StoreError, TrimPolicy, WallClockStore};
|
||||
pub use transport::{Event, FrameBuf, SendError, Transport};
|
||||
pub use wire::{frame_sender, Frame, WireError};
|
||||
|
||||
|
||||
+17
-8
@@ -12,7 +12,7 @@
|
||||
|
||||
use crate::{
|
||||
consts, exchange::Exchange, BeliefPolicy, Dest, NodeEvent, NodeId, Observation, ObservationId,
|
||||
Payload, Store, StoreError, Tick, Topic, Transport, TrimPolicy,
|
||||
Payload, Store, StoreError, Tick, Topic, Transport, TrimPolicy, WallClockStore,
|
||||
};
|
||||
|
||||
/// Errors returned by [`Node::observe`].
|
||||
@@ -219,13 +219,22 @@ impl<S: Store, T: Transport> Node<S, T> {
|
||||
&self.store
|
||||
}
|
||||
|
||||
/// Mutable access to the backing store.
|
||||
///
|
||||
/// Used by the host for the trusted-time state machine — peer-observation
|
||||
/// time estimation (`LogStore::peer_time_estimate`) and, once trusted,
|
||||
/// anchoring the wall clock (`LogStore::set_wall_clock`).
|
||||
pub fn store_mut(&mut self) -> &mut S {
|
||||
&mut self.store
|
||||
/// Lift the quarantine on held observations once the host has trusted wall
|
||||
/// time, by folding the wall clock into a [`WallClockStore`] backend.
|
||||
pub fn set_wall_clock(&mut self, wall_now: u64, now: Tick) -> <S as WallClockStore>::FoldReport
|
||||
where
|
||||
S: WallClockStore,
|
||||
{
|
||||
self.store.set_wall_clock(wall_now, now)
|
||||
}
|
||||
|
||||
/// Best estimate of trusted wall time from a peer's observation, if the
|
||||
/// backend supports it (see [`WallClockStore`]).
|
||||
pub fn peer_time_estimate(&self, now: Tick) -> Option<u64>
|
||||
where
|
||||
S: WallClockStore,
|
||||
{
|
||||
self.store.peer_time_estimate(now)
|
||||
}
|
||||
|
||||
/// Best-effort durability flush, advancing each stored observation's age
|
||||
|
||||
@@ -127,3 +127,25 @@ pub trait Store {
|
||||
pub(crate) fn current_age(obs: &Observation, stored_at: Tick, now: Tick) -> u64 {
|
||||
obs.age_ms.saturating_add(now.saturating_sub(stored_at))
|
||||
}
|
||||
|
||||
/// A [`Store`] that a host can feed trusted wall-clock time into.
|
||||
///
|
||||
/// tines-core itself never deals with wall time — this trait is a host-facing
|
||||
/// hook so a host can lift the quarantine on observations held across a
|
||||
/// power-off, and estimate trusted time from a peer's observation, without a
|
||||
/// general `&mut Store` backdoor (decision F in the spec). Only backends that
|
||||
/// support a wall-clock fold implement it; `MemStore` and other pure-tick
|
||||
/// stores do not.
|
||||
pub trait WallClockStore: Store {
|
||||
/// Summary of a wall-clock fold, for the host's logs.
|
||||
type FoldReport;
|
||||
|
||||
/// Fold trusted wall time into the store, lifting the quarantine on held
|
||||
/// observations. The host calls this exactly once, on the first trusted
|
||||
/// time.
|
||||
fn set_wall_clock(&mut self, wall_now: u64, now: Tick) -> Self::FoldReport;
|
||||
|
||||
/// Best estimate of trusted wall time from a peer's observation stored
|
||||
/// since the last open, if any. `None` means stay quarantined.
|
||||
fn peer_time_estimate(&self, now: Tick) -> Option<u64>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user