From 6d2cc99e35980e0748e60e81bcbd43b85e8ad321 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sat, 18 Feb 2017 00:08:41 +0400 Subject: [PATCH] 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) --- src/governance.cpp | 24 +++++++++++++++------- src/governance.h | 6 ++++-- src/masternode-sync.cpp | 45 +++++++++++++++++++++++++++-------------- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/governance.cpp b/src/governance.cpp index 0ef3fcf444..7e76a1bdee 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -71,6 +71,12 @@ bool CGovernanceManager::HaveVoteForHash(uint256 nHash) return true; } +int CGovernanceManager::GetVoteCount() const +{ + LOCK(cs); + return (int)mapVoteToObject.GetSize(); +} + bool CGovernanceManager::SerializeVoteForHash(uint256 nHash, CDataStream& ss) { LOCK(cs); @@ -987,22 +993,24 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH 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 vNodesCopy; vNodesCopy.push_back(pnode); - RequestGovernanceObjectVotes(vNodesCopy); + return RequestGovernanceObjectVotes(vNodesCopy); } -void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& vNodesCopy) +int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& vNodesCopy) { static std::map > mapAskedRecently; - if(vNodesCopy.empty()) return; + if(vNodesCopy.empty()) return -1; LOCK2(cs_main, cs); + if(mapObjects.empty()) return -2; + int64_t nNow = GetTime(); int nTimeout = 60 * 60; size_t nPeersPerHashMax = 3; @@ -1040,7 +1048,7 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& } } - 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()); InsecureRand insecureRand; @@ -1087,8 +1095,10 @@ void CGovernanceManager::RequestGovernanceObjectVotes(const std::vector& } 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()); + + return int(vpGovObjsTriggersTmp.size() + vpGovObjsTmp.size()); } bool CGovernanceManager::AcceptObjectMessage(const uint256& nHash) diff --git a/src/governance.h b/src/governance.h index 99f84a4b59..fe10a0beaf 100644 --- a/src/governance.h +++ b/src/governance.h @@ -345,6 +345,8 @@ public: bool HaveVoteForHash(uint256 nHash); + int GetVoteCount() const; + bool SerializeObjectForHash(uint256 nHash, CDataStream& ss); bool SerializeVoteForHash(uint256 nHash, CDataStream& ss); @@ -376,8 +378,8 @@ public: void InitOnLoad(); - void RequestGovernanceObjectVotes(CNode* pnode); - void RequestGovernanceObjectVotes(const std::vector& vNodesCopy); + int RequestGovernanceObjectVotes(CNode* pnode); + int RequestGovernanceObjectVotes(const std::vector& vNodesCopy); private: void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, bool fUseFilter = false); diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index e173085f6d..ac0c69f7ef 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -465,7 +465,7 @@ void CMasternodeSync::ProcessTick() // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS 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 if(GetTime() - nTimeLastGovernanceItem > MASTERNODE_SYNC_TIMEOUT_SECONDS) { @@ -479,22 +479,37 @@ void CMasternodeSync::ProcessTick() 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 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; } netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");