diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d6fd18bb9..c4364465c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -84,6 +84,7 @@ public: consensus.nSuperblockStartBlock = 600000; // TODO, the block at which 12.1 goes live. consensus.nSuperblockCycle = 16616; // ~(60*24*30)/2.6, actual number of blocks per month is 200700 / 12 = 16725 consensus.nGovernanceMinQuorum = 10; + consensus.nGovernanceFilterElements = 20000; consensus.nMasternodeMinimumConfirmations = 15; consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; @@ -207,6 +208,7 @@ public: consensus.nSuperblockStartBlock = 61000; // NOTE: Should satisfy nSuperblockStartBlock > nBudgetPeymentsStartBlock consensus.nSuperblockCycle = 24; // Superblocks can be issued hourly on testnet consensus.nGovernanceMinQuorum = 1; + consensus.nGovernanceFilterElements = 500; consensus.nMasternodeMinimumConfirmations = 1; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; @@ -313,6 +315,7 @@ public: consensus.nSuperblockStartBlock = 1500; consensus.nSuperblockCycle = 10; consensus.nGovernanceMinQuorum = 1; + consensus.nGovernanceFilterElements = 100; consensus.nMasternodeMinimumConfirmations = 1; consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; diff --git a/src/consensus/params.h b/src/consensus/params.h index 23fa8f301..504577f40 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -47,7 +47,8 @@ struct Params { int nBudgetProposalEstablishingTime; // in seconds int nSuperblockStartBlock; int nSuperblockCycle; // in blocks - int nGovernanceMinQuorum; // Min absolute vote count to trigger an action + int nGovernanceMinQuorum; // Min absolute vote count to trigger an action + int nGovernanceFilterElements; int nMasternodeMinimumConfirmations; /** Used to check majorities for block version upgrade */ int nMajorityEnforceBlockUpgrade; diff --git a/src/governance-object.h b/src/governance-object.h index e37fbc770..b8e8b3144 100644 --- a/src/governance-object.h +++ b/src/governance-object.h @@ -25,6 +25,9 @@ class CGovernanceVote; static const int MAX_GOVERNANCE_OBJECT_DATA_SIZE = 16 * 1024; static const int MIN_GOVERNANCE_PEER_PROTO_VERSION = 70204; +static const int GOVERNANCE_FILTER_PROTO_VERSION = 70206; + +static const double GOVERNANCE_FILTER_FP_RATE = 0.001; static const int GOVERNANCE_OBJECT_UNKNOWN = 0; static const int GOVERNANCE_OBJECT_PROPOSAL = 1; diff --git a/src/governance.cpp b/src/governance.cpp index 10d6bf1c1..8ef883d70 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -113,8 +113,18 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C if (!masternodeSync.IsSynced()) return; uint256 nProp; + CBloomFilter filter; + vRecv >> nProp; + if(pfrom->nVersion >= GOVERNANCE_FILTER_PROTO_VERSION) { + vRecv >> filter; + filter.UpdateEmptyFull(); + } + else { + filter.clear(); + } + if(nProp == uint256()) { if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MNGOVERNANCESYNC)) { // Asking for the whole list multiple times in a short period of time is no good @@ -125,7 +135,7 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C netfulfilledman.AddFulfilledRequest(pfrom->addr, NetMsgType::MNGOVERNANCESYNC); } - Sync(pfrom, nProp); + Sync(pfrom, nProp, filter); LogPrint("gobject", "MNGOVERNANCESYNC -- syncing governance objects to our peer at %s\n", pfrom->addr.ToString()); } @@ -640,11 +650,14 @@ bool CGovernanceManager::ConfirmInventoryRequest(const CInv& inv) LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest added inv to requested set\n"); } + // Keep sync alive + masternodeSync.AddedGovernanceItem(); + LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest reached end, returning true\n"); return true; } -void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp) +void CGovernanceManager::Sync(CNode* pfrom, const uint256& nProp, const CBloomFilter& filter) { /* @@ -709,6 +722,9 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp) if(!vecVotes[i].IsValid(true)) { continue; } + if(filter.contains(vecVotes[i].GetHash())) { + continue; + } pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, vecVotes[i].GetHash())); ++nVoteCount; } @@ -927,13 +943,33 @@ void CGovernanceManager::CheckMasternodeOrphanObjects() fRateChecksEnabled = true; } -void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash) +void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter) { if(!pfrom) { return; } - pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, nHash); + if(pfrom->nVersion < GOVERNANCE_FILTER_PROTO_VERSION) { + pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, nHash); + return; + } + + CBloomFilter filter; + filter.clear(); + + if(fUseFilter) { + CGovernanceObject* pObj = FindGovernanceObject(nHash); + + if(pObj) { + filter = CBloomFilter(Params().GetConsensus().nGovernanceFilterElements, GOVERNANCE_FILTER_FP_RATE, GetRandInt(999999), BLOOM_UPDATE_ALL); + std::vector vecVotes = pObj->GetVoteFile().GetVotes(); + for(size_t i = 0; i < vecVotes.size(); ++i) { + filter.insert(vecVotes[i].GetHash()); + } + } + } + + pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, nHash, filter); } void CGovernanceManager::RequestGovernanceObjectVotes(CNode* pnode) @@ -979,7 +1015,7 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& vpGovObjsTmp.erase(vpGovObjsTmp.begin() + r); } LogPrintf("CGovernanceManager::RequestGovernanceObjectVotes -- Requesting votes for %s, peer=%d\n", nHashGovobj.ToString(), pnode->id); - RequestGovernanceObject(pnode, nHashGovobj); + RequestGovernanceObject(pnode, nHashGovobj, true); mapAskedRecently[nHashGovobj] = nNow + mapObjects.size() * 60; // ask again after full cycle } } diff --git a/src/governance.h b/src/governance.h index 67318491b..99f84a4b5 100644 --- a/src/governance.h +++ b/src/governance.h @@ -7,6 +7,7 @@ //#define ENABLE_DASH_DEBUG +#include "bloom.h" #include "cachemap.h" #include "cachemultimap.h" #include "chain.h" @@ -271,7 +272,7 @@ public: */ bool ConfirmInventoryRequest(const CInv& inv); - void Sync(CNode* node, uint256 nProp); + void Sync(CNode* node, const uint256& nProp, const CBloomFilter& filter); void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); @@ -379,7 +380,7 @@ public: void RequestGovernanceObjectVotes(const std::vector& vNodesCopy); private: - void RequestGovernanceObject(CNode* pfrom, const uint256& nHash); + void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter = false); void AddInvalidVote(const CGovernanceVote& vote) { diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index 0f982fc8e..c90067344 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -344,8 +344,7 @@ void CMasternodeSync::ProcessTick() } else if(nRequestedMasternodeAttempt < 6) { int nMnCount = mnodeman.CountMasternodes(); pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes - uint256 n = uint256(); - pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes + SendGovernanceSyncRequest(pnode); } else { nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED; } @@ -497,7 +496,7 @@ void CMasternodeSync::ProcessTick() if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue; nRequestedMasternodeAttempt++; - pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes + SendGovernanceSyncRequest(pnode); ReleaseNodes(vNodesCopy); return; //this will cause each peer to get one request each six seconds for the various assets we need @@ -508,6 +507,19 @@ void CMasternodeSync::ProcessTick() ReleaseNodes(vNodesCopy); } +void CMasternodeSync::SendGovernanceSyncRequest(CNode* pnode) +{ + if(pnode->nVersion >= GOVERNANCE_FILTER_PROTO_VERSION) { + CBloomFilter filter; + filter.clear(); + + pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256(), filter); + } + else { + pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); + } +} + void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex) { pCurrentBlockIndex = pindex; diff --git a/src/masternode-sync.h b/src/masternode-sync.h index 447e230e3..7f4666dac 100644 --- a/src/masternode-sync.h +++ b/src/masternode-sync.h @@ -67,6 +67,8 @@ public: void AddedPaymentVote() { nTimeLastPaymentVote = GetTime(); } void AddedGovernanceItem() { nTimeLastGovernanceItem = GetTime(); }; + void SendGovernanceSyncRequest(CNode* pnode); + bool IsFailed() { return nRequestedMasternodeAssets == MASTERNODE_SYNC_FAILED; } bool IsBlockchainSynced(bool fBlockAccepted = false); bool IsMasternodeListSynced() { return nRequestedMasternodeAssets > MASTERNODE_SYNC_LIST; }