LCOV - code coverage report
Current view: top level - src/masternode - sync.cpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 18 92 19.6 %
Date: 2026-06-25 07:23:51 Functions: 5 14 35.7 %

          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         368 : CMasternodeSync::CMasternodeSync(std::unique_ptr<NodeSyncNotifier>&& sync_notifier) :
      18             :     nTimeAssetSyncStarted{GetTime()},
      19             :     nTimeLastBumped{GetTime()},
      20             :     m_sync_notifier{std::move(sync_notifier)}
      21         184 : {
      22             :     assert(m_sync_notifier != nullptr);
      23         184 : }
      24             : 
      25         368 : CMasternodeSync::~CMasternodeSync() = default;
      26             : 
      27           2 : void CMasternodeSync::Reset(bool fForce, bool fNotifyReset)
      28             : {
      29             :     // Avoid resetting the sync process if we just "recently" received a new block
      30           2 :     if (!fForce) {
      31           2 :         if (GetTime() - nTimeLastUpdateBlockTip < MASTERNODE_SYNC_RESET_SECONDS) {
      32           0 :             return;
      33             :         }
      34           2 :     }
      35           2 :     nCurrentAsset = MASTERNODE_SYNC_BLOCKCHAIN;
      36           2 :     nTriedPeerCount = 0;
      37           2 :     nTimeAssetSyncStarted = GetTime();
      38           2 :     nTimeLastBumped = GetTime();
      39           2 :     nTimeLastUpdateBlockTip = 0;
      40           2 :     fReachedBestHeader = false;
      41           2 :     if (fNotifyReset) {
      42           2 :         m_sync_notifier->SyncReset();
      43           2 :     }
      44           2 : }
      45             : 
      46           0 : void CMasternodeSync::BumpAssetLastTime(const std::string& strFuncName)
      47             : {
      48           0 :     if (IsSynced()) return;
      49           0 :     nTimeLastBumped = GetTime();
      50           0 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::BumpAssetLastTime -- %s\n", strFuncName);
      51           0 : }
      52             : 
      53           0 : std::string CMasternodeSync::GetAssetName() const
      54             : {
      55           0 :     switch(nCurrentAsset)
      56             :     {
      57           0 :         case(MASTERNODE_SYNC_BLOCKCHAIN):   return "MASTERNODE_SYNC_BLOCKCHAIN";
      58           0 :         case(MASTERNODE_SYNC_GOVERNANCE):   return "MASTERNODE_SYNC_GOVERNANCE";
      59           0 :         case MASTERNODE_SYNC_FINISHED:      return "MASTERNODE_SYNC_FINISHED";
      60           0 :         default:                            return "UNKNOWN";
      61             :     }
      62           0 : }
      63             : 
      64           0 : void CMasternodeSync::SwitchToNextAsset()
      65             : {
      66           0 :     switch(nCurrentAsset)
      67             :     {
      68             :         case(MASTERNODE_SYNC_BLOCKCHAIN):
      69           0 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
      70           0 :             nCurrentAsset = MASTERNODE_SYNC_GOVERNANCE;
      71           0 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
      72           0 :             break;
      73             :         case(MASTERNODE_SYNC_GOVERNANCE):
      74           0 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
      75           0 :             nCurrentAsset = MASTERNODE_SYNC_FINISHED;
      76           0 :             m_sync_notifier->SyncFinished();
      77           0 :             LogPrintf("CMasternodeSync::SwitchToNextAsset -- Sync has finished\n");
      78             : 
      79           0 :             break;
      80             :     }
      81           0 :     nTriedPeerCount = 0;
      82           0 :     nTimeAssetSyncStarted = GetTime();
      83           0 :     BumpAssetLastTime("CMasternodeSync::SwitchToNextAsset");
      84           0 : }
      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           0 : void CMasternodeSync::AcceptedBlockHeader(const CBlockIndex *pindexNew)
      97             : {
      98           0 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::AcceptedBlockHeader -- pindexNew->nHeight: %d\n", pindexNew->nHeight);
      99             : 
     100           0 :     if (!IsBlockchainSynced()) {
     101             :         // Postpone timeout each time new block header arrives while we are still syncing blockchain
     102           0 :         BumpAssetLastTime("CMasternodeSync::AcceptedBlockHeader");
     103           0 :     }
     104           0 : }
     105             : 
     106           0 : void CMasternodeSync::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
     107             : {
     108           0 :     if (pindexNew == nullptr) {
     109           0 :         return;
     110             :     }
     111           0 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::NotifyHeaderTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
     112           0 :     if (IsSynced())
     113           0 :         return;
     114             : 
     115           0 :     if (!IsBlockchainSynced()) {
     116             :         // Postpone timeout each time new block arrives while we are still syncing blockchain
     117           0 :         BumpAssetLastTime("CMasternodeSync::NotifyHeaderTip");
     118           0 :     }
     119           0 : }
     120             : 
     121           0 : void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexTip, const CBlockIndex *pindexNew, bool fInitialDownload)
     122             : {
     123           0 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
     124           0 :     nTimeLastUpdateBlockTip = GetTime<std::chrono::seconds>().count();
     125             : 
     126           0 :     if (IsSynced())
     127           0 :         return;
     128             : 
     129           0 :     if (!IsBlockchainSynced()) {
     130             :         // Postpone timeout each time new block arrives while we are still syncing blockchain
     131           0 :         BumpAssetLastTime("CMasternodeSync::UpdatedBlockTip");
     132           0 :     }
     133             : 
     134           0 :     if (fInitialDownload) {
     135             :         // switched too early
     136           0 :         if (IsBlockchainSynced()) {
     137           0 :             Reset(true);
     138           0 :         }
     139             : 
     140             :         // no need to check any further while still in IBD mode
     141           0 :         return;
     142             :     }
     143             : 
     144             :     // Note: since we sync headers first, it should be ok to use this
     145           0 :     if (pindexTip == nullptr) return;
     146           0 :     bool fReachedBestHeaderNew = pindexNew->GetBlockHash() == pindexTip->GetBlockHash();
     147             : 
     148           0 :     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           0 :         Reset(true);
     153           0 :     }
     154             : 
     155           0 :     fReachedBestHeader = fReachedBestHeaderNew;
     156           0 :     LogPrint(BCLog::MNSYNC, "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d pindexTip->nHeight: %d fInitialDownload=%d fReachedBestHeader=%d\n",
     157             :                 pindexNew->nHeight, pindexTip->nHeight, fInitialDownload, fReachedBestHeader);
     158           0 : }

Generated by: LCOV version 1.16