Fix 463 MissingTcToken recovery flow and dedupe concurrent token re-issuance#2517
Fix 463 MissingTcToken recovery flow and dedupe concurrent token re-issuance#2517Kunboruto20 wants to merge 3 commits intoWhiskeySockets:masterfrom
Conversation
…e-hour-on-repository Handle 463 MissingTcToken ack by issuing and storing TC tokens (deduped)
|
Thanks for opening this pull request and contributing to the project! The next step is for the maintainers to review your changes. If everything looks good, it will be approved and merged into the main branch. In the meantime, anyone in the community is encouraged to test this pull request and provide feedback. ✅ How to confirm it worksIf you’ve tested this PR, please comment below with: This helps us speed up the review and merge process. 📦 To test this PR locally:If you encounter any issues or have feedback, feel free to comment as well. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughWhen an ack returns error code 463 (MissingTcToken), the receiver now launches an asynchronous recovery: it deduplicates concurrent recoveries per target JID, resolves storage and issuance JIDs, issues privacy tokens for the issuance JID, persists tokens to the TC store, and always clears the in-flight marker. Changes
Sequence Diagram(s)sequenceDiagram
participant Receiver as Receiver
participant Dedup as Dedup_Set
participant JIDResolver as JID_Resolver
participant TokenIssuer as Token_Issuer
participant TCStore as TC_Store
participant Logger as Logger
Receiver->>Receiver: Detect 463 MissingTcToken
Receiver->>Dedup: Check `inFlight463Recoveries`
alt already in-flight
Dedup-->>Receiver: Skip recovery
else start recovery
Dedup->>Dedup: Add JID to set
Receiver->>JIDResolver: Resolve storage & issuance JIDs
JIDResolver-->>Receiver: Return resolved JIDs
Receiver->>TokenIssuer: Issue privacy tokens (timestamped)
TokenIssuer-->>Receiver: Return tokens
Receiver->>TCStore: Persist tokens to TC store
TCStore-->>Receiver: Ack persist
Receiver->>Logger: Log success/failure
Receiver->>Dedup: Remove JID from set (finally)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/Socket/messages-recv.ts`:
- Around line 1574-1579: The storeTcTokensFromIqResult call in this branch
stores tokens but never updates the TC-token index; after awaiting
storeTcTokensFromIqResult({ result, fallbackJid: tcStorageJid, keys:
authState.keys, getLIDForPN }) add a call to trackTcTokenJid using the recovered
JID (use result.jid if present, otherwise tcStorageJid) and include the
token/key context (e.g., authState.keys) so the in-memory/persisted index is
updated like the other sites that call storeTcTokensFromIqResult.
- Around line 1560-1584: The dedupe set in the 463 recovery flow currently keys
by raw attrs.from (ackFrom) which allows duplicates for the same peer presented
as PN vs LID; compute a canonical key before checking/adding to
inFlight463Recoveries by calling jidNormalizedUser(ackFrom) or, preferably,
using the resolved tcStorageJid returned by resolveTcTokenJid and use that
canonicalId for the has/add/delete and log entries; specifically, call
resolveTcTokenJid(ackFrom, getLIDForPN) early, set const canonicalId =
tcStorageJid (or jidNormalizedUser(ackFrom) if resolve fails), then replace all
uses of ackFrom in inFlight463Recoveries.has/add/delete and the logger debug
context with canonicalId while still passing ackFrom to the downstream
resolution/issuance calls where the raw JID is required.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e2eb9ce0-387d-432b-aa49-0860ea6a8313
📒 Files selected for processing (1)
src/Socket/messages-recv.ts
There was a problem hiding this comment.
2 issues found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/Socket/messages-recv.ts">
<violation number="1" location="src/Socket/messages-recv.ts:1561">
P2: The dedupe set `inFlight463Recoveries` is keyed on the raw `attrs.from` value, but the same contact can appear under different JID forms (PN vs LID). When that happens, parallel recovery requests will be issued for the same underlying contact, defeating the deduplication. Key the set by the resolved `tcStorageJid` (or at minimum `jidNormalizedUser(ackFrom)`) instead.</violation>
<violation number="2" location="src/Socket/messages-recv.ts:1574">
P2: This `storeTcTokensFromIqResult` call does not pass `onNewJidStored: trackTcTokenJid`, unlike the other call sites in this file. The recovered token will be persisted but the contact won't be added to the TC token index, causing later prune/index-save passes to miss it.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This PR improves how Baileys handles ACK error 463 (MissingTcToken).
What changed
Added a self-healing recovery path in messages-recv when the server returns ACK error 463.
On 463, the client now:
Resolves the correct storage and issuance JIDs,
Calls issuePrivacyTokens(...),
Persists the returned token via storeTcTokensFromIqResult(...).
Added an in-flight dedupe set (inFlight463Recoveries) to avoid starting multiple recovery jobs for the same contact at the same time.
Kept this flow non-blocking and preserved existing behavior (no automatic message resend loop).
Why
Previously, 463 was mostly logged, which could leave the session stuck without a refreshed token for that contact.
With this change, the client proactively recovers token state so subsequent sends can succeed more reliably.
Safety / behavior notes
No message auto-retry was introduced (to avoid retry loops and extra reachout pressure).
Recovery is best-effort and isolated; failures are logged and dedupe state is always released in finally.
Testing
Ran focused token tests:
npm test -- --runInBand src/tests/Utils/tc-token.test.ts
Result: PASS (all tests passed).
Summary by CodeRabbit