#35786 wallet: drop spent parents redundant cache invalidation and notification

ReviewabilityReviewsAgreementSize
#35786 furszy wallet: drop spent parents redundant cache invalidation and notificationWaiting on author0 (+2)Blocked7 + 101 tests
  • Eliminate redundant cache recalculation and unnecessary UI refreshes when wallet outputs are spent
  • Ready to review
  • Unaddressed objection: keypool expansion during spend leaves parent cache outdated in gettransaction (w0xlt)
  • Confirmed the edge case with keypool expansion during a spend (vicjuma)
  • Support for removing redundant cache invalidations and GUI notifications (pablomartin4btc, Bicaru20)
  • Concept approval for simplifying confusing invalidation code (rkrux)
  • 7 lines added or modified outside tests
  • 101 lines added or modified in tests
  • 32 lines removed in total
  • 4 files, 3 commits
Wallet#74 of 92
P3 · cleanup
  • P3 because it is a routine cleanup removing redundant cache invalidations and dead GUI notifications
  • The performance gain is minor, saving unneeded recalculations and status refreshes after spends
  • Ranking pass: Moved down: unmeasured micro-optimization plus dead-notification removal.
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Removes redundant cache invalidation and UI change notifications for parent transactions when wallet outputs are spent. Deletes MarkInputsDirty and stops CommitTransaction from notifying spent parent transactions. Adds unit tests verifying that spending an output, abandoning a spend, or receiving a spend via mempool does not alter parent transaction cached values.

Problem: Previously, CWalletTx cached available amounts, requiring spent parent transactions to invalidate their caches and notify the GUI when their outputs were spent. Following #27286, available balance is computed from separate structures while CWalletTx caches only transaction-specific credit, debit, and change amounts that do not change upon spending, leaving the invalidation and GUI notification logic redundant.

Evidence of importance:

  • Author notes that since #27286, "the balance is read live from m_txos and mapTxSpends, and CWalletTx cache only its own, tx specific, incoming and outgoing amounts... So the cache invalidation recomputes the same values, and the notification makes the GUI refresh a status that has not changed." (PR description)
  • Commit 4591142a8f notes that the GUI is the only consumer of the notification, and its status refresh depends on depth, maturity, and abandoned flags, none of which change when an output is spent.

Scope: Removes the MarkInputsDirty helper and its call sites across wallet.cpp, accompanied by new unit tests in wallet_tests.cpp.

Reviewability

Paused · Waiting on author

Open objection from w0xlt with no author reply for 30 days; review would repeat what has been asked.

Waiting on (from the thread read):

  • author: response to w0xlt's reproduction of outdated parent cache after keypool expansion 2026-09-15
  • author: author response or fix for w0xlt's objection regarding keypool expansion edge case leaving parent transaction cache outdated 2026-09-15

Agreement

Blocked

objection that needs a change, nobody has replied (w0xlt)

Thread notes: Added participant vicjuma who gave a Concept ACK and confirmed w0xlt's keypool logic finding. Under schema reread rules, recorded pablomartin4btc's question from rc:3647241045 as accepted, and adjusted clears_with to change on w0xlt's correctness objection. / Added pablomartin4btc's answered question from rc:3647241045. Updated w0xlt's objection clears_with to change because it reports a regression/defect. Added vicjuma to participants and support; vicjuma's comment agreeing with w0xlt's edge ca

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
pablomartin4btc (member)question, approachAsks if the reasoning is that any wallet-relevant parent transaction would be its own desc_tx and get MarkDirty() in its own iterationanswered · author explained cache resetting recomputes identical values without new descriptors; reviewer later ACKedansweredyes2026-07-24: 'any parent tx that is wallet-relevant would be its own `desc_tx` and get `MarkDirty()` in its own iteration, is that the reasoning?'
Status from: 2026-07-27: furszy: 'Resetting a transaction's cache when no new descriptor has been imported results on the exact same values being re-computed again.'
w0xlt (contributor)objection, correctnessgettransaction reports an outdated cached amount if keypool expansion during a spend causes another output of the parent transaction to become recognized as wallet-ownedopenchangedno2026-09-15: 'This invalidation is still needed in a narrow case. A transaction pays 1 BTC to each of two wallet addresses, but the wallet hasn’t derived one address yet... Without this invalidation, gettransaction'

Support:

  • pablomartin4btc (member) (Concept ACK, 2026-07-24) [read: CommitTransaction, MarkInputsDirty, m_amounts, m_cached_from_me]: per-transaction caches reflect tx-specific amounts that do not change when child spends output, making invalidation and notification dead work
  • Bicaru20 (contributor) (ACK, 2026-07-29) [both: CWalletTx, MarkInputsDirty, m_amounts, m_cached_from_me, m_txos, mapTxSpends, src/wallet/test/wallet_tests.cpp, tests]: agrees MarkInputsDirty is redundant since spendable amounts moved to m_txos and mapTxSpends, and verified tests
  • w0xlt (contributor) (Concept ACK, 2026-08-03): (no reason given) [not substantive]
  • rkrux (member) (Concept ACK, 2026-08-26) [read: mark dirty calls]: removing mark dirty calls cleans up confusing code
  • pablomartin4btc (member) (ACK, 2026-08-28) [read]: confirmed only typo fix and rebase since last review
  • vicjuma (contributor) (Concept ACK, 2026-10-02): (no reason given) [not substantive]

Participants:

  • pablomartin4btc (member, support, 8 statements 2026-07-24 to 2026-08-28): ACKed after verifying cache invalidation is redundant dead work
  • Bicaru20 (contributor, support, 1 statements 2026-07-29 to 2026-07-29): ACKed verifying cache semantics and tests
  • w0xlt (contributor, objection, 2 statements 2026-08-03 to 2026-09-15): Concept ACKed, then reported an edge case where spending expands the keypool and leaves parent cache outdated
  • rkrux (member, support, 1 statements 2026-08-26 to 2026-08-26): Concept ACKed, welcoming the removal of confusing mark dirty calls
  • vicjuma (contributor, support, 3 statements 2026-10-02 to 2026-10-02): Concept ACKed; confirmed w0xlt's edge case regarding keypool logic

Files

101 lines under test/bench/ci.

  • src/wallet/test/wallet_tests.cpp +101/-0
  • src/wallet/wallet.cpp +0/-26
  • src/wallet/transaction.h +7/-3
  • src/wallet/wallet.h +0/-3

Card

The short text the ranking pass compares across PRs.

Removes redundant cache invalidation and GUI change notifications for parent transactions when their outputs are spent. Since #27286, available amounts are tracked separately and CWalletTx caches only static per-transaction credit and debit values, making parent dirty-marking and UI updates superfluous. The author notes that invalidation recomputes identical values and UI rows refresh for statuses that did not change, though no performance benchmarks are provided. There are no dependencies.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-03T01:23, confidence high, input hash ffcabfcf0ec81d7c
thread read through 2026-10-02 (20 statements), head 4591142a8f
labels: Wallet

Categories

Wallet

P3 · cleanup (ranking pass: Moved down: unmeasured micro-optimization plus dead-notification removal.)

Removes obsolete cache invalidation and GUI notification logic left redundant after #27286. As the author notes, CWalletTx caches only transaction-specific amounts that do not change upon spending, making MarkInputsDirty recompute the same values and trigger unnecessary UI refreshes.

Membership: Matches the Wallet maintainer label and modifies wallet transaction caching and notification logic in src/wallet/.

Factors: security/stability 0, bug 0, performance 1, user value 0, leverage 0