Stop (avoid?) spending malleable change #17583

issue gmaxwell opened this issue on November 24, 2019
  1. gmaxwell commented at 8:35 PM on November 24, 2019: contributor

    Transactions that spend unconfirmed change outputs from prior transactions which aren't entirely P2W* are exposed to being invalidated.

    Because importation of old keys remains a supported feature, and people sometimes continue to pay to old addresses, and old style outputs can hang around in the wallet for an unbounded amount of time, the fact that immune addresses are now a default doesn't eliminate exposure. Running a wallet that has never had old keys, however does-- so this isn't the most cosmic of problems.

    The software currently exposes "-spendzeroconfchange" which completely disables spending any unconfirmed inputs. This solves the problem but for most users it is has extremely poor usability, because the wallet will stop being able to spend when there is plenty of balance remaining simply because there isn't enough confirmed balance. For all except the largest users this is a common case. So spendzeroconfchange is mostly only useful during active attacks when not using it is clearly worse, or for the largest users.

    Now that P2W* addresses have been the default for a while, the only exposure comes from spending change from unconfirmed transactions with old or mixed input types. I suspect a spendunsafezeroconfchange could be added, and perhaps could reasonably be defaulted to off. (Or it could be a wallet flag, like the address reuse one).

    Because new change is created using P2W* scripts even the case of a one-input-only wallet being disrupted by spendunsafezeroconfchange=false should be close to a one-time event.

    Even if it couldn't immediately be defaulted to off it would be a much less disruptive alternative to the current spendzeroconfchange.

    It might be desirable to first adopt a "try to avoidpartial first" coin selection strategy, which would help sweep up vulnerable inputs or at least reduce the total number of mixed-input transactions which are created.

    I don't know if spendzeroconfchange could be removed entirely at the same time, because it's also a privacy feature analogous to disabling reuse since spending an unconfirmed input pretty much identifies that input as change. (though ultimately, perhaps that should be done with a replacement into a sendmany ... which is also not particularly private, but at least its more fee/space efficient.)

    Spendzeroconfchange=true also has an advantage in fee calculations right now independent of the invalidation concerns: At the moment, effective value and total-fee calculations don't consider the additional fees required when there is an unconfirmed input to bump the ancestor chain up to the requested feerate. So any spending of unconfirmed inputs risks underestimating the effective feerate for the transaction until the inputs confirm. (but still, spendzeroconfchange is hardly an adequate way of addressing that, since it just makes the wallet reject transactions since the unconfirmed spend was already a last-resort)

  2. laanwj added the label Wallet on Nov 26, 2019
  3. laanwj commented at 10:31 AM on November 26, 2019: member

    ping re: coin selection strategies @achow101 @meshcollider @kallewoof

    PR #14582 "wallet: try -avoidpartialspends mode and use its result if fees do not change" seems vaguely related.

  4. promag commented at 4:18 PM on December 14, 2019: member

    Makes sense, concept ACK.

    A stupid approach would be to first select unspents from non malleable transactions and then, if necessary, select from remaining transactions?

  5. gmaxwell commented at 12:06 PM on December 21, 2019: contributor

    @promag indeed. It somewhat already does, in the sense that it will only try any unconfirmed coins if the txn can't be accomplished with confirmed coins. So it could gain an extra layer of trying confirmed+unconfirmed-non-malleable first before trying all coins only as a last resort. Has the nice property that it could be a default behaviour without risking disrupting anyone.

  6. murchandamus commented at 8:08 PM on October 26, 2022: contributor

    At this point, I don't think we need to explicitly address this case anymore. Meanwhile, we generally create segwit change by default, except when we pay a recipient that explicitly requested payment to a legacy output and match the type for the change output. We also already avoid unconfirmed change in the initial coin selection pass, so having special logic to deprioritize unconfirmed P2PKH change in coin selection feels like unnecessary additional complexity for an increasingly rare case: it would only be relevant when we need to spend unconfirmed change, but have multiple unconfirmed change outputs of which some are non-segwit and some are segwit.

    If we do add a reliability score next to the waste score in coin selection, we should consider third-party malleability, though.

    cc: @josibake

  7. achow101 closed this on Oct 26, 2022

  8. bitcoin locked this on Oct 26, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-18 21:14 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me