Skip to content

Commit

Permalink
Merge bitcoin#13756: wallet: "avoid_reuse" wallet flag for improved p…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
meshcollider authored and sidhujag committed Jun 19, 2019
1 parent 9dcb976 commit 6bcaa95
Show file tree
Hide file tree
Showing 11 changed files with 477 additions and 27 deletions.
39 changes: 39 additions & 0 deletions doc/release-notes-13756.md
@@ -0,0 +1,39 @@
Coin selection
--------------

### Reuse Avoidance

A new wallet flag `avoid_reuse` has been added (default off). When enabled,
a wallet will distinguish between used and unused addresses, and default to not
use the former in coin selection.

(Note: rescanning the blockchain is required, to correctly mark previously
used destinations.)

Together with "avoid partial spends" (present as of Bitcoin v0.17), this
addresses a serious privacy issue where a malicious user can track spends by
peppering a previously paid to address with near-dust outputs, which would then
be inadvertently included in future payments.

New RPCs
--------

- A new `setwalletflag` RPC sets/unsets flags for an existing wallet.


Updated RPCs
------------

Several RPCs have been updated to include an "avoid_reuse" flag, used to control
whether already used addresses should be left out or included in the operation.
These include:

- createwallet
- getbalance
- sendtoaddress

In addition, `sendtoaddress` has been changed to enable `-avoidpartialspends` when
`avoid_reuse` is enabled.

The listunspent RPC has also been updated to now include a "reused" bool, for nodes
with "avoid_reuse" enabled.
4 changes: 4 additions & 0 deletions src/rpc/client.cpp
Expand Up @@ -38,6 +38,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendtoaddress", 4, "subtractfeefromamount" },
{ "sendtoaddress", 5 , "replaceable" },
{ "sendtoaddress", 6 , "conf_target" },
{ "sendtoaddress", 8, "avoid_reuse" },
{ "settxfee", 0, "amount" },
{ "sethdseed", 0, "newkeypool" },
{ "getreceivedbyaddress", 1, "minconf" },
Expand All @@ -50,6 +51,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listreceivedbylabel", 2, "include_watchonly" },
{ "getbalance", 1, "minconf" },
{ "getbalance", 2, "include_watchonly" },
{ "getbalance", 3, "avoid_reuse" },
{ "getblockhash", 0, "height" },
{ "waitforblockheight", 0, "height" },
{ "waitforblockheight", 1, "timeout" },
Expand Down Expand Up @@ -143,6 +145,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "setban", 2, "bantime" },
{ "setban", 3, "absolute" },
{ "setnetworkactive", 0, "state" },
{ "setwalletflag", 1, "value" },
{ "getmempoolancestors", 1, "verbose" },
{ "getmempooldescendants", 1, "verbose" },
{ "bumpfee", 1, "options" },
Expand All @@ -164,6 +167,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "rescanblockchain", 1, "stop_height"},
{ "createwallet", 1, "disable_private_keys"},
{ "createwallet", 2, "blank"},
{ "createwallet", 4, "avoid_reuse"},
{ "getnodeaddresses", 0, "count"},
{ "stop", 0, "wait" },
{ "getsuperblockbudget", 0, "index" },
Expand Down
2 changes: 2 additions & 0 deletions src/script/ismine.h
Expand Up @@ -20,7 +20,9 @@ enum isminetype
ISMINE_NO = 0,
ISMINE_WATCH_ONLY = 1 << 0,
ISMINE_SPENDABLE = 1 << 1,
ISMINE_USED = 1 << 2,
ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE,
ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED,
ISMINE_ENUM_ELEMENTS,
};
/** used for bitflags of isminetype */
Expand Down
1 change: 1 addition & 0 deletions src/wallet/coincontrol.cpp
Expand Up @@ -13,6 +13,7 @@ void CCoinControl::SetNull()
fAllowOtherInputs = false;
fAllowWatchOnly = false;
m_avoid_partial_spends = gArgs.GetBoolArg("-avoidpartialspends", DEFAULT_AVOIDPARTIALSPENDS);
m_avoid_address_reuse = false;
setSelected.clear();
m_feerate.reset();
fOverrideFeeRate = false;
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/coincontrol.h
Expand Up @@ -34,6 +34,8 @@ class CCoinControl
boost::optional<bool> m_signal_bip125_rbf;
//! Avoid partial use of funds sent to a given address
bool m_avoid_partial_spends;
//! Forbids inclusion of dirty (previously used) addresses
bool m_avoid_address_reuse;
//! Fee estimation mode to control arguments to estimateSmartFee
FeeEstimateMode m_fee_mode;
//! Minimum chain depth value for coin availability
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/init.cpp
Expand Up @@ -34,7 +34,7 @@ const WalletInitInterface& g_wallet_init_interface = WalletInit();
void WalletInit::AddWalletOptions() const
{
gArgs.AddArg("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(DEFAULT_ADDRESS_TYPE)), false, OptionsCategory::WALLET);
gArgs.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u)", DEFAULT_AVOIDPARTIALSPENDS), false, OptionsCategory::WALLET);
gArgs.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u (always enabled for wallets with \"avoid_reuse\" enabled))", DEFAULT_AVOIDPARTIALSPENDS), false, OptionsCategory::WALLET);
gArgs.AddArg("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)", false, OptionsCategory::WALLET);
gArgs.AddArg("-disablewallet", "Do not load the wallet and disable wallet RPC calls", false, OptionsCategory::WALLET);
gArgs.AddArg("-discardfee=<amt>", strprintf("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
Expand Down

0 comments on commit 6bcaa95

Please sign in to comment.