mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #1828 from UdjinM6/bp_1810_1819
Backport critical fixes from develop
This commit is contained in:
commit
57e7cc4c63
@ -122,15 +122,11 @@ bool CInstantSend::ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CCo
|
|||||||
}
|
}
|
||||||
LogPrintf("CInstantSend::ProcessTxLockRequest -- accepted, txid=%s\n", txHash.ToString());
|
LogPrintf("CInstantSend::ProcessTxLockRequest -- accepted, txid=%s\n", txHash.ToString());
|
||||||
|
|
||||||
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
|
|
||||||
CTxLockCandidate& txLockCandidate = itLockCandidate->second;
|
|
||||||
Vote(txLockCandidate, connman);
|
|
||||||
ProcessOrphanTxLockVotes(connman);
|
|
||||||
|
|
||||||
// Masternodes will sometimes propagate votes before the transaction is known to the client.
|
// Masternodes will sometimes propagate votes before the transaction is known to the client.
|
||||||
// If this just happened - lock inputs, resolve conflicting locks, update transaction status
|
// If this just happened - lock inputs, resolve conflicting locks, update transaction status
|
||||||
// forcing external script notification.
|
// forcing external script notification.
|
||||||
TryToFinalizeLockCandidate(txLockCandidate);
|
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
|
||||||
|
TryToFinalizeLockCandidate(itLockCandidate->second);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -182,6 +178,18 @@ void CInstantSend::CreateEmptyTxLockCandidate(const uint256& txHash)
|
|||||||
mapTxLockCandidates.insert(std::make_pair(txHash, CTxLockCandidate(txLockRequest)));
|
mapTxLockCandidates.insert(std::make_pair(txHash, CTxLockCandidate(txLockRequest)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInstantSend::Vote(const uint256& txHash, CConnman& connman)
|
||||||
|
{
|
||||||
|
AssertLockHeld(cs_main);
|
||||||
|
LOCK(cs_instantsend);
|
||||||
|
|
||||||
|
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
|
||||||
|
if (itLockCandidate == mapTxLockCandidates.end()) return;
|
||||||
|
Vote(itLockCandidate->second, connman);
|
||||||
|
// Let's see if our vote changed smth
|
||||||
|
TryToFinalizeLockCandidate(itLockCandidate->second);
|
||||||
|
}
|
||||||
|
|
||||||
void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
|
void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
|
||||||
{
|
{
|
||||||
if(!fMasterNode) return;
|
if(!fMasterNode) return;
|
||||||
@ -190,6 +198,8 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
|
|||||||
LOCK2(cs_main, cs_instantsend);
|
LOCK2(cs_main, cs_instantsend);
|
||||||
|
|
||||||
uint256 txHash = txLockCandidate.GetHash();
|
uint256 txHash = txLockCandidate.GetHash();
|
||||||
|
// We should never vote on a Transaction Lock Request that was not (yet) accepted by the mempool
|
||||||
|
if(mapLockRequestAccepted.find(txHash) == mapLockRequestAccepted.end()) return;
|
||||||
// check if we need to vote on this candidate's outpoints,
|
// check if we need to vote on this candidate's outpoints,
|
||||||
// it's possible that we need to vote for several of them
|
// it's possible that we need to vote for several of them
|
||||||
std::map<COutPoint, COutPointLock>::iterator itOutpointLock = txLockCandidate.mapOutPointLocks.begin();
|
std::map<COutPoint, COutPointLock>::iterator itOutpointLock = txLockCandidate.mapOutPointLocks.begin();
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman);
|
||||||
|
|
||||||
bool ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CConnman& connman);
|
bool ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CConnman& connman);
|
||||||
|
void Vote(const uint256& txHash, CConnman& connman);
|
||||||
|
|
||||||
bool AlreadyHave(const uint256& hash);
|
bool AlreadyHave(const uint256& hash);
|
||||||
|
|
||||||
|
@ -1635,6 +1635,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
LogPrintf("TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n",
|
LogPrintf("TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n",
|
||||||
tx.GetHash().ToString(), pfrom->id);
|
tx.GetHash().ToString(), pfrom->id);
|
||||||
instantsend.AcceptLockRequest(txLockRequest);
|
instantsend.AcceptLockRequest(txLockRequest);
|
||||||
|
instantsend.Vote(tx.GetHash(), connman);
|
||||||
}
|
}
|
||||||
|
|
||||||
mempool.check(pcoinsTip);
|
mempool.check(pcoinsTip);
|
||||||
|
@ -873,23 +873,19 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon
|
|||||||
|
|
||||||
vecMasternodesUsed.push_back(dsq.vin.prevout);
|
vecMasternodesUsed.push_back(dsq.vin.prevout);
|
||||||
|
|
||||||
CNode* pnodeFound = NULL;
|
bool fSkip = false;
|
||||||
bool fDisconnect = false;
|
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) {
|
||||||
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
|
fSkip = pnode->fDisconnect || pnode->fMasternode;
|
||||||
pnodeFound = pnode;
|
|
||||||
if(pnodeFound->fDisconnect) {
|
|
||||||
fDisconnect = true;
|
|
||||||
} else {
|
|
||||||
pnodeFound->AddRef();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
if (fDisconnect)
|
if (fSkip) {
|
||||||
|
LogPrintf("CPrivateSendClient::JoinExistingQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString());
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LogPrintf("CPrivateSendClient::JoinExistingQueue -- attempt to connect to masternode from queue, addr=%s\n", infoMn.addr.ToString());
|
LogPrintf("CPrivateSendClient::JoinExistingQueue -- attempt to connect to masternode from queue, addr=%s\n", infoMn.addr.ToString());
|
||||||
// connect to Masternode and submit the queue request
|
// connect to Masternode and submit the queue request
|
||||||
CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
|
CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
|
||||||
if(pnode) {
|
if(pnode) {
|
||||||
infoMixingMasternode = infoMn;
|
infoMixingMasternode = infoMn;
|
||||||
nSessionDenom = dsq.nDenom;
|
nSessionDenom = dsq.nDenom;
|
||||||
@ -900,9 +896,6 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon
|
|||||||
strAutoDenomResult = _("Mixing in progress...");
|
strAutoDenomResult = _("Mixing in progress...");
|
||||||
SetState(POOL_STATE_QUEUE);
|
SetState(POOL_STATE_QUEUE);
|
||||||
nTimeLastSuccessfulStep = GetTimeMillis();
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
if(pnodeFound) {
|
|
||||||
pnodeFound->Release();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("CPrivateSendClient::JoinExistingQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
|
LogPrintf("CPrivateSendClient::JoinExistingQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
|
||||||
@ -947,24 +940,19 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNode* pnodeFound = NULL;
|
bool fSkip = false;
|
||||||
bool fDisconnect = false;
|
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) {
|
||||||
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
|
fSkip = pnode->fDisconnect || pnode->fMasternode;
|
||||||
pnodeFound = pnode;
|
|
||||||
if(pnodeFound->fDisconnect) {
|
|
||||||
fDisconnect = true;
|
|
||||||
} else {
|
|
||||||
pnodeFound->AddRef();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
if (fDisconnect) {
|
if (fSkip) {
|
||||||
|
LogPrintf("CPrivateSendClient::StartNewQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString());
|
||||||
nTries++;
|
nTries++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("CPrivateSendClient::StartNewQueue -- attempt %d connection to Masternode %s\n", nTries, infoMn.addr.ToString());
|
LogPrintf("CPrivateSendClient::StartNewQueue -- attempt %d connection to Masternode %s\n", nTries, infoMn.addr.ToString());
|
||||||
CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
|
CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
|
||||||
if(pnode) {
|
if(pnode) {
|
||||||
LogPrintf("CPrivateSendClient::StartNewQueue -- connected, addr=%s\n", infoMn.addr.ToString());
|
LogPrintf("CPrivateSendClient::StartNewQueue -- connected, addr=%s\n", infoMn.addr.ToString());
|
||||||
infoMixingMasternode = infoMn;
|
infoMixingMasternode = infoMn;
|
||||||
@ -982,9 +970,6 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA
|
|||||||
strAutoDenomResult = _("Mixing in progress...");
|
strAutoDenomResult = _("Mixing in progress...");
|
||||||
SetState(POOL_STATE_QUEUE);
|
SetState(POOL_STATE_QUEUE);
|
||||||
nTimeLastSuccessfulStep = GetTimeMillis();
|
nTimeLastSuccessfulStep = GetTimeMillis();
|
||||||
if(pnodeFound) {
|
|
||||||
pnodeFound->Release();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("CPrivateSendClient::StartNewQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
|
LogPrintf("CPrivateSendClient::StartNewQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
|
||||||
@ -1002,13 +987,24 @@ bool CPrivateSendClient::SubmitDenominate(CConnman& connman)
|
|||||||
std::vector<CTxOut> vecTxOutRet;
|
std::vector<CTxOut> vecTxOutRet;
|
||||||
|
|
||||||
// Submit transaction to the pool if we get here
|
// Submit transaction to the pool if we get here
|
||||||
// Try to use only inputs with the same number of rounds starting from the highest number of rounds possible
|
if (nLiquidityProvider) {
|
||||||
for(int i = nPrivateSendRounds; i > 0; i--) {
|
// Try to use only inputs with the same number of rounds starting from the lowest number of rounds possible
|
||||||
if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) {
|
for(int i = 0; i< nPrivateSendRounds; i++) {
|
||||||
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
|
if(PrepareDenominate(i, i + 1, strError, vecTxDSInRet, vecTxOutRet)) {
|
||||||
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
|
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
|
||||||
|
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
|
||||||
|
}
|
||||||
|
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Try to use only inputs with the same number of rounds starting from the highest number of rounds possible
|
||||||
|
for(int i = nPrivateSendRounds; i > 0; i--) {
|
||||||
|
if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) {
|
||||||
|
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
|
||||||
|
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
|
||||||
|
}
|
||||||
|
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
|
||||||
}
|
}
|
||||||
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We failed? That's strange but let's just make final attempt and try to mix everything
|
// We failed? That's strange but let's just make final attempt and try to mix everything
|
||||||
@ -1100,7 +1096,7 @@ bool CPrivateSendClient::PrepareDenominate(int nMinRounds, int nMaxRounds, std::
|
|||||||
vecTxDSIn.erase(it);
|
vecTxDSIn.erase(it);
|
||||||
vCoins.erase(it2);
|
vCoins.erase(it2);
|
||||||
|
|
||||||
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain).GetScriptForDestination();
|
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain);
|
||||||
|
|
||||||
// add new output
|
// add new output
|
||||||
CTxOut txout(nValueDenom, scriptDenom);
|
CTxOut txout(nValueDenom, scriptDenom);
|
||||||
@ -1276,7 +1272,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo
|
|||||||
// ****** Add an output for mixing collaterals ************ /
|
// ****** Add an output for mixing collaterals ************ /
|
||||||
|
|
||||||
if(fCreateMixingCollaterals) {
|
if(fCreateMixingCollaterals) {
|
||||||
CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
|
CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain);
|
||||||
vecSend.push_back((CRecipient){ scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false });
|
vecSend.push_back((CRecipient){ scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false });
|
||||||
nValueLeft -= CPrivateSend::GetMaxCollateralAmount();
|
nValueLeft -= CPrivateSend::GetMaxCollateralAmount();
|
||||||
}
|
}
|
||||||
@ -1311,7 +1307,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo
|
|||||||
|
|
||||||
// add each output up to 11 times until it can't be added again
|
// add each output up to 11 times until it can't be added again
|
||||||
while(nValueLeft - nDenomValue >= 0 && nOutputs <= 10) {
|
while(nValueLeft - nDenomValue >= 0 && nOutputs <= 10) {
|
||||||
CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
|
CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain);
|
||||||
|
|
||||||
vecSend.push_back((CRecipient){ scriptDenom, nDenomValue, false });
|
vecSend.push_back((CRecipient){ scriptDenom, nDenomValue, false });
|
||||||
|
|
||||||
|
@ -25,14 +25,16 @@ CScript CKeyHolder::GetScriptForDestination() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const CKeyHolder& CKeyHolderStorage::AddKey(CWallet* pwallet)
|
CScript CKeyHolderStorage::AddKey(CWallet* pwallet)
|
||||||
{
|
{
|
||||||
|
LOCK(cs_storage);
|
||||||
storage.emplace_back(std::unique_ptr<CKeyHolder>(new CKeyHolder(pwallet)));
|
storage.emplace_back(std::unique_ptr<CKeyHolder>(new CKeyHolder(pwallet)));
|
||||||
LogPrintf("CKeyHolderStorage::%s -- storage size %lld\n", __func__, storage.size());
|
LogPrintf("CKeyHolderStorage::%s -- storage size %lld\n", __func__, storage.size());
|
||||||
return *storage.back();
|
return storage.back()->GetScriptForDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeyHolderStorage::KeepAll(){
|
void CKeyHolderStorage::KeepAll(){
|
||||||
|
LOCK(cs_storage);
|
||||||
if (storage.size() > 0) {
|
if (storage.size() > 0) {
|
||||||
for (auto &key : storage) {
|
for (auto &key : storage) {
|
||||||
key->KeepKey();
|
key->KeepKey();
|
||||||
@ -44,6 +46,7 @@ void CKeyHolderStorage::KeepAll(){
|
|||||||
|
|
||||||
void CKeyHolderStorage::ReturnAll()
|
void CKeyHolderStorage::ReturnAll()
|
||||||
{
|
{
|
||||||
|
LOCK(cs_storage);
|
||||||
if (storage.size() > 0) {
|
if (storage.size() > 0) {
|
||||||
for (auto &key : storage) {
|
for (auto &key : storage) {
|
||||||
key->ReturnKey();
|
key->ReturnKey();
|
||||||
|
@ -27,9 +27,10 @@ class CKeyHolderStorage
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<CKeyHolder> > storage;
|
std::vector<std::unique_ptr<CKeyHolder> > storage;
|
||||||
|
mutable CCriticalSection cs_storage;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const CKeyHolder& AddKey(CWallet* pwalletIn);
|
CScript AddKey(CWallet* pwalletIn);
|
||||||
void KeepAll();
|
void KeepAll();
|
||||||
void ReturnAll();
|
void ReturnAll();
|
||||||
|
|
||||||
|
@ -132,7 +132,8 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
|
|||||||
currentWatchOnlyBalance(-1),
|
currentWatchOnlyBalance(-1),
|
||||||
currentWatchUnconfBalance(-1),
|
currentWatchUnconfBalance(-1),
|
||||||
currentWatchImmatureBalance(-1),
|
currentWatchImmatureBalance(-1),
|
||||||
txdelegate(new TxViewDelegate(platformStyle, this))
|
txdelegate(new TxViewDelegate(platformStyle, this)),
|
||||||
|
timer(nullptr)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
QString theme = GUIUtil::getThemeName();
|
QString theme = GUIUtil::getThemeName();
|
||||||
@ -195,7 +196,7 @@ void OverviewPage::handleOutOfSyncWarningClicks()
|
|||||||
|
|
||||||
OverviewPage::~OverviewPage()
|
OverviewPage::~OverviewPage()
|
||||||
{
|
{
|
||||||
if(!fLiteMode && !fMasterNode) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
|
if(timer) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,6 +404,8 @@ void TransactionView::contextualMenu(const QPoint &point)
|
|||||||
{
|
{
|
||||||
QModelIndex index = transactionView->indexAt(point);
|
QModelIndex index = transactionView->indexAt(point);
|
||||||
QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
|
QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
|
||||||
|
if (selection.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
// check if transaction can be abandoned, disable context menu action in case it doesn't
|
// check if transaction can be abandoned, disable context menu action in case it doesn't
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
|
@ -204,7 +204,7 @@ struct mempoolentry_txid
|
|||||||
class CompareTxMemPoolEntryByDescendantScore
|
class CompareTxMemPoolEntryByDescendantScore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
||||||
{
|
{
|
||||||
bool fUseADescendants = UseDescendantScore(a);
|
bool fUseADescendants = UseDescendantScore(a);
|
||||||
bool fUseBDescendants = UseDescendantScore(b);
|
bool fUseBDescendants = UseDescendantScore(b);
|
||||||
@ -226,7 +226,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate which score to use for an entry (avoiding division).
|
// Calculate which score to use for an entry (avoiding division).
|
||||||
bool UseDescendantScore(const CTxMemPoolEntry &a)
|
bool UseDescendantScore(const CTxMemPoolEntry &a) const
|
||||||
{
|
{
|
||||||
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
|
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
|
||||||
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
|
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
|
||||||
@ -241,7 +241,7 @@ public:
|
|||||||
class CompareTxMemPoolEntryByScore
|
class CompareTxMemPoolEntryByScore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
||||||
{
|
{
|
||||||
double f1 = (double)a.GetModifiedFee() * b.GetTxSize();
|
double f1 = (double)a.GetModifiedFee() * b.GetTxSize();
|
||||||
double f2 = (double)b.GetModifiedFee() * a.GetTxSize();
|
double f2 = (double)b.GetModifiedFee() * a.GetTxSize();
|
||||||
@ -255,7 +255,7 @@ public:
|
|||||||
class CompareTxMemPoolEntryByEntryTime
|
class CompareTxMemPoolEntryByEntryTime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
|
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
||||||
{
|
{
|
||||||
return a.GetTime() < b.GetTime();
|
return a.GetTime() < b.GetTime();
|
||||||
}
|
}
|
||||||
|
@ -2410,7 +2410,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
|
static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
|
||||||
vector<char>& vfBest, CAmount& nBest, int iterations = 1000, bool fUseInstantSend = false)
|
vector<char>& vfBest, CAmount& nBest, bool fUseInstantSend = false, int iterations = 1000)
|
||||||
{
|
{
|
||||||
vector<char> vfIncluded;
|
vector<char> vfIncluded;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user