diff --git a/src/governance-object.cpp b/src/governance-object.cpp index c8d5b9104..f9d27c674 100644 --- a/src/governance-object.cpp +++ b/src/governance-object.cpp @@ -437,7 +437,7 @@ bool CGovernanceObject::IsValidLocally(const CBlockIndex* pindex, std::string& s // IF ABSOLUTE NO COUNT (NO-YES VALID VOTES) IS MORE THAN 10% OF THE NETWORK MASTERNODES, OBJ IS INVALID if(GetAbsoluteNoCount(VOTE_SIGNAL_VALID) > mnodeman.CountEnabled(MIN_GOVERNANCE_PEER_PROTO_VERSION)/10) { - strError = "Automated removal"; + strError = "Voted invalid"; return false; } @@ -666,6 +666,7 @@ void CGovernanceObject::UpdateSentinelVariables(const CBlockIndex *pCurrentBlock // todo - 12.1 - should be set to `10` after governance vote compression is implemented int nAbsVoteReq = std::max(Params().GetConsensus().nGovernanceMinQuorum, nMnCount / 10); + int nAbsDeleteReq = std::max(Params().GetConsensus().nGovernanceMinQuorum, (2 * nMnCount) / 3); // todo - 12.1 - Temporarily set to 1 for testing - reverted //nAbsVoteReq = 1; @@ -681,20 +682,13 @@ void CGovernanceObject::UpdateSentinelVariables(const CBlockIndex *pCurrentBlock // ARE ANY OF THESE FLAGS CURRENTLY ACTIVATED? if(GetAbsoluteYesCount(VOTE_SIGNAL_FUNDING) >= nAbsVoteReq) fCachedFunding = true; - if(GetAbsoluteYesCount(VOTE_SIGNAL_VALID) >= nAbsVoteReq) fCachedValid = true; - if(GetAbsoluteYesCount(VOTE_SIGNAL_DELETE) >= nAbsVoteReq) { + if(GetAbsoluteYesCount(VOTE_SIGNAL_DELETE) >= nAbsDeleteReq) { fCachedDelete = true; nDeletionTime = GetAdjustedTime(); } if(GetAbsoluteYesCount(VOTE_SIGNAL_ENDORSED) >= nAbsVoteReq) fCachedEndorsed = true; - // ARE ANY OF THE VOTING FLAGS NEGATIVELY SET BY THE NETWORK? - // THIS CAN BE CACHED, THE VOTES BEING HOT-LOADED AS NEEDED TO RECALCULATE - - if(GetAbsoluteNoCount(VOTE_SIGNAL_FUNDING) >= nAbsVoteReq) fCachedFunding = false; if(GetAbsoluteNoCount(VOTE_SIGNAL_VALID) >= nAbsVoteReq) fCachedValid = false; - if(GetAbsoluteNoCount(VOTE_SIGNAL_DELETE) >= nAbsVoteReq) fCachedDelete = false; - if(GetAbsoluteNoCount(VOTE_SIGNAL_ENDORSED) >= nAbsVoteReq) fCachedEndorsed = false; } void CGovernanceObject::swap(CGovernanceObject& first, CGovernanceObject& second) // nothrow diff --git a/src/governance-object.h b/src/governance-object.h index 36f1ef70f..05994a8fb 100644 --- a/src/governance-object.h +++ b/src/governance-object.h @@ -48,6 +48,7 @@ static const int64_t GOVERNANCE_FEE_CONFIRMATIONS = 6; static const int64_t GOVERNANCE_UPDATE_MIN = 60*60; static const int64_t GOVERNANCE_DELETION_DELAY = 10*60; static const int64_t GOVERNANCE_ORPHAN_EXPIRATION_TIME = 10*60; +static const int64_t GOVERNANCE_WATCHDOG_EXPIRATION_TIME = 2*60*60; // FOR SEEN MAP ARRAYS - GOVERNANCE OBJECTS AND VOTES diff --git a/src/governance.cpp b/src/governance.cpp index c69782bac..133f22f5b 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -37,6 +37,7 @@ CGovernanceManager::CGovernanceManager() mapObjects(), mapSeenGovernanceObjects(), mapMasternodeOrphanObjects(), + mapWatchdogObjects(), mapVoteToObject(MAX_CACHE_SIZE), mapInvalidVotes(MAX_CACHE_SIZE), mapOrphanVotes(MAX_CACHE_SIZE), @@ -283,6 +284,8 @@ bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj) DBG( cout << "CGovernanceManager::AddGovernanceObject START" << endl; ); + uint256 nHash = govobj.GetHash(); + // MAKE SURE THIS OBJECT IS OK if(!govobj.IsValidLocally(pCurrentBlockIndex, strError, true)) { @@ -292,13 +295,13 @@ bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj) // IF WE HAVE THIS OBJECT ALREADY, WE DON'T WANT ANOTHER COPY - if(mapObjects.count(govobj.GetHash())) { + if(mapObjects.count(nHash)) { LogPrintf("CGovernanceManager::AddGovernanceObject -- already have governance object - %s\n", strError); return false; } // INSERT INTO OUR GOVERNANCE OBJECT MEMORY - mapObjects.insert(std::make_pair(govobj.GetHash(), govobj)); + mapObjects.insert(std::make_pair(nHash, govobj)); // SHOULD WE ADD THIS OBJECT TO ANY OTHER MANANGERS? @@ -315,9 +318,12 @@ bool CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj) case GOVERNANCE_OBJECT_TRIGGER: mapLastMasternodeTrigger[govobj.vinMasternode.prevout] = nCachedBlockHeight; DBG( cout << "CGovernanceManager::AddGovernanceObject Before AddNewTrigger" << endl; ); - triggerman.AddNewTrigger(govobj.GetHash()); + triggerman.AddNewTrigger(nHash); DBG( cout << "CGovernanceManager::AddGovernanceObject After AddNewTrigger" << endl; ); break; + case GOVERNANCE_OBJECT_WATCHDOG: + mapWatchdogObjects[nHash] = GetAdjustedTime() + GOVERNANCE_WATCHDOG_EXPIRATION_TIME; + break; default: break; } @@ -335,6 +341,25 @@ void CGovernanceManager::UpdateCachesAndClean() LOCK(cs); + // Flag expired watchdogs for removal + int64_t nNow = GetAdjustedTime(); + if(mapWatchdogObjects.size() > 1) { + hash_time_m_it it = mapWatchdogObjects.begin(); + while(it != mapWatchdogObjects.end()) { + if(it->second < nNow) { + object_m_it it2 = mapObjects.find(it->first); + if(it2 != mapObjects.end()) { + it2->second.fExpired = true; + it2->second.nDeletionTime = nNow; + } + mapWatchdogObjects.erase(it++); + } + else { + ++it; + } + } + } + for(size_t i = 0; i < vecDirtyHashes.size(); ++i) { object_m_it it = mapObjects.find(vecDirtyHashes[i]); if(it == mapObjects.end()) { diff --git a/src/governance.h b/src/governance.h index 33429e519..0765cc105 100644 --- a/src/governance.h +++ b/src/governance.h @@ -92,6 +92,12 @@ public: // Types typedef object_time_m_t::const_iterator object_time_m_cit; + typedef std::map hash_time_m_t; + + typedef hash_time_m_t::iterator hash_time_m_it; + + typedef hash_time_m_t::const_iterator hash_time_m_cit; + private: static const int MAX_CACHE_SIZE = 1000000; @@ -110,6 +116,8 @@ private: object_time_m_t mapMasternodeOrphanObjects; + hash_time_m_t mapWatchdogObjects; + object_ref_cache_t mapVoteToObject; vote_cache_t mapInvalidVotes;