pub trait ProtocolStateStorage: Send + Sync {
// Required methods
fn store(
&self,
key_type: &str,
key_id: &str,
data: &[u8],
) -> ProtocolStateResult<()>;
fn load(
&self,
key_type: &str,
key_id: &str,
) -> ProtocolStateResult<Option<Vec<u8>>>;
fn delete(&self, key_type: &str, key_id: &str) -> ProtocolStateResult<()>;
fn list_keys(&self, key_type: &str) -> ProtocolStateResult<Vec<String>>;
}Expand description
Storage for restartable protocol and message-plane state.
Implementations must be app-container scoped and must not use a credential
store whose lifetime can exceed the app container. The operations retain
the atomicity and durability contract defined by
offline_protocol_mls::MlsStorage, but this
trait deliberately does not inherit from the crypto-storage contract:
lifecycle separation should be structural, not a marker on the wrong
abstraction.
Values for sensitive categories arrive already sealed (see the module docs), so an implementation must store and return the bytes it is given verbatim — it must not inspect, re-encode, or truncate them.
Required Methods§
Sourcefn store(
&self,
key_type: &str,
key_id: &str,
data: &[u8],
) -> ProtocolStateResult<()>
fn store( &self, key_type: &str, key_id: &str, data: &[u8], ) -> ProtocolStateResult<()>
Atomically stores or replaces one protocol-state entry.
Implementations may refuse a value over
MAX_PROTOCOL_STATE_RECORD_TRANSFER_BYTES; core never sends one.
Sourcefn load(
&self,
key_type: &str,
key_id: &str,
) -> ProtocolStateResult<Option<Vec<u8>>>
fn load( &self, key_type: &str, key_id: &str, ) -> ProtocolStateResult<Option<Vec<u8>>>
Loads one protocol-state entry, returning None when absent.
Implementations must bound the read. Check the stored entry’s size
before materializing it and never return — or allocate — more than
MAX_PROTOCOL_STATE_RECORD_TRANSFER_BYTES. An entry above the ceiling
is corrupt or tampered by construction; drop it and report
ProtocolStateError::Corrupted, which is what lets core settle the
message ids the application is still holding for it. Returning the
oversized value instead defeats the size policy, because core can only
check a length it has already been handed.
The same applies to a record whose framing does not parse. Reserve
Corrupted for losses that are permanent — anything transient belongs
in ProtocolStateError::LoadFailed, which core leaves in place to
retry.
Sourcefn delete(&self, key_type: &str, key_id: &str) -> ProtocolStateResult<()>
fn delete(&self, key_type: &str, key_id: &str) -> ProtocolStateResult<()>
Deletes one protocol-state entry and succeeds when it is already absent.
Sourcefn list_keys(&self, key_type: &str) -> ProtocolStateResult<Vec<String>>
fn list_keys(&self, key_type: &str) -> ProtocolStateResult<Vec<String>>
Lists entry IDs within one protocol-state category.
Like Self::load, enumeration should stay bounded: core caps every
category well below any sane ceiling, so a store holding vastly more
has been tampered with and an implementation may stop early.
An empty category is Ok(vec![]). A backend that can only spell it as
ProtocolStateError::NotFound is read the same way, so honoring that
contract does not fail restore.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".