#36040 Wallet: Don't backdate locktime rbf

full analysis

https://github.com/bitcoin/bitcoin/pull/36040 · Bicaru20 · +153/-8 in 6 files, 2 commits · labels: Wallet

Goal

  • Prevent fee-bumped transactions from getting an earlier locktime than the transaction they replace
  • Stops an anomalous on-chain pattern that leaks a recognizable wallet fingerprint

This PR modifies wallet fee bumping so that replacement transactions generated via `bumpfee` do not receive an `nLockTime` earlier than the original transaction being replaced. It passes the original transaction's locktime as a lower bound into `DiscourageFeeSniping`, ensuring random anti-fee-sniping backdating is constrained between the original locktime and the current chain tip, and adds unit tests covering boundary and stale-chain behaviors.

Problem: Bitcoin Core's anti-fee-sniping mechanism randomly backdates transaction locktimes by up to 99 blocks roughly 10% of the time. When fee-bumping an existing transaction, this random choice can result in a replacement transaction having an older locktime than the transaction it replaces, an anomalous condition on-chain that serves as a recognizable wallet fingerprint.

Category: Wallet (#39 of 84)

P3 · bug fix

  • P3 because this fixes an observable wallet fingerprinting defect during RBF fee bumping
  • Occurs in under 2% of fee-bumped transactions on chain with clear privacy benefit but no safety risk

P3 because this fixes an observable wallet fingerprinting defect during RBF fee bumping. Anti-fee-sniping backdating in replacements where A.locktime > B.locktime is estimated to occur in less than 2% of on-chain RBF transactions, so while it has clear privacy value for transaction creation, it does not threaten fund safety or node stability.

Membership: Modifies wallet transaction creation and fee bumping logic in src/wallet/feebumper.cpp, src/wallet/spend.cpp, and src/wallet/coincontrol.h.

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

Reviewability: Ready

  • Worth reviewing now
  • The patch is clean, rebased, and all functional concerns have been addressed in code

The patch is clean, rebased, tested, and all material reviewer concerns have been addressed in code.

Author status: active

Open concerns:

  • Minor commit message typo suggestions on the latest commit (nervana21)

Resolved concerns:

  • Off-by-one error in random backdate range calculation and proper inclusive bounds (nervana21, polespinasa)
  • Handling of locktimes during stale chain conditions or chain reorganizations where minimum_height exceeds block_height (molnard, nervana21)
  • Architectural discussion on whether to keep replacement locktime state in CCoinControl or feebumper.cpp (molnard)
  • Replacement of flaky functional test with deterministic unit tests in spend_tests and feebumper_tests (molnard, polespinasa)

Agreement: Strong

  • Strong agreement with no blocking objections
  • Support after architectural discussions and test hardening (molnard)
  • Tested approval with minor commit message typo suggestions (nervana21)
  • Approach approval on earlier revision (polespinasa)

Strong: substantive ACKs from molnard and nervana21 with no blocking objections

Reviewers agreed with the approach and confirmed testing after architectural discussions and test hardening were completed.

  • molnard reviewed and gave full ACK on e34f934
  • nervana21 gave tested ACK on e34f934 with minor formatting nits
  • polespinasa gave Approach ACK on earlier revision

Review verdicts (DrahtBot): 2

Files

121 lines under test/bench/ci.

  • src/wallet/test/spend_tests.cpp +90/-0
  • src/wallet/test/feebumper_tests.cpp +31/-0
  • src/wallet/spend.cpp +20/-6
  • src/wallet/spend.h +6/-2
  • src/wallet/feebumper.cpp +4/-0
  • src/wallet/coincontrol.h +2/-0

Card

This PR updates wallet transaction construction so that bumpfee replacements do not backdate nLockTime below that of the original transaction. Under current behavior, anti-fee-sniping backdating can randomly assign a replacement transaction a locktime older than the original, creating an anomalous fingerprint that identifies Bitcoin Core or Electrum wallets. The PR bounds backdating in DiscourageFeeSniping to no lower than the prior locktime and adds deterministic unit tests for bounds and stale-tip scenarios. Review is active and supportive, with multiple ACKs from experienced contributors.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T16:22, confidence high, input hash 5c44aaebed67ef02