Skip to content

docs(signal-protocol): document DSM destination trait and chain key buffer reuse - #449

Merged
jlucaso1 merged 2 commits into
mainfrom
claude/nifty-bohr-xj6e9b
Jul 27, 2026
Merged

docs(signal-protocol): document DSM destination trait and chain key buffer reuse#449
jlucaso1 merged 2 commits into
mainfrom
claude/nifty-bohr-xj6e9b

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Documents two of the four allocation cuts from whatsapp-rust#1137 that touch behavior already described in advanced/signal-protocol.mdx:

  • DsmDestination traitMessageUtils::encode_dm_plaintexts / dm_plaintexts_from_encoded now take impl DsmDestination instead of destination_jid: &str, so the DM send path passes &Jid directly instead of stringifying it first. Added as a note under DM device fanout, next to the existing description of the DeviceSentMessage wrapper.
  • Chain key buffer reusewrite_chain_key reuses the persisted chain key's existing Bytes buffer in place when it is uniquely owned and the right length, instead of allocating on every ratchet advance. Added as a new "Chain key buffer reuse" subsection under Performance optimizations, alongside the existing session-cache/Arc documentation it builds on.

The other two cuts in #1137 (the send_raw_bytes_burst out-parameter and the streaming reporting-token HMAC) are internal to pub(crate)/private functions with no existing doc surface to update, so they're left out here — this PR only touches content that was already documenting the affected code paths.

Test plan

  • Reviewed the added prose against the PR #1137 diff for accuracy (trait shape, guard conditions, PR-linked precedent style already used elsewhere in this file for #1118/#1124/#1131)
  • N/A — documentation-only change, no build/test suite in this repo beyond the docs site itself

🤖 Generated with Claude Code


Generated by Claude Code


Summary by cubic

Updates advanced/signal-protocol.mdx to document two allocation cuts from whatsapp-rust#1137.
Notes DsmDestination usage in DM encoding (pass &Jid without a String) and chain key Bytes buffer reuse; clarifies the single-device benchmark context and that the length check avoids a copy_from_slice panic.

Written for commit 0aa5807. Summary will update on new commits.

…uffer reuse (whatsapp-rust#1137)

Adds two notes to the Signal Protocol doc for PR #1137's allocation
cuts: the DsmDestination trait that lets a Jid name the
DeviceSentMessage destination without an intermediate String, and
write_chain_key's in-place reuse of the persisted chain key buffer
across ratchet advances.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jlucaso1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 4 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 16a80492-758a-4d3f-a261-d5231cedc59f

📥 Commits

Reviewing files that changed from the base of the PR and between 32ef11c and 0aa5807.

📒 Files selected for processing (1)
  • advanced/signal-protocol.mdx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mintlify

mintlify Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
whatsapp-rust 🟢 Ready View Preview Jul 27, 2026, 11:43 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown

Greptile Summary

Documents two upstream Signal Protocol allocation optimizations:

  • Explains direct destination JID encoding through the DsmDestination trait.
  • Describes safe reuse of uniquely owned chain-key buffers during ratchet advancement.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
advanced/signal-protocol.mdx Adds focused documentation for destination JID encoding and chain-key buffer reuse without changing site structure or runtime behavior.

Reviews (2): Last reviewed commit: "docs(signal-protocol): address Codex rev..." | Re-trigger Greptile

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f06670f037

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread advanced/signal-protocol.mdx Outdated
- **Own other devices** (your other linked devices) receive a `DeviceSentMessage` wrapper containing the message plus the destination JID, so your other devices can display the sent message in the correct chat

<Note>
**Destination JID encoding via `DsmDestination` ([#1137](https://github.com/oxidezap/whatsapp-rust/pull/1137)).** The `DeviceSentMessage` wrapper writes its destination JID as a length-prefixed protobuf field, which needs the encoded length before the bytes. `wacore::messages::MessageUtils::encode_dm_plaintexts` and `dm_plaintexts_from_encoded` used to take `destination_jid: &str`, so the caller rendered the `Jid` into a `String` purely to measure and copy it. Both now take `impl DsmDestination` — a trait implemented directly on `Jid` (so it can measure and write its own wire form without an intermediate `String`) and on `str` plus the standard string wrappers (`String`, `Box<str>`, `Rc<str>`, `Arc<str>`, `Cow<str>`), carried through references of any depth via two blanket impls. The DM send path now passes `to_jid: &Jid` directly instead of `&to_jid.to_string()`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Split the destination note into concise sentences

The sentence beginning Both now take... combines the signature change, supported wrapper types, blanket implementations, allocation behavior, and call-site impact into one dense statement. This makes the API change difficult to scan and violates the project's one-idea-per-sentence convention. Split these details into concise sentences.

AGENTS.md reference: AGENTS.md:L25-L25

Useful? React with 👍 / 👎.

Comment thread advanced/signal-protocol.mdx Outdated

### Chain key buffer reuse

As of [#1137](https://github.com/oxidezap/whatsapp-rust/pull/1137), advancing a chain key no longer allocates a fresh buffer for its persisted 32-byte key material on every step. `SessionState` stores each chain key's bytes as `Option<bytes::Bytes>` on the underlying protobuf `ChainKey` field; since `Bytes` is immutable, writing the ratcheted key used to be an unconditional `Bytes::copy_from_slice(..)`, and the ratchet advances three times per message round trip (twice sending, once receiving).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Qualify the fixed ratchet-advance count

The claim that a message round trip always advances chain keys three times only describes a particular two-device send scenario. As the DM fanout section documents, encryption runs for every resolved recipient device and every own linked device, so the number of sending advances varies with device topology and can be less or greater than two. Qualify this as a benchmark scenario or describe the cost per destination device.

Useful? React with 👍 / 👎.

Comment thread advanced/signal-protocol.mdx Outdated
}
```

Reuse only happens when both guards pass: `try_into_mut()` succeeds solely when the `Bytes` is uniquely owned (no other clone observing the old key), and the length check keeps a differently-sized buffer (e.g. from a legacy record) from being partially overwritten. Either guard failing falls back to the original allocating behavior. In steady state a checked-out session record is uniquely owned — the cache takes it out of its `Arc` via `try_unwrap` (see [Session object cache](#session-object-cache) above) — so the fallback is rare.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Describe the length guard as panic prevention

For a legacy record with a differently sized buffer, BytesMut::copy_from_slice does not partially overwrite the destination; like slice copy_from_slice, it requires equal lengths and panics on a mismatch. The guard therefore prevents that panic and selects the allocating fallback, so the current explanation gives readers the wrong safety model.

Useful? React with 👍 / 👎.

- Split the DsmDestination note into one-idea-per-sentence, per this
  repo's style convention (AGENTS.md).
- Qualify "three advances per round trip" as the harness benchmark's
  single-device scenario, not a fixed count — real sends touch as
  many sessions as DM device fanout resolves.
- Correct the length-guard rationale: a mismatched length would panic
  in copy_from_slice, not partially overwrite the buffer.
@greptile-apps
greptile-apps Bot dismissed their stale review July 27, 2026 11:48

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@jlucaso1
jlucaso1 merged commit d9b43eb into main Jul 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants