0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00
bitcoin-core/src/wallet
Ava Chow 1d334d830f
Merge bitcoin/bitcoin#27877: wallet: Add CoinGrinder coin selection algorithm
13161ecf03 opt: Skip over barren combinations of tiny UTXOs (Murch)
b7672c7cdd opt: Skip checking max_weight separately (Murch)
1edd2baa37 opt: Cut if last addition was minimal weight (Murch)
5248e2a60d opt: Skip heavier UTXOs with same effective value (Murch)
9124c73742 opt: Tiebreak UTXOs by weight for CoinGrinder (Murch)
451be19dc1 opt: Skip evaluation of equivalent input sets (Murch)
407b1e3432 opt: Track remaining effective_value in lookahead (Murch)
5f84f3cc04 opt: Skip branches with worse weight (Murch)
d68bc74fb2 fuzz: Test optimality of CoinGrinder (Murch)
67df6c629a fuzz: Add CoinGrinder fuzz target (Murch)
1502231229 coinselection: Track whether CG completed (Murch)
7488acc646 test: Add coin_grinder_tests (Murch)
6cc9a46cd0 coinselection: Add CoinGrinder algorithm (Murch)
89d0956643 opt: Tie-break UTXO sort by waste for BnB (Murch)
aaee65823c doc: Document max_weight on BnB (Murch)

Pull request description:

  ***Please refer to the [topic on Delving Bitcoin](https://delvingbitcoin.org/t/gutterguard-and-coingrinder-simulation-results/279) discussing Gutter Guard/Coingrinder simulation results.***

  Adds a coin selection algorithm that minimizes the weight of the input set while creating change.

  Motivations
  ---

  - At high feerates, using unnecessary inputs can significantly increase the fees
  - Users are upset when fees are relatively large compared to the amount sent
  - Some users struggle to maintain a sufficient count of UTXOs in their wallet

  Approach
  ---

  So far, Bitcoin Core has used a balanced approach to coin selection, where it will generate multiple input set candidates using various coin selection algorithms and pick the least wasteful among their results, but not explicitly minimize the input set weight. Under some circumstances, we _do_ want to minimize the weight of the input set. Sometimes changeless solutions require many or heavy inputs, and there is not always a changeless solution for Branch and Bound to find in the first place. This can cause expensive transactions unnecessarily. Given a wallet with sufficient funds, `CoinGrinder` will pick the minimal-waste input set for a transaction with a change output. The current implementation only runs `CoinGrinder` at feerates over 3×long-term-feerate-estimate (by default 30 ṩ/vB), which may be a decent compromise between our goal to reduce costs for the users, but still permit transactions at lower feerates to naturally reduce the wallet’s UTXO pool to curb bloat.

  Trade-offs
  ---

  Simulations for my thesis on coin selection ([see Section 6.3.2.1 [PDF]](https://murch.one/erhardt2016coinselection.pdf)) suggest that minimizing the input set for all transactions tends to grind a wallet’s UTXO pool to dust (pun intended): an approach selecting inputs per coin-age-priority (in effect similar to “largest first selection”) on average produced a UTXO pool with 15× the UTXO count as Bitcoin Core’s Knapsack-based Coin Selection then (in 2016). Therefore, I do not recommend running `CoinGrinder` under all circumstances, but only at extreme feerates or when we have another good reason to minimize the input set for other reasons. In the long-term, we should introduce additional metrics to score different input set candidates, e.g. on basis of their privacy and wallet health impact, to pick from all our coin selection results, but until then, we may want to limit use of `CoinGrinder` in other ways.

ACKs for top commit:
  achow101:
    ACK 13161ecf03
  sr-gi:
    ACK [13161ec](13161ecf03)
  sipa:
    ACK 13161ecf03

Tree-SHA512: 895b08b2ebfd0b71127949b7dba27146a6d10700bf8590402b14f261e7b937f4e2e1b24ca46de440c35f19349043ed2eba4159dc2aa3edae57721384186dae40
2024-02-09 16:38:13 -05:00
..
rpc wallet: clarify replaced_by_txid and replaces_txid in help output 2024-01-23 17:34:16 -07:00
test Merge bitcoin/bitcoin#27877: wallet: Add CoinGrinder coin selection algorithm 2024-02-09 16:38:13 -05:00
bdb.cpp refactor: Return enum in LockDirectory 2023-10-26 10:25:22 +02:00
bdb.h
coincontrol.cpp wallet: Explicitly preserve scriptSig and scriptWitness in CreateTransaction 2023-12-08 17:12:19 -05:00
coincontrol.h wallet: Explicitly preserve scriptSig and scriptWitness in CreateTransaction 2023-12-08 17:12:19 -05:00
coinselection.cpp opt: Skip over barren combinations of tiny UTXOs 2024-02-09 11:03:18 +01:00
coinselection.h coinselection: Track whether CG completed 2024-02-09 10:50:10 +01:00
context.cpp
context.h interfaces: Add schedulerMockForward method so mockscheduler RPC can work across processes 2023-10-20 10:30:16 -04:00
crypter.cpp
crypter.h
db.cpp refactor: Fix bugprone-string-constructor warning 2023-10-30 14:59:17 +01:00
db.h wallet: remove unused 'accept_no_keys' arg from decryption process 2024-02-03 12:56:43 -03:00
dump.cpp wallettool: Don't create CWallet when dumping DB 2023-12-19 16:54:06 -05:00
dump.h wallettool: Don't create CWallet when dumping DB 2023-12-19 16:54:06 -05:00
external_signer_scriptpubkeyman.cpp wallet: batch external signer descriptor import 2023-11-21 23:07:00 -03:00
external_signer_scriptpubkeyman.h wallet: batch external signer descriptor import 2023-11-21 23:07:00 -03:00
feebumper.cpp test: wallet, fix change position out of range error 2023-12-12 15:20:38 -03:00
feebumper.h
fees.cpp
fees.h
init.cpp init: completely remove -zapwallettxes (remaining hidden option) 2023-11-03 20:00:44 +01:00
interfaces.cpp wallet: use optional for change position as an optional in CreateTransaction 2023-12-08 17:12:19 -05:00
load.cpp interfaces: Add schedulerMockForward method so mockscheduler RPC can work across processes 2023-10-20 10:30:16 -04:00
load.h interfaces: Add schedulerMockForward method so mockscheduler RPC can work across processes 2023-10-20 10:30:16 -04:00
receive.cpp Use Txid in COutpoint 2023-11-21 13:15:44 +00:00
receive.h
salvage.cpp tidy: modernize-use-emplace 2023-10-12 11:27:19 +02:00
salvage.h
scriptpubkeyman.cpp Merge bitcoin/bitcoin#28833: wallet: refactor: remove unused SignatureData instances in spkm's FillPSBT methods 2024-02-06 13:35:41 -05:00
scriptpubkeyman.h wallet: remove unused 'accept_no_keys' arg from decryption process 2024-02-03 12:56:43 -03:00
spend.cpp Merge bitcoin/bitcoin#27877: wallet: Add CoinGrinder coin selection algorithm 2024-02-09 16:38:13 -05:00
spend.h refactor: pass CRecipient to FundTransaction 2024-01-19 15:04:56 +01:00
sqlite.cpp sqlite: Ensure that only one SQLiteBatch is writing to db at a time 2024-02-06 12:24:36 -05:00
sqlite.h sqlite: Ensure that only one SQLiteBatch is writing to db at a time 2024-02-06 12:24:36 -05:00
transaction.cpp wallet, refactor: Add CWalletTx::updateState function 2023-10-23 17:35:36 -04:00
transaction.h Use ParamsWrapper for witness serialization 2023-11-14 08:45:30 +10:00
types.h
wallet.cpp Merge bitcoin/bitcoin#26836: wallet: batch and simplify addressbook migration process 2024-02-08 09:05:00 -05:00
wallet.h Merge bitcoin/bitcoin#26836: wallet: batch and simplify addressbook migration process 2024-02-08 09:05:00 -05:00
walletdb.cpp refactor: Compile unreachable code 2024-01-25 16:25:55 +01:00
walletdb.h
wallettool.cpp wallettool: Don't create CWallet when dumping DB 2023-12-19 16:54:06 -05:00
wallettool.h
walletutil.cpp
walletutil.h wallet: cache descriptor ID to avoid repeated descriptor string creation 2023-11-05 23:50:58 +01:00