diff --git a/src/governance.cpp b/src/governance.cpp index 8368bb6a5..691d68075 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -35,6 +35,7 @@ CGovernanceManager::CGovernanceManager() nCachedBlockHeight(0), mapObjects(), mapSeenGovernanceObjects(), + mapMasternodeOrphanObjects(), mapVoteToObject(MAX_CACHE_SIZE), mapInvalidVotes(MAX_CACHE_SIZE), mapOrphanVotes(MAX_CACHE_SIZE), @@ -170,7 +171,15 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C std::string strError = ""; // CHECK OBJECT AGAINST LOCAL BLOCKCHAIN - if(!govobj.IsValidLocally(pCurrentBlockIndex, strError, true)) { + bool fMasternodeMissing = false; + bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, fMasternodeMissing, true); + + if(fMasternodeMissing) { + mapMasternodeOrphanObjects.insert(std::make_pair(govobj.GetHash(), govobj)); + LogPrint("gobject", "CGovernanceManager -- Missing masternode for: %s\n", strHash); + // fIsValid must also be false here so we will return early in the next if block + } + if(!fIsValid) { mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_ERROR_INVALID)); LogPrintf("MNGOVERNANCEOBJECT -- Governance object is invalid - %s\n", strError); return; @@ -655,6 +664,37 @@ void CGovernanceManager::CheckMasternodeOrphanVotes() } } +void CGovernanceManager::CheckMasternodeOrphanObjects() +{ + LOCK(cs); + object_m_it it = mapMasternodeOrphanObjects.begin(); + while(it != mapMasternodeOrphanObjects.end()) { + CGovernanceObject& govobj = it->second; + + string strError; + bool fMasternodeMissing = false; + bool fIsValid = govobj.IsValidLocally(pCurrentBlockIndex, strError, fMasternodeMissing, true); + if(!fIsValid) { + if(!fMasternodeMissing) { + mapMasternodeOrphanObjects.erase(it++); + } + else { + ++it; + continue; + } + } + + if(AddGovernanceObject(govobj)) { + LogPrintf("CGovernanceManager::CheckMasternodeOrphanObjects -- %s new\n", govobj.GetHash().ToString()); + govobj.Relay(); + mapMasternodeOrphanObjects.erase(it++); + } + else { + ++it; + } + } +} + void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash) { if(!pfrom) { diff --git a/src/governance.h b/src/governance.h index 5431a98ab..7dab00f44 100644 --- a/src/governance.h +++ b/src/governance.h @@ -120,6 +120,8 @@ private: count_m_t mapSeenGovernanceObjects; + object_m_t mapMasternodeOrphanObjects; + object_ref_cache_t mapVoteToObject; vote_cache_t mapInvalidVotes; @@ -252,6 +254,8 @@ public: void CheckMasternodeOrphanVotes(); + void CheckMasternodeOrphanObjects(); + private: void RequestGovernanceObject(CNode* pfrom, const uint256& nHash); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index c83dd8737..4054f4258 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -1536,6 +1536,7 @@ void CMasternodeMan::NotifyMasternodeUpdates() } if(fMasternodesAddedLocal) { + governance.CheckMasternodeOrphanObjects(); governance.CheckMasternodeOrphanVotes(); } if(fMasternodesRemovedLocal) {