@@ -2674,6 +2674,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
2674
2674
bool CWallet::SelectCoins (const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl& coin_control, CoinSelectionParams& coin_selection_params, bool & bnb_used) const
2675
2675
{
2676
2676
std::vector<COutput> vCoins (vAvailableCoins);
2677
+ CAmount value_to_select = nTargetValue;
2677
2678
2678
2679
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
2679
2680
if (coin_control.HasSelected () && !coin_control.fAllowOtherInputs )
@@ -2699,22 +2700,33 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2699
2700
coin_control.ListSelected (vPresetInputs);
2700
2701
for (const COutPoint& outpoint : vPresetInputs)
2701
2702
{
2702
- // For now, don't use BnB if preset inputs are selected. TODO: Enable this later
2703
- bnb_used = false ;
2704
- coin_selection_params.use_bnb = false ;
2705
-
2706
2703
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find (outpoint.hash );
2707
2704
if (it != mapWallet.end ())
2708
2705
{
2709
2706
const CWalletTx& wtx = it->second ;
2710
2707
// Clearly invalid input, fail
2711
- if (wtx.tx ->vout .size () <= outpoint.n )
2708
+ if (wtx.tx ->vout .size () <= outpoint.n ) {
2709
+ bnb_used = false ;
2712
2710
return false ;
2711
+ }
2713
2712
// Just to calculate the marginal byte size
2714
- nValueFromPresetInputs += wtx.tx ->vout [outpoint.n ].nValue ;
2715
- setPresetCoins.insert (CInputCoin (wtx.tx , outpoint.n ));
2716
- } else
2713
+ CInputCoin coin (wtx.tx , outpoint.n , wtx.GetSpendSize (outpoint.n , false ));
2714
+ nValueFromPresetInputs += coin.txout .nValue ;
2715
+ if (coin.m_input_bytes <= 0 ) {
2716
+ bnb_used = false ;
2717
+ return false ; // Not solvable, can't estimate size for fee
2718
+ }
2719
+ coin.effective_value = coin.txout .nValue - coin_selection_params.effective_fee .GetFee (coin.m_input_bytes );
2720
+ if (coin_selection_params.use_bnb ) {
2721
+ value_to_select -= coin.effective_value ;
2722
+ } else {
2723
+ value_to_select -= coin.txout .nValue ;
2724
+ }
2725
+ setPresetCoins.insert (coin);
2726
+ } else {
2727
+ bnb_used = false ;
2717
2728
return false ; // TODO: Allow non-wallet inputs
2729
+ }
2718
2730
}
2719
2731
2720
2732
// remove preset inputs from vCoins
@@ -2743,14 +2755,14 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
2743
2755
size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
2744
2756
bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
2745
2757
2746
- bool res = nTargetValue <= nValueFromPresetInputs ||
2747
- SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (1 , 6 , 0 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2748
- SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (1 , 1 , 0 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2749
- (m_spend_zero_conf_change && SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (0 , 1 , 2 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2750
- (m_spend_zero_conf_change && SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (0 , 1 , std::min ((size_t )4 , max_ancestors/3 ), std::min ((size_t )4 , max_descendants/3 )), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2751
- (m_spend_zero_conf_change && SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2752
- (m_spend_zero_conf_change && SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2753
- (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf (nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max ()), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2758
+ bool res = value_to_select <= 0 ||
2759
+ SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (1 , 6 , 0 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2760
+ SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (1 , 1 , 0 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2761
+ (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (0 , 1 , 2 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2762
+ (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 )), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2763
+ (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2764
+ (m_spend_zero_conf_change && SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 ), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2765
+ (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf (value_to_select , CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max ()), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2754
2766
2755
2767
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2756
2768
util::insert (setCoinsRet, setPresetCoins);
0 commit comments