Merge pull request #1141 from tgflynn/v0.12.1.x-gov-mn-sync-fix-pr-2

Masternode syncing fix
This commit is contained in:
UdjinM6 2016-11-16 12:28:40 +04:00 committed by GitHub
commit 426051687d
3 changed files with 63 additions and 3 deletions

View File

@ -35,6 +35,7 @@ CGovernanceManager::CGovernanceManager()
nCachedBlockHeight(0), nCachedBlockHeight(0),
mapObjects(), mapObjects(),
mapSeenGovernanceObjects(), mapSeenGovernanceObjects(),
mapMasternodeOrphanObjects(),
mapVoteToObject(MAX_CACHE_SIZE), mapVoteToObject(MAX_CACHE_SIZE),
mapInvalidVotes(MAX_CACHE_SIZE), mapInvalidVotes(MAX_CACHE_SIZE),
mapOrphanVotes(MAX_CACHE_SIZE), mapOrphanVotes(MAX_CACHE_SIZE),
@ -170,7 +171,15 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
std::string strError = ""; std::string strError = "";
// CHECK OBJECT AGAINST LOCAL BLOCKCHAIN // 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)); mapSeenGovernanceObjects.insert(std::make_pair(nHash, SEEN_OBJECT_ERROR_INVALID));
LogPrintf("MNGOVERNANCEOBJECT -- Governance object is invalid - %s\n", strError); LogPrintf("MNGOVERNANCEOBJECT -- Governance object is invalid - %s\n", strError);
return; return;
@ -542,7 +551,10 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
CGovernanceObject& govobj = it->second; 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 // Push the inventory budget proposal message over to the other client
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h)); pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT, h));
++nInvCount; ++nInvCount;
@ -560,7 +572,7 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
} }
pfrom->PushMessage(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ, nInvCount); 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) void CGovernanceManager::SyncParentObjectByVote(CNode* pfrom, const CGovernanceVote& vote)
@ -655,6 +667,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) void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash)
{ {
if(!pfrom) { if(!pfrom) {
@ -1113,12 +1156,21 @@ void CGovernanceObject::UpdateLocalValidity(const CBlockIndex *pCurrentBlockInde
bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral) 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) { if(!pindex) {
strError = "Tip is NULL"; strError = "Tip is NULL";
return true; return true;
} }
if(fUnparsable) { if(fUnparsable) {
strError = "Object data unparseable";
return false; return false;
} }
@ -1146,6 +1198,7 @@ bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& s
std::string strOutpoint = vinMasternode.prevout.ToStringShort(); std::string strOutpoint = vinMasternode.prevout.ToStringShort();
masternode_info_t infoMn = mnodeman.GetMasternodeInfo(vinMasternode); masternode_info_t infoMn = mnodeman.GetMasternodeInfo(vinMasternode);
if(!infoMn.fInfoValid) { if(!infoMn.fInfoValid) {
fMissingMasternode = true;
strError = "Masternode not found: " + strOutpoint; strError = "Masternode not found: " + strOutpoint;
return false; return false;
} }

View File

@ -120,6 +120,8 @@ private:
count_m_t mapSeenGovernanceObjects; count_m_t mapSeenGovernanceObjects;
object_m_t mapMasternodeOrphanObjects;
object_ref_cache_t mapVoteToObject; object_ref_cache_t mapVoteToObject;
vote_cache_t mapInvalidVotes; vote_cache_t mapInvalidVotes;
@ -252,6 +254,8 @@ public:
void CheckMasternodeOrphanVotes(); void CheckMasternodeOrphanVotes();
void CheckMasternodeOrphanObjects();
private: private:
void RequestGovernanceObject(CNode* pfrom, const uint256& nHash); void RequestGovernanceObject(CNode* pfrom, const uint256& nHash);
@ -481,6 +485,8 @@ public:
bool IsValidLocally(const CBlockIndex* pindex, std::string& strError, bool fCheckCollateral); 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 /// Check the collateral transaction for the budget proposal/finalized budget
bool IsCollateralValid(std::string& strError); bool IsCollateralValid(std::string& strError);

View File

@ -1536,6 +1536,7 @@ void CMasternodeMan::NotifyMasternodeUpdates()
} }
if(fMasternodesAddedLocal) { if(fMasternodesAddedLocal) {
governance.CheckMasternodeOrphanObjects();
governance.CheckMasternodeOrphanVotes(); governance.CheckMasternodeOrphanVotes();
} }
if(fMasternodesRemovedLocal) { if(fMasternodesRemovedLocal) {