@ -2674,6 +2674,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
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
{
std : : vector < COutput > vCoins ( vAvailableCoins ) ;
CAmount value_to_select = nTargetValue ;
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
if ( coin_control . HasSelected ( ) & & ! coin_control . fAllowOtherInputs )
@ -2699,23 +2700,34 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
coin_control . ListSelected ( vPresetInputs ) ;
for ( const COutPoint & outpoint : vPresetInputs )
{
// For now, don't use BnB if preset inputs are selected. TODO: Enable this later
bnb_used = false ;
coin_selection_params . use_bnb = false ;
std : : map < uint256 , CWalletTx > : : const_iterator it = mapWallet . find ( outpoint . hash ) ;
if ( it ! = mapWallet . end ( ) )
{
const CWalletTx & wtx = it - > second ;
// Clearly invalid input, fail
if ( wtx . tx - > vout . size ( ) < = outpoint . n )
if ( wtx . tx - > vout . size ( ) < = outpoint . n ) {
bnb_used = false ;
return false ;
}
// Just to calculate the marginal byte size
nValueFromPresetInputs + = wtx . tx - > vout [ outpoint . n ] . nValue ;
setPresetCoins . insert ( CInputCoin ( wtx . tx , outpoint . n ) ) ;
} else
CInputCoin coin ( wtx . tx , outpoint . n , wtx . GetSpendSize ( outpoint . n , false ) ) ;
nValueFromPresetInputs + = coin . txout . nValue ;
if ( coin . m_input_bytes < = 0 ) {
bnb_used = false ;
return false ; // Not solvable, can't estimate size for fee
}
coin . effective_value = coin . txout . nValue - coin_selection_params . effective_fee . GetFee ( coin . m_input_bytes ) ;
if ( coin_selection_params . use_bnb ) {
value_to_select - = coin . effective_value ;
} else {
value_to_select - = coin . txout . nValue ;
}
setPresetCoins . insert ( coin ) ;
} else {
bnb_used = false ;
return false ; // TODO: Allow non-wallet inputs
}
}
// remove preset inputs from vCoins
for ( std : : vector < COutput > : : iterator it = vCoins . begin ( ) ; it ! = vCoins . end ( ) & & coin_control . HasSelected ( ) ; )
@ -2743,14 +2755,14 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
size_t max_descendants = ( size_t ) std : : max < int64_t > ( 1 , limit_descendant_count ) ;
bool fRejectLongChains = gArgs . GetBoolArg ( " -walletrejectlongchains " , DEFAULT_WALLET_REJECT_LONG_CHAINS ) ;
bool res = nTargetValue < = nValueFromPresetInputs | |
SelectCoinsMinConf ( nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter ( 1 , 6 , 0 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) | |
SelectCoinsMinConf ( nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter ( 1 , 1 , 0 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) | |
( m_spend_zero_conf_change & & SelectCoinsMinConf ( nTargetValue - nValueFromPresetInputs , CoinEligibilityFilter ( 0 , 1 , 2 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) ) | |
( 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 ) ) | |
( 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 ) ) | |
( 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 ) ) | |
( 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 ) ) ;
bool res = value_to_select < = 0 | |
SelectCoinsMinConf ( value_to_select , CoinEligibilityFilter ( 1 , 6 , 0 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) | |
SelectCoinsMinConf ( value_to_select , CoinEligibilityFilter ( 1 , 1 , 0 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) | |
( m_spend_zero_conf_change & & SelectCoinsMinConf ( value_to_select , CoinEligibilityFilter ( 0 , 1 , 2 ) , groups , setCoinsRet , nValueRet , coin_selection_params , bnb_used ) ) | |
( 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 ) ) | |
( 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 ) ) | |
( 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 ) ) | |
( 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 ) ) ;
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
util : : insert ( setCoinsRet , setPresetCoins ) ;