LCOV - code coverage report
Current view: top level - src/masternode - sync.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 79 92 85.9 %
Date: 2026-06-25 07:23:43 Functions: 11 14 78.6 %

          Line data    Source code
       1             : // Copyright (c) 2014-2025 The Dash Core developers
       2             : // Distributed under the MIT/X11 software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <masternode/sync.h>
       6             : 
       7             : #include <chain.h>
       8             : #include <logging.h>
       9             : #include <util/time.h>
      10             : #include <util/translation.h>
      11             : 
      12             : #include <cassert>
      13             : 
      14           0 : void NullNodeSyncNotifier::SyncReset() { assert(false); }
      15           0 : void NullNodeSyncNotifier::SyncFinished() { assert(false); }
      16             : 
      17        6138 : CMasternodeSync::CMasternodeSync(std::unique_ptr<NodeSyncNotifier>&& sync_notifier) :
      18             :     nTimeAssetSyncStarted{GetTime()},
      19             :     nTimeLastBumped{GetTime()},
      20             :     m_sync_notifier{std::move(sync_notifier)}
      21        3069 : {
      22             :     assert(m_sync_notifier != nullptr);
      23        3069 : }
      24             : 
      25        6138 : CMasternodeSync::~CMasternodeSync() = default;
      26             : 
      27       10345 : void CMasternodeSync::Reset(bool fForce, bool fNotifyReset)
      28             : {
      29             :     // Avoid resetting the sync process if we just "recently" received a new block
      30       10345 :     if (!fForce) {
      31        4013 :         if (GetTime() - nTimeLastUpdateBlockTip < MASTERNODE_SYNC_RESET_SECONDS) {
      32        3879 :             return;
      33             :         }
      34         134 :     }
      35        6466 :     nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN;
      36        6466 :     nTriedPeerCount = 0;
      37        6466 :     nTimeAssetSyncStarted = GetTime();
      38        6466 :     nTimeLastBumped = GetTime();
      39        6466 :     nTimeLastUpdateBlockTip = 0;
      40        6466 :     fReachedBestHeader = false;
      41        6466 :     if (fNotifyReset) {
      42        6466 :         m_sync_notifier->SyncReset();
      43        6466 :     }
      44       10345 : }
      45             : 
      46      374228 : void CMasternodeSync::BumpAssetLastTime(const std::string& strFuncName)
      47             : {
      48      374228 :     if (IsSynced()) return;
      49      371866 :     nTimeLastBumped = GetTime();
      50      371866 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::BumpAssetLastTime -- %s\n", strFuncName);
      51      374228 : }
      52             : 
      53        8578 : std::string CMasternodeSync::GetAssetName() const
      54             : {
      55        8578 :     switch(nCurrentAsset)
      56             :     {
      57        1863 :         case(MASTERNODE_SYNC_BLOCKCHAIN):   return "MASTERNODE_SYNC_BLOCKCHAIN";
      58        5121 :         case(MASTERNODE_SYNC_GOVERNANCE):   return "MASTERNODE_SYNC_GOVERNANCE";
      59        1594 :         case MASTERNODE_SYNC_FINISHED:      return "MASTERNODE_SYNC_FINISHED";
      60           0 :         default:                            return "UNKNOWN";
      61             :     }
      62        8578 : }
      63             : 
      64        1758 : void CMasternodeSync::SwitchToNextAsset()
      65             : {
      66        1758 :     switch(nCurrentAsset)
      67             :     {
      68             :         case(MASTERNODE_SYNC_BLOCKCHAIN):
      69         901 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
      70         901 :             nCurrentAsset = MASTERNODE_SYNC_GOVERNANCE;
      71         901 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
      72         901 :             break;
      73             :         case(MASTERNODE_SYNC_GOVERNANCE):
      74         857 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
      75         857 :             nCurrentAsset = MASTERNODE_SYNC_FINISHED;
      76         857 :             m_sync_notifier->SyncFinished();
      77         857 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Sync has finished\n");
      78             : 
      79         857 :             break;
      80             :     }
      81        1758 :     nTriedPeerCount = 0;
      82        1758 :     nTimeAssetSyncStarted = GetTime();
      83        1758 :     BumpAssetLastTime("CMasternodeSync::SwitchToNextAsset");
      84        1758 : }
      85             : 
      86           0 : std::string CMasternodeSync::GetSyncStatus() const
      87             : {
      88           0 :     switch (nCurrentAsset) {
      89           0 :         case MASTERNODE_SYNC_BLOCKCHAIN:    return _("Synchronizing blockchain…").translated;
      90           0 :         case MASTERNODE_SYNC_GOVERNANCE:    return _("Synchronizing governance objects…").translated;
      91           0 :         case MASTERNODE_SYNC_FINISHED:      return _("Synchronization finished").translated;
      92           0 :         default:                            return "";
      93             :     }
      94           0 : }
      95             : 
      96      244470 : void CMasternodeSync::AcceptedBlockHeader(const CBlockIndex *pindexNew)
      97             : {
      98      244470 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::AcceptedBlockHeader -- pindexNew->nHeight: %d\n", pindexNew->nHeight);
      99             : 
     100      244470 :     if (!IsBlockchainSynced()) {
     101             :         // Postpone timeout each time new block header arrives while we are still syncing blockchain
     102      145204 :         BumpAssetLastTime("CMasternodeSync::AcceptedBlockHeader");
     103      145204 :     }
     104      244470 : }
     105             : 
     106      192109 : void CMasternodeSync::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
     107             : {
     108      192109 :     if (pindexNew == nullptr) {
     109           0 :         return;
     110             :     }
     111      192109 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::NotifyHeaderTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
     112      192109 :     if (IsSynced())
     113       91137 :         return;
     114             : 
     115      100972 :     if (!IsBlockchainSynced()) {
     116             :         // Postpone timeout each time new block arrives while we are still syncing blockchain
     117      100860 :         BumpAssetLastTime("CMasternodeSync::NotifyHeaderTip");
     118      100860 :     }
     119      192109 : }
     120             : 
     121      224210 : void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexTip, const CBlockIndex *pindexNew, bool fInitialDownload)
     122             : {
     123      224210 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
     124      224210 :     nTimeLastUpdateBlockTip = GetTime<std::chrono::seconds>().count();
     125             : 
     126      224210 :     if (IsSynced())
     127       99243 :         return;
     128             : 
     129      124967 :     if (!IsBlockchainSynced()) {
     130             :         // Postpone timeout each time new block arrives while we are still syncing blockchain
     131      124882 :         BumpAssetLastTime("CMasternodeSync::UpdatedBlockTip");
     132      124882 :     }
     133             : 
     134      124967 :     if (fInitialDownload) {
     135             :         // switched too early
     136       16652 :         if (IsBlockchainSynced()) {
     137           0 :             Reset(true);
     138           0 :         }
     139             : 
     140             :         // no need to check any further while still in IBD mode
     141       16652 :         return;
     142             :     }
     143             : 
     144             :     // Note: since we sync headers first, it should be ok to use this
     145      108315 :     if (pindexTip == nullptr) return;
     146      108315 :     bool fReachedBestHeaderNew = pindexNew->GetBlockHash() == pindexTip->GetBlockHash();
     147             : 
     148      108315 :     if (fReachedBestHeader && !fReachedBestHeaderNew) {
     149             :         // Switching from true to false means that we previously stuck syncing headers for some reason,
     150             :         // probably initial timeout was not enough,
     151             :         // because there is no way we can update tip not having best header
     152        6308 :         Reset(true);
     153        6308 :     }
     154             : 
     155      108315 :     fReachedBestHeader = fReachedBestHeaderNew;
     156      108315 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d pindexTip->nHeight: %d fInitialDownload=%d fReachedBestHeader=%d\n",
     157             :                 pindexNew->nHeight, pindexTip->nHeight, fInitialDownload, fReachedBestHeader);
     158      224210 : }

Generated by: LCOV version 1.16