fix(wallet): retire tracked sends that only paid the wallet itself

A send stays tracked until z_viewtransaction shows an outgoing output.
Shields, merges/consolidations and chat note splits pay only the wallet
itself, so they never showed one. They stayed tracked for the whole
session and forced a full history refresh past the scan throttle on
every tab.

- A tracked send whose view has no outgoing output is retired once it
  is mined (1+ confirmations) or conflicted.
- Tracked sends are enriched first, and reaching the per-cycle view cap
  no longer ends the loop, so the cap can't starve them.
- Backstop: a tracked send still unsettled 20 blocks after it was added
  (expired, dropped from the mempool) stops being tracked.
- Tracked sends are cleared on disconnect: they belong to that
  connection's wallet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 19:52:09 -05:00
co-authored by Claude Opus 5.5
parent 1cb03332e7
commit 43fc0090d4
6 changed files with 168 additions and 3 deletions
+4
View File
@@ -1507,6 +1507,10 @@ private:
// even when they don't appear in listtransactions or
// z_listreceivedbyaddress.
std::unordered_set<std::string> send_txids_;
// Tip height when each tracked txid was added (TTL backstop, see pruneTrackedSendTxids()).
std::unordered_map<std::string, int> send_txid_heights_;
static constexpr int kTrackedSendTtlBlocks = 20;
void pruneTrackedSendTxids();
// First-run wizard state
WizardPhase wizard_phase_ = WizardPhase::None;