fix(core): ack only observations the store kept
Exchange::accept enqueued a pending ack whenever !(duplicate && addressed && released) held, even when the backend store.insert returned Err (store full / backend error). On Err the released flag computed to false, so an ack was still enqueued: a receiver that did not keep the message acked it. For an addressed offer that releases the sender's custody for a message nobody holds; for a broadcast it fires a false confidence event at the sender. Gate the ack enqueue on res.is_ok(): enqueue only when the store actually retained the observation. The existing released-holder exception still applies among kept copies. No bounce is recorded on Err (already the case). Adds a unit test exercising a capped store (StoreError::Full) for both a broadcast and an addressed offer, and a tines-sim property that drives custody with CappedStore-backed nodes and asserts the "at least one holder" invariant still holds when stores fill.
This commit is contained in:
+18
-3
@@ -19,15 +19,30 @@ use tines_core::{MemStore, Node, NodeId, ObservationId, Store};
|
||||
pub type SimNode = Node<MemStore, SimTransport>;
|
||||
|
||||
/// A run of the simulation, owned by the test.
|
||||
pub struct Sim {
|
||||
///
|
||||
/// Generic over the store backend `S` so tests can drive custody with a store
|
||||
/// that fills (see [`CappedStore`](crate::CappedStore)); the default is the
|
||||
/// unbounded [`MemStore`].
|
||||
pub struct Sim<S = MemStore>
|
||||
where
|
||||
S: Store,
|
||||
{
|
||||
pub world: Rc<RefCell<SimWorld>>,
|
||||
pub nodes: Vec<SimNode>,
|
||||
pub nodes: Vec<Node<S, SimTransport>>,
|
||||
pub t: u64,
|
||||
pub step_ms: u64,
|
||||
}
|
||||
|
||||
impl Sim {
|
||||
/// A run over `nodes` nodes, each with its own unbounded [`MemStore`].
|
||||
pub fn new(cfg: WorldConfig, trace: ContactTrace) -> Sim {
|
||||
Sim::with_store(cfg, trace)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Store + Default> Sim<S> {
|
||||
/// A run over `nodes` nodes, each given a fresh `S::default()` store.
|
||||
pub fn with_store(cfg: WorldConfig, trace: ContactTrace) -> Sim<S> {
|
||||
let n = cfg.nodes;
|
||||
let world = SimWorld::new(cfg, trace);
|
||||
let mut nodes = Vec::with_capacity(n);
|
||||
@@ -35,7 +50,7 @@ impl Sim {
|
||||
nodes.push(Node::new(
|
||||
[i as u8; 16],
|
||||
0,
|
||||
MemStore::new(),
|
||||
S::default(),
|
||||
SimTransport::new(world.clone(), i),
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user