Concept
Following #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:
- Alice has a wallet with bech32 type UTXOs and pays Bob, who gives her a P2SH address
- Alice’s wallet generates a P2SH change output, preserving her privacy in
txid: a
- Alice then pays Carol, who gives her a bech32 address
- 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
.