@@ -2478,7 +2478,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2478
2478
}
2479
2479
}
2480
2480
2481
- // remove preset inputs from vCoins
2481
+ // remove preset inputs from vCoins so that Coin Selection doesn't pick them.
2482
2482
for (std::vector<COutput>::iterator it = vCoins.begin (); it != vCoins.end () && coin_control.HasSelected ();)
2483
2483
{
2484
2484
if (setPresetCoins.count (it->GetInputCoin ()))
@@ -2490,9 +2490,9 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2490
2490
unsigned int limit_ancestor_count = 0 ;
2491
2491
unsigned int limit_descendant_count = 0 ;
2492
2492
chain ().getPackageLimits (limit_ancestor_count, limit_descendant_count);
2493
- size_t max_ancestors = (size_t )std::max<int64_t >(1 , limit_ancestor_count);
2494
- size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
2495
- bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
2493
+ const size_t max_ancestors = (size_t )std::max<int64_t >(1 , limit_ancestor_count);
2494
+ const size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
2495
+ const bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
2496
2496
2497
2497
// form groups from remaining coins; note that preset coins will not
2498
2498
// automatically have their associated (same address) coins included
@@ -2502,16 +2502,53 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2502
2502
// explicitly shuffling the outputs before processing
2503
2503
Shuffle (vCoins.begin (), vCoins.end (), FastRandomContext ());
2504
2504
}
2505
- bool res = value_to_select <= 0 ||
2506
- SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2507
- SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2508
- (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2509
- (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , std::min ((size_t )4 , max_ancestors/3 ), std::min ((size_t )4 , max_descendants/3 )), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2510
- (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2511
- (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 , true /* include_partial_groups */ ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2512
- (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max (), std::numeric_limits<uint64_t >::max (), true /* include_partial_groups */ ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2513
2505
2514
- // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2506
+ // Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
2507
+ // transaction at a target feerate. If an attempt fails, more attempts may be made using a more
2508
+ // permissive CoinEligibilityFilter.
2509
+ const bool res = [&] {
2510
+ // Pre-selected inputs already cover the target amount.
2511
+ if (value_to_select <= 0 ) return true ;
2512
+
2513
+ // If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
2514
+ // confirmations on outputs received from other wallets and only spend confirmed change.
2515
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true ;
2516
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true ;
2517
+
2518
+ // Fall back to using zero confirmation change (but with as few ancestors in the mempool as
2519
+ // possible) if we cannot fund the transaction otherwise. We never spend unconfirmed
2520
+ // outputs received from other wallets.
2521
+ if (m_spend_zero_conf_change) {
2522
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) return true ;
2523
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , std::min ((size_t )4 , max_ancestors/3 ), std::min ((size_t )4 , max_descendants/3 )),
2524
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) {
2525
+ return true ;
2526
+ }
2527
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ),
2528
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) {
2529
+ return true ;
2530
+ }
2531
+ // If partial groups are allowed, relax the requirement of spending OutputGroups (groups
2532
+ // of UTXOs sent to the same address, which are obviously controlled by a single wallet)
2533
+ // in their entirety.
2534
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 , true /* include_partial_groups */ ),
2535
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) {
2536
+ return true ;
2537
+ }
2538
+ // Try with unlimited ancestors/descendants. The transaction will still need to meet
2539
+ // mempool ancestor/descendant policy to be accepted to mempool and broadcasted, but
2540
+ // OutputGroups use heuristics that may overestimate ancestor/descendant counts.
2541
+ if (!fRejectLongChains && SelectCoinsMinConf (value_to_select,
2542
+ CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max (), std::numeric_limits<uint64_t >::max (), true /* include_partial_groups */ ),
2543
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) {
2544
+ return true ;
2545
+ }
2546
+ }
2547
+ // Coin Selection failed.
2548
+ return false ;
2549
+ }();
2550
+
2551
+ // SelectCoinsMinConf clears setCoinsRet, so add the preset inputs from coin_control to the coinset
2515
2552
util::insert (setCoinsRet, setPresetCoins);
2516
2553
2517
2554
// add preset inputs to the total value selected
0 commit comments