LCOV - code coverage report
Current view: top level - src - timedata.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 29 35 82.9 %
Date: 2025-02-23 09:33:43 Functions: 3 5 60.0 %

          Line data    Source code
       1             : // Copyright (c) 2014-2017 The Bitcoin developers
       2             : // Copyright (c) 2017-2021 The PIVX Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #if defined(HAVE_CONFIG_H)
       7             : #include "config/pivx-config.h"
       8             : #endif
       9             : 
      10             : #include "timedata.h"
      11             : 
      12             : #include "chainparams.h"
      13             : #include "guiinterface.h"
      14             : #include "netaddress.h"
      15             : #include "sync.h"
      16             : #include "util/system.h"
      17             : #include "warnings.h"
      18             : 
      19             : 
      20             : static RecursiveMutex cs_nTimeOffset;
      21             : static int64_t nTimeOffset = 0;
      22             : 
      23             : /**
      24             :  * "Never go to sea with two chronometers; take one or three."
      25             :  * Our three time sources are:
      26             :  *  - System clock
      27             :  *  - Median of other nodes clocks
      28             :  *  - The user (asking the user to fix the system clock if the first two disagree)
      29             :  */
      30     5996678 : int64_t GetTimeOffset()
      31             : {
      32     5996678 :     LOCK(cs_nTimeOffset);
      33     5996678 :     return nTimeOffset;
      34             : }
      35             : 
      36     5995455 : int64_t GetAdjustedTime()
      37             : {
      38     5995455 :     return GetTime() + GetTimeOffset();
      39             : }
      40             : 
      41             : #define BITCOIN_TIMEDATA_MAX_SAMPLES 200
      42             : 
      43        1360 : void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample, int nOffsetLimit)
      44             : {
      45        2720 :     LOCK(cs_nTimeOffset);
      46             :     // Ignore duplicates (Except on regtest where all nodes have the same ip)
      47        1360 :     static std::set<CNetAddr> setKnown;
      48        1360 :     if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
      49           0 :         return;
      50        1360 :     if (!Params().IsRegTestNet() && !setKnown.insert(ip).second)
      51             :         return;
      52             : 
      53             :     // Add data
      54        1360 :     static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
      55        1360 :     vTimeOffsets.input(nOffsetSample);
      56        1360 :     LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample / 60);
      57             : 
      58             :     // There is a known issue here (see issue #4521):
      59             :     //
      60             :     // - The structure vTimeOffsets contains up to 200 elements, after which
      61             :     // any new element added to it will not increase its size, replacing the
      62             :     // oldest element.
      63             :     //
      64             :     // - The condition to update nTimeOffset includes checking whether the
      65             :     // number of elements in vTimeOffsets is odd, which will never happen after
      66             :     // there are 200 elements.
      67             :     //
      68             :     // But in this case the 'bug' is protective against some attacks, and may
      69             :     // actually explain why we've never seen attacks which manipulate the
      70             :     // clock offset.
      71             :     //
      72             :     // So we should hold off on fixing this and clean it up as part of
      73             :     // a timing cleanup that strengthens it in a number of other ways.
      74             :     //
      75        1360 :     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) {
      76         460 :         int64_t nMedian = vTimeOffsets.median();
      77         920 :         std::vector<int64_t> vSorted = vTimeOffsets.sorted();
      78             :         // Only let other nodes change our time by so much
      79         460 :         if (abs64(nMedian) < nOffsetLimit) {
      80         458 :             nTimeOffset = nMedian;
      81         916 :             SetMiscWarning("");
      82             :         } else {
      83           2 :             nTimeOffset = (nMedian > 0 ? 1 : -1) * nOffsetLimit;
      84           4 :             std::string strMessage = strprintf(_("Warning: Please check that your computer's date and time are correct! If your clock is wrong %s will not work properly."), PACKAGE_NAME);
      85           2 :             SetMiscWarning(strMessage);
      86           2 :             LogPrintf("*** %s\n", strMessage);
      87           4 :             uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR);
      88             :         }
      89         460 :         if (!gArgs.GetBoolArg("-shrinkdebugfile", g_logger->DefaultShrinkDebugFile())) {
      90        5740 :             for (int64_t n : vSorted)
      91        5288 :                 LogPrintf("%+d  ", n); /* Continued */
      92         452 :             LogPrintf("|  "); /* Continued */
      93             :         }
      94         460 :         LogPrintf("nTimeOffset = %+d\n", nTimeOffset);
      95             :     }
      96             : }
      97             : 
      98             : // Time Protocol V2
      99             : // Timestamp for time protocol V2: slot duration 15 seconds
     100           0 : int64_t GetTimeSlot(const int64_t nTime)
     101             : {
     102           0 :     const int slotLen = Params().GetConsensus().nTimeSlotLength;
     103           0 :     return (nTime / slotLen) * slotLen;
     104             : }
     105             : 
     106           0 : int64_t GetCurrentTimeSlot()
     107             : {
     108           0 :     return GetTimeSlot(GetAdjustedTime());
     109             : }

Generated by: LCOV version 1.14