Skip to main content

PoolStateStore

Trait PoolStateStore 

Source
pub trait PoolStateStore: Send + Sync {
    // Required methods
    fn load_all(&self) -> Result<Vec<LaneState>, StoreError>;
    fn record(&self, state: &LaneState) -> Result<(), StoreError>;
    fn forget(&self, key: LaneKey) -> Result<(), StoreError>;
    fn get(&self, key: LaneKey) -> Result<Option<LaneState>, StoreError>;

    // Provided methods
    fn flush(&self) -> Result<(), StoreError> { ... }
    fn set_registered_until(
        &self,
        key: LaneKey,
        registered_until: u64,
    ) -> Result<(), StoreError> { ... }
    fn set_paid_cumulative(
        &self,
        key: LaneKey,
        paid_cumulative: U256,
    ) -> Result<(), StoreError> { ... }
}
Expand description

Durable backing store for LaneState, keyed by LaneKey.

The trait is intentionally synchronous. record and forget mutate a working set and MAY defer durability to flush; an implementation is equally free to commit inside record instead, so the cost of any one call is the implementation’s to document. A caller on a Tokio runtime therefore decides per implementation what to run from tokio::task::spawn_blocking: against the runtime’s redb store, record and forget are map writes cheap enough to call inline, and flush is the one that fsyncs.

Required Methods§

Source

fn load_all(&self) -> Result<Vec<LaneState>, StoreError>

Load every persisted lane. Called once during node bring-up so the runtime can hydrate its in-memory map before the voucher-accepting handler starts.

§Errors

Returns a StoreError if the backing store is unreadable or contains corrupt entries.

Source

fn record(&self, state: &LaneState) -> Result<(), StoreError>

Record the post-acceptance state for one lane in the store’s working set. A disk-backed store MAY buffer this in memory and make it durable later via flush; it is not required to fsync before returning Ok. Frontier state is safe to lose on a crash (an honest client resumes forward; an un-redeemed replay is still on-chain-payable).

Implementations MUST NOT block: this is called inline on the per-stream open path, on a runtime worker, with no timeout around it. An implementation that does I/O here stalls a worker for the duration and the latency is attributed nowhere.

Callers MUST pass a LaneState whose last_* tuple is a non-strict monotonic successor of any previously-recorded state for the same LaneKey. The trait does not re-validate this — LaneState::apply_voucher is the canonical caller and enforces monotonicity upstream.

§Errors

Returns a StoreError if the write fails. Callers MUST NOT advance their in-memory state on failure.

Source

fn forget(&self, key: LaneKey) -> Result<(), StoreError>

Drop the persisted entry for a settled lane. A no-op if the lane has no record.

A disk-backed store MAY buffer the removal and apply it on the next flush; it is not required to fsync before returning Ok.

§Errors

Returns a StoreError if the underlying delete fails.

Source

fn get(&self, key: LaneKey) -> Result<Option<LaneState>, StoreError>

Point-lookup the persisted state for one lane, or None if no record exists. Used by the on-chain seller redemption path to read the latest accepted voucher (last_amount / last_bytes_delivered / last_signature) when deciding whether an accrued claim crosses the redemption threshold — always the freshest committed voucher.

§Errors

Returns a StoreError if the backing store is unreadable or the record is corrupt.

Provided Methods§

Source

fn flush(&self) -> Result<(), StoreError>

Force all buffered lane state durable (fsync, for disk-backed impls).

The default is a no-op: a volatile store (MemoryPoolStateStore) holds nothing to flush, and a store that commits inside record has nothing buffered. A disk-backed implementation MAY override this to buffer record and forget in memory and make them durable here in one fsynced transaction.

§Errors

Returns a StoreError if the durable write fails.

Source

fn set_registered_until( &self, key: LaneKey, registered_until: u64, ) -> Result<(), StoreError>

Raise this lane’s observed on-chain registration expiry (LaneState::registered_until) to registered_until, monotonically — a lower or equal value is a no-op, and 0 (unknown) never lowers a known value. Touches ONLY that field, never the replay-critical last_* tuple, so the seller redeemer can record a fresh registration without racing a concurrent voucher advance into a lost update. A no-op for a lane with no record. Buffered like record; durability is the next flush’s job.

§Errors

Returns a StoreError if the backing store is unwritable.

Source

fn set_paid_cumulative( &self, key: LaneKey, paid_cumulative: U256, ) -> Result<(), StoreError>

Raise this lane’s paid cumulative (LaneState::paid_cumulative) to paid_cumulative, monotonically — a lower or equal value is a no-op. Touches ONLY that field, never the replay-critical last_* tuple, so the seller PoolRedeemed watcher can record an observed redemption without racing a concurrent voucher advance into a lost update. A no-op for a lane with no record. Buffered like record; durability is the next flush’s job. Persisting it is what stops a restarted node from forgetting prior redemptions and re-submitting already-redeemed lanes (#2052).

§Errors

Returns a StoreError if the backing store is unwritable.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§