pub struct InMemoryStateStore { /* private fields */ }Expand description
In-memory atomic single-use state store for boundary tests.
Atomicity guarantee: holds a tokio::sync::Mutex<HashMap>
across both put and take. A second take for the same key
— concurrent or sequential — returns None, regardless of
whether the first take happened in the same task or another.
This is the load-bearing CSRF / state-replay defense the
boundary tests exercise.
Optional fault injection: with_put_failure /
with_take_failure queue substrate-level errors for the next N
calls so tests can drive the
StartError::StateStore
/
CallbackError::StateStore
branches without standing up a fake substrate.
Implementations§
Source§impl InMemoryStateStore
impl InMemoryStateStore
pub fn new() -> Self
pub fn with_clock(self, clock: ArcClock) -> Self
Sourcepub async fn with_put_failure(self, err: StateStoreError) -> Self
pub async fn with_put_failure(self, err: StateStoreError) -> Self
Queue a put failure. The next call to put returns this
error; subsequent calls return queued failures in order, then
fall through to normal behavior.
Sourcepub async fn with_take_failure(self, err: StateStoreError) -> Self
pub async fn with_take_failure(self, err: StateStoreError) -> Self
Queue a take failure (same semantics as with_put_failure).
Trait Implementations§
Source§impl Default for InMemoryStateStore
impl Default for InMemoryStateStore
Source§impl StateStore for InMemoryStateStore
impl StateStore for InMemoryStateStore
Source§fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 State,
pending: PendingAuthRequest,
ttl: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), StateStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn put<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 State,
pending: PendingAuthRequest,
ttl: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), StateStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
pending under state with ttl. Substrate must
expire the entry server-side on TTL (no stale-state leakage). Read moreSource§fn take<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 State,
) -> Pin<Box<dyn Future<Output = Result<Option<PendingAuthRequest>, StateStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn take<'life0, 'life1, 'async_trait>(
&'life0 self,
state: &'life1 State,
) -> Pin<Box<dyn Future<Output = Result<Option<PendingAuthRequest>, StateStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
state. Returns
None if the entry never existed, was already consumed, or
expired. The three cases are intentionally indistinguishable
to the caller — they all map to
super::CallbackError::StateNotFoundOrConsumed.