Expand description
Devices, E2E key material, to-device inbox, device-list change log,
cross-signing, and key backup — the devices/keys/backup half of
messenger.db (the rooms/events/state half is matrix_store.rs, a
separate work item). See
the messenger protocol notes §2
second SQL block for the DDL this module implements, §1.1 for the
device-per-credential model, and §3.7 for the /sync delta shapes this
module’s read functions serve.
Crypto stays entirely client-side here too: device_keys.keys,
one_time_keys.key_json, fallback_keys.key_json,
cross_signing_keys.key_json, cross_signing_signatures.signature_json,
key_backup_versions.auth_data, and key_backup_sessions.session_data
are all opaque JSON this module never inspects or verifies — pure
storage/relay, identical in spirit to matrix_store.rs’s own treatment
of event content.
§Single-writer discipline
Same rule as matrix_store.rs: every function here takes an
already-open Connection; the caller holds it behind one
std::sync::Mutex. Every stream-ordered table in this module
(to_device_messages, device_list_changes) shares matrix_store’s
one global stream_counter — this module never mints its own counter,
it calls [crate::store::next_stream_id] inside the same transaction as
the row it stamps, exactly like matrix_store.rs does for its own
tables.
§Deviation from the plan’s literal DDL text
fallback_keys gains a key_id TEXT NOT NULL column not present in the
plan’s printed DDL — see create_matrix_keys_schema’s doc comment for
why: the plan’s own CRUD contract for claim_one_time_key requires a
real key_id for a fallback-key claim, exactly like it already returns
one for a real one-time-key claim, and there was no column to source
that from.
Structs§
Enums§
- Credential
Kind - Which of the two existing auth mechanisms (plan §1.1) minted a device.
- Cross
Signing Usage - A cross-signing key’s usage, per the Matrix cross-signing model.
- Matrix
Keys Store Error - Why a write into this store was refused, on top of a real database
failure — same shape as
crate::store::MatrixStoreError. - ToDevice
Dedup Outcome - What
enqueue_to_device_dedupeddid.
Functions§
- add_
one_ time_ keys - Upload a batch of one-time keys. Per key: a brand-new
key_idis inserted; akey_idthat already exists with byte-identicalkey_jsonis a silent no-op (idempotent resubmission); akey_idthat already exists with DIFFERENTkey_jsonrefuses the WHOLE batch withMatrixKeysStoreError::OneTimeKeyConflict(one transaction — a refused call leaves no partial insert from this batch). - add_
signatures - Append a batch of
/keys/signatures/uploadsignatures — pure storage, never verified server-side (opaque, per this module’s own doc comment). One transaction. - backup_
count_ and_ etag (session count, current etag)forversion— theGET /room_keys/version[/{version}]response shape’scount/etagpair.- claim_
one_ time_ key - Claim one one-time key of
algorithmfor(user_id, device_id): an atomicDELETE ... RETURNINGon the lowestkey_id— the “exactly once” guarantee, no window where two claimants could race the same key. If none remain, falls back to the (reusable, never-deleted) fallback key for that algorithm and marks itused = 1— the client reads its ownunused_fallback_key_typesto know when it should upload a fresh one. - clear_
device_ one_ time_ material - Wipe one-time and fallback keys for
(user_id, device_id)— used when an authenticated device resets its Olm identity under the same device id. Does not touchdevice_keysitself (the caller replaces that row) ordevice_list_changes(the followingupsert_device_keyslogs the change). - count_
one_ time_ keys - How many one-time keys remain per algorithm —
/keys/upload’s response and/sync’sdevice_one_time_keys_count. - create_
backup_ version - Create a brand-new key-backup version — a version number is never
reused (soft-delete only, see
delete_backup_version), so this is a plain insert. - create_
device - Mint a fresh device for
user_idauthenticated by(credential_kind, credential_ref), returning the new device id. Does not check for an existing row for this credential — callers usedevice_for_credentialfirst (the get-or-create orchestration is P4’sdevice_id_for, not this module’s job). - create_
matrix_ keys_ schema - Create every table/index this module needs — idempotent, called from
crate::store::init_messenger_dbright aftercreate_matrix_schema, and directly by this module’s own tests. - cross_
signing_ key_ for - One user’s cross-signing key of a specific
usage, if uploaded —routes::matrix::keys’s own lookup when it needs exactly one (verifying a self/user-signing key against a caller’s stored master key; deciding whether a master key already exists before a/keys/device_signing/uploadcall).cross_signing_keys_forstays the batch entry point/keys/queryuses. - cross_
signing_ keys_ for - Every cross-signing key belonging to any of
user_ids— the/keys/querybatch shape. Empty input returns an empty vec. - current_
backup_ version user_id’s current (highest-numbered, non-deleted) backup version, if any.- delete_
backup_ sessions - Delete backup sessions for
version, same three-shape narrowing asget_backup_sessions. Bumpsetagonce iff at least one row was removed. One transaction. Returns the number of rows deleted. - delete_
backup_ version - Soft-delete a backup version (the version number is never reused, so
its
key_backup_sessionsrows are left in place as inert history). Idempotent: deleting an already-deleted version returnsfalse. - delete_
device - The manual “log out this device” path (
DELETE /devices/{deviceId}, P9): delete the device, cascade its key material and pending to-device rows, and append one [device_list_changes] row foruser_id. One transaction. Returns whether a device existed to delete. - delete_
device_ by_ credential - The credential-revoke path (plan §1.1,
on_credential_revokedsteps 1-3 — the wake fan-out, step 4, is the caller’s job in P4): find the device minted for(credential_kind, credential_ref), delete it and its key material and pending to-device rows, and append onedevice_list_changesrow for its owner. One transaction. ReturnsSome((user_id, device_id))on a hit,Noneif no device was ever minted for this credential. - delete_
to_ device_ up_ to - Delete every to-device row for
(user_id, device_id)at or beforestream_id— plan §3.7’s delete-after-ack rule: a/synccall withsince=stream_idis itself the proof the client already durably received everything up to that point. Returns the number of rows removed. - device_
for_ credential - The device already minted for
(credential_kind, credential_ref), if any (the unique-index lookup behinddevice_id_for, P4). - device_
keys_ for - Every device-keys row belonging to any of
user_ids— the/keys/querybatch shape. Empty input returns an empty vec without touching the database. - device_
list_ changes_ between - Every distinct
user_idwhose device list changed in(from_exclusive, to_inclusive]—/sync’sdevice_lists.changedcandidate set, before the caller restricts it to shared-room users (plan §3.7). - devices_
for_ reaper - Every device in the system, for the P14 boot+hourly reaper sweep (plan
manager decision 3): the sweep itself checks each credential against
the identity database and calls
delete_device_by_credentialfor the ones that are gone or expired — not this module’s job. - enqueue_
to_ device - Fan out one
PUT /sendToDevicecall’smessagesmap (already flattened to one row per(recipient_user_id, recipient_device_id)— a*device wildcard is resolved by the caller before this function ever sees it) as one transaction sharingmatrix_store’s global stream counter. Returns the last stream id minted, or the counter’s current value unchanged ifmessagesis empty. - enqueue_
to_ device_ deduped enqueue_to_device, but dedup-checked and recorded in the SAME transaction as the inserts — mirrorscrate::store::insert_timeline_event_deduped’s own shape for the to-device case, which recordsNULLfortxn_dedup.event_id(that column’s own doc,matrix_store’s DDL, states this is the to-device case). A repeat of(sender_user_id, sender_device_id, txn_id)is a no-op: no second set ofto_device_messagesrows, matchingPUT /sendToDevice/{eventType}/{txnId}’s own idempotency contract (routes::matrix::keys, P9).- get_
backup_ sessions - Read backup sessions for
version, optionally narrowed to one room and/or one session (mirroringGET /room_keys/keys[/{roomId}[/{sessionId}]]’s three shapes). Asession_idwithout aroom_idis treated the same as neither being given — the wire path never allows that combination. - get_
backup_ version - One specific backup version by number, regardless of its
is_deletedstate — the caller decides how to treat a deleted version (a fetch by an explicit version number is a different question than “what’s current”). - get_
device - One of
user_id’s own devices, by id. - list_
devices - Every device
user_idowns. - log_
device_ list_ change - Standalone entry point for a caller that is not already inside one of this module’s own multi-step transactions (e.g. a future piece that needs to log a change without also writing a keys row). Every write in THIS module that is documented to log a change does so inline, in the same transaction as that write — this function is for everyone else.
- put_
backup_ sessions - Upload a batch of backup sessions into
version— refuses withMatrixKeysStoreError::WrongBackupVersionunlessversionisuser_id’s current non-deleted version (plan §2 manager decision 5). Bumpsetagonce for the whole batch. One transaction. - set_
device_ display_ name - Rename (or clear, with
None) a device’sdisplay_name. Returns whether a row was found and updated. - signatures_
for - Every signature filed against
(target_user_id, target_key_id). - to_
device_ for - Every to-device message still pending for
(user_id, device_id)afterafter_stream, oldest first —/sync’sto_device.events. - touch_
device - Bump
last_seen_aton an existing device — a no-op if the device does not exist. - unused_
fallback_ key_ types - Every fallback-key algorithm that has not yet been claimed — the client uses this to decide which algorithms need a fresh fallback key uploaded.
- update_
backup_ version_ auth_ data - Update a non-deleted backup version’s opaque
auth_data, bumping itsetag. Returns whether a row was found and updated. - upsert_
cross_ signing_ key - Store (or replace) one of
user_id’s three cross-signing keys. Appends one [device_list_changes] row, same asupsert_device_keys— a peer’s trust chain changed, not just a device. - upsert_
device_ keys - Store (or replace)
POST /keys/upload’s device-keys object verbatim. Appends one [device_list_changes] row foruser_id— every peer sharing a room learns about the change on their next/sync. One transaction. - upsert_
fallback_ key - Upload (or replace) the one active fallback key for
algorithm— replacing always resetsusedback to0, per spec (“a new fallback key is unused until it is actually claimed”).