@@ -2674,6 +2674,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
26742674bool 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
26752675{
26762676 std::vector<COutput> vCoins (vAvailableCoins);
2677+ CAmount value_to_select = nTargetValue;
26772678
26782679 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
26792680 if (coin_control.HasSelected () && !coin_control.fAllowOtherInputs )
@@ -2699,22 +2700,33 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
26992700 coin_control.ListSelected (vPresetInputs);
27002701 for (const COutPoint& outpoint : vPresetInputs)
27012702 {
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-
27062703 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find (outpoint.hash );
27072704 if (it != mapWallet.end ())
27082705 {
27092706 const CWalletTx& wtx = it->second ;
27102707 // Clearly invalid input, fail
2711- if (wtx.tx ->vout .size () <= outpoint.n )
2708+ if (wtx.tx ->vout .size () <= outpoint.n ) {
2709+ bnb_used = false ;
27122710 return false ;
2711+ }
27132712 // 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 ;
27172728 return false ; // TODO: Allow non-wallet inputs
2729+ }
27182730 }
27192731
27202732 // remove preset inputs from vCoins
@@ -2743,14 +2755,14 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
27432755 size_t max_descendants = (size_t )std::max<int64_t >(1 , limit_descendant_count);
27442756 bool fRejectLongChains = gArgs .GetBoolArg (" -walletrejectlongchains" , DEFAULT_WALLET_REJECT_LONG_CHAINS);
27452757
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));
27542766
27552767 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
27562768 util::insert (setCoinsRet, setPresetCoins);
0 commit comments