Skip to content

Conversation

kallewoof
Copy link
Contributor

@kallewoof kallewoof commented May 11, 2017

(Note: putting this on hold until #12257 is merged.)

#10065 brings up a privacy issue where a user can send a bunch of near-dust transactions to an address, which would be picked up by the coin select code when the owner funded transactions, connecting multiple transactions and addresses to the same user.

This adds a (by default turned off) flag -avoidreuse. When enabled, the wallet will mark any addresses that were used to fund a transaction as "dirty" and will avoid using them in funding additional transactions, unless an "allow dirty" flag is set.

It also adds support to allow dirty addresses in sendtoaddress. More tweaks to other RPC commands is necessary but I wanted to keep the PR as small as possible.

Retroactive flagging of dirty addresses can be done by rescanning the chain.

@luke-jr
Copy link
Member

luke-jr commented May 11, 2017

IMO this isn't complete unless incoming transactions to dirty addresses (even before being used!) are hidden as well (or at least flagged in some visible manner).

Also, shouldn't rescanning be sufficient?

@kallewoof kallewoof force-pushed the feature-white-black-address branch from 794beca to 2e85d49 Compare May 11, 2017 02:50
@kallewoof
Copy link
Contributor Author

kallewoof commented May 11, 2017

@luke-jr: Maybe I am misunderstanding you, but incoming transactions are irrelevant. The only thing that matters is when you spend from an address. Each time you do, that address is marked dirty and any UTXOs pointing to it are automatically considered dirty in this implementation. Am I missing a case?

Also, shouldn't rescanning be sufficient?

Oops - yes, rescanning is sufficient. Updated OP, thanks.

Edit: my definition of address reuse has always been "spending from the same address 2+ times", whereas @luke-jr's definition seems to be "any UTXOs which send to an address that has already been sent to". Both definitions would solve the issue in question, but the latter would mean people could no longer say "to support my work send BTC to [static address]" if they wished to use this feature. The question ultimately is "which one of the two definitions makes the most sense?"

@kallewoof kallewoof force-pushed the feature-white-black-address branch 2 times, most recently from 66a68dc to a05d03a Compare May 11, 2017 04:21
@@ -846,6 +875,14 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)

uint256 hash = wtxIn.GetHash();

if (GetBoolArg("-avoidreuse", false)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use a constant for the default value here.

@@ -3598,6 +3639,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
strUsage += HelpMessageOpt("-avoidreuse", _("Mark addresses which have been used to fund transactions in the past, and avoid reusing these in future funding, except when explicitly requested"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing default value (something like (strprintf(_("(default: %u)"), DEFAULT_AVOIDREUSE));).

if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) {
if (::IsMine(*this, dst)) {
if (dirty && !GetDestData(dst, "dirty", NULL)) {
AddDestData(dst, "dirty", "p"); // p for "present", opposite of absent (null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a AssertLockHeld(cs_wallet); somewhere above GetDestData?

@@ -416,12 +419,15 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
" transaction, just kept in your wallet.\n"
"5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
" The recipient will receive less bitcoins than you enter in the amount field.\n"
"6. allowdirty (boolean, optional, " + (GetBoolArg("-avoidreuse", false) ? "default=false" : "unavailable") + ") Allows spending from dirty addresses; addresses are considered\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why unavailable? Someone may just have enabled -avoidreuse but hasn't rescanned. Maybe keep a state somewhere if we have scanned with -avoidreuse up to the wallets bestblock.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It returns "unavailable" if you do not have the feature turned on. I don't want people to think they can avoid using dirty coins if they are running without the flag. I.e. even by explicitly saying allowdirty=false, it will still use dirty coins when -avoidreuse is not enabled.

You are right though, that it will still use dirty coins unless you rescan. Feels like that should be mentioned somewhere, but not sure where.

@kallewoof kallewoof force-pushed the feature-white-black-address branch 2 times, most recently from dd58577 to daf9e57 Compare May 11, 2017 08:11
@gmaxwell
Copy link
Contributor

I support the goal, but: If an address is paid 10 btc then 0.0001 btc and then a transaction spends the latter, A would be dirty and the 10 BTC are stuck. That seems sub-optimal.

The best idea I had to deal with that previously is that whenever you spend from A you make an effort to spend all payments to A or at least all non-dust payments to A. Then the only time you get dirty funds is when someone pays a non-negligible amount to an address after you've already spent to it.

If something is going to cause transactions to fail, we probably will need another kind of balance display to make the behavior explicable.

Independently from this (but also useful for it) we probably should have an icon in the transaction list for reused addresses. (Trefoil made of arrows? :P )

@kallewoof
Copy link
Contributor Author

kallewoof commented May 18, 2017

You are able to spend by using the allowdirty flag in sendtoaddress, and you can always make a raw transaction yourself. The intention of this is to give expert users a way to plug the gaping security hole that exists in the system -- to make it intuitive and wonderful for the average user is not an aspiration at this point (as mentioned, in particular RPC commands need some work before this could ever be made a default-on feature).

The solutions you present are all solutions an expert user could make use of with this implementation. It would simply stop their clients from shooting them (privacy wise) in the foot automatically.

Edit: Re-reading, I realize you are talking about coin select algorithm. That's an interesting idea. It would make sense to consider all "coins" going to A as a single coin for as long as you haven't spent from A yet. That way you select on an all-or-nothing basis (perhaps excluding dust).

@kallewoof kallewoof force-pushed the feature-white-black-address branch from daf9e57 to bc9084c Compare May 19, 2017 00:47
@kallewoof kallewoof force-pushed the feature-white-black-address branch from bc9084c to 1d7f054 Compare July 13, 2017 01:59
@kallewoof
Copy link
Contributor Author

Rebased (and code became slightly more clean thanks to new coin control being present).

@kallewoof kallewoof force-pushed the feature-white-black-address branch 4 times, most recently from d3385e3 to 7c7268b Compare September 28, 2017 09:05
@kallewoof kallewoof force-pushed the feature-white-black-address branch 2 times, most recently from 8ff3de5 to c3226d4 Compare October 11, 2017 09:19
@kallewoof kallewoof force-pushed the feature-white-black-address branch from c3226d4 to f596a41 Compare December 5, 2017 04:48
Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should creating transactions to dirty addresses fail?

Needs rebase.

Nit, commit messages don't have period.

@@ -27,6 +27,8 @@ class CCoinControl
boost::optional<CFeeRate> m_feerate;
//! Override the default confirmation target if set
boost::optional<unsigned int> m_confirm_target;
//! Allows inclusion of dirty (previously used) addresses
bool fAllowDirtyAddresses;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool allow_dirty_addresses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed this comment earlier; fixed.

@@ -500,6 +504,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
}
}

coin_control.fAllowDirtyAddresses = !request.params[8].isNull() && request.params[8].get_bool();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not default to DEFAULT_AVOIDREUSE.

@kallewoof kallewoof force-pushed the feature-white-black-address branch from f596a41 to 1f7bc58 Compare January 10, 2018 01:03
@kallewoof
Copy link
Contributor Author

kallewoof commented Jan 10, 2018

@promag Thanks for the review! Fixed the default usage issue.

Edit: and the commit message dots.

@kallewoof kallewoof force-pushed the feature-white-black-address branch from 1f7bc58 to 511234a Compare January 11, 2018 07:32
@kallewoof kallewoof force-pushed the feature-white-black-address branch from 511234a to 1f99433 Compare January 19, 2018 00:53
@kallewoof kallewoof changed the title [wallet] Optional '-avoidreuse' flag which defaults to not reusing addresses in sends [WIP] [wallet] Optional '-avoidreuse' flag which defaults to not reusing addresses in sends Feb 20, 2018
@kallewoof kallewoof closed this Mar 15, 2018
laanwj added a commit that referenced this pull request Jul 24, 2018
…n select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements #10386, in particular it addresses @luke-jr and @gmaxwell's concerns in #10386 (comment) and #10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in #10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621
@kallewoof kallewoof reopened this Jul 24, 2018
@DrahtBot
Copy link
Contributor

Needs rebase

@kallewoof kallewoof force-pushed the feature-white-black-address branch from 1f99433 to c353877 Compare July 25, 2018 06:40
@kallewoof kallewoof closed this Jul 25, 2018
@kallewoof kallewoof deleted the feature-white-black-address branch July 25, 2018 07:34
meshcollider added a commit that referenced this pull request Jun 18, 2019
5ebc6b0 bitcoind: update -avoidpartialspends description to account for auto-enable for avoid_reuse wallets (Karl-Johan Alm)
ada258f doc: release notes for avoid_reuse (Karl-Johan Alm)
2766955 wallet: enable avoid_partial_spends by default if avoid_reuse is set (Karl-Johan Alm)
8f2e208 test: add test for avoidreuse feature (Karl-Johan Alm)
0bdfbd3 wallet/rpc: add 'avoid_reuse' option to RPC commands (Karl-Johan Alm)
f904723 wallet/rpc: add setwalletflag RPC and MUTABLE_WALLET_FLAGS (Karl-Johan Alm)
8247a0d wallet: enable avoid_reuse feature (Karl-Johan Alm)
eec1566 wallet: avoid reuse flags (Karl-Johan Alm)
5892809 wallet: make IsWalletFlagSet() const (Karl-Johan Alm)
129a5ba wallet: rename g_known_wallet_flags constant to KNOWN_WALLET_FLAGS (Karl-Johan Alm)

Pull request description:

  Add a new wallet flag called `avoid_reuse` which, when enabled, will keep track of when a specific destination has been spent from, and will actively "blacklist" any new UTXOs which send to an already-spent-from destination.

  This improves privacy, as a payer could otherwise begin tracking a payee's wallet by regularly peppering a known UTXO with dust outputs, which would then be scooped up and used in payments by the payee, allowing the payer to map out (1) the inputs owned by the payee and (2) the destinations to which the payee is making payments.

  This replaces #10386 and together with the (now merged) #12257 it addresses #10065 in full. The concerns raised in #10386 (comment) are also addressed due to #12257.

  ~~Note: this builds on top of #15780.~~ (merged)

ACKs for commit 5ebc6b:
  jnewbery:
    ACK 5ebc6b0
  laanwj:
    Concept and code-review ACK 5ebc6b0
  meshcollider:
    Code review ACK 5ebc6b0
  achow101:
    ACK 5ebc6b0 modulo above nits

Tree-SHA512: fdef45826af544cbbb45634ac367852cc467ec87081d86d08b53ca849e588617e9a0a255b7e7bb28692d15332de58d6c3d274ac003355220e4213d7d9070742e
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jun 19, 2019
…rivacy

5ebc6b0 bitcoind: update -avoidpartialspends description to account for auto-enable for avoid_reuse wallets (Karl-Johan Alm)
ada258f doc: release notes for avoid_reuse (Karl-Johan Alm)
2766955 wallet: enable avoid_partial_spends by default if avoid_reuse is set (Karl-Johan Alm)
8f2e208 test: add test for avoidreuse feature (Karl-Johan Alm)
0bdfbd3 wallet/rpc: add 'avoid_reuse' option to RPC commands (Karl-Johan Alm)
f904723 wallet/rpc: add setwalletflag RPC and MUTABLE_WALLET_FLAGS (Karl-Johan Alm)
8247a0d wallet: enable avoid_reuse feature (Karl-Johan Alm)
eec1566 wallet: avoid reuse flags (Karl-Johan Alm)
5892809 wallet: make IsWalletFlagSet() const (Karl-Johan Alm)
129a5ba wallet: rename g_known_wallet_flags constant to KNOWN_WALLET_FLAGS (Karl-Johan Alm)

Pull request description:

  Add a new wallet flag called `avoid_reuse` which, when enabled, will keep track of when a specific destination has been spent from, and will actively "blacklist" any new UTXOs which send to an already-spent-from destination.

  This improves privacy, as a payer could otherwise begin tracking a payee's wallet by regularly peppering a known UTXO with dust outputs, which would then be scooped up and used in payments by the payee, allowing the payer to map out (1) the inputs owned by the payee and (2) the destinations to which the payee is making payments.

  This replaces bitcoin#10386 and together with the (now merged) bitcoin#12257 it addresses bitcoin#10065 in full. The concerns raised in bitcoin#10386 (comment) are also addressed due to bitcoin#12257.

  ~~Note: this builds on top of bitcoin#15780.~~ (merged)

ACKs for commit 5ebc6b:
  jnewbery:
    ACK 5ebc6b0
  laanwj:
    Concept and code-review ACK 5ebc6b0
  meshcollider:
    Code review ACK bitcoin@5ebc6b0
  achow101:
    ACK 5ebc6b0 modulo above nits

Tree-SHA512: fdef45826af544cbbb45634ac367852cc467ec87081d86d08b53ca849e588617e9a0a255b7e7bb28692d15332de58d6c3d274ac003355220e4213d7d9070742e
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 15, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 15, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 16, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 22, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 24, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 24, 2021
… in coin select

232f96f doc: Add release notes for -avoidpartialspends (Karl-Johan Alm)
e00b469 clean-up: Remove no longer used ivars from CInputCoin (Karl-Johan Alm)
43e04d1 wallet: Remove deprecated OutputEligibleForSpending (Karl-Johan Alm)
0128121 test: Add basic testing for wallet groups (Karl-Johan Alm)
59d6f7b wallet: Switch to using output groups instead of coins in coin selection (Karl-Johan Alm)
87ebce2 wallet: Add output grouping (Karl-Johan Alm)
bb629cb Add -avoidpartialspends and m_avoid_partial_spends (Karl-Johan Alm)
65b3eda wallet: Add input bytes to CInputCoin (Karl-Johan Alm)
a443d7a moveonly: CoinElegibilityFilter into coinselection.h (Karl-Johan Alm)
173e18a utils: Add insert() convenience templates (Karl-Johan Alm)

Pull request description:

  This PR adds an optional (off by default) `-avoidpartialspends` flag, which changes coin select to use output groups rather than outputs, where each output group corresponds to all outputs with the same destination.

  It is a privacy improvement, as each time you spend some output, any other output that is publicly associated with the destination (address) will also be spent at the same time, at the cost of fee increase for cases where coin select without group restriction would find a more optimal set of coins (see example below).

  For regular use without address reuse, this PR should have no effect on the user experience whatsoever; it only affects users who, for some reason, have multiple outputs with the same destination (i.e. address reuse).

  Nodes with this turned off will still try to avoid partial spending, if the fee of the resulting transaction is not greater than the fee of the original transaction.

  Example: a node has four outputs linked to two addresses `A` and `B`:

  * 1.0 btc to `A`
  * 0.5 btc to `A`
  * 1.0 btc to `B`
  * 0.5 btc to `B`

  The node sends 0.2 btc to `C`. Without `-avoidpartialspends`, the following coin selection will occur:
  * 0.5 btc to `A` or `B` is picked
  * 0.2 btc is output to `C`
  * 0.3 - fee is output to (unique change address)

  With `-avoidpartialspends`, the following will instead happen:
  * Both of (0.5, 1.0) btc to `A` or `B` is picked (one or the other pair)
  * 0.2 btc is output to `C`
  * 1.3 - fee is output to (unique change address)

  As noted, the pro here is that, assuming nobody sends to the address after you spend from it, you will only ever use one address once. The con is that the transaction becomes slightly larger in this case, because it is overpicking outputs to adhere to the no partial spending rule.

  This complements bitcoin#10386, in particular it addresses @luke-jr and @gmaxwell's concerns in bitcoin#10386 (comment) and bitcoin#10386 (comment).

  Together with `-avoidreuse`, this fully addresses the concerns in bitcoin#10065 I believe.

Tree-SHA512: 24687a4490ba59cf4198ed90052944ff4996653a4257833bb52ed24d058b3e924800c9b3790aeb6be6385b653b49e304453e5d7ff960e64c682fc23bfc447621

# Conflicts:
#	src/Makefile.am
#	src/bench/coin_selection.cpp
#	src/wallet/coincontrol.h
#	src/wallet/coinselection.cpp
#	src/wallet/coinselection.h
#	src/wallet/init.cpp
#	src/wallet/test/coinselector_tests.cpp
#	src/wallet/wallet.cpp
#	src/wallet/wallet.h
#	test/functional/test_runner.py
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants