From 5c683ccb9651e5b46b32fb3cbfd1d84bc6e9ab82 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 13:40:53 +0200 Subject: [PATCH 01/11] masternode: Replace sync states INITIAL and WAITING with BLOCKCHAIN --- src/masternode/masternode-sync.cpp | 36 ++++++++---------------------- src/masternode/masternode-sync.h | 8 ++++--- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index 8a2423db1b66..dd306d476eeb 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -16,10 +16,11 @@ CMasternodeSync masternodeSync; void CMasternodeSync::Reset() { - nCurrentAsset = MASTERNODE_SYNC_INITIAL; + nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN; nTriedPeerCount = 0; nTimeAssetSyncStarted = GetTime(); nTimeLastBumped = GetTime(); + fReachedBestHeader = false; } void CMasternodeSync::BumpAssetLastTime(const std::string& strFuncName) @@ -33,8 +34,7 @@ std::string CMasternodeSync::GetAssetName() const { switch(nCurrentAsset) { - case(MASTERNODE_SYNC_INITIAL): return "MASTERNODE_SYNC_INITIAL"; - case(MASTERNODE_SYNC_WAITING): return "MASTERNODE_SYNC_WAITING"; + case(MASTERNODE_SYNC_BLOCKCHAIN): return "MASTERNODE_SYNC_BLOCKCHAIN"; case(MASTERNODE_SYNC_GOVERNANCE): return "MASTERNODE_SYNC_GOVERNANCE"; case MASTERNODE_SYNC_FINISHED: return "MASTERNODE_SYNC_FINISHED"; default: return "UNKNOWN"; @@ -45,11 +45,7 @@ void CMasternodeSync::SwitchToNextAsset(CConnman& connman) { switch(nCurrentAsset) { - case(MASTERNODE_SYNC_INITIAL): - nCurrentAsset = MASTERNODE_SYNC_WAITING; - LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName()); - break; - case(MASTERNODE_SYNC_WAITING): + case(MASTERNODE_SYNC_BLOCKCHAIN): LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted); nCurrentAsset = MASTERNODE_SYNC_GOVERNANCE; LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName()); @@ -74,8 +70,7 @@ void CMasternodeSync::SwitchToNextAsset(CConnman& connman) std::string CMasternodeSync::GetSyncStatus() const { switch (nCurrentAsset) { - case MASTERNODE_SYNC_INITIAL: return _("Synchronizing blockchain..."); - case MASTERNODE_SYNC_WAITING: return _("Synchronization pending..."); + case MASTERNODE_SYNC_BLOCKCHAIN: return _("Synchronizing blockchain..."); case MASTERNODE_SYNC_GOVERNANCE: return _("Synchronizing governance objects..."); case MASTERNODE_SYNC_FINISHED: return _("Synchronization finished"); default: return ""; @@ -110,7 +105,6 @@ void CMasternodeSync::ProcessTick(CConnman& connman) if(GetTime() - nTimeLastProcess > 60*60 && !fMasternodeMode) { LogPrintf("CMasternodeSync::ProcessTick -- WARNING: no actions for too long, restarting sync...\n"); Reset(); - SwitchToNextAsset(connman); nTimeLastProcess = GetTime(); return; } @@ -150,7 +144,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // QUICK MODE (REGTEST ONLY!) if(Params().NetworkIDString() == CBaseChainParams::REGTEST) { - if (nCurrentAsset == MASTERNODE_SYNC_WAITING) { + if (nCurrentAsset == MASTERNODE_SYNC_BLOCKCHAIN) { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETSPORKS)); //get current network sporks SwitchToNextAsset(connman); } else if (nCurrentAsset == MASTERNODE_SYNC_GOVERNANCE) { @@ -187,21 +181,18 @@ void CMasternodeSync::ProcessTick(CConnman& connman) LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nCurrentAsset %d -- requesting sporks from peer=%d\n", nTick, nCurrentAsset, pnode->GetId()); } - // INITIAL TIMEOUT - - if(nCurrentAsset == MASTERNODE_SYNC_WAITING) { + if (nCurrentAsset == MASTERNODE_SYNC_BLOCKCHAIN) { if(pnode->nVersion >= 70216 && !pnode->fInbound && gArgs.GetBoolArg("-syncmempool", DEFAULT_SYNC_MEMPOOL) && !netfulfilledman.HasFulfilledRequest(pnode->addr, "mempool-sync")) { netfulfilledman.AddFulfilledRequest(pnode->addr, "mempool-sync"); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MEMPOOL)); LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nCurrentAsset %d -- syncing mempool from peer=%d\n", nTick, nCurrentAsset, pnode->GetId()); } - if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { + if (fReachedBestHeader && GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { // At this point we know that: // a) there are peers (because we are looping on at least one of them); // b) we waited for at least MASTERNODE_SYNC_TIMEOUT_SECONDS since we reached - // the headers tip the last time (i.e. since we switched from - // MASTERNODE_SYNC_INITIAL to MASTERNODE_SYNC_WAITING and bumped time); + // the headers tip the last time (i.e. since fReachedBestHeader has been set to true); // c) there were no blocks (UpdatedBlockTip, NotifyHeaderTip) or headers (AcceptedBlockHeader) // for at least MASTERNODE_SYNC_TIMEOUT_SECONDS. // We must be at the tip already, let's move to the next asset. @@ -341,7 +332,6 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitia } // Note: since we sync headers first, it should be ok to use this - static bool fReachedBestHeader = false; bool fReachedBestHeaderNew = pindexNew->GetBlockHash() == pindexBestHeader->GetBlockHash(); if (fReachedBestHeader && !fReachedBestHeaderNew) { @@ -349,20 +339,12 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitia // probably initial timeout was not enough, // because there is no way we can update tip not having best header Reset(); - fReachedBestHeader = false; - return; } fReachedBestHeader = fReachedBestHeaderNew; LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d pindexBestHeader->nHeight: %d fInitialDownload=%d fReachedBestHeader=%d\n", pindexNew->nHeight, pindexBestHeader->nHeight, fInitialDownload, fReachedBestHeader); - - if (!IsBlockchainSynced() && fReachedBestHeader) { - // Reached best header while being in initial mode. - // We must be at the tip already, let's move to the next asset. - SwitchToNextAsset(connman); - } } void CMasternodeSync::DoMaintenance(CConnman &connman) diff --git a/src/masternode/masternode-sync.h b/src/masternode/masternode-sync.h index fe160b6767b1..659603fe0919 100644 --- a/src/masternode/masternode-sync.h +++ b/src/masternode/masternode-sync.h @@ -9,8 +9,7 @@ class CMasternodeSync; -static const int MASTERNODE_SYNC_INITIAL = 0; // sync just started, was reset recently or still in IDB -static const int MASTERNODE_SYNC_WAITING = 1; // waiting after initial to see if we can get more headers/blocks +static const int MASTERNODE_SYNC_BLOCKCHAIN = 1; static const int MASTERNODE_SYNC_GOVERNANCE = 4; static const int MASTERNODE_SYNC_GOVOBJ = 10; static const int MASTERNODE_SYNC_GOVOBJ_VOTE = 11; @@ -38,12 +37,15 @@ class CMasternodeSync // ... last bumped int64_t nTimeLastBumped; + /// Set to true if best header is reached in CMasternodeSync::UpdatedBlockTip + bool fReachedBestHeader{false}; + public: CMasternodeSync() { Reset(); } static void SendGovernanceSyncRequest(CNode* pnode, CConnman& connman); - bool IsBlockchainSynced() const { return nCurrentAsset > MASTERNODE_SYNC_WAITING; } + bool IsBlockchainSynced() const { return nCurrentAsset > MASTERNODE_SYNC_BLOCKCHAIN; } bool IsSynced() const { return nCurrentAsset == MASTERNODE_SYNC_FINISHED; } int GetAssetID() const { return nCurrentAsset; } From f63242bef7f575eb1033c088028889216ec1e872 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 22:02:50 +0200 Subject: [PATCH 02/11] masternode: Peer dependent "assume tip" timeout I would say its enough to only wait 1 tick if we have more than 3 peers before we move over to governance sync. --- src/masternode/masternode-sync.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index dd306d476eeb..abd96b03f4a2 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -188,13 +188,15 @@ void CMasternodeSync::ProcessTick(CConnman& connman) LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nCurrentAsset %d -- syncing mempool from peer=%d\n", nTick, nCurrentAsset, pnode->GetId()); } - if (fReachedBestHeader && GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { + if (fReachedBestHeader && GetTime() - nTimeLastBumped > (vNodesCopy.size() > 3 ? MASTERNODE_SYNC_TICK_SECONDS : MASTERNODE_SYNC_TIMEOUT_SECONDS)) { // At this point we know that: // a) there are peers (because we are looping on at least one of them); - // b) we waited for at least MASTERNODE_SYNC_TIMEOUT_SECONDS since we reached - // the headers tip the last time (i.e. since fReachedBestHeader has been set to true); + // b) we waited for at least MASTERNODE_SYNC_TICK_SECONDS/MASTERNODE_SYNC_TIMEOUT_SECONDS + // (depending on the number of connected peers) since we reached the headers tip the last + // time (i.e. since fReachedBestHeader has been set to true); // c) there were no blocks (UpdatedBlockTip, NotifyHeaderTip) or headers (AcceptedBlockHeader) - // for at least MASTERNODE_SYNC_TIMEOUT_SECONDS. + // for at least MASTERNODE_SYNC_TICK_SECONDS/MASTERNODE_SYNC_TIMEOUT_SECONDS (depending on + // the number of connected peers). // We must be at the tip already, let's move to the next asset. SwitchToNextAsset(connman); } From 063467c8eb610724b28c1f9b5a94e8ea142f38e5 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 16:30:40 +0200 Subject: [PATCH 03/11] masternode: Notify the UI instantly if switched to governance sync Without this it takes one iteration more for the UI to receive the update. --- src/masternode/masternode-sync.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index abd96b03f4a2..383579ba02cd 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -199,6 +199,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // the number of connected peers). // We must be at the tip already, let's move to the next asset. SwitchToNextAsset(connman); + uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); } } From 24f0b23a1816889e0a6773390a6be44bfab99cb3 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 16:32:19 +0200 Subject: [PATCH 04/11] masternode: Notify the UI about CMasternodeSync::Reset calls --- src/masternode/masternode-sync.cpp | 5 ++++- src/masternode/masternode-sync.h | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index 383579ba02cd..898f1da7f2d7 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -14,13 +14,16 @@ class CMasternodeSync; CMasternodeSync masternodeSync; -void CMasternodeSync::Reset() +void CMasternodeSync::Reset(bool fNotifyReset) { nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN; nTriedPeerCount = 0; nTimeAssetSyncStarted = GetTime(); nTimeLastBumped = GetTime(); fReachedBestHeader = false; + if (fNotifyReset) { + uiInterface.NotifyAdditionalDataSyncProgressChanged(-1); + } } void CMasternodeSync::BumpAssetLastTime(const std::string& strFuncName) diff --git a/src/masternode/masternode-sync.h b/src/masternode/masternode-sync.h index 659603fe0919..904c22968ef8 100644 --- a/src/masternode/masternode-sync.h +++ b/src/masternode/masternode-sync.h @@ -41,7 +41,7 @@ class CMasternodeSync bool fReachedBestHeader{false}; public: - CMasternodeSync() { Reset(); } + CMasternodeSync() { Reset(false); } static void SendGovernanceSyncRequest(CNode* pnode, CConnman& connman); @@ -55,7 +55,7 @@ class CMasternodeSync std::string GetAssetName() const; std::string GetSyncStatus() const; - void Reset(); + void Reset(bool fNotifyReset = true); void SwitchToNextAsset(CConnman& connman); void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv) const; From 814fa0881b5a5a7e5c1d8c927eeea26a27fab8f2 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 21:57:01 +0200 Subject: [PATCH 05/11] masternode: Don't instantly reset the sync process Give it MASTERNODE_SYNC_RESET_SECONDS (600) seconds time after the last UpdateBlockTip call. --- src/masternode/masternode-sync.cpp | 28 +++++++++++++++++----------- src/masternode/masternode-sync.h | 7 +++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index 898f1da7f2d7..5769bb28d08d 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -14,15 +14,19 @@ class CMasternodeSync; CMasternodeSync masternodeSync; -void CMasternodeSync::Reset(bool fNotifyReset) +void CMasternodeSync::Reset(bool fForce, bool fNotifyReset) { - nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN; - nTriedPeerCount = 0; - nTimeAssetSyncStarted = GetTime(); - nTimeLastBumped = GetTime(); - fReachedBestHeader = false; - if (fNotifyReset) { - uiInterface.NotifyAdditionalDataSyncProgressChanged(-1); + // Avoid resetting the sync process if we just "recently" received a new block + if (fForce || !nTimeLastUpdateBlockTip || ((GetTime() - nTimeLastUpdateBlockTip) > MASTERNODE_SYNC_RESET_SECONDS)) { + nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN; + nTriedPeerCount = 0; + nTimeAssetSyncStarted = GetTime(); + nTimeLastBumped = GetTime(); + nTimeLastUpdateBlockTip = 0; + fReachedBestHeader = false; + if (fNotifyReset) { + uiInterface.NotifyAdditionalDataSyncProgressChanged(-1); + } } } @@ -107,7 +111,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman) static int64_t nTimeLastProcess = GetTime(); if(GetTime() - nTimeLastProcess > 60*60 && !fMasternodeMode) { LogPrintf("CMasternodeSync::ProcessTick -- WARNING: no actions for too long, restarting sync...\n"); - Reset(); + Reset(true); nTimeLastProcess = GetTime(); return; } @@ -319,6 +323,8 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitia { LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload); + nTimeLastUpdateBlockTip = GetAdjustedTime(); + if (IsSynced() || !pindexBestHeader) return; @@ -330,7 +336,7 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitia if (fInitialDownload) { // switched too early if (IsBlockchainSynced()) { - Reset(); + Reset(true); } // no need to check any further while still in IBD mode @@ -344,7 +350,7 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitia // Switching from true to false means that we previously stuck syncing headers for some reason, // probably initial timeout was not enough, // because there is no way we can update tip not having best header - Reset(); + Reset(true); } fReachedBestHeader = fReachedBestHeaderNew; diff --git a/src/masternode/masternode-sync.h b/src/masternode/masternode-sync.h index 904c22968ef8..5246513cb241 100644 --- a/src/masternode/masternode-sync.h +++ b/src/masternode/masternode-sync.h @@ -17,6 +17,7 @@ static const int MASTERNODE_SYNC_FINISHED = 999; static const int MASTERNODE_SYNC_TICK_SECONDS = 6; static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine +static const int MASTERNODE_SYNC_RESET_SECONDS = 600; // Reset fReachedBestHeader in CMasternodeSync::Reset if UpdateBlockTip hasn't been called for this seconds extern CMasternodeSync masternodeSync; @@ -39,9 +40,11 @@ class CMasternodeSync /// Set to true if best header is reached in CMasternodeSync::UpdatedBlockTip bool fReachedBestHeader{false}; + /// Last time UpdateBlockTip has been called + int64_t nTimeLastUpdateBlockTip{0}; public: - CMasternodeSync() { Reset(false); } + CMasternodeSync() { Reset(true, false); } static void SendGovernanceSyncRequest(CNode* pnode, CConnman& connman); @@ -55,7 +58,7 @@ class CMasternodeSync std::string GetAssetName() const; std::string GetSyncStatus() const; - void Reset(bool fNotifyReset = true); + void Reset(bool fForce = false, bool fNotifyReset = true); void SwitchToNextAsset(CConnman& connman); void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv) const; From 003de347a81d574f9bcafdec6bc38fa0db4cc7e1 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Mon, 7 Sep 2020 13:30:30 +0200 Subject: [PATCH 06/11] rpc: Don't switch to next asset in "mnsync reset" --- src/rpc/misc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0b726810a2c0..6f630bf0fcce 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -109,7 +109,6 @@ UniValue mnsync(const JSONRPCRequest& request) if(strMode == "reset") { masternodeSync.Reset(); - masternodeSync.SwitchToNextAsset(*g_connman); return "success"; } return "failure"; From 3363e8ad21207dd4872210fa5aa17ea8562a73c7 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Wed, 9 Sep 2020 21:10:13 +0200 Subject: [PATCH 07/11] rpc: Force the reset in "mnsync reset" --- src/rpc/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 6f630bf0fcce..d14c48994bc9 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -108,7 +108,7 @@ UniValue mnsync(const JSONRPCRequest& request) if(strMode == "reset") { - masternodeSync.Reset(); + masternodeSync.Reset(true); return "success"; } return "failure"; From 9f5d2804fdb202a4e4871a4e1e3aea2f33919d41 Mon Sep 17 00:00:00 2001 From: xdustinface Date: Wed, 9 Sep 2020 23:05:51 +0200 Subject: [PATCH 08/11] net: Make sure the sync gets a reset if required after network changes This will reset the sync process if its outdated in the following cases: - If the connections dropped to zero - If the connections went from zero to one - If the network has been enabled or disabled --- src/net.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 0ae4ad46f9a1..8d6f2b7e2e4d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1391,6 +1391,13 @@ void CConnman::NotifyNumConnectionsChanged() LOCK(cs_vNodes); vNodesSize = vNodes.size(); } + + // If we had zero connections before and new connections now or if we just dropped + // to zero connections reset the sync process if its outdated. + if (vNodesSize && !nPrevNodeCount || !vNodesSize && nPrevNodeCount) { + masternodeSync.Reset(); + } + if(vNodesSize != nPrevNodeCount) { nPrevNodeCount = vNodesSize; if(clientInterface) @@ -2899,6 +2906,10 @@ void CConnman::SetNetworkActive(bool active) fNetworkActive = active; + // Always call the Reset() if the network gets enabled/disabled to make sure the sync process + // gets a reset if its outdated.. + masternodeSync.Reset(); + uiInterface.NotifyNetworkActiveChanged(fNetworkActive); } From 362b6d3d0dd36389b2eba918b55c978db2e9846e Mon Sep 17 00:00:00 2001 From: dustinface <35775977+xdustinface@users.noreply.github.com> Date: Thu, 10 Sep 2020 04:11:39 +0200 Subject: [PATCH 09/11] Apply suggestions from code review Co-authored-by: UdjinM6 --- src/masternode/masternode-sync.cpp | 5 +++-- src/net.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/masternode/masternode-sync.cpp b/src/masternode/masternode-sync.cpp index 5769bb28d08d..9a6d03af89c4 100644 --- a/src/masternode/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -17,7 +17,7 @@ CMasternodeSync masternodeSync; void CMasternodeSync::Reset(bool fForce, bool fNotifyReset) { // Avoid resetting the sync process if we just "recently" received a new block - if (fForce || !nTimeLastUpdateBlockTip || ((GetTime() - nTimeLastUpdateBlockTip) > MASTERNODE_SYNC_RESET_SECONDS)) { + if (fForce || (GetTime() - nTimeLastUpdateBlockTip > MASTERNODE_SYNC_RESET_SECONDS)) { nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN; nTriedPeerCount = 0; nTimeAssetSyncStarted = GetTime(); @@ -195,7 +195,8 @@ void CMasternodeSync::ProcessTick(CConnman& connman) LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nCurrentAsset %d -- syncing mempool from peer=%d\n", nTick, nCurrentAsset, pnode->GetId()); } - if (fReachedBestHeader && GetTime() - nTimeLastBumped > (vNodesCopy.size() > 3 ? MASTERNODE_SYNC_TICK_SECONDS : MASTERNODE_SYNC_TIMEOUT_SECONDS)) { + int64_t nTimeSyncTimeout = vNodesCopy.size() > 3 ? MASTERNODE_SYNC_TICK_SECONDS : MASTERNODE_SYNC_TIMEOUT_SECONDS; + if (fReachedBestHeader && (GetTime() - nTimeLastBumped > nTimeSyncTimeout)) { // At this point we know that: // a) there are peers (because we are looping on at least one of them); // b) we waited for at least MASTERNODE_SYNC_TICK_SECONDS/MASTERNODE_SYNC_TIMEOUT_SECONDS diff --git a/src/net.cpp b/src/net.cpp index 8d6f2b7e2e4d..735e7782a05e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1394,7 +1394,7 @@ void CConnman::NotifyNumConnectionsChanged() // If we had zero connections before and new connections now or if we just dropped // to zero connections reset the sync process if its outdated. - if (vNodesSize && !nPrevNodeCount || !vNodesSize && nPrevNodeCount) { + if ((vNodesSize > 0 && nPrevNodeCount == 0) || (vNodesSize == 0 && nPrevNodeCount > 0)) { masternodeSync.Reset(); } From f3baf155fdf1fa3b1b0bce079ba3b389dac2e19d Mon Sep 17 00:00:00 2001 From: xdustinface Date: Thu, 10 Sep 2020 05:12:21 +0200 Subject: [PATCH 10/11] net: Only open masternode connections if the blockchain is synced In general it doesn't make sense to connect to masternodes before due to MNAUTH requires blockchain sync. This could lead to failing quorum connections/failing masternode probing.. if a just restarted node/a out of sync node would hit a dkg block.. Then they would not try to open those llmq/probing connections for the next 60s (nLLMQConnectionRetryTimeout). Thats basically what happens in tests right now and they fail without this commit. --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 735e7782a05e..b7ca460c8435 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2516,7 +2516,7 @@ void CConnman::ThreadOpenMasternodeConnections() didConnect = false; - if (!fNetworkActive) + if (!fNetworkActive || !masternodeSync.IsBlockchainSynced()) continue; std::set connectedNodes; From de4318ceb15446ce5cc2ec7862dff1802fcabcce Mon Sep 17 00:00:00 2001 From: xdustinface Date: Thu, 10 Sep 2020 13:39:39 +0200 Subject: [PATCH 11/11] test: Make sure nodes are synced when they get restored after isolation Their sync might be out of date otherwise due to bigger mocktime bumps --- test/functional/feature_llmq_simplepose.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index 800c8c31c822..8e3f17ae36ab 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -113,6 +113,7 @@ def repair_masternodes(self, restart): mn.node.setnetworkactive(False) wait_until(lambda: mn.node.getconnectioncount() == 0) mn.node.setnetworkactive(True) + force_finish_mnsync(mn.node) connect_nodes(mn.node, 0) def reset_probe_timeouts(self):