From a3277ea4227a44f5a36435d6cae7ea22cf6726b7 Mon Sep 17 00:00:00 2001 From: Tim Flynn Date: Fri, 11 Nov 2016 16:07:28 -0500 Subject: [PATCH 1/5] Set error string for unparseable objects --- src/governance.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/governance.cpp b/src/governance.cpp index f8f616473..cd28a05f6 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1119,6 +1119,7 @@ bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& s } if(fUnparsable) { + strError = "Object data unparseable"; return false; } From 35a45097ed271b75a95f3c7714d46485df2f2211 Mon Sep 17 00:00:00 2001 From: Tim Flynn Date: Fri, 11 Nov 2016 15:47:04 -0500 Subject: [PATCH 2/5] Added IsValidLocallyMethod overload which returns masternode status flag --- src/governance.cpp | 9 +++++++++ src/governance.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/governance.cpp b/src/governance.cpp index cd28a05f6..8368bb6a5 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1113,6 +1113,14 @@ void CGovernanceObject::UpdateLocalValidity(const CBlockIndex *pCurrentBlockInde bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral) { + bool fMissingMasternode = false; + + return IsValidLocally(pindex, strError, fMissingMasternode, fCheckCollateral); +} + +bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool& fMissingMasternode, bool fCheckCollateral) +{ + fMissingMasternode = false; if(!pindex) { strError = "Tip is NULL"; return true; @@ -1147,6 +1155,7 @@ bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& s std::string strOutpoint = vinMasternode.prevout.ToStringShort(); masternode_info_t infoMn = mnodeman.GetMasternodeInfo(vinMasternode); if(!infoMn.fInfoValid) { + fMissingMasternode = true; strError = "Masternode not found: " + strOutpoint; return false; } diff --git a/src/governance.h b/src/governance.h index 8b655c969..5431a98ab 100644 --- a/src/governance.h +++ b/src/governance.h @@ -481,6 +481,8 @@ public: bool IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral); + bool IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool& fMissingMasternode, bool fCheckCollateral); + /// Check the collateral transaction for the budget proposal/finalized budget bool IsCollateralValid(std::string& strError); From 6deb3a65a336dcadd34caa8ebcb1840b80aef3ac Mon Sep 17 00:00:00 2001 From: Tim Flynn Date: Fri, 11 Nov 2016 20:51:45 -0500 Subject: [PATCH 3/5] Implemented missing masternode handling --- src/governance.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- src/governance.h | 4 ++++ src/masternodeman.cpp | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) 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) { From c4c4f1dad721e71d59b40d0d65163265b8c3baf5 Mon Sep 17 00:00:00 2001 From: Tim Flynn Date: Mon, 14 Nov 2016 21:27:05 -0500 Subject: [PATCH 4/5] Ensure governance objects are still valid before relaying --- src/governance.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/governance.cpp b/src/governance.cpp index 691d68075..556a75704 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -551,7 +551,10 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp) CGovernanceObject& govobj = it->second; - if(govobj.IsSetCachedValid() && (nProp == uint256() || h == nProp)) { + std::string strError; + if(govobj.IsSetCachedValid() && + (nProp == uint256() || h == nProp) && + govobj.IsValidLocally(pCurrentBlockIndex, strError, true)) { // Push the inventory budget proposal message over to the other client pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h)); ++nInvCount; From c00fdb524a4f9ad67cd2f66c9c8a4e4ba2014e2b Mon Sep 17 00:00:00 2001 From: Tim Flynn Date: Tue, 15 Nov 2016 08:23:49 -0500 Subject: [PATCH 5/5] Added peer id to CGovernanceManager::Sync log message --- src/governance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/governance.cpp b/src/governance.cpp index 556a75704..3656fa707 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -572,7 +572,7 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp) } pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ, nInvCount); - LogPrintf("CGovernanceManager::Sync -- sent %d items\n", nInvCount); + LogPrintf("CGovernanceManager::Sync -- sent %d items, peer=%d\n", nInvCount, pfrom->id); } void CGovernanceManager::SyncParentObjectByVote(CNode* pfrom, const CGovernanceVote& vote)