mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Move heavy coin selection out of the loop in SubmitDenominate (#2274)
* extend CTxOut constructor * Move heavy coin selection out of the loop in SubmitDenominate
This commit is contained in:
parent
016681cd38
commit
d192d642f6
@ -48,11 +48,11 @@ std::string CTxIn::ToString() const
|
||||
return str;
|
||||
}
|
||||
|
||||
CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
|
||||
CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn, int nRoundsIn)
|
||||
{
|
||||
nValue = nValueIn;
|
||||
scriptPubKey = scriptPubKeyIn;
|
||||
nRounds = -10;
|
||||
nRounds = nRoundsIn;
|
||||
}
|
||||
|
||||
std::string CTxOut::ToString() const
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
SetNull();
|
||||
}
|
||||
|
||||
CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
|
||||
CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn, int nRoundsIn = -10);
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
@ -457,7 +457,7 @@ void CPrivateSendClientManager::CheckTimeout()
|
||||
// Execute a mixing denomination via a Masternode.
|
||||
// This is only ran from clients
|
||||
//
|
||||
bool CPrivateSendClientSession::SendDenominate(const std::vector<CTxDSIn>& vecTxDSIn, const std::vector<CTxOut>& vecTxOut, CConnman& connman)
|
||||
bool CPrivateSendClientSession::SendDenominate(const std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman)
|
||||
{
|
||||
if(fMasternodeMode) {
|
||||
LogPrintf("CPrivateSendClientSession::SendDenominate -- PrivateSend from a Masternode is not supported currently.\n");
|
||||
@ -473,8 +473,8 @@ bool CPrivateSendClientSession::SendDenominate(const std::vector<CTxDSIn>& vecTx
|
||||
for (const auto& txin : txMyCollateral.vin)
|
||||
vecOutPointLocked.push_back(txin.prevout);
|
||||
|
||||
for (const auto& txdsin : vecTxDSIn)
|
||||
vecOutPointLocked.push_back(txdsin.prevout);
|
||||
for (const auto& pair : vecPSInOutPairsIn)
|
||||
vecOutPointLocked.push_back(pair.first.prevout);
|
||||
|
||||
// we should already be connected to a Masternode
|
||||
if(!nSessionID) {
|
||||
@ -498,28 +498,22 @@ bool CPrivateSendClientSession::SendDenominate(const std::vector<CTxDSIn>& vecTx
|
||||
|
||||
LogPrintf("CPrivateSendClientSession::SendDenominate -- Added transaction to pool.\n");
|
||||
|
||||
{
|
||||
// construct a pseudo tx, for debugging purpuses only
|
||||
CMutableTransaction tx; // for debug purposes only
|
||||
std::vector<CTxDSIn> vecTxDSInTmp;
|
||||
std::vector<CTxOut> vecTxOutTmp;
|
||||
|
||||
CMutableTransaction tx;
|
||||
|
||||
for (const auto& txdsin : vecTxDSIn) {
|
||||
LogPrint("privatesend", "CPrivateSendClientSession::SendDenominate -- txdsin=%s\n", txdsin.ToString());
|
||||
tx.vin.push_back(txdsin);
|
||||
}
|
||||
|
||||
for (const CTxOut& txout : vecTxOut) {
|
||||
LogPrint("privatesend", "CPrivateSendClientSession::SendDenominate -- txout=%s\n", txout.ToString());
|
||||
tx.vout.push_back(txout);
|
||||
}
|
||||
|
||||
LogPrintf("CPrivateSendClientSession::SendDenominate -- Submitting partial tx %s", tx.ToString());
|
||||
for (const auto& pair : vecPSInOutPairsIn) {
|
||||
vecTxDSInTmp.emplace_back(pair.first);
|
||||
vecTxOutTmp.emplace_back(pair.second);
|
||||
tx.vin.emplace_back(pair.first);
|
||||
tx.vout.emplace_back(pair.second);
|
||||
}
|
||||
|
||||
LogPrintf("CPrivateSendClientSession::SendDenominate -- Submitting partial tx %s", tx.ToString());
|
||||
|
||||
// store our entry for later use
|
||||
CDarkSendEntry entry(vecTxDSIn, vecTxOut, txMyCollateral);
|
||||
vecEntries.push_back(entry);
|
||||
RelayIn(entry, connman);
|
||||
vecEntries.emplace_back(vecTxDSInTmp, vecTxOutTmp, txMyCollateral);
|
||||
RelayIn(vecEntries.back(), connman);
|
||||
nTimeLastSuccessfulStep = GetTime();
|
||||
|
||||
return true;
|
||||
@ -1029,14 +1023,12 @@ bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymize
|
||||
|
||||
LogPrint("privatesend", "CPrivateSendClientSession::JoinExistingQueue -- found valid queue: %s\n", dsq.ToString());
|
||||
|
||||
CAmount nValueInTmp = 0;
|
||||
std::vector<CTxDSIn> vecTxDSInTmp;
|
||||
std::vector<COutput> vCoinsTmp;
|
||||
std::vector< std::pair<CTxDSIn, CTxOut> > vecPSInOutPairsTmp;
|
||||
CAmount nMinAmount = vecStandardDenoms[vecBits.front()];
|
||||
CAmount nMaxAmount = nBalanceNeedsAnonymized;
|
||||
|
||||
// Try to match their denominations if possible, select exact number of denominations
|
||||
if(!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nMinAmount, nMaxAmount, vecTxDSInTmp, vCoinsTmp, nValueInTmp, 0, privateSendClient.nPrivateSendRounds - 1, true)) {
|
||||
if (!pwalletMain->SelectPSInOutPairsByDenominations(dsq.nDenom, nMinAmount, nMaxAmount, vecPSInOutPairsTmp)) {
|
||||
LogPrintf("CPrivateSendClientSession::JoinExistingQueue -- Couldn't match %d denominations %d (%s)\n", vecBits.front(), dsq.nDenom, CPrivateSend::GetDenominationsToString(dsq.nDenom));
|
||||
continue;
|
||||
}
|
||||
@ -1189,8 +1181,13 @@ bool CPrivateSendClientSession::SubmitDenominate(CConnman& connman)
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
std::string strError;
|
||||
std::vector<CTxDSIn> vecTxDSInRet;
|
||||
std::vector<CTxOut> vecTxOutRet;
|
||||
std::vector< std::pair<CTxDSIn, CTxOut> > vecPSInOutPairs, vecPSInOutPairsTmp;
|
||||
|
||||
if (!SelectDenominate(strError, vecPSInOutPairs)) {
|
||||
LogPrintf("CPrivateSendClientSession::SubmitDenominate -- SelectDenominate failed, error: %s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// lean towards "highest" branch but still mix via "lowest" one someties
|
||||
bool fMixLowest = privateSendClient.nLiquidityProvider || (GetRandInt(4) == 0);
|
||||
// Try to use only inputs with the same number of rounds, from low to high, or vice versa
|
||||
@ -1205,9 +1202,9 @@ bool CPrivateSendClientSession::SubmitDenominate(CConnman& connman)
|
||||
// Submit transaction to the pool if we get here
|
||||
while (true) {
|
||||
for (int i = nRoundStart; i >= 0 && i < privateSendClient.nPrivateSendRounds; i += nLoopStep) {
|
||||
if (PrepareDenominate(i, i, strError, vecTxDSInRet, vecTxOutRet)) {
|
||||
if (PrepareDenominate(i, i, strError, vecPSInOutPairs, vecPSInOutPairsTmp)) {
|
||||
LogPrintf("CPrivateSendClientSession::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
|
||||
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
|
||||
return SendDenominate(vecPSInOutPairsTmp, connman);
|
||||
}
|
||||
LogPrint("privatesend", "CPrivateSendClientSession::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
|
||||
}
|
||||
@ -1216,9 +1213,9 @@ bool CPrivateSendClientSession::SubmitDenominate(CConnman& connman)
|
||||
}
|
||||
|
||||
// We failed? That's strange but let's just make final attempt and try to mix everything
|
||||
if(PrepareDenominate(0, privateSendClient.nPrivateSendRounds - 1, strError, vecTxDSInRet, vecTxOutRet)) {
|
||||
if (PrepareDenominate(0, privateSendClient.nPrivateSendRounds - 1, strError, vecPSInOutPairs, vecPSInOutPairsTmp)) {
|
||||
LogPrintf("CPrivateSendClientSession::SubmitDenominate -- Running PrivateSend denominate for all rounds, success\n");
|
||||
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
|
||||
return SendDenominate(vecPSInOutPairsTmp, connman);
|
||||
}
|
||||
|
||||
// Should never actually get here but just in case
|
||||
@ -1227,9 +1224,9 @@ bool CPrivateSendClientSession::SubmitDenominate(CConnman& connman)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, std::vector<CTxDSIn>& vecTxDSInRet, std::vector<CTxOut>& vecTxOutRet)
|
||||
bool CPrivateSendClientSession::SelectDenominate(std::string& strErrorRet, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet)
|
||||
{
|
||||
if(!pwalletMain) {
|
||||
if (!pwalletMain) {
|
||||
strErrorRet = "Wallet is not initialized";
|
||||
return false;
|
||||
}
|
||||
@ -1244,101 +1241,76 @@ bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure returning vectors are empty before filling them up
|
||||
vecTxDSInRet.clear();
|
||||
vecTxOutRet.clear();
|
||||
vecPSInOutPairsRet.clear();
|
||||
|
||||
// ** find the coins we'll use
|
||||
std::vector<CTxDSIn> vecTxDSIn;
|
||||
std::vector<COutput> vCoins;
|
||||
CAmount nValueIn = 0;
|
||||
|
||||
/*
|
||||
Select the coins we'll use
|
||||
|
||||
if nMinRounds >= 0 it means only denominated inputs are going in and coming out
|
||||
*/
|
||||
std::vector<int> vecBits;
|
||||
if (!CPrivateSend::GetDenominationsBits(nSessionDenom, vecBits)) {
|
||||
strErrorRet = "Incorrect session denom";
|
||||
return false;
|
||||
}
|
||||
std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
|
||||
bool fSelected = pwalletMain->SelectCoinsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], CPrivateSend::GetMaxPoolAmount(), vecTxDSIn, vCoins, nValueIn, nMinRounds, nMaxRounds, true);
|
||||
if (nMinRounds >= 0 && !fSelected) {
|
||||
|
||||
bool fSelected = pwalletMain->SelectPSInOutPairsByDenominations(nSessionDenom, vecStandardDenoms[vecBits.front()], CPrivateSend::GetMaxPoolAmount(), vecPSInOutPairsRet);
|
||||
if (!fSelected) {
|
||||
strErrorRet = "Can't select current denominated inputs";
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CPrivateSendClientSession::PrepareDenominate -- max value: %f\n", (double)nValueIn/COIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
for (const auto& txin : vecTxDSIn) {
|
||||
pwalletMain->LockCoin(txin.prevout);
|
||||
}
|
||||
bool CPrivateSendClientSession::PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet)
|
||||
{
|
||||
std::vector<int> vecBits;
|
||||
if (!CPrivateSend::GetDenominationsBits(nSessionDenom, vecBits)) {
|
||||
strErrorRet = "Incorrect session denom";
|
||||
return false;
|
||||
}
|
||||
|
||||
CAmount nValueLeft = nValueIn;
|
||||
for (const auto& pair : vecPSInOutPairsIn) {
|
||||
pwalletMain->LockCoin(pair.first.prevout);
|
||||
}
|
||||
|
||||
// Try to add every needed denomination, repeat up to 5-PRIVATESEND_ENTRY_MAX_SIZE times.
|
||||
// NOTE: No need to randomize order of inputs because they were
|
||||
// initially shuffled in CWallet::SelectCoinsByDenominations already.
|
||||
int nStep = 0;
|
||||
// initially shuffled in CWallet::SelectPSInOutPairsByDenominations already.
|
||||
int nStepsMax = 5 + GetRandInt(PRIVATESEND_ENTRY_MAX_SIZE - 5 + 1);
|
||||
int nDenomResult{0};
|
||||
|
||||
while (nStep < nStepsMax) {
|
||||
std::vector<CAmount> vecStandardDenoms = CPrivateSend::GetStandardDenominations();
|
||||
std::vector<int> vecSteps(vecStandardDenoms.size(), 0);
|
||||
vecPSInOutPairsRet.clear();
|
||||
|
||||
for (const auto& pair: vecPSInOutPairsIn) {
|
||||
if (pair.second.nRounds < nMinRounds || pair.second.nRounds > nMaxRounds) {
|
||||
// unlock unused coins
|
||||
pwalletMain->UnlockCoin(pair.first.prevout);
|
||||
continue;
|
||||
}
|
||||
bool fFound = false;
|
||||
for (const auto& nBit : vecBits) {
|
||||
if (vecSteps[nBit] >= nStepsMax) break;
|
||||
CAmount nValueDenom = vecStandardDenoms[nBit];
|
||||
if (nValueLeft - nValueDenom < 0) continue;
|
||||
|
||||
// Note: this relies on a fact that both vectors MUST have same size
|
||||
std::vector<CTxDSIn>::iterator it = vecTxDSIn.begin();
|
||||
std::vector<COutput>::iterator it2 = vCoins.begin();
|
||||
while (it2 != vCoins.end()) {
|
||||
// we have matching inputs
|
||||
if ((*it2).tx->tx->vout[(*it2).i].nValue == nValueDenom) {
|
||||
// add new input in resulting vector
|
||||
vecTxDSInRet.push_back(*it);
|
||||
// remove corresponding items from initial vectors
|
||||
vecTxDSIn.erase(it);
|
||||
vCoins.erase(it2);
|
||||
|
||||
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain);
|
||||
|
||||
// add new output
|
||||
CTxOut txout(nValueDenom, scriptDenom);
|
||||
vecTxOutRet.push_back(txout);
|
||||
|
||||
// subtract denomination amount
|
||||
nValueLeft -= nValueDenom;
|
||||
|
||||
// step is complete
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
++it2;
|
||||
if (pair.second.nValue == nValueDenom) {
|
||||
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain);
|
||||
vecPSInOutPairsRet.emplace_back(pair.first, CTxOut(nValueDenom, scriptDenom));
|
||||
fFound = true;
|
||||
nDenomResult |= 1 << nBit;
|
||||
// step is complete
|
||||
++vecSteps[nBit];
|
||||
break;
|
||||
}
|
||||
}
|
||||
nStep++;
|
||||
if(nValueLeft == 0) break;
|
||||
}
|
||||
|
||||
{
|
||||
// unlock unused coins
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
for (const auto& txin : vecTxDSIn) {
|
||||
pwalletMain->UnlockCoin(txin.prevout);
|
||||
if (!fFound) {
|
||||
// unlock unused coins
|
||||
pwalletMain->UnlockCoin(pair.first.prevout);
|
||||
}
|
||||
}
|
||||
|
||||
if (CPrivateSend::GetDenominations(vecTxOutRet) != nSessionDenom) {
|
||||
{
|
||||
// unlock used coins on failure
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
for (const auto& txin : vecTxDSInRet) {
|
||||
pwalletMain->UnlockCoin(txin.prevout);
|
||||
}
|
||||
if (nDenomResult != nSessionDenom) {
|
||||
// unlock used coins on failure
|
||||
for (const auto& pair : vecPSInOutPairsRet) {
|
||||
pwalletMain->UnlockCoin(pair.first.prevout);
|
||||
}
|
||||
keyHolderStorage.ReturnAll();
|
||||
strErrorRet = "Can't prepare current denominated outputs";
|
||||
|
@ -106,10 +106,12 @@ private:
|
||||
bool JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
||||
bool StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsAnonymized, CConnman& connman);
|
||||
|
||||
/// step 0: select denominated inputs and txouts
|
||||
bool SelectDenominate(std::string& strErrorRet, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet);
|
||||
/// step 1: prepare denominated inputs and outputs
|
||||
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, std::vector<CTxDSIn>& vecTxDSInRet, std::vector<CTxOut>& vecTxOutRet);
|
||||
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet);
|
||||
/// step 2: send denominated inputs and outputs prepared in step 1
|
||||
bool SendDenominate(const std::vector<CTxDSIn>& vecTxDSIn, const std::vector<CTxOut>& vecTxOut, CConnman& connman);
|
||||
bool SendDenominate(const std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman);
|
||||
|
||||
/// Get Masternode updates about the progress of mixing
|
||||
bool CheckPoolStateUpdate(PoolState nStateNew, int nEntriesCountNew, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, int nSessionIDNew=0);
|
||||
|
@ -3007,63 +3007,52 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector<CTxDSIn>& vecTxDSInRet, std::vector<COutput>& vCoinsRet, CAmount& nValueRet, int nPrivateSendRoundsMin, int nPrivateSendRoundsMax, bool fNoDuplicateTxIds)
|
||||
bool CWallet::SelectPSInOutPairsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet)
|
||||
{
|
||||
CAmount nValueTotal{0};
|
||||
int nDenomResult{0};
|
||||
|
||||
std::set<uint256> setRecentTxIds;
|
||||
|
||||
vecTxDSInRet.clear();
|
||||
vCoinsRet.clear();
|
||||
nValueRet = 0;
|
||||
|
||||
std::vector<COutput> vCoins;
|
||||
AvailableCoins(vCoins, true, NULL, false, ONLY_DENOMINATED);
|
||||
|
||||
std::random_shuffle(vCoins.rbegin(), vCoins.rend(), GetRandInt);
|
||||
|
||||
// ( bit on if present )
|
||||
// bit 0 - 100DASH+1
|
||||
// bit 1 - 10DASH+1
|
||||
// bit 2 - 1DASH+1
|
||||
// bit 3 - .1DASH+1
|
||||
vecPSInOutPairsRet.clear();
|
||||
|
||||
std::vector<int> vecBits;
|
||||
if (!CPrivateSend::GetDenominationsBits(nDenom, vecBits)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int nDenomResult = 0;
|
||||
AvailableCoins(vCoins, true, NULL, false, ONLY_DENOMINATED);
|
||||
LogPrintf("CWallet::%s -- vCoins.size(): %d\n", __func__, vCoins.size());
|
||||
|
||||
std::random_shuffle(vCoins.rbegin(), vCoins.rend(), GetRandInt);
|
||||
|
||||
std::vector<CAmount> vecPrivateSendDenominations = CPrivateSend::GetStandardDenominations();
|
||||
FastRandomContext insecure_rand;
|
||||
for (const auto& out : vCoins)
|
||||
{
|
||||
// masternode-like input should not be selected by AvailableCoins now anyway
|
||||
//if(out.tx->vout[out.i].nValue == 1000*COIN) continue;
|
||||
if(fNoDuplicateTxIds && setRecentTxIds.find(out.tx->GetHash()) != setRecentTxIds.end()) continue;
|
||||
if(nValueRet + out.tx->tx->vout[out.i].nValue <= nValueMax){
|
||||
for (const auto& out : vCoins) {
|
||||
uint256 txHash = out.tx->GetHash();
|
||||
int nValue = out.tx->tx->vout[out.i].nValue;
|
||||
if (setRecentTxIds.find(txHash) != setRecentTxIds.end()) continue; // no duplicate txids
|
||||
if (nValueTotal + nValue > nValueMax) continue;
|
||||
|
||||
CTxIn txin = CTxIn(out.tx->GetHash(), out.i);
|
||||
CTxIn txin = CTxIn(txHash, out.i);
|
||||
CScript scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
|
||||
int nRounds = GetRealOutpointPrivateSendRounds(txin.prevout);
|
||||
if (nRounds >= privateSendClient.nPrivateSendRounds) continue;
|
||||
|
||||
int nRounds = GetCappedOutpointPrivateSendRounds(txin.prevout);
|
||||
if(nRounds > nPrivateSendRoundsMax) continue;
|
||||
if(nRounds < nPrivateSendRoundsMin) continue;
|
||||
|
||||
for (const auto& nBit : vecBits) {
|
||||
if(out.tx->tx->vout[out.i].nValue == vecPrivateSendDenominations[nBit]) {
|
||||
nValueRet += out.tx->tx->vout[out.i].nValue;
|
||||
vecTxDSInRet.push_back(CTxDSIn(txin, out.tx->tx->vout[out.i].scriptPubKey));
|
||||
vCoinsRet.push_back(out);
|
||||
nDenomResult |= 1 << nBit;
|
||||
setRecentTxIds.emplace(out.tx->GetHash());
|
||||
LogPrint("privatesend", "CWallet::SelectCoinsByDenominations -- hash %s nValue %d\n", out.tx->GetHash().ToString(), out.tx->tx->vout[out.i].nValue);
|
||||
}
|
||||
}
|
||||
for (const auto& nBit : vecBits) {
|
||||
if (nValue != vecPrivateSendDenominations[nBit]) continue;
|
||||
nValueTotal += nValue;
|
||||
vecPSInOutPairsRet.emplace_back(CTxDSIn(txin, scriptPubKey), CTxOut(nValue, scriptPubKey, nRounds));
|
||||
setRecentTxIds.emplace(txHash);
|
||||
nDenomResult |= 1 << nBit;
|
||||
LogPrint("privatesend", "CWallet::%s -- hash: %s, nValue: %d.%08d, nRounds: %d\n",
|
||||
__func__, txHash.ToString(), nValue / COIN, nValue % COIN, nRounds);
|
||||
}
|
||||
}
|
||||
|
||||
LogPrintf("CWallet::SelectCoinsByDenominations -- setRecentTxIds.size() %d\n", setRecentTxIds.size());
|
||||
LogPrintf("CWallet::%s -- setRecentTxIds.size(): %d\n", __func__, setRecentTxIds.size());
|
||||
|
||||
return nValueRet >= nValueMin && nDenom == nDenomResult;
|
||||
return nValueTotal >= nValueMin && nDenom == nDenomResult;
|
||||
}
|
||||
|
||||
struct CompareByAmount
|
||||
|
@ -806,7 +806,7 @@ public:
|
||||
bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool fUseInstantSend = false) const;
|
||||
|
||||
// Coin selection
|
||||
bool SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector<CTxDSIn>& vecTxDSInRet, std::vector<COutput>& vCoinsRet, CAmount& nValueRet, int nPrivateSendRoundsMin, int nPrivateSendRoundsMax, bool fNoDuplicateTxIds);
|
||||
bool SelectPSInOutPairsByDenominations(int nDenom, CAmount nValueMin, CAmount nValueMax, std::vector< std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet);
|
||||
bool GetCollateralTxDSIn(CTxDSIn& txdsinRet, CAmount& nValueRet) const;
|
||||
bool SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector<CTxIn>& vecTxInRet, CAmount& nValueRet, int nPrivateSendRoundsMin, int nPrivateSendRoundsMax) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user