diff --git a/src/instantx.cpp b/src/instantx.cpp index 7cd95298d..f0a65fa7f 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -122,15 +122,11 @@ bool CInstantSend::ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CCo } LogPrintf("CInstantSend::ProcessTxLockRequest -- accepted, txid=%s\n", txHash.ToString()); - std::map::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. // If this just happened - lock inputs, resolve conflicting locks, update transaction status // forcing external script notification. - TryToFinalizeLockCandidate(txLockCandidate); + std::map::iterator itLockCandidate = mapTxLockCandidates.find(txHash); + TryToFinalizeLockCandidate(itLockCandidate->second); return true; } @@ -182,6 +178,18 @@ void CInstantSend::CreateEmptyTxLockCandidate(const uint256& txHash) mapTxLockCandidates.insert(std::make_pair(txHash, CTxLockCandidate(txLockRequest))); } +void CInstantSend::Vote(const uint256& txHash, CConnman& connman) +{ + AssertLockHeld(cs_main); + LOCK(cs_instantsend); + + std::map::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) { if(!fMasterNode) return; @@ -190,6 +198,8 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman) LOCK2(cs_main, cs_instantsend); 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, // it's possible that we need to vote for several of them std::map::iterator itOutpointLock = txLockCandidate.mapOutPointLocks.begin(); diff --git a/src/instantx.h b/src/instantx.h index 73815c99e..9f071e3b8 100644 --- a/src/instantx.h +++ b/src/instantx.h @@ -86,6 +86,7 @@ public: void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman); bool ProcessTxLockRequest(const CTxLockRequest& txLockRequest, CConnman& connman); + void Vote(const uint256& txHash, CConnman& connman); bool AlreadyHave(const uint256& hash); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index c32256cc5..137a0462a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1635,6 +1635,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrintf("TXLOCKREQUEST -- Transaction Lock Request accepted, txid=%s, peer=%d\n", tx.GetHash().ToString(), pfrom->id); instantsend.AcceptLockRequest(txLockRequest); + instantsend.Vote(tx.GetHash(), connman); } mempool.check(pcoinsTip);