feat(chat): 0-conf fast-scan so incoming messages show before a block

The receive harvest gates each z-address behind scannedAtTip — it only re-scans
when a new block advances the tip — so incoming chat waited ~1 confirmation even
though the daemon already exposes mempool notes (FindMySaplingNotes runs on
mempool txs; z_listreceivedbyaddress(addr,0) returns them).

Add App::fastScanChatMemos(): every transaction-refresh cycle, re-scan JUST the
chat reply address (where peers send) at minconf=0, extract chat metadata, and
ingest — so messages surface at mempool speed (a few seconds) instead of waiting
for a block. Full-node only (lite has its own harvest). An in-flight guard avoids
stacking RPCs; the store dedups on txid+position, so the confirmed harvest never
double-inserts.

Hidden conversations are deliberately skipped by the fast path — they don't get
the mempool speed-up and still come back through the normal confirmed harvest
(which un-hides on a new message). New non-muted messages toast off-tab as usual.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-17 00:38:41 -05:00
parent 29fbe46cce
commit 30bd0d99ff
3 changed files with 74 additions and 0 deletions

View File

@@ -730,6 +730,11 @@ private:
bool broadcastChatMemos(const chat::OutgoingChatMemos& memos, const std::string& echoLocalId); // true if submitted
bool broadcastChatMemosLite(const chat::OutgoingChatMemos& memos); // lite two-recipient send
void ingestLiteChatMemos(const wallet::LiteWalletAppRefreshModel& model); // lite chat receive harvest
// Full-node 0-conf fast path: re-scan just the chat reply address at minconf=0 every refresh cycle
// so incoming messages surface at mempool speed (before a block). Hidden conversations are skipped
// (they still un-hide via the normal confirmed harvest). Self-gated; no-op without a chat identity.
void fastScanChatMemos();
bool chat_fast_scan_in_flight_ = false; // guard against overlapping fast-scan RPCs
// Lite first-run welcome prompt: dismissed for the session once the user picks an action.
bool lite_firstrun_dismissed_ = false;
// Lite send-time unlock: set to show the unlock modal when a spend is attempted while locked.