FIFO selection wallet.cpp

This wallet.cpp is selects the UTXOs based on FIFO. Coin selection is done in selectCoins function
This commit is contained in:
saizsassin 2018-05-10 15:01:04 +05:30 committed by GitHub
parent 38202a0953
commit 51293f733e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2458,12 +2458,16 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin
bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
{
/*This selectCoins function selects the coins (UTXOs) in FIFO order i.e, the coins that is received first will be sent to spending first*/
//get the received time of each coin and store in set time (using set because the content will be automatically stored in ascending order of the data)
std::vector<COutput> vCoinsTmp(vAvailableCoins);
std::vector<COutput>::iterator it;
std::set<unsigned int> time;
for(it=vCoinsTmp.begin();it!=vCoinsTmp.end();it++)
time.insert(it->tx->nTimeReceived);
time.insert(it->tx->nTimeReceived); //nTimeReceived is the received time of the UTXO
//store UTXOs in vCoins in the ascending order of time
std::vector<COutput> vCoins;
vCoins.clear();
for(std::set<unsigned int>::iterator its = time.begin();its!=time.end();its++)
@ -2471,7 +2475,7 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
if(it->tx->nTimeReceived == *its)
vCoins.push_back(*it);
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure) [manual selection] has no effect in default FIFO selection
if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
{
for (const COutput& out : vCoins)
@ -2484,31 +2488,31 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
return (nValueRet >= nTargetValue);
}
// calculate value from preset inputs and store them
std::vector<CInputCoin> setPresetCoins;
CAmount nValueFromPresetInputs = 0;
// calculate value from preset inputs and store them in PresetCoins set
std::vector<CInputCoin> setPresetCoins;
CAmount nValueFromPresetInputs = 0;
setPresetCoins.clear();
std::vector<COutPoint> vPresetInputs;
if (coinControl)
coinControl->ListSelected(vPresetInputs);
for (const COutPoint& outpoint : vPresetInputs)
{
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
if (it != mapWallet.end())
{
const CWalletTx* pcoin = &it->second;
// Clearly invalid input, fail
if (pcoin->tx->vout.size() <= outpoint.n)
return false;
nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
setPresetCoins.push_back(CInputCoin(pcoin, outpoint.n));
} else
return false; // TODO: Allow non-wallet inputs
std::vector<COutPoint> vPresetInputs;
if (coinControl)
coinControl->ListSelected(vPresetInputs);
for (const COutPoint& outpoint : vPresetInputs)
{
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
if (it != mapWallet.end())
{
const CWalletTx* pcoin = &it->second;
// Clearly invalid input, fail
if (pcoin->tx->vout.size() <= outpoint.n)
return false;
nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
setPresetCoins.push_back(CInputCoin(pcoin, outpoint.n));
} else
return false; // TODO: Allow non-wallet inputs
}
// remove preset inputs from vCoins
// remove preset inputs from vCoins (utxo)
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
{
if (std::find(setPresetCoins.begin(), setPresetCoins.end(), CInputCoin(it->tx, it->i)) != setPresetCoins.end())
@ -2516,14 +2520,17 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
else
++it;
}
//insert all preset Inputs to the setCoinsRet (returning set of selected utxo)
setCoinsRet.clear();
setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
nValueRet = nValueFromPresetInputs;
if (nValueFromPresetInputs >= nTargetValue)
//return true if total preset input value is greater than required amount
if (nValueFromPresetInputs >= nTargetValue)
return true;
//select UTXOs from vCoins and insert into setCoinsRet (returning set of selected utxo) until required amount is obtained
CAmount nRemainReqValue = nTargetValue - nValueFromPresetInputs;
for (const COutput &output : vCoins)
{
@ -2537,13 +2544,13 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
nRemainReqValue -= coin.txout.nValue;
nValueRet += coin.txout.nValue;
//return true if coins of required Value are selected
//return true if coins of required amount are selected
if (nRemainReqValue <= 0)
return true;
}
//return false since coins of required Value are not selected
//return false since coins of required amount is not available
return false;
}