mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-15 12:51:00 +02:00
add support for existing vins for fundrawtransaction
This commit is contained in:
parent
018828d666
commit
cd42202ac3
4 changed files with 341 additions and 47 deletions
|
|
@ -1334,27 +1334,73 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
|
||||
bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, vector<CTxIn> vPresetVINs, const CCoinControl* coinControl) const
|
||||
{
|
||||
vector<COutput> vCoins;
|
||||
AvailableCoins(vCoins, true, coinControl);
|
||||
|
||||
|
||||
// create a empty set to store possible VINS
|
||||
set<pair<const CWalletTx*,unsigned int> > setTempCoins;
|
||||
CAmount nValueTroughVINs = 0;
|
||||
|
||||
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
|
||||
if (coinControl && coinControl->HasSelected())
|
||||
{
|
||||
BOOST_FOREACH(const COutput& out, vCoins)
|
||||
{
|
||||
if(!out.fSpendable)
|
||||
continue;
|
||||
if (!out.fSpendable)
|
||||
continue;
|
||||
nValueRet += out.tx->vout[out.i].nValue;
|
||||
setCoinsRet.insert(make_pair(out.tx, out.i));
|
||||
}
|
||||
return (nValueRet >= nTargetValue);
|
||||
}
|
||||
|
||||
// fill up the tx with possible predefined VINs
|
||||
BOOST_FOREACH(const CTxIn& txin, vPresetVINs)
|
||||
{
|
||||
bool vinOk = false;
|
||||
// search for VIN in available coins
|
||||
for (vector<COutput>::iterator it = vCoins.begin() ; it != vCoins.end();)
|
||||
{
|
||||
const COutput& out = *it;
|
||||
if (out.tx->GetHash() == txin.prevout.hash && txin.prevout.n == (uint32_t)out.i)
|
||||
{
|
||||
if (!out.fSpendable)
|
||||
continue;
|
||||
|
||||
nValueTroughVINs += out.tx->vout[out.i].nValue;
|
||||
|
||||
// temporary keep the coin to add them later after SelectCoinsMinConf has added some
|
||||
setTempCoins.insert(make_pair(out.tx, out.i));
|
||||
vinOk = true;
|
||||
|
||||
// remove the coins from available coins vector to avoid double use because of a upcomming SelectCoinsMinConf
|
||||
it = vCoins.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if (!vinOk)
|
||||
return false; // if vin was not an available coin, cancel (will return "Insufficient funds")
|
||||
}
|
||||
|
||||
return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
|
||||
SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
|
||||
bool state = true;
|
||||
|
||||
// only select further coins if we need to
|
||||
if (nTargetValue-nValueTroughVINs > 0)
|
||||
state = (SelectCoinsMinConf(nTargetValue-nValueTroughVINs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
|
||||
SelectCoinsMinConf(nTargetValue-nValueTroughVINs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
|
||||
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue-nValueTroughVINs, 0, 1, vCoins, setCoinsRet, nValueRet)));
|
||||
|
||||
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible VINs to the coinset
|
||||
setCoinsRet.insert(setTempCoins.begin(), setTempCoins.end());
|
||||
|
||||
// increase return value due of possible vins
|
||||
nValueRet+=nValueTroughVINs;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1362,19 +1408,32 @@ bool CWallet::FundTransaction(const CTransaction& txToFund, CMutableTransaction&
|
|||
{
|
||||
|
||||
vector<pair<CScript, CAmount> > vecSend;
|
||||
vector<CTxIn> vin;
|
||||
|
||||
BOOST_FOREACH (const CTxOut& out, txToFund.vout)
|
||||
BOOST_FOREACH (const CTxOut& txOut, txToFund.vout)
|
||||
{
|
||||
vecSend.push_back(make_pair(out.scriptPubKey, out.nValue));
|
||||
vecSend.push_back(make_pair(txOut.scriptPubKey, txOut.nValue));
|
||||
}
|
||||
|
||||
BOOST_FOREACH (const CTxIn& txIn, txToFund.vin)
|
||||
{
|
||||
vin.push_back(txIn);
|
||||
}
|
||||
|
||||
CReserveKey reservekey(this);
|
||||
CWalletTx wtx;
|
||||
return CreateTransaction(vecSend, wtx, txNew, reservekey, nFeeRet, strFailReason, NULL, false);
|
||||
return CreateTransaction(vecSend, vin, wtx, txNew, reservekey, nFeeRet, strFailReason, NULL, false);
|
||||
}
|
||||
|
||||
bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
|
||||
CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
|
||||
{
|
||||
vector<CTxIn> vINs;
|
||||
return CreateTransaction(vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign);
|
||||
}
|
||||
|
||||
bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend, const vector<CTxIn> vINs,
|
||||
CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
|
||||
{
|
||||
CAmount nValue = 0;
|
||||
BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend)
|
||||
|
|
@ -1422,7 +1481,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
|
|||
// Choose coins to use
|
||||
set<pair<const CWalletTx*,unsigned int> > setCoins;
|
||||
CAmount nValueIn = 0;
|
||||
if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
|
||||
if (!SelectCoins(nTotalValue, setCoins, nValueIn, vINs, coinControl))
|
||||
{
|
||||
strFailReason = _("Insufficient funds");
|
||||
return false;
|
||||
|
|
@ -1566,7 +1625,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue,
|
|||
vector< pair<CScript, CAmount> > vecSend;
|
||||
vecSend.push_back(make_pair(scriptPubKey, nValue));
|
||||
CMutableTransaction txNew;
|
||||
return CreateTransaction(vecSend, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign);
|
||||
vector<CTxIn> vINs;
|
||||
return CreateTransaction(vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue