Wallet fingerprinting and `avoidpartialspends` #22018

issue ghost opened this issue on May 21, 2021
  1. ghost commented at 9:45 PM on May 21, 2021: none

    Issue

    In Bitcoin Core you cannot spend unconfirmed UTXO (except using createrawtransaction or createpsbt in CLI) and if avoidpartialspends=1 UTXOs will grouped by addresses. So an attacker can send small amounts in Tx1(100sat/vByte) and Tx2(1sat/vByte) to address A. If only one of the UTXO (Tx1) associated with address A is spent then it can be assumed the victim is using Bitcoin Core wallet.

    If avoidpartialspends=0 (default) then its easier to identify, get more information about victim's addresses because other wallets do the grouping by default.

    Expected behavior

    avoidpartialspends=1 should be default IMO

    1. If 'reused address' group has an unconfirmed UTXO, then the whole group is unconfirmed.
    2. Users should be able to spend unconfirmed UTXO

    If we only fix 1, attacker can do more than just fingerprinting because users will be unable to spend from addresses used in attack except if they are good with Bitcoin Core RPCs like createrawtransaction or createpsbt. Or we can consider it same as Joinmarket in which any deposit to an already-used address is freezed by default.

    If we only fix 2, it may help but not sure if enough people will agree to such change based on https://github.com/bitcoin-core/gui/issues/242#issuecomment-802666743

    Actual behavior

    Examples of few transactions in different wallets (PoC):

    Bitcoin Core: e710968190ce5ee3d4a23c5c2773ae227baddbe8b2221a6677f46d030cba6741 (using GUI) 82d3180b7f6bd29acf8c21c2b6cfdc2f9afa4660b5abd53f2536e2741b5e221e (using CLI)

    Samourai: 60b80ecace4d1357f797b1d62eb0f514a57779fc5d37256f8256e5be229f9190 Electrum: 35ce2d882eaf870011002958351aef7ef882720116c8abbb9d5b68d97d490d28 Wasabi: 35ce2d882eaf870011002958351aef7ef882720116c8abbb9d5b68d97d490d28

    To reproduce

    1. Create a new wallet
    2. Create new receiving address
    3. Send 0.01 to address returned in (2) and wait for 1 confirmation
    4. Send 0.01 to address returned in (2)
    5. Send 0.008 to a random address

    System information

    Bitcoin Core v0.21.1

    Other information

    There are other things which may help in wallet fingerprinting: version, locktime, rbf, fee estimation, change address, address type etc. but I wanted to focus on avoidpartialspends in this issue.

    Sending small amounts in more than 10 transactions to same address can also help in fingerprinting as there are no such max limits in lot of other wallets. OUTPUT_GROUP_MAX_ENTRIES will be increased to 100 if PR: #18418 is merged which makes the attack costly but still worth trying depending on the victim, attacker's goal and money. IMO there should not be any limit like other wallets or let the users decide. Bitcoin Core with default settings is even easier to attack because other wallets that I mentioned above use the groups/buckets by default.

  2. unknown added the label Bug on May 21, 2021
  3. achow101 commented at 10:00 PM on May 21, 2021: member

    Users should be able to spend unconfirmed UTXO

    NACK. The dangers of spending untrusted and unconfirmed UTXOs are well understood. We should not be spending such UTXOs.


    I don't think it is useful to compare our behavior to a select few wallets. Rather the analysis needs to be done across all transactions on the blockchain. While not avoiding partial spends may be a fingerprint, avoiding partial spends may also provide a way to fingerprint transactions. It's not as if this option magically makes fingerprinting impossible.

  4. ghost commented at 5:46 AM on May 25, 2021: none

    The dangers of spending untrusted and unconfirmed UTXOs are well understood. We should not be spending such UTXOs.

    What are these dangers that don't affect other wallets or power users who can use CLI?

    I don't think it is useful to compare our behavior to a select few wallets. Rather the analysis needs to be done across all transactions on the blockchain

    I can include few other wallets that are used more. It is a privacy issue even if attacker can identify core wallet addresses based on few wallets that victim might be using.

    It's not as if this option magically makes fingerprinting impossible.

    There is no option or technology that magically solves all privacy issues.

  5. fanquake removed the label Bug on May 25, 2021
  6. fjahr commented at 12:06 AM on May 27, 2021: contributor

    NACK on spending unconfirmed outputs. Just because other wallets do dangerous things we don't have to do the same thing. This has a higher priority than wallet fingerprinting in almost everyone's mind, I think. But I also don't have a good, exhaustive resource on the dangers of 0-conf handy at the moment, I will see if I can find something soon.

    For your other comments concerning OUTPUT_GROUP_MAX_ENTRIES I think #17854 is relevant. I had briefly started to work on an alternative suggestion back then, maybe I can dig up an old branch.

  7. ghost commented at 7:25 AM on May 27, 2021: none

    NACK on spending unconfirmed outputs. Just because other wallets do dangerous things we don't have to do the same thing. This has a higher priority than wallet fingerprinting in almost everyone's mind, I think. But I also don't have a good, exhaustive resource on the dangers of 0-conf handy at the moment, I will see if I can find something soon.

    How about locking all UTXOs associated with a scriptpubkey until all are confirmed?

    For your other comments concerning OUTPUT_GROUP_MAX_ENTRIES I think #17854 is relevant. I had briefly started to work on an alternative suggestion back then, maybe I can dig up an old branch

    Thanks for the link. Alternative suggestion branch will be helpful if you can find it.

  8. harding commented at 12:45 AM on May 29, 2021: contributor

    I'm also NACK on spending incoming unconfirmed outputs unless the user is made aware of the many problems associated with that behavior.


    @prayank23

    How about locking all UTXOs associated with a scriptpubkey until all are confirmed?

    I think that would require additional communication to the user about why they can't spend their funds. For existing incoming payments, the GUI and the RPCs track confirmed and unconfirmed balances separately, so I think it's pretty clear why you can't spend the money you just received. But if you previously received a confirmed 1.00 BTC to address bc1blahblah and you just received an additional unconfirmed 0.01 BTC to that same address, it would be confusing why you couldn't spend your previous 1.00 BTC balance.

    Additionally, an attacker could prevent an honest user from being able to spending their coins by simply always keeping a transaction paying a reused address in the mempool.

  9. achow101 commented at 3:32 AM on May 29, 2021: member

    How about locking all UTXOs associated with a scriptpubkey until all are confirmed?

    NACK. It would make it trivial to make it impossible for an attacker to start locking people out of their funds. All that it would take is for an attacker to create a dust spam transaction that sends to a bunch of addresses. If this transaction were at the min relay fee, and if fees were above the minimum, then the transaction could remain in the mempool for a very long time, during which time all of the users whose addresses are in receiving the spam would be unable to send some or all of their funds. Furthermore, this would become another way to fingerprint a user - from this, it would be possible to learn that users are not using Bitcoin Core.

  10. ghost commented at 7:03 AM on May 29, 2021: none

    @harding

    I'm also NACK on spending incoming unconfirmed outputs unless the user is made aware of the many problems associated with that behavior.

    Is there a link to know about all the problems associated with spending unconfirmed outputs? How can we make the users aware of these things?

    I think that would require additional communication to the user about why they can't spend their funds.

    It can be done with a warning message in GUI, highlight the locked unspents with red color etc. and similar warning printed as log in bitcoind.

    it would be confusing why you couldn't spend your previous 1.00 BTC balance

    Confusion in some cases is better than unknowingly using one of inputs selected by algorithm that affects your privacy. People who use coin control for all transactions will never have issues but others who use coin selection algorithm are already confused lot of times about the inputs selected in different transactions.

    Additionally, an attacker could prevent an honest user from being able to spending their coins by simply always keeping a transaction paying a reused address in the mempool.

    I have mentioned this above but I think it will not be an issue. Consider this example:

    Attacker sends 0.001 BTC to one of my address so I am unable to use UTXOs associated with it.

    Positive: Automatically locking UTXOs associated with the address is good for my privacy and attacker has no clue about my wallet or reasons for not spending these UTXOs

    Negative: I am unable to use some of my bitcoin. What can I do to change this? Unlock UTXOs if I really want to use them.

    At least I know someone is trying to know more about my wallet and transactions. @achow101

    Furthermore, this would become another way to fingerprint a user - from this, it would be possible to learn that users are not using Bitcoin Core.

    This is incorrect. If someone sends me 0.001 BTC to one of my address which already has 0.01 UTXO associated with it, it is almost impossible to guess the reason why I did not spend them yet. It could be any wallet and I have just decide not use them yet or they were not selected by algorithm.


    There is a problem and I am looking for solutions. Unfortunately NACKs with no alternative solution do not solve the problem.

  11. harding commented at 7:58 AM on May 29, 2021: contributor

    Is there a link to know about all the problems associated with spending unconfirmed outputs?

    Not that I know of, but I can list the problems I'm aware of:

    • If the payment to you is conflicted, your re-spend becomes invalid but you still might be legally obligated to pay your receipient
    • If the payment to you is RBF'd, your re-spend becomes invalid, requiring you to issue a new payment. This can be quite an ordeal (you might need to ask for a new invoice and a new exchange rate, you might need to update your accounting records)
    • If you issue a new payment, you must be absolutely certain it conflicts with all previous payments you issued for that item/service so that a mempool reshuffling or block chain reorg doesn't result in you double paying
    • You payment might not be relayed due to mempool ancestor/descendent limits
    • All the problems above are multiplied by each additional person spending unconfirmed incoming payments, e.g. if Alice pays Bob who pays Carol who pays Dan, now payment to Dan are broken each time any one of Alice, Bob, or Carol decides to RBF fee bump their transaction, or when Bob's decides to create a large transaction with his change output, or Carol's low feerate transaction gets dropped from the mempool, etc.

    How can we make the users aware of these things?

    I think that's too much technical detail to put on end users for such a minor issue as spending money they haven't fully received yet. Even if we could solve all of the above problems with a nice UI, I'd be wary of making it easy for people to spend unconfirmed incoming payments---letting users do that minimizes the essential security difference between unconfirmed transactions and confirmed transactions. For developers, I think it's ok to allow them to bypass the restriction if we (or someone else) provides documentation. I think the recently-added exceptions to the PSBT commands is a reasonable way to do that.

    Confusion in some cases is better than unknowingly using one of inputs selected by algorithm that affects your privacy. People who use coin control for all transactions will never have issues but others who use coin selection algorithm are already confused lot of times about the inputs selected in different transactions.

    Huh? Most users don't care about what inputs gets selected, so why would they be confused by that?

    Negative: I am unable to use some of my bitcoin. What can I do to change this? Unlock UTXOs if I really want to use them.

    At least I know someone is trying to know more about my wallet and transactions.

    A better approach IMO to making Bitcoin Core users perform extra steps to spend their money would be to get other wallets to use the same safety-first approach of Bitcoin Core to not allowing spending of incoming unconfirmed outputs.

    There is a problem and I am looking for solutions. Unfortunately NACKs with no alternative solution do not solve the problem.

    The only truly effective approach to preventing wallet fingerprinting is to get all wallets to implement a standardized set of behavior. To do that, I think you want to first identify what the best practices are and then try to get every wallet to implement those best practices. In the case of incoming unconfirmed outputs, I think the best practice is to not spend them (except for CPFP fee bumping). Bitcoin Core implements that non-spending behavior, so I think the goal should be to get other wallets to adopt that same behavior.

  12. ghost commented at 8:37 AM on May 29, 2021: none

    Not that I know of, but I can list the problems I'm aware of:

    Thanks for sharing. Will research more about this.

    Huh? Most users don't care about what inputs gets selected, so why would they be confused by that?

    This problem is only applicable to users who have saved avoidpartialspends=1 in bitcoin.conf so we can assume they care about privacy. There are few questions that I regularly see on Stackexchange about confusion related to inputs used in a transaction.

    A better approach IMO to making Bitcoin Core users perform extra steps to spend their money would be to get other wallets to use the same safety-first approach of Bitcoin Core to not allowing spending of incoming unconfirmed outputs.

    Do we need a BIP for this?

    The only truly effective approach to preventing wallet fingerprinting is to get all wallets to implement a standardized set of behavior. To do that, I think you want to first identify what the best practices are and then try to get every wallet to implement those best practices

    Either spend all coins associated with a scriptpubkey in a transaction or none is one of the best practices.

    Is Bitcoin Core following it? No Did I try to suggest this change? Yes (https://github.com/bitcoin/bitcoin/pull/18418#issuecomment-847564511) Was it considered? No Will it be considered? No (https://github.com/bitcoin/bitcoin/pull/18418#issuecomment-847825592)

    It has been mentioned lot of times that Bitcoin Core needs more reviewers. What is the use of spending time, doing research, testing something and providing relevant information if it doesn't matter?

  13. harding commented at 9:26 AM on May 29, 2021: contributor

    Do we need a BIP for this?

    We don't need BIPs for best practices, but we've had problems with bad practices getting BIPs and people implementing them because they thought they were "standards". In those cases, it may be a good idea to BIP the best practice.

    Either spend all coins associated with a scriptpubkey in a transaction or none is one of the best practices.

    Is Bitcoin Core following it? No

    I think this is a matter of interpretation. IMO you don't actually have a coin until it's confirmed, so Bitcoin Core's opt-in behavior of avoiding partial spends is following the best practice when you only consider confirmed coins.

    It has been mentioned lot of times that Bitcoin Core needs more reviewers. What is the use of spending time, doing research, testing something and providing relevant information if it doesn't matter?

    I understand that it's frustrating when your suggestions aren't accepted. It's also uncomfortable for those of us who are criticizing your idea---we want you to have a good experience contributing to Bitcoin Core and we're sorry when that doesn't happen. The way to ensure your time hasn't been wasted is to try to understand the concerns raised on this issue so that you can apply them towards future proposals.

    For example, we currently use avoidpartialspends by default when there's no fee difference between using it and not using it. If you propose to implement the case where we don't spend from a set of reused scripts when there's an unconfirmed payment to one of those scripts in any case where avoiding that partial spend ensures there's still sufficient funds and when it doesn't increase fees, maybe your idea might find more traction. That's a lot more work to implement, I expect, but it moves us slightly closer to your goal without producing any adverse effects for the user.

    Alternatively, you could look into other past suggestions to address problems with avoding partial spends. E.g., I think there was a suggestion that, once a script had been spent once, any further funds received to that script would be shunted into a sub-wallet so that they wouldn't be mingled with the main wallet's funds. Users could then run their "dirty" funds through a coinjoin once a year (or whatever) before moving them back into their main wallet.

    In short, I think there's still options available in the solution space if you want to keep trying. But if you don't want to keep trying, I think that's ok too. In the seven years I've been contributing to Bitcoin, I've often had to give up on ideas when I realized they were either impractical or too big for me to accomplish. This has allowed me to focus my time on things I could accomplish (and even, sometimes, do well).

  14. ghost commented at 10:51 AM on May 29, 2021: none

    I think this is a matter of interpretation. IMO you don't actually have a coin until it's confirmed, so Bitcoin Core's opt-in behavior of avoiding partial spends is following the best practice when you only consider confirmed coins.

    There are two things:

    1. Unable to spend unconfirmed UTXOs
    2. OUTPUT_GROUP_MAX_ENTRIES

    My suggestion mentioned in last comment was for 2. It should not be 10 or 100 or any random number chosen by a group of devs which is neither best practice nor similar to other wallets.

    How are few other wallets that managing such UTXOs?

    https://github.com/spesmilo/electrum/blob/cad4e77853b1d3ae5fdaaa868c2fce67780a8870/electrum/coinchooser.py#L441

    https://github.com/zkSNACKs/WalletWasabi/pull/2338

    https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/release-notes/release-notes-0.6.2.md#auto-freeze-of-deposits-to-reused-addresses

    Alternatively, you could look into other past suggestions to address problems with avoding partial spends. E.g., I think there was a suggestion that, once a script had been spent once, any further funds received to that script would be shunted into a sub-wallet so that they wouldn't be mingled with the main wallet's funds. Users could then run their "dirty" funds through a coinjoin once a year (or whatever) before moving them back into their main wallet.

    Interesting. I like this solution and will experiment in next few days to figure out implementation.

    In short, I think there's still options available in the solution space if you want to keep trying.

    Agree and I will keep trying until I resolve the issues.

  15. harding commented at 8:33 PM on May 29, 2021: contributor

    @prayank23

    Interesting. I like this solution and will experiment in next few days to figure out implementation.

    You probably want to start by looking at #13756 , which implements the behavior of preventing reuse. Additional improvements should probably be built on top of that.

  16. MarcoFalke commented at 3:25 PM on August 11, 2022: member

    The feature request didn't seem to attract much attention in the past. Also, the issue seems not important enough right now to keep it sitting around idle in the list of open issues.

    Closing due to lack of interest. Pull requests with improvements are always welcome.

  17. MarcoFalke closed this on Aug 11, 2022

  18. bitcoin locked this on Aug 11, 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-17 15:14 UTC

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