Skip to content

Commit 57e7cc4

Browse files
authored
Merge pull request #1828 from UdjinM6/bp_1810_1819
Backport critical fixes from develop
2 parents 63e0e30 + 4768886 commit 57e7cc4

10 files changed

+68
-53
lines changed

Diff for: src/instantx.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,11 @@ bool CInstantSend::ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CCo
122122
}
123123
LogPrintf("CInstantSend::ProcessTxLockRequest -- accepted, txid=%s\n", txHash.ToString());
124124

125-
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
126-
CTxLockCandidate& txLockCandidate = itLockCandidate->second;
127-
Vote(txLockCandidate, connman);
128-
ProcessOrphanTxLockVotes(connman);
129-
130125
// Masternodes will sometimes propagate votes before the transaction is known to the client.
131126
// If this just happened - lock inputs, resolve conflicting locks, update transaction status
132127
// forcing external script notification.
133-
TryToFinalizeLockCandidate(txLockCandidate);
128+
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
129+
TryToFinalizeLockCandidate(itLockCandidate->second);
134130

135131
return true;
136132
}
@@ -182,6 +178,18 @@ void CInstantSend::CreateEmptyTxLockCandidate(const uint256& txHash)
182178
mapTxLockCandidates.insert(std::make_pair(txHash, CTxLockCandidate(txLockRequest)));
183179
}
184180

181+
void CInstantSend::Vote(const uint256& txHash, CConnman& connman)
182+
{
183+
AssertLockHeld(cs_main);
184+
LOCK(cs_instantsend);
185+
186+
std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash);
187+
if (itLockCandidate == mapTxLockCandidates.end()) return;
188+
Vote(itLockCandidate->second, connman);
189+
// Let's see if our vote changed smth
190+
TryToFinalizeLockCandidate(itLockCandidate->second);
191+
}
192+
185193
void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
186194
{
187195
if(!fMasterNode) return;
@@ -190,6 +198,8 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
190198
LOCK2(cs_main, cs_instantsend);
191199

192200
uint256 txHash = txLockCandidate.GetHash();
201+
// We should never vote on a Transaction Lock Request that was not (yet) accepted by the mempool
202+
if(mapLockRequestAccepted.find(txHash) == mapLockRequestAccepted.end()) return;
193203
// check if we need to vote on this candidate's outpoints,
194204
// it's possible that we need to vote for several of them
195205
std::map<COutPoint, COutPointLock>::iterator itOutpointLock = txLockCandidate.mapOutPointLocks.begin();

Diff for: src/instantx.h

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class CInstantSend
8686
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman);
8787

8888
bool ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CConnman& connman);
89+
void Vote(const uint256& txHash, CConnman& connman);
8990

9091
bool AlreadyHave(const uint256& hash);
9192

Diff for: src/net_processing.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
16351635
LogPrintf("TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n",
16361636
tx.GetHash().ToString(), pfrom->id);
16371637
instantsend.AcceptLockRequest(txLockRequest);
1638+
instantsend.Vote(tx.GetHash(), connman);
16381639
}
16391640

16401641
mempool.check(pcoinsTip);

Diff for: src/privatesend-client.cpp

+33-37
Original file line numberDiff line numberDiff line change
@@ -873,23 +873,19 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon
873873

874874
vecMasternodesUsed.push_back(dsq.vin.prevout);
875875

876-
CNode* pnodeFound = NULL;
877-
bool fDisconnect = false;
878-
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
879-
pnodeFound = pnode;
880-
if(pnodeFound->fDisconnect) {
881-
fDisconnect = true;
882-
} else {
883-
pnodeFound->AddRef();
884-
}
876+
bool fSkip = false;
877+
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) {
878+
fSkip = pnode->fDisconnect || pnode->fMasternode;
885879
return true;
886880
});
887-
if (fDisconnect)
881+
if (fSkip) {
882+
LogPrintf("CPrivateSendClient::JoinExistingQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString());
888883
continue;
884+
}
889885

890886
LogPrintf("CPrivateSendClient::JoinExistingQueue -- attempt to connect to masternode from queue, addr=%s\n", infoMn.addr.ToString());
891887
// connect to Masternode and submit the queue request
892-
CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
888+
CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
893889
if(pnode) {
894890
infoMixingMasternode = infoMn;
895891
nSessionDenom = dsq.nDenom;
@@ -900,9 +896,6 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CCon
900896
strAutoDenomResult = _("Mixing in progress...");
901897
SetState(POOL_STATE_QUEUE);
902898
nTimeLastSuccessfulStep = GetTimeMillis();
903-
if(pnodeFound) {
904-
pnodeFound->Release();
905-
}
906899
return true;
907900
} else {
908901
LogPrintf("CPrivateSendClient::JoinExistingQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
@@ -947,24 +940,19 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA
947940
continue;
948941
}
949942

950-
CNode* pnodeFound = NULL;
951-
bool fDisconnect = false;
952-
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&pnodeFound, &fDisconnect](CNode* pnode) {
953-
pnodeFound = pnode;
954-
if(pnodeFound->fDisconnect) {
955-
fDisconnect = true;
956-
} else {
957-
pnodeFound->AddRef();
958-
}
943+
bool fSkip = false;
944+
connman.ForNode(infoMn.addr, CConnman::AllNodes, [&fSkip](CNode* pnode) {
945+
fSkip = pnode->fDisconnect || pnode->fMasternode;
959946
return true;
960947
});
961-
if (fDisconnect) {
948+
if (fSkip) {
949+
LogPrintf("CPrivateSendClient::StartNewQueue -- skipping masternode connection, addr=%s\n", infoMn.addr.ToString());
962950
nTries++;
963951
continue;
964952
}
965953

966954
LogPrintf("CPrivateSendClient::StartNewQueue -- attempt %d connection to Masternode %s\n", nTries, infoMn.addr.ToString());
967-
CNode* pnode = (pnodeFound && pnodeFound->fMasternode) ? pnodeFound : connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
955+
CNode* pnode = connman.ConnectNode(CAddress(infoMn.addr, NODE_NETWORK), NULL, true);
968956
if(pnode) {
969957
LogPrintf("CPrivateSendClient::StartNewQueue -- connected, addr=%s\n", infoMn.addr.ToString());
970958
infoMixingMasternode = infoMn;
@@ -982,9 +970,6 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA
982970
strAutoDenomResult = _("Mixing in progress...");
983971
SetState(POOL_STATE_QUEUE);
984972
nTimeLastSuccessfulStep = GetTimeMillis();
985-
if(pnodeFound) {
986-
pnodeFound->Release();
987-
}
988973
return true;
989974
} else {
990975
LogPrintf("CPrivateSendClient::StartNewQueue -- can't connect, addr=%s\n", infoMn.addr.ToString());
@@ -1002,13 +987,24 @@ bool CPrivateSendClient::SubmitDenominate(CConnman& connman)
1002987
std::vector<CTxOut> vecTxOutRet;
1003988

1004989
// Submit transaction to the pool if we get here
1005-
// Try to use only inputs with the same number of rounds starting from the highest number of rounds possible
1006-
for(int i = nPrivateSendRounds; i > 0; i--) {
1007-
if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) {
1008-
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
1009-
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
990+
if (nLiquidityProvider) {
991+
// Try to use only inputs with the same number of rounds starting from the lowest number of rounds possible
992+
for(int i = 0; i< nPrivateSendRounds; i++) {
993+
if(PrepareDenominate(i, i + 1, strError, vecTxDSInRet, vecTxOutRet)) {
994+
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
995+
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
996+
}
997+
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
998+
}
999+
} else {
1000+
// Try to use only inputs with the same number of rounds starting from the highest number of rounds possible
1001+
for(int i = nPrivateSendRounds; i > 0; i--) {
1002+
if(PrepareDenominate(i - 1, i, strError, vecTxDSInRet, vecTxOutRet)) {
1003+
LogPrintf("CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, success\n", i);
1004+
return SendDenominate(vecTxDSInRet, vecTxOutRet, connman);
1005+
}
1006+
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
10101007
}
1011-
LogPrint("privatesend", "CPrivateSendClient::SubmitDenominate -- Running PrivateSend denominate for %d rounds, error: %s\n", i, strError);
10121008
}
10131009

10141010
// 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::
11001096
vecTxDSIn.erase(it);
11011097
vCoins.erase(it2);
11021098

1103-
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain).GetScriptForDestination();
1099+
CScript scriptDenom = keyHolderStorage.AddKey(pwalletMain);
11041100

11051101
// add new output
11061102
CTxOut txout(nValueDenom, scriptDenom);
@@ -1276,7 +1272,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo
12761272
// ****** Add an output for mixing collaterals ************ /
12771273

12781274
if(fCreateMixingCollaterals) {
1279-
CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
1275+
CScript scriptCollateral = keyHolderStorageDenom.AddKey(pwalletMain);
12801276
vecSend.push_back((CRecipient){ scriptCollateral, CPrivateSend::GetMaxCollateralAmount(), false });
12811277
nValueLeft -= CPrivateSend::GetMaxCollateralAmount();
12821278
}
@@ -1311,7 +1307,7 @@ bool CPrivateSendClient::CreateDenominated(const CompactTallyItem& tallyItem, bo
13111307

13121308
// add each output up to 11 times until it can't be added again
13131309
while(nValueLeft - nDenomValue >= 0 && nOutputs <= 10) {
1314-
CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain).GetScriptForDestination();
1310+
CScript scriptDenom = keyHolderStorageDenom.AddKey(pwalletMain);
13151311

13161312
vecSend.push_back((CRecipient){ scriptDenom, nDenomValue, false });
13171313

Diff for: src/privatesend-util.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ CScript CKeyHolder::GetScriptForDestination() const
2525
}
2626

2727

28-
const CKeyHolder& CKeyHolderStorage::AddKey(CWallet* pwallet)
28+
CScript CKeyHolderStorage::AddKey(CWallet* pwallet)
2929
{
30+
LOCK(cs_storage);
3031
storage.emplace_back(std::unique_ptr<CKeyHolder>(new CKeyHolder(pwallet)));
3132
LogPrintf("CKeyHolderStorage::%s -- storage size %lld\n", __func__, storage.size());
32-
return *storage.back();
33+
return storage.back()->GetScriptForDestination();
3334
}
3435

3536
void CKeyHolderStorage::KeepAll(){
37+
LOCK(cs_storage);
3638
if (storage.size() > 0) {
3739
for (auto &key : storage) {
3840
key->KeepKey();
@@ -44,6 +46,7 @@ void CKeyHolderStorage::KeepAll(){
4446

4547
void CKeyHolderStorage::ReturnAll()
4648
{
49+
LOCK(cs_storage);
4750
if (storage.size() > 0) {
4851
for (auto &key : storage) {
4952
key->ReturnKey();

Diff for: src/privatesend-util.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ class CKeyHolderStorage
2727
{
2828
private:
2929
std::vector<std::unique_ptr<CKeyHolder> > storage;
30+
mutable CCriticalSection cs_storage;
3031

3132
public:
32-
const CKeyHolder& AddKey(CWallet* pwalletIn);
33+
CScript AddKey(CWallet* pwalletIn);
3334
void KeepAll();
3435
void ReturnAll();
3536

Diff for: src/qt/overviewpage.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
132132
currentWatchOnlyBalance(-1),
133133
currentWatchUnconfBalance(-1),
134134
currentWatchImmatureBalance(-1),
135-
txdelegate(new TxViewDelegate(platformStyle, this))
135+
txdelegate(new TxViewDelegate(platformStyle, this)),
136+
timer(nullptr)
136137
{
137138
ui->setupUi(this);
138139
QString theme = GUIUtil::getThemeName();
@@ -195,7 +196,7 @@ void OverviewPage::handleOutOfSyncWarningClicks()
195196

196197
OverviewPage::~OverviewPage()
197198
{
198-
if(!fLiteMode && !fMasterNode) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
199+
if(timer) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus()));
199200
delete ui;
200201
}
201202

Diff for: src/qt/transactionview.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ void TransactionView::contextualMenu(const QPoint &point)
404404
{
405405
QModelIndex index = transactionView->indexAt(point);
406406
QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
407+
if (selection.empty())
408+
return;
407409

408410
// check if transaction can be abandoned, disable context menu action in case it doesn't
409411
uint256 hash;

Diff for: src/txmempool.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ struct mempoolentry_txid
204204
class CompareTxMemPoolEntryByDescendantScore
205205
{
206206
public:
207-
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
207+
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
208208
{
209209
bool fUseADescendants = UseDescendantScore(a);
210210
bool fUseBDescendants = UseDescendantScore(b);
@@ -226,7 +226,7 @@ class CompareTxMemPoolEntryByDescendantScore
226226
}
227227

228228
// Calculate which score to use for an entry (avoiding division).
229-
bool UseDescendantScore(const CTxMemPoolEntry &a)
229+
bool UseDescendantScore(const CTxMemPoolEntry &a) const
230230
{
231231
double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants();
232232
double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize();
@@ -241,7 +241,7 @@ class CompareTxMemPoolEntryByDescendantScore
241241
class CompareTxMemPoolEntryByScore
242242
{
243243
public:
244-
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
244+
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
245245
{
246246
double f1 = (double)a.GetModifiedFee() * b.GetTxSize();
247247
double f2 = (double)b.GetModifiedFee() * a.GetTxSize();
@@ -255,7 +255,7 @@ class CompareTxMemPoolEntryByScore
255255
class CompareTxMemPoolEntryByEntryTime
256256
{
257257
public:
258-
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
258+
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
259259
{
260260
return a.GetTime() < b.GetTime();
261261
}

Diff for: src/wallet/wallet.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2410,7 +2410,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
24102410
}
24112411

24122412
static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
2413-
vector<char>& vfBest, CAmount& nBest, int iterations = 1000, bool fUseInstantSend = false)
2413+
vector<char>& vfBest, CAmount& nBest, bool fUseInstantSend = false, int iterations = 1000)
24142414
{
24152415
vector<char> vfIncluded;
24162416

0 commit comments

Comments
 (0)