Add "enough data" stop conditions for gov sync (#1350)

* Add "enough data" stop conditions for gov sync

* fix:
- make sure condition is checked only once per tick
- let condition be fully used on resync (reset nTimeNoObjectsLeft)
This commit is contained in:
UdjinM6 2017-02-18 00:08:41 +04:00 committed by GitHub
parent 91f7e57402
commit 6d2cc99e35
3 changed files with 51 additions and 24 deletions

View File

@ -71,6 +71,12 @@ bool CGovernanceManager::HaveVoteForHash(uint256 nHash)
return true; return true;
} }
int CGovernanceManager::GetVoteCount() const
{
LOCK(cs);
return (int)mapVoteToObject.GetSize();
}
bool CGovernanceManager::SerializeVoteForHash(uint256 nHash, CDataStream& ss) bool CGovernanceManager::SerializeVoteForHash(uint256 nHash, CDataStream& ss)
{ {
LOCK(cs); LOCK(cs);
@ -987,22 +993,24 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH
pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, nHash, filter); pfrom->PushMessage(NetMsgType::MNGOVERNANCESYNC, nHash, filter);
} }
void CGovernanceManager::RequestGovernanceObjectVotes(CNode* pnode) int CGovernanceManager::RequestGovernanceObjectVotes(CNode* pnode)
{ {
if(pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) return; if(pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) return -3;
std::vector<CNode*> vNodesCopy; std::vector<CNode*> vNodesCopy;
vNodesCopy.push_back(pnode); vNodesCopy.push_back(pnode);
RequestGovernanceObjectVotes(vNodesCopy); return RequestGovernanceObjectVotes(vNodesCopy);
} }
void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy) int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy)
{ {
static std::map<uint256, std::map<CService, int64_t> > mapAskedRecently; static std::map<uint256, std::map<CService, int64_t> > mapAskedRecently;
if(vNodesCopy.empty()) return; if(vNodesCopy.empty()) return -1;
LOCK2(cs_main, cs); LOCK2(cs_main, cs);
if(mapObjects.empty()) return -2;
int64_t nNow = GetTime(); int64_t nNow = GetTime();
int nTimeout = 60 * 60; int nTimeout = 60 * 60;
size_t nPeersPerHashMax = 3; size_t nPeersPerHashMax = 3;
@ -1040,7 +1048,7 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>&
} }
} }
LogPrint("governance", "CGovernanceManager::RequestGovernanceObjectVotes -- start: vpGovObjsTriggersTmp %d vpGovObjsTmp %d mapAskedRecently %d\n", LogPrint("gobject", "CGovernanceManager::RequestGovernanceObjectVotes -- start: vpGovObjsTriggersTmp %d vpGovObjsTmp %d mapAskedRecently %d\n",
vpGovObjsTriggersTmp.size(), vpGovObjsTmp.size(), mapAskedRecently.size()); vpGovObjsTriggersTmp.size(), vpGovObjsTmp.size(), mapAskedRecently.size());
InsecureRand insecureRand; InsecureRand insecureRand;
@ -1087,8 +1095,10 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>&
} }
if(!fAsked) i--; if(!fAsked) i--;
} }
LogPrint("governance", "CGovernanceManager::RequestGovernanceObjectVotes -- end: vpGovObjsTriggersTmp %d vpGovObjsTmp %d mapAskedRecently %d\n", LogPrint("gobject", "CGovernanceManager::RequestGovernanceObjectVotes -- end: vpGovObjsTriggersTmp %d vpGovObjsTmp %d mapAskedRecently %d\n",
vpGovObjsTriggersTmp.size(), vpGovObjsTmp.size(), mapAskedRecently.size()); vpGovObjsTriggersTmp.size(), vpGovObjsTmp.size(), mapAskedRecently.size());
return int(vpGovObjsTriggersTmp.size() + vpGovObjsTmp.size());
} }
bool CGovernanceManager::AcceptObjectMessage(const uint256& nHash) bool CGovernanceManager::AcceptObjectMessage(const uint256& nHash)

View File

@ -345,6 +345,8 @@ public:
bool HaveVoteForHash(uint256 nHash); bool HaveVoteForHash(uint256 nHash);
int GetVoteCount() const;
bool SerializeObjectForHash(uint256 nHash, CDataStream& ss); bool SerializeObjectForHash(uint256 nHash, CDataStream& ss);
bool SerializeVoteForHash(uint256 nHash, CDataStream& ss); bool SerializeVoteForHash(uint256 nHash, CDataStream& ss);
@ -376,8 +378,8 @@ public:
void InitOnLoad(); void InitOnLoad();
void RequestGovernanceObjectVotes(CNode* pnode); int RequestGovernanceObjectVotes(CNode* pnode);
void RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy); int RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy);
private: private:
void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter = false); void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter = false);

View File

@ -465,7 +465,7 @@ void CMasternodeSync::ProcessTick()
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) { if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
LogPrint("mnpayments", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastPaymentVote %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastPaymentVote, GetTime(), GetTime() - nTimeLastPaymentVote); LogPrint("gobject", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastGovernanceItem %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastGovernanceItem, GetTime(), GetTime() - nTimeLastGovernanceItem);
// check for timeout first // check for timeout first
if(GetTime() - nTimeLastGovernanceItem > MASTERNODE_SYNC_TIMEOUT_SECONDS) { if(GetTime() - nTimeLastGovernanceItem > MASTERNODE_SYNC_TIMEOUT_SECONDS) {
@ -479,22 +479,37 @@ void CMasternodeSync::ProcessTick()
return; return;
} }
// check for data
// if(nCountBudgetItemProp > 0 && nCountBudgetItemFin)
// {
// if(governance.CountProposalInventoryItems() >= (nSumBudgetItemProp / nCountBudgetItemProp)*0.9)
// {
// if(governance.CountFinalizedInventoryItems() >= (nSumBudgetItemFin / nCountBudgetItemFin)*0.9)
// {
// SwitchToNextAsset();
// return;
// }
// }
// }
// only request obj sync once from each peer, then request votes on per-obj basis // only request obj sync once from each peer, then request votes on per-obj basis
if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) { if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) {
governance.RequestGovernanceObjectVotes(pnode); int nObjsLeftToAsk = governance.RequestGovernanceObjectVotes(pnode);
static int64_t nTimeNoObjectsLeft = 0;
// check for data
if(nObjsLeftToAsk == 0) {
static int nLastTick = 0;
static int nLastVotes = 0;
if(nTimeNoObjectsLeft == 0) {
// asked all objects for votes for the first time
nTimeNoObjectsLeft = GetTime();
}
// make sure the condition below is checked only once per tick
if(nLastTick == nTick) continue;
if(GetTime() - nTimeNoObjectsLeft > MASTERNODE_SYNC_TIMEOUT_SECONDS &&
governance.GetVoteCount() - nLastVotes < std::max(int(0.0001 * nLastVotes), MASTERNODE_SYNC_TICK_SECONDS)
) {
// We already asked for all objects, waited for MASTERNODE_SYNC_TIMEOUT_SECONDS
// after that and less then 0.01% or MASTERNODE_SYNC_TICK_SECONDS
// (i.e. 1 per second) votes were recieved during the last tick.
// We can be pretty sure that we are done syncing.
LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- asked for all objects, nothing to do\n", nTick, nRequestedMasternodeAssets);
// reset nTimeNoObjectsLeft to be able to use the same condition on resync
nTimeNoObjectsLeft = 0;
SwitchToNextAsset();
ReleaseNodes(vNodesCopy);
return;
}
nLastTick = nTick;
nLastVotes = governance.GetVoteCount();
}
continue; continue;
} }
netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync"); netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");