@@ -2877,7 +2877,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2877
2877
}
2878
2878
}
2879
2879
2880
- // remove preset inputs from vCoins
2880
+ // remove preset inputs from vCoins so that Coin Selection doesn't pick them.
2881
2881
for (std::vector<COutput>::iterator it = vCoins.begin (); it != vCoins.end () && coin_control.HasSelected ();)
2882
2882
{
2883
2883
if (setPresetCoins.count (it->GetInputCoin ()))
@@ -2889,9 +2889,9 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2889
2889
unsigned int limit_ancestor_count = 0 ;
2890
2890
unsigned int limit_descendant_count = 0 ;
2891
2891
chain ().getPackageLimits (limit_ancestor_count, limit_descendant_count);
2892
- size_t max_ancestors = (size_t )std::max<int64_t >(1 , limit_ancestor_count);
2893
- size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
2894
- bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
2892
+ const size_t max_ancestors = (size_t )std::max<int64_t >(1 , limit_ancestor_count);
2893
+ const size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
2894
+ const bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
2895
2895
2896
2896
// form groups from remaining coins; note that preset coins will not
2897
2897
// automatically have their associated (same address) coins included
@@ -2901,16 +2901,52 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2901
2901
// explicitly shuffling the outputs before processing
2902
2902
Shuffle (vCoins.begin (), vCoins.end (), FastRandomContext ());
2903
2903
}
2904
- bool res = value_to_select <= 0 ||
2905
- SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType) ||
2906
- SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType) ||
2907
- (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) ||
2908
- (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, nCoinType)) ||
2909
- (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, nCoinType)) ||
2910
- (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, nCoinType)) ||
2911
- (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, nCoinType));
2904
+ // Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
2905
+ // transaction at a target feerate. If an attempt fails, more attempts may be made using a more
2906
+ // permissive CoinEligibilityFilter.
2907
+ const bool res = [&] {
2908
+ // Pre-selected inputs already cover the target amount.
2909
+ if (value_to_select <= 0 ) return true ;
2910
+
2911
+ // If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
2912
+ // confirmations on outputs received from other wallets and only spend confirmed change.
2913
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) return true ;
2914
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) return true ;
2915
+
2916
+ // Fall back to using zero confirmation change (but with as few ancestors in the mempool as
2917
+ // possible) if we cannot fund the transaction otherwise. We never spend unconfirmed
2918
+ // outputs received from other wallets.
2919
+ if (m_spend_zero_conf_change) {
2920
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) return true ;
2921
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , std::min ((size_t )4 , max_ancestors/3 ), std::min ((size_t )4 , max_descendants/3 )),
2922
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) {
2923
+ return true ;
2924
+ }
2925
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ),
2926
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) {
2927
+ return true ;
2928
+ }
2929
+ // If partial groups are allowed, relax the requirement of spending OutputGroups (groups
2930
+ // of UTXOs sent to the same address, which are obviously controlled by a single wallet)
2931
+ // in their entirety.
2932
+ if (SelectCoinsMinConf (value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 , true /* include_partial_groups */ ),
2933
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) {
2934
+ return true ;
2935
+ }
2936
+ // Try with unlimited ancestors/descendants. The transaction will still need to meet
2937
+ // mempool ancestor/descendant policy to be accepted to mempool and broadcasted, but
2938
+ // OutputGroups use heuristics that may overestimate ancestor/descendant counts.
2939
+ if (!fRejectLongChains && SelectCoinsMinConf (value_to_select,
2940
+ CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max (), std::numeric_limits<uint64_t >::max (), true /* include_partial_groups */ ),
2941
+ vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used, nCoinType)) {
2942
+ return true ;
2943
+ }
2944
+ }
2945
+ // Coin Selection failed.
2946
+ return false ;
2947
+ }();
2912
2948
2913
- // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2949
+ // SelectCoinsMinConf clears setCoinsRet, so add the preset inputs from coin_control to the coinset
2914
2950
util::insert (setCoinsRet, setPresetCoins);
2915
2951
2916
2952
// add preset inputs to the total value selected
0 commit comments