Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 2,529 Lines • ▼ Show 20 Lines | bool CWallet::SelectCoins(const std::vector<COutput> &vAvailableCoins, | ||||
const Amount nTargetValue, | const Amount nTargetValue, | ||||
std::set<CInputCoin> &setCoinsRet, Amount &nValueRet, | std::set<CInputCoin> &setCoinsRet, Amount &nValueRet, | ||||
const CCoinControl &coin_control, | const CCoinControl &coin_control, | ||||
CoinSelectionParams &coin_selection_params, | CoinSelectionParams &coin_selection_params, | ||||
bool &bnb_used) const { | bool &bnb_used) const { | ||||
std::vector<COutput> vCoins(vAvailableCoins); | std::vector<COutput> vCoins(vAvailableCoins); | ||||
Amount value_to_select = nTargetValue; | Amount value_to_select = nTargetValue; | ||||
// Default to bnb was not used. If we use it, we set it later | |||||
bnb_used = false; | |||||
// coin control -> return all selected outputs (we want all selected to go | // coin control -> return all selected outputs (we want all selected to go | ||||
// into the transaction for sure) | // into the transaction for sure) | ||||
if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) { | if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) { | ||||
// We didn't use BnB here, so set it to false. | |||||
bnb_used = false; | |||||
for (const COutput &out : vCoins) { | for (const COutput &out : vCoins) { | ||||
if (!out.fSpendable) { | if (!out.fSpendable) { | ||||
continue; | continue; | ||||
} | } | ||||
nValueRet += out.tx->tx->vout[out.i].nValue; | nValueRet += out.tx->tx->vout[out.i].nValue; | ||||
setCoinsRet.insert(out.GetInputCoin()); | setCoinsRet.insert(out.GetInputCoin()); | ||||
} | } | ||||
Show All 10 Lines | bool CWallet::SelectCoins(const std::vector<COutput> &vAvailableCoins, | ||||
for (const COutPoint &outpoint : vPresetInputs) { | for (const COutPoint &outpoint : vPresetInputs) { | ||||
std::map<TxId, CWalletTx>::const_iterator it = | std::map<TxId, CWalletTx>::const_iterator it = | ||||
mapWallet.find(outpoint.GetTxId()); | mapWallet.find(outpoint.GetTxId()); | ||||
if (it != mapWallet.end()) { | if (it != mapWallet.end()) { | ||||
const CWalletTx &wtx = it->second; | const CWalletTx &wtx = it->second; | ||||
// Clearly invalid input, fail | // Clearly invalid input, fail | ||||
if (wtx.tx->vout.size() <= outpoint.GetN()) { | if (wtx.tx->vout.size() <= outpoint.GetN()) { | ||||
bnb_used = false; | |||||
return false; | return false; | ||||
} | } | ||||
// Just to calculate the marginal byte size | // Just to calculate the marginal byte size | ||||
CInputCoin coin(wtx.tx, outpoint.GetN(), | CInputCoin coin(wtx.tx, outpoint.GetN(), | ||||
wtx.GetSpendSize(outpoint.GetN(), false)); | wtx.GetSpendSize(outpoint.GetN(), false)); | ||||
nValueFromPresetInputs += coin.txout.nValue; | nValueFromPresetInputs += coin.txout.nValue; | ||||
if (coin.m_input_bytes <= 0) { | if (coin.m_input_bytes <= 0) { | ||||
bnb_used = false; | |||||
// Not solvable, can't estimate size for fee | // Not solvable, can't estimate size for fee | ||||
return false; | return false; | ||||
} | } | ||||
coin.effective_value = | coin.effective_value = | ||||
coin.txout.nValue - | coin.txout.nValue - | ||||
coin_selection_params.effective_fee.GetFee(coin.m_input_bytes); | coin_selection_params.effective_fee.GetFee(coin.m_input_bytes); | ||||
if (coin_selection_params.use_bnb) { | if (coin_selection_params.use_bnb) { | ||||
value_to_select -= coin.effective_value; | value_to_select -= coin.effective_value; | ||||
} else { | } else { | ||||
value_to_select -= coin.txout.nValue; | value_to_select -= coin.txout.nValue; | ||||
} | } | ||||
setPresetCoins.insert(coin); | setPresetCoins.insert(coin); | ||||
} else { | } else { | ||||
bnb_used = false; | |||||
return false; // TODO: Allow non-wallet inputs | return false; // TODO: Allow non-wallet inputs | ||||
} | } | ||||
} | } | ||||
// Remove preset inputs from vCoins | // Remove preset inputs from vCoins | ||||
for (std::vector<COutput>::iterator it = vCoins.begin(); | for (std::vector<COutput>::iterator it = vCoins.begin(); | ||||
it != vCoins.end() && coin_control.HasSelected();) { | it != vCoins.end() && coin_control.HasSelected();) { | ||||
if (setPresetCoins.count(it->GetInputCoin())) { | if (setPresetCoins.count(it->GetInputCoin())) { | ||||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | txNew.nLockTime = GetLocktimeForNewTransaction(chain(), locked_chainIn); | ||||
return false; | return false; | ||||
} | } | ||||
txNew.vout.push_back(txout); | txNew.vout.push_back(txout); | ||||
} | } | ||||
// Choose coins to use | // Choose coins to use | ||||
bool bnb_used; | bool bnb_used = false; | ||||
if (pick_new_inputs) { | if (pick_new_inputs) { | ||||
nValueIn = Amount::zero(); | nValueIn = Amount::zero(); | ||||
setCoins.clear(); | setCoins.clear(); | ||||
coin_selection_params.change_spend_size = | coin_selection_params.change_spend_size = | ||||
CalculateMaximumSignedInputSize(change_prototype_txout, | CalculateMaximumSignedInputSize(change_prototype_txout, | ||||
this); | this); | ||||
coin_selection_params.effective_fee = nFeeRateNeeded; | coin_selection_params.effective_fee = nFeeRateNeeded; | ||||
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, | if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, | ||||
▲ Show 20 Lines • Show All 1,502 Lines • Show Last 20 Lines |