Skip to content

wallet: abandoning a transaction leaves its input addresses marked as used under avoid_reuse #8017

Open

Description

@PastaPastaPasta

With avoid_reuse set, abandoning a transaction doesn't clear the "previously spent" marker on its input addresses. The wallet then keeps treating those addresses as reused even though the transaction never reached the network.

CWallet::AddToWallet marks every wallet-owned input address of a new transaction as used (SetSpentKeyState(..., used=true, ...)). That happens before the broadcast, so it also happens for a transaction the mempool refuses. CWallet::AbandonTransaction gives the inputs back but never clears those marks. SetSpentKeyState is only ever called with used = true.

Effect on an avoid_reuse wallet after a refused or abandoned send:

  • getbalances counts the coins at those addresses under used instead of trusted, and so does GetBalance(avoid_reuse=true), which the GUI's balance display uses.
  • In the GUI, WalletModel::prepareTransaction checks the amount against that cached balance. A retry above the remaining balance fails with AmountExceedsBalance, although coin selection itself would spend the coins (the GUI's CCoinControl leaves m_avoid_address_reuse false).
  • RPC sends without avoid_reuse=false leave those coins out of coin selection.

#7905 makes the GUI abandon a send that the mempool refuses, so this is easier to hit there. The same thing happens on develop through the abandontransaction RPC, and Bitcoin Core behaves the same way. #7905 adds a TestGUI check in src/qt/test/wallettests.cpp that pins the current behaviour; a fix should flip it.

Clearing the marks isn't as simple as reversing AddToWallet. The marker is one bit per address with no count, so an earlier spend that was relayed may already have set it for the same address. Clearing it for every input of the abandoned transaction would erase that history. A fix needs to either:

  • record which addresses a transaction newly marked, and clear only those when it is abandoned, or
  • recompute the marker for each affected address from the wallet's remaining non-abandoned spends.

It belongs in AbandonTransaction so that every caller gets it. Check upstream first, in case Bitcoin Core has fixed it in the meantime.

Activity

  1. added 2 commits that reference this issue on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions