wallet: Avoid leaking nLockTime fingerprint when anti-fee-sniping #15039

pull MarcoFalke wants to merge 2 commits into bitcoin:master from MarcoFalke:Mf1812-walletLocktimeFingerprint changing 4 files +97 −31
  1. MarcoFalke commented at 3:07 PM on December 26, 2018: member

    The wallet sets the locktime to the current height of our active chain. This is fine, as long as our node is connected to other nodes. However, when we fall back and get stuck at a particular height (e.g. taking the wallet offline), the same (potentially unique) locktime is used for all transactions. This makes it easier for passive observers to cluster transactions by wallet.

    For reference, I visualized "locktime-reuse" with the data:

    • blocks 545k-555k (both inclusive)
    • locktimes<=60k
    • excluding coinbase txs

    distribution of height-based tx locktimes used at least twice

  2. MarcoFalke added the label Wallet on Dec 26, 2018
  3. MarcoFalke force-pushed on Dec 26, 2018
  4. SomberNight cross-referenced this on Dec 26, 2018 from issue wallet: randomise locktime of transactions a bit. also check if stale. by SomberNight
  5. in src/wallet/wallet.cpp:2619 in fa6cb28ff0 outdated
    2612 | @@ -2599,8 +2613,15 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
    2613 |      if (GetRandInt(10) == 0)
    2614 |          txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
    2615 |  
    2616 | +    // If our chain is lagging behind, we can't discourage fee sniping nor help
    2617 | +    // the privacy of high-latency transactions. To avoid leaking a potentially
    2618 | +    // unique "nLockTime fingerprint", set nLockTime to a constant.
    2619 | +    if (!IsCurrentForAntiFeeSniping()) txNew.nLockTime = 0;
    


    luke-jr commented at 10:37 PM on December 26, 2018:

    Why not just skip the above setting it?

  6. [test] wallet_txn_clone: Correctly clone txin sequence 453803adc9
  7. MarcoFalke force-pushed on Dec 26, 2018
  8. MarcoFalke force-pushed on Dec 26, 2018
  9. in src/wallet/wallet.cpp:2553 in fa7c5c7eef outdated
    2548 | +{
    2549 | +    if (IsInitialBlockDownload()) {
    2550 | +        return false;
    2551 | +    }
    2552 | +    constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
    2553 | +    if (chainActive.Tip()->GetBlockTime() < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
    


    Empact commented at 12:27 AM on December 27, 2018:

    nit: could return this directly (inverted)

  10. MarcoFalke force-pushed on Dec 27, 2018
  11. wallet: Avoid leaking locktime fingerprint when anti-fee-sniping fa48baf23e
  12. MarcoFalke force-pushed on Dec 27, 2018
  13. DrahtBot commented at 11:57 AM on December 28, 2018: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #14711 (Remove uses of chainActive and mapBlockIndex in wallet code by ryanofsky)
    • #10973 (Refactor: separate wallet from node by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  14. laanwj commented at 4:16 PM on January 2, 2019: member

    Concept ACK

    This is fine, as long as our node is connected to other nodes.

    I remember this was one of the remarks back then too. Anti-fee sniping only makes sense if it's catched up with the chain.

  15. fanquake requested review from meshcollider on Jan 3, 2019
  16. in src/wallet/wallet.cpp:2524 in fa48baf23e
    2515 | @@ -2516,6 +2516,65 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
    2516 |      return true;
    2517 |  }
    2518 |  
    2519 | +static bool IsCurrentForAntiFeeSniping(interfaces::Chain::Lock& locked_chain)
    2520 | +{
    2521 | +    if (IsInitialBlockDownload()) {
    2522 | +        return false;
    2523 | +    }
    2524 | +    constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
    


    meshcollider commented at 10:45 AM on January 3, 2019:

    Any rationale on why 8 hours was chosen? Seems sane though

  17. in src/wallet/wallet.cpp:2565 in fa48baf23e
    2560 | +
    2561 | +        // Secondly occasionally randomly pick a nLockTime even further back, so
    2562 | +        // that transactions that are delayed after signing for whatever reason,
    2563 | +        // e.g. high-latency mix networks and some CoinJoin implementations, have
    2564 | +        // better privacy.
    2565 | +        if (GetRandInt(10) == 0)
    


    laanwj commented at 8:30 AM on January 4, 2019:

    This if needs {} but I understand if you prefer to keep this move-only.

  18. pull[bot] referenced this in commit cebe910718 on Jan 10, 2019
  19. laanwj merged this on Jan 10, 2019
  20. laanwj closed this on Jan 10, 2019

  21. ryanofsky cross-referenced this on Jan 10, 2019 from issue Remove uses of chainActive and mapBlockIndex in wallet code by ryanofsky
  22. MarcoFalke deleted the branch on Jan 10, 2019
  23. MarcoFalke commented at 9:12 PM on January 10, 2019: member

    Unrelated also the same dataset (blocks 545k-555k (both inclusive), excl. coinbase) in a different representation:

    distribution of height-based tx locktimes

  24. keystrike cross-referenced this on Jan 15, 2019 from issue Setting nLockTime on all transactions allows offline clients to be fingerprinted by keystrike
  25. keystrike commented at 3:35 PM on January 15, 2019: contributor

    Thanks for fixing this. My analysis from 2017 is here, although the full output text file is no longer online. I had looked at all blocks to mid-2017. At that time there were 33 old locktimes in the blockchain in 94 transactions.

  26. MarcoFalke cross-referenced this on Mar 5, 2019 from issue wallet: use headers chain for anti fee sniping by ghost
  27. deadalnix referenced this in commit 35224e8f86 on Mar 26, 2020
  28. ftrader referenced this in commit 95a9c0ab4b on Aug 17, 2020
  29. kwvg referenced this in commit 7b905fc2a9 on Oct 16, 2021
  30. kwvg referenced this in commit 26f3988977 on Oct 19, 2021
  31. PastaPastaPasta referenced this in commit c70ada1e33 on Oct 19, 2021
  32. kwvg referenced this in commit d75e1e00f1 on Oct 21, 2021
  33. kwvg referenced this in commit e354a0e847 on Oct 31, 2021
  34. kwvg referenced this in commit e5c21c917e on Oct 31, 2021
  35. kwvg cross-referenced this on Oct 31, 2021 from issue merge bitcoin#10973: separate wallet from node by kwvg
  36. kwvg cross-referenced this on Nov 1, 2021 from issue merge bitcoin#10973, #15039, #15288: separate wallet from node by kwvg
  37. kwvg referenced this in commit aa2c3ed3e7 on Nov 1, 2021
  38. kwvg referenced this in commit 84087b4318 on Nov 4, 2021
  39. kwvg referenced this in commit 365e5c4205 on Nov 14, 2021
  40. kwvg referenced this in commit a97eebd068 on Nov 14, 2021
  41. UdjinM6 referenced this in commit a3a8bfee08 on Nov 15, 2021
  42. pravblockc referenced this in commit 878727b529 on Nov 18, 2021
  43. pravblockc referenced this in commit 491608ffa3 on Nov 18, 2021
  44. CharesFang cross-referenced this on Dec 8, 2021 from issue Backports from Bitcoin by CharesFang
  45. CharesFang cross-referenced this on Dec 8, 2021 from issue Backports from Bitcoin by CharesFang
  46. CharesFang cross-referenced this on Dec 9, 2021 from issue Backports from Bitcoin by CharesFang
  47. CharesFang cross-referenced this on Dec 9, 2021 from issue Backports from Bitcoin by CharesFang
  48. CharesFang cross-referenced this on Dec 9, 2021 from issue Backports from Bitcoin by CharesFang
  49. CharesFang cross-referenced this on Dec 11, 2021 from issue Backports from Bitcoin by CharesFang
  50. CharesFang cross-referenced this on Dec 12, 2021 from issue Backports from Bitcoin by CharesFang
  51. CharesFang cross-referenced this on Dec 13, 2021 from issue [Backport] Backports from Bitcoin by CharesFang
  52. bitcoin locked this on Dec 16, 2021

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-05-20 06:54 UTC