Skip to main content

Store

Struct Store 

Source
pub struct Store<C: RecordCodec> { /* private fields */ }
Expand description

The in-memory working set: every mutable piece of state mail4agent-messenger’s core needs across a process lifetime, plus the FlushGate that turns mutations into sealed records a shell persists. Generic over the RecordCodec used to seal/open every record — see the module doc’s “Sealing is a codec, not a concrete algorithm” section.

Implementations§

Source§

impl<C: RecordCodec> Store<C>

Source

pub fn new(device_id: DeviceId, codec: C) -> Self

Builds an empty working set for device_id, backed by codec for every future flush export. Nothing is dirty yet — this is the brand-new-device case (plan §4.1’s first unlock); a shell that already has records from an earlier session calls Store::load instead.

Source

pub fn load( records: impl IntoIterator<Item = SealedRecord>, codec: C, device_id: DeviceId, ) -> Result<Self, StoreError>

Rebuilds a working set from sealed records a shell read back from durable storage (plan decision #3’s MessengerCore::open). See the module doc’s “Forward compatibility” section for what happens to a key this version of the store does not recognize, and this type’s own doc for what a recognized-but-malformed or a recognized-but-uninterpretable key does.

Source

pub fn take_flush_batch(&mut self) -> Option<FlushBatch>

Drains everything dirtied since the previous call into one FlushBatch for a shell to write durably — see FlushGate::take_batch.

Source

pub fn ack_flush(&mut self, id: u64)

Acknowledges that batch id has been durably written — see FlushGate::ack.

Trait Implementations§

Source§

impl<C: RecordCodec> CryptoStore for Store<C>

Source§

fn account(&self) -> Result<Option<&[u8]>, StoreError>

The pickled Olm account, if one has been created yet.
Source§

fn save_account(&mut self, account: Vec<u8>) -> Result<(), StoreError>

Persists the pickled Olm account, replacing any earlier one.
Source§

fn olm_sessions_for_device( &self, their_curve25519: &str, ) -> Result<Vec<Vec<u8>>, StoreError>

Every pickled Olm session this store currently has for their_curve25519, ordered MOST-recently-used first (see Store::save_olm_session’s own doc for what “used” means here). At most [MAX_OLM_SESSIONS_PER_DEVICE] entries – older, less recently used sessions are evicted, never accumulated. Empty (never an error) if none exist yet.
Source§

fn save_olm_session( &mut self, their_curve25519: &str, session_id: &str, session: Vec<u8>, ) -> Result<(), StoreError>

Persists the pickled Olm session identified by session_id, REPLACING any earlier record for the same (their_curve25519, session_id) pair and marking it the most-recently-used session for that peer. This is a hard requirement, not an optimization: an Olm session’s own pickle is its FULL ratchet state, including every chain/message key it has ever derived and not yet forgotten. Keeping an older snapshot of the SAME session_id around after a newer one has been saved would mean an already-consumed message key survives on disk somewhere the newer snapshot itself no longer has it – exactly the forward-secrecy property Olm’s ratchet exists to provide, and exactly the kind of stale state a decrypt path must never be able to resurrect to replay an already-decrypted message. A caller with a genuinely different session for the same peer (e.g. two independently-established sessions from a real Olm race) passes a different session_id and gets a second, independent slot – up to [MAX_OLM_SESSIONS_PER_DEVICE] per peer; saving beyond that evicts the least-recently-used one (its record is deleted, riding in the same flush batch as this save).
Source§

fn inbound_group_session( &self, room_id: &RoomId, session_id: &str, ) -> Result<Option<&[u8]>, StoreError>

The pickled inbound Megolm session for (room_id, session_id), if this device has ever received one.
Source§

fn save_inbound_group_session( &mut self, room_id: &RoomId, session_id: &str, session: Vec<u8>, ) -> Result<(), StoreError>

Persists a pickled inbound Megolm session, replacing any earlier one for the same (room_id, session_id).
Source§

fn outbound_group_session( &self, room_id: &RoomId, ) -> Result<Option<&[u8]>, StoreError>

The room’s current pickled outbound Megolm session, if one exists.
Source§

fn save_outbound_group_session( &mut self, room_id: &RoomId, session: Vec<u8>, ) -> Result<(), StoreError>

Persists the room’s pickled outbound Megolm session, replacing any earlier one.
Source§

fn devices_for_user( &self, user_id: &UserId, ) -> Result<Option<&[u8]>, StoreError>

The serialized device list this store has cached for user_id, if any.
Source§

fn save_devices( &mut self, user_id: &UserId, devices: Vec<u8>, ) -> Result<(), StoreError>

Replaces the cached device list for user_id.
Source§

fn tracked_users(&self) -> Result<Vec<(UserId, bool)>, StoreError>

Every user this device tracks device lists for, with its outdated flag.
Source§

fn mark_user_tracked( &mut self, user_id: &UserId, outdated: bool, ) -> Result<(), StoreError>

Starts (or updates) tracking user_id, recording whether its device list is known to be stale.
Source§

fn withheld_reason( &self, room_id: &RoomId, session_id: &str, ) -> Result<Option<&[u8]>, StoreError>

The withheld-reason code recorded for (room_id, session_id), if any.
Source§

fn save_withheld( &mut self, room_id: &RoomId, session_id: &str, code: Vec<u8>, ) -> Result<(), StoreError>

Records a withheld-reason code for (room_id, session_id).
Source§

fn backup_key(&self) -> Result<Option<&[u8]>, StoreError>

The pickled key-backup material, if one has been set up.
Source§

fn save_backup_key(&mut self, key: Vec<u8>) -> Result<(), StoreError>

Persists pickled key-backup material, replacing any earlier one.
Source§

fn cross_signing_keys(&self) -> Result<Option<&[u8]>, StoreError>

The pickled cross-signing key material, if one has been set up.
Source§

fn save_cross_signing_keys(&mut self, keys: Vec<u8>) -> Result<(), StoreError>

Persists pickled cross-signing key material, replacing any earlier one.
Source§

impl<C: Debug + RecordCodec> Debug for Store<C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C: RecordCodec> FlushEpoch for Store<C>

Source§

fn seal_for_request(&mut self) -> (RequiredSeq, Option<FlushBatch>)

Seals whatever is currently pending (dirtied but not yet batched) into a fresh FlushBatch, returning the RequiredSeq a request minted right now must wait on, plus that batch if one was produced (None if nothing was pending). See the module doc’s worked example for the exact rule this implements.
Source§

fn is_released(&self, required: RequiredSeq) -> bool

true iff every batch at or before required’s sequence id has been acknowledged — i.e. it is safe to release a request that recorded required as its RequiredSeq.
Source§

impl<C: RecordCodec> StateStore for Store<C>

Source§

fn sync_token(&self) -> Result<Option<&str>, StoreError>

The /sync next_batch token from the most recent successful sync, if any.
Source§

fn save_sync_token(&mut self, token: String) -> Result<(), StoreError>

Persists the /sync next_batch token, replacing any earlier one.
Source§

fn room_state(&self, room_id: &RoomId) -> Result<Option<&[u8]>, StoreError>

The serialized state blob for room_id, if this store has one.
Source§

fn save_room_state( &mut self, room_id: &RoomId, state: Vec<u8>, ) -> Result<(), StoreError>

Replaces the serialized state blob for room_id.
Source§

fn room_ids(&self) -> Result<Vec<RoomId>, StoreError>

Every room this store currently has state for.
Source§

fn pending_requests(&self) -> Result<Vec<PendingRequest>, StoreError>

Every outgoing request still waiting to be sent or acked.
Source§

fn save_pending_request( &mut self, req: PendingRequest, ) -> Result<(), StoreError>

Records an outgoing request as pending (survives a crash/restart until StateStore::delete_pending_request removes it).
Source§

fn delete_pending_request(&mut self, id: &RequestId) -> Result<(), StoreError>

Removes a pending request, e.g. once its response has arrived. A no-op if id is not currently pending.
Source§

fn counters(&self) -> Result<Option<Counters>, StoreError>

The most recently persisted Counters, if this device has ever minted a crate::ids::RequestId/crate::ids::TxnId before. None only for a brand-new device — crate::core::MessengerCore::open treats that the same as Counters::default().
Source§

fn save_counters(&mut self, counters: Counters) -> Result<(), StoreError>

Persists counters, replacing any earlier value. Called every time either sequence advances — see crate::core’s module doc for why this write must land in the same flush batch as (or an earlier one than) any request carrying the id it just minted.

Auto Trait Implementations§

§

impl<C> Freeze for Store<C>
where C: Freeze,

§

impl<C> RefUnwindSafe for Store<C>
where C: RefUnwindSafe,

§

impl<C> Send for Store<C>
where C: Send,

§

impl<C> Sync for Store<C>
where C: Sync,

§

impl<C> Unpin for Store<C>
where C: Unpin,

§

impl<C> UnsafeUnpin for Store<C>
where C: UnsafeUnpin,

§

impl<C> UnwindSafe for Store<C>
where C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V