Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions advanced/signal-protocol.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ Prior to [#807](https://github.com/oxidezap/whatsapp-rust/pull/807), a single ch
`prepare_group_stanza` now acquires the SKDM targets' per-device session locks through `SendContextResolver::lock_device_sessions()` before taking the chain lock, and releases them right after the fan-out — the `skmsg` chain encrypt that follows only touches the sender-key chain, never a pairwise session. The `Client` implementation of this hook reuses `build_session_lock_keys()` + `session_mutexes_for()`, so the group and DM paths serialize on the exact same mutexes, in the same sorted order, and always acquire session locks before the chain lock — no path takes the reverse order, so this cannot deadlock. The hook defaults to a no-op, so a custom `SendContextResolver` (as used in tests and benches) is unaffected unless it opts in.
</Note>

<Note>
**Session-setup failures are isolated per device (v0.6).** `ensure_sessions_for_devices` used to abort with `Err` the moment `process_prekey_bundle` failed for *any* one target device. Since `prepare_group_stanza` gates the entire SKDM fan-out on `session_plan.is_some()`, one device's X3DH failure nulled the plan and **every** device in the cohort — not just the failing one — got no SKDM, even though the `skmsg` still shipped and the phash covered the full set. An external member recovers via a retry receipt, but an own companion's retry hits `mark_forget_sender_key` with `exclude_own_devices=true`, which filters own-user JIDs and returns early — so that companion stayed `has_key=true` forever and couldn't decrypt the group from that device until an unrelated full rotation (participant removal or PN↔LID migration).

As of [#996](https://github.com/oxidezap/whatsapp-rust/pull/996), a device whose session setup fails is logged and skipped rather than aborting the plan — matching WhatsApp Web's `GroupKeyDistributionMsg`, which wraps each device's `ensureE2ESessions` in its own try/catch and drops only the failing one. The sessionless device is then naturally excluded by the encrypt fan-out (which already skips devices without a session), so every other device still receives its pairwise SKDM.
</Note>

### In-memory sender key device cache

The `SenderKeyDeviceCache` provides an in-memory caching layer over the per-device sender key tracking data stored in the database. Without this cache, every group send would require a database round-trip to load the sender key device map — the cache eliminates that overhead after the first load for each group.
Expand Down