0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-23 12:33:26 -05:00
bitcoin-bitcoin-core/src/wallet
Andrew Chow 1abbae65eb
Merge bitcoin/bitcoin#24584: wallet: avoid mixing different OutputTypes during coin selection
71d1d13627 test: add unit test for AvailableCoins (josibake)
da03cb41a4 test: functional test for new coin selection logic (josibake)
438e04845b wallet: run coin selection by `OutputType` (josibake)
77b0707206 refactor: use CoinsResult struct in SelectCoins (josibake)
2e67291ca3 refactor: store by OutputType in CoinsResult (josibake)

Pull request description:

  # Concept

  Following https://github.com/bitcoin/bitcoin/pull/23789, Bitcoin Core wallet will now generate a change address that matches the payment address type. This improves privacy by not revealing which of the outputs is the change at the time of the transaction in scenarios where the input address types differ from the payment address type. However, information about the change can be leaked in a later transaction. This proposal attempts to address that concern.

  ## Leaking information in a later transaction

  Consider the following scenario:

  ![mix input types(1)](https://user-images.githubusercontent.com/7444140/158597086-788339b0-c698-4b60-bd45-9ede4cd3a483.png)

  1. Alice has a wallet with bech32 type UTXOs and pays Bob, who gives her a P2SH address
  2. Alice's wallet generates a P2SH change output, preserving her privacy in `txid: a`
  3. Alice then pays Carol, who gives her a bech32 address
  4. Alice's wallet combines the P2SH UTXO with a bech32 UTXO and `txid: b` has two bech32 outputs

  From a chain analysis perspective, it is reasonable to infer that the P2SH input in `txid: b` was the change from `txid: a`. To avoid leaking information in this scenario, Alice's wallet should avoid picking the P2SH output and instead fund the transaction with only bech32 Outputs. If the payment to Carol can be funded with just the P2SH output, it should be preferred over the bech32 outputs as this will convert the P2SH UTXO to bech32 UTXOs via the payment and change outputs of the new transaction.

  **TLDR;** Avoid mixing output types, spend non-default `OutputTypes` when it is economical to do so.

  # Approach

  `AvailableCoins` now populates a struct, which makes it easier to access coins by `OutputType`. Coin selection tries to find a funding solution by each output type and chooses the most economical by waste metric. If a solution can't be found without mixing, coin selection runs over the entire wallet, allowing mixing, which is the same as the current behavior.

  I've also added a functional test (`test/functional/wallet_avoid_mixing_output_types.py`) and unit test (`src/wallet/test/availablecoins_tests.cpp`.

ACKs for top commit:
  achow101:
    re-ACK 71d1d13627
  aureleoules:
    ACK 71d1d13627.
  Xekyo:
    reACK 71d1d13627 via `git range-diff master 6530d19 71d1d13`
  LarryRuane:
    ACK 71d1d13627

Tree-SHA512: 2e0716efdae5adf5479446fabc731ae81d595131d3b8bade98b64ba323d0e0c6d964a67f8c14c89c428998bda47993fa924f3cfca1529e2bd49eaa4e31b7e426
2022-07-28 18:16:51 -04:00
..
rpc Merge bitcoin/bitcoin#24584: wallet: avoid mixing different OutputTypes during coin selection 2022-07-28 18:16:51 -04:00
test Merge bitcoin/bitcoin#24584: wallet: avoid mixing different OutputTypes during coin selection 2022-07-28 18:16:51 -04:00
bdb.cpp compat: document S_I* defines when building for Windows 2022-07-20 13:10:07 +01:00
bdb.h scripted-diff: replace non-standard fixed width integer types (u_int... -> uint`...) 2022-05-12 15:44:24 +02:00
coincontrol.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
coincontrol.h scripted-diff: rename fAllowOtherInputs -> m_allow_other_inputs 2022-06-19 20:32:51 -03:00
coinselection.cpp Revert "bnb: exit selection when best_waste is 0" 2022-06-28 17:27:06 -04:00
coinselection.h Set effective_value when initializing a COutput 2022-05-21 11:25:54 -04:00
context.cpp refactor: use C++11 default initializers 2022-05-17 17:18:58 +01:00
context.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
crypter.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
crypter.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
db.cpp Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
db.h Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
dump.cpp Use HashWriter where possible 2022-07-20 15:34:36 +02:00
dump.h Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
external_signer_scriptpubkeyman.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
external_signer_scriptpubkeyman.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
feebumper.cpp send: refactor CreateTransaction flow to return a BResult<CTransactionRef> 2022-07-08 11:18:35 -03:00
feebumper.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
fees.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
fees.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
init.cpp scripted-diff: Avoid incompatibility with CMake AUTOUIC feature 2022-06-14 10:38:51 +02:00
interfaces.cpp refactor: Return BResult from restoreWallet 2022-07-12 19:20:01 +02:00
ismine.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
load.cpp wallet: Postpone NotifyWalletLoaded() for encrypted wallets 2022-03-30 21:28:53 +02:00
load.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
receive.cpp Merge bitcoin/bitcoin#25543: wallet: cleanup cached amount and input mine check code 2022-07-20 16:59:41 -04:00
receive.h wallet: unify CachedTxGetImmatureCredit and CachedTxGetImmatureWatchOnlyCredit 2022-07-05 10:10:27 -03:00
salvage.cpp Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
salvage.h Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
scriptpubkeyman.cpp wallet: refactor GetNewDestination, use BResult 2022-07-08 11:18:35 -03:00
scriptpubkeyman.h wallet: refactor GetNewDestination, use BResult 2022-07-08 11:18:35 -03:00
spend.cpp wallet: run coin selection by OutputType 2022-07-19 18:42:15 +02:00
spend.h wallet: run coin selection by OutputType 2022-07-19 18:42:15 +02:00
sqlite.cpp scripted-diff: Convert global Mutexes to GlobalMutexes 2022-05-21 01:23:23 +10:00
sqlite.h Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
transaction.cpp Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
transaction.h wallet: add GetWitnessHash() 2022-02-01 08:44:51 -03:00
wallet.cpp Merge bitcoin/bitcoin#25494: indexes: Stop using node internal types 2022-07-19 21:42:48 +01:00
wallet.h interfaces, refactor: Add more block information to block connected notifications 2022-07-18 13:39:55 -05:00
walletdb.cpp Merge bitcoin/bitcoin#25383: wallet: don't read db every time that a new 'WalletBatch' is created 2022-06-30 18:38:20 +02:00
walletdb.h walletdb: Create a mock database of specific type 2022-05-10 11:54:02 -04:00
wallettool.cpp Replace use of ArgsManager with DatabaseOptions 2022-03-16 08:26:28 +01:00
wallettool.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00
walletutil.cpp Use ArgsManager::GetPathArg() for "-walletdir" option 2022-02-09 19:31:23 +02:00
walletutil.h Add src/wallet/* code to wallet:: namespace 2022-01-06 22:14:16 -05:00