wallet: don’t back-date locktime when spending unconfirmed UTXOs #26527

issue 0xB10C openend this issue on November 17, 2022
  1. 0xB10C commented at 5:35 pm on November 17, 2022: contributor

    As mentioned in #26451 (comment) example 3:

    If we do anti-fee sniping, the Bitcoin Core wallet has a 10% chance to back-date the locktime of a transaction to up to 100 blocks. Electrum has similar behavior.

    https://github.com/bitcoin/bitcoin/blob/48174c0f287b19931ca110670610bd03a03eb914/src/wallet/spend.cpp#L725-L731

    When spending an unconfirmed UTXO, it can happen that we back-date the locktime of our transaction to a locktime before the locktime of the unconfirmed parent. In this case, the “transaction signed earlier but only broadcast now” is unrealistic I think (please correct me if you think there is a protocol where this makes sense). This is a fingerprint that we are a Bitcoin Core or Electrum wallet.

    related #26526 electrum issue: https://github.com/spesmilo/electrum/issues/8073

  2. 0xB10C added the label Feature on Nov 17, 2022
  3. maflcko added the label Wallet on Nov 17, 2022
  4. maflcko added the label RPC/REST/ZMQ on Nov 17, 2022
  5. bitcoin deleted a comment on Nov 19, 2022
  6. murchandamus commented at 8:25 pm on January 10, 2023: member
    Good catch, it would be good to not backdate when spending unconfirmed inputs, or at least limit the locktime to the maximum of the parent transactions’ locktimes. The former is probably easier.
  7. willcl-ark commented at 3:00 pm on October 21, 2025: member
    @danielabrozzoni you might like to take a look here and #26526?
  8. danielabrozzoni commented at 4:33 pm on January 29, 2026: member

    Hey! I spent some time thinking about this, and implemented it in #34449 (I closed this one, a revised one will be opened). Instead of not backdating at all, I decided to limit the locktime to the maximum of the parent transactions’ locktimes.

    However… While writing the PR description, I realized, why would we enforce this only for unconfirmed parents? Wouldn’t it make sense to make sure that the fee sniping nlocktime is >= the locktime of any parent, regardless of whether they’re unconfirmed or not?

    We want to use anti fee sniping while preserving some plausible deniability, so that it’s not obvious from a transaction whether we’re fee sniping or simply using nLockTime. If a child transaction has an nLockTime earlier than its parent’s nLockTime, even when the parent is confirmed, it’s not really possible to explain it as “signed earlier and broadcast later”, and everyone can infer we’re fee sniping. Am I missing something?

  9. achow101 commented at 9:43 pm on February 2, 2026: member

    Wouldn’t it make sense to make sure that the fee sniping nlocktime is >= the locktime of any parent, regardless of whether they’re unconfirmed or not?

    That seems reasonable

  10. gmaxwell commented at 7:38 pm on February 14, 2026: contributor

    This is Not A Bug.

    Sure, if no inputs are ANYONECANPAY then setting a locktime less aggressive than any input is semantically no different than setting it to the input. But it’s harmless. Kinda like people noting the the ‘duration between blocks’ can be negative. :P

    Clamping to the inputs is non-trivial because locktimes are a union type between a lock height, a lock time, and a lockmeaningless-state due to sequences. A PR attempting to ‘fix’ this issue in core (#34480) appears to have gotten it wrong due to these complexities, and also introduced a potential information leak over which inputs are wallet inputs vs non-wallet (e.g. in a payjoin or coinjoin).


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-03-04 00:13 UTC

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