Improve governance syncing efficiency with bloom filter (#1299)
* Use bloom filter for governance vote syncing Modify masternode-sync to send bloom filters Correctly initialize bloom filter Set fUseFilter argument Increase bloom filter size to account for multiple signals Set bloom filter parameters Use constants for bloom filter parameters Added filter size check Added filter size check in masternode-sync Update bloom filter Changed bloom parameters * Bump protocol version * Update sync time for inv's * Changes based on code review comments * Make bloom filter size network dependent * Fix network dependent filter parameters * Remove unneeded constant definition * Move constant definition * Add blank line
This commit is contained in:
parent
cfc8954b42
commit
399330d42d
@ -84,6 +84,7 @@ public:
|
|||||||
consensus.nSuperblockStartBlock = 600000; // TODO, the block at which 12.1 goes live.
|
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.nSuperblockCycle = 16616; // ~(60*24*30)/2.6, actual number of blocks per month is 200700 / 12 = 16725
|
||||||
consensus.nGovernanceMinQuorum = 10;
|
consensus.nGovernanceMinQuorum = 10;
|
||||||
|
consensus.nGovernanceFilterElements = 20000;
|
||||||
consensus.nMasternodeMinimumConfirmations = 15;
|
consensus.nMasternodeMinimumConfirmations = 15;
|
||||||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||||
consensus.nMajorityRejectBlockOutdated = 950;
|
consensus.nMajorityRejectBlockOutdated = 950;
|
||||||
@ -207,6 +208,7 @@ public:
|
|||||||
consensus.nSuperblockStartBlock = 61000; // NOTE: Should satisfy nSuperblockStartBlock > nBudgetPeymentsStartBlock
|
consensus.nSuperblockStartBlock = 61000; // NOTE: Should satisfy nSuperblockStartBlock > nBudgetPeymentsStartBlock
|
||||||
consensus.nSuperblockCycle = 24; // Superblocks can be issued hourly on testnet
|
consensus.nSuperblockCycle = 24; // Superblocks can be issued hourly on testnet
|
||||||
consensus.nGovernanceMinQuorum = 1;
|
consensus.nGovernanceMinQuorum = 1;
|
||||||
|
consensus.nGovernanceFilterElements = 500;
|
||||||
consensus.nMasternodeMinimumConfirmations = 1;
|
consensus.nMasternodeMinimumConfirmations = 1;
|
||||||
consensus.nMajorityEnforceBlockUpgrade = 51;
|
consensus.nMajorityEnforceBlockUpgrade = 51;
|
||||||
consensus.nMajorityRejectBlockOutdated = 75;
|
consensus.nMajorityRejectBlockOutdated = 75;
|
||||||
@ -313,6 +315,7 @@ public:
|
|||||||
consensus.nSuperblockStartBlock = 1500;
|
consensus.nSuperblockStartBlock = 1500;
|
||||||
consensus.nSuperblockCycle = 10;
|
consensus.nSuperblockCycle = 10;
|
||||||
consensus.nGovernanceMinQuorum = 1;
|
consensus.nGovernanceMinQuorum = 1;
|
||||||
|
consensus.nGovernanceFilterElements = 100;
|
||||||
consensus.nMasternodeMinimumConfirmations = 1;
|
consensus.nMasternodeMinimumConfirmations = 1;
|
||||||
consensus.nMajorityEnforceBlockUpgrade = 750;
|
consensus.nMajorityEnforceBlockUpgrade = 750;
|
||||||
consensus.nMajorityRejectBlockOutdated = 950;
|
consensus.nMajorityRejectBlockOutdated = 950;
|
||||||
|
@ -47,7 +47,8 @@ struct Params {
|
|||||||
int nBudgetProposalEstablishingTime; // in seconds
|
int nBudgetProposalEstablishingTime; // in seconds
|
||||||
int nSuperblockStartBlock;
|
int nSuperblockStartBlock;
|
||||||
int nSuperblockCycle; // in blocks
|
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;
|
int nMasternodeMinimumConfirmations;
|
||||||
/** Used to check majorities for block version upgrade */
|
/** Used to check majorities for block version upgrade */
|
||||||
int nMajorityEnforceBlockUpgrade;
|
int nMajorityEnforceBlockUpgrade;
|
||||||
|
@ -25,6 +25,9 @@ class CGovernanceVote;
|
|||||||
|
|
||||||
static const int MAX_GOVERNANCE_OBJECT_DATA_SIZE = 16 * 1024;
|
static const int MAX_GOVERNANCE_OBJECT_DATA_SIZE = 16 * 1024;
|
||||||
static const int MIN_GOVERNANCE_PEER_PROTO_VERSION = 70204;
|
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_UNKNOWN = 0;
|
||||||
static const int GOVERNANCE_OBJECT_PROPOSAL = 1;
|
static const int GOVERNANCE_OBJECT_PROPOSAL = 1;
|
||||||
|
@ -113,8 +113,18 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
if (!masternodeSync.IsSynced()) return;
|
if (!masternodeSync.IsSynced()) return;
|
||||||
|
|
||||||
uint256 nProp;
|
uint256 nProp;
|
||||||
|
CBloomFilter filter;
|
||||||
|
|
||||||
vRecv >> nProp;
|
vRecv >> nProp;
|
||||||
|
|
||||||
|
if(pfrom->nVersion >= GOVERNANCE_FILTER_PROTO_VERSION) {
|
||||||
|
vRecv >> filter;
|
||||||
|
filter.UpdateEmptyFull();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
filter.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if(nProp == uint256()) {
|
if(nProp == uint256()) {
|
||||||
if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MNGOVERNANCESYNC)) {
|
if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MNGOVERNANCESYNC)) {
|
||||||
// Asking for the whole list multiple times in a short period of time is no good
|
// 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);
|
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());
|
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");
|
LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest added inv to requested set\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep sync alive
|
||||||
|
masternodeSync.AddedGovernanceItem();
|
||||||
|
|
||||||
LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest reached end, returning true\n");
|
LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest reached end, returning true\n");
|
||||||
return true;
|
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)) {
|
if(!vecVotes[i].IsValid(true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(filter.contains(vecVotes[i].GetHash())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, vecVotes[i].GetHash()));
|
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, vecVotes[i].GetHash()));
|
||||||
++nVoteCount;
|
++nVoteCount;
|
||||||
}
|
}
|
||||||
@ -927,13 +943,33 @@ void CGovernanceManager::CheckMasternodeOrphanObjects()
|
|||||||
fRateChecksEnabled = true;
|
fRateChecksEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash)
|
void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter)
|
||||||
{
|
{
|
||||||
if(!pfrom) {
|
if(!pfrom) {
|
||||||
return;
|
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<CGovernanceVote> 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)
|
void CGovernanceManager::RequestGovernanceObjectVotes(CNode* pnode)
|
||||||
@ -979,7 +1015,7 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>&
|
|||||||
vpGovObjsTmp.erase(vpGovObjsTmp.begin() + r);
|
vpGovObjsTmp.erase(vpGovObjsTmp.begin() + r);
|
||||||
}
|
}
|
||||||
LogPrintf("CGovernanceManager::RequestGovernanceObjectVotes -- Requesting votes for %s, peer=%d\n", nHashGovobj.ToString(), pnode->id);
|
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
|
mapAskedRecently[nHashGovobj] = nNow + mapObjects.size() * 60; // ask again after full cycle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
//#define ENABLE_DASH_DEBUG
|
//#define ENABLE_DASH_DEBUG
|
||||||
|
|
||||||
|
#include "bloom.h"
|
||||||
#include "cachemap.h"
|
#include "cachemap.h"
|
||||||
#include "cachemultimap.h"
|
#include "cachemultimap.h"
|
||||||
#include "chain.h"
|
#include "chain.h"
|
||||||
@ -271,7 +272,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool ConfirmInventoryRequest(const CInv& inv);
|
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);
|
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
||||||
|
|
||||||
@ -379,7 +380,7 @@ public:
|
|||||||
void RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy);
|
void RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RequestGovernanceObject(CNode* pfrom, const uint256& nHash);
|
void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter = false);
|
||||||
|
|
||||||
void AddInvalidVote(const CGovernanceVote& vote)
|
void AddInvalidVote(const CGovernanceVote& vote)
|
||||||
{
|
{
|
||||||
|
@ -344,8 +344,7 @@ void CMasternodeSync::ProcessTick()
|
|||||||
} else if(nRequestedMasternodeAttempt < 6) {
|
} else if(nRequestedMasternodeAttempt < 6) {
|
||||||
int nMnCount = mnodeman.CountMasternodes();
|
int nMnCount = mnodeman.CountMasternodes();
|
||||||
pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
|
pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
|
||||||
uint256 n = uint256();
|
SendGovernanceSyncRequest(pnode);
|
||||||
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes
|
|
||||||
} else {
|
} else {
|
||||||
nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
|
nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
|
||||||
}
|
}
|
||||||
@ -497,7 +496,7 @@ void CMasternodeSync::ProcessTick()
|
|||||||
if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue;
|
if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue;
|
||||||
nRequestedMasternodeAttempt++;
|
nRequestedMasternodeAttempt++;
|
||||||
|
|
||||||
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes
|
SendGovernanceSyncRequest(pnode);
|
||||||
|
|
||||||
ReleaseNodes(vNodesCopy);
|
ReleaseNodes(vNodesCopy);
|
||||||
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
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);
|
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)
|
void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex)
|
||||||
{
|
{
|
||||||
pCurrentBlockIndex = pindex;
|
pCurrentBlockIndex = pindex;
|
||||||
|
@ -67,6 +67,8 @@ public:
|
|||||||
void AddedPaymentVote() { nTimeLastPaymentVote = GetTime(); }
|
void AddedPaymentVote() { nTimeLastPaymentVote = GetTime(); }
|
||||||
void AddedGovernanceItem() { nTimeLastGovernanceItem = GetTime(); };
|
void AddedGovernanceItem() { nTimeLastGovernanceItem = GetTime(); };
|
||||||
|
|
||||||
|
void SendGovernanceSyncRequest(CNode* pnode);
|
||||||
|
|
||||||
bool IsFailed() { return nRequestedMasternodeAssets == MASTERNODE_SYNC_FAILED; }
|
bool IsFailed() { return nRequestedMasternodeAssets == MASTERNODE_SYNC_FAILED; }
|
||||||
bool IsBlockchainSynced(bool fBlockAccepted = false);
|
bool IsBlockchainSynced(bool fBlockAccepted = false);
|
||||||
bool IsMasternodeListSynced() { return nRequestedMasternodeAssets > MASTERNODE_SYNC_LIST; }
|
bool IsMasternodeListSynced() { return nRequestedMasternodeAssets > MASTERNODE_SYNC_LIST; }
|
||||||
|
Loading…
Reference in New Issue
Block a user