LCOV - code coverage report
Current view: top level - src - timedata.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 49 49 100.0 %
Date: 2021-06-29 14:35:33 Functions: 3 3 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 26 36 72.2 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2014-2020 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : #if defined(HAVE_CONFIG_H)
#       6                 :            : #include <config/bitcoin-config.h>
#       7                 :            : #endif
#       8                 :            : 
#       9                 :            : #include <timedata.h>
#      10                 :            : 
#      11                 :            : #include <netaddress.h>
#      12                 :            : #include <node/ui_interface.h>
#      13                 :            : #include <sync.h>
#      14                 :            : #include <util/system.h>
#      15                 :            : #include <util/translation.h>
#      16                 :            : #include <warnings.h>
#      17                 :            : 
#      18                 :            : static Mutex g_timeoffset_mutex;
#      19                 :            : static int64_t nTimeOffset GUARDED_BY(g_timeoffset_mutex) = 0;
#      20                 :            : 
#      21                 :            : /**
#      22                 :            :  * "Never go to sea with two chronometers; take one or three."
#      23                 :            :  * Our three time sources are:
#      24                 :            :  *  - System clock
#      25                 :            :  *  - Median of other nodes clocks
#      26                 :            :  *  - The user (asking the user to fix the system clock if the first two disagree)
#      27                 :            :  */
#      28                 :            : int64_t GetTimeOffset()
#      29                 :    2825174 : {
#      30                 :    2825174 :     LOCK(g_timeoffset_mutex);
#      31                 :    2825174 :     return nTimeOffset;
#      32                 :    2825174 : }
#      33                 :            : 
#      34                 :            : int64_t GetAdjustedTime()
#      35                 :    2825101 : {
#      36                 :    2825101 :     return GetTime() + GetTimeOffset();
#      37                 :    2825101 : }
#      38                 :            : 
#      39                 :       2134 : #define BITCOIN_TIMEDATA_MAX_SAMPLES 200
#      40                 :            : 
#      41                 :            : void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
#      42                 :       1352 : {
#      43                 :       1352 :     LOCK(g_timeoffset_mutex);
#      44                 :            :     // Ignore duplicates
#      45                 :       1352 :     static std::set<CNetAddr> setKnown;
#      46         [ -  + ]:       1352 :     if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
#      47                 :       1352 :         return;
#      48         [ +  + ]:       1352 :     if (!setKnown.insert(ip).second)
#      49                 :        570 :         return;
#      50                 :            : 
#      51                 :            :     // Add data
#      52                 :        782 :     static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
#      53                 :        782 :     vTimeOffsets.input(nOffsetSample);
#      54         [ +  - ]:        782 :     LogPrint(BCLog::NET, "added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample / 60);
#      55                 :            : 
#      56                 :            :     // There is a known issue here (see issue #4521):
#      57                 :            :     //
#      58                 :            :     // - The structure vTimeOffsets contains up to 200 elements, after which
#      59                 :            :     // any new element added to it will not increase its size, replacing the
#      60                 :            :     // oldest element.
#      61                 :            :     //
#      62                 :            :     // - The condition to update nTimeOffset includes checking whether the
#      63                 :            :     // number of elements in vTimeOffsets is odd, which will never happen after
#      64                 :            :     // there are 200 elements.
#      65                 :            :     //
#      66                 :            :     // But in this case the 'bug' is protective against some attacks, and may
#      67                 :            :     // actually explain why we've never seen attacks which manipulate the
#      68                 :            :     // clock offset.
#      69                 :            :     //
#      70                 :            :     // So we should hold off on fixing this and clean it up as part of
#      71                 :            :     // a timing cleanup that strengthens it in a number of other ways.
#      72                 :            :     //
#      73 [ +  + ][ +  + ]:        782 :     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) {
#      74                 :        196 :         int64_t nMedian = vTimeOffsets.median();
#      75                 :        196 :         std::vector<int64_t> vSorted = vTimeOffsets.sorted();
#      76                 :            :         // Only let other nodes change our time by so much
#      77                 :        196 :         int64_t max_adjustment = std::max<int64_t>(0, gArgs.GetArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT));
#      78 [ +  - ][ +  + ]:        196 :         if (nMedian >= -max_adjustment && nMedian <= max_adjustment) {
#      79                 :        192 :             nTimeOffset = nMedian;
#      80                 :        192 :         } else {
#      81                 :          4 :             nTimeOffset = 0;
#      82                 :            : 
#      83                 :          4 :             static bool fDone;
#      84         [ +  + ]:          4 :             if (!fDone) {
#      85                 :            :                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
#      86                 :          2 :                 bool fMatch = false;
#      87         [ +  + ]:         10 :                 for (const int64_t nOffset : vSorted) {
#      88 [ +  + ][ +  - ]:         10 :                     if (nOffset != 0 && nOffset > -5 * 60 && nOffset < 5 * 60) fMatch = true;
#                 [ -  + ]
#      89                 :         10 :                 }
#      90                 :            : 
#      91         [ +  - ]:          2 :                 if (!fMatch) {
#      92                 :          2 :                     fDone = true;
#      93                 :          2 :                     bilingual_str strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly."), PACKAGE_NAME);
#      94                 :          2 :                     SetMiscWarning(strMessage);
#      95                 :          2 :                     uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
#      96                 :          2 :                 }
#      97                 :          2 :             }
#      98                 :          4 :         }
#      99                 :            : 
#     100         [ +  - ]:        196 :         if (LogAcceptCategory(BCLog::NET)) {
#     101         [ +  + ]:      19992 :             for (const int64_t n : vSorted) {
#     102         [ +  - ]:      19992 :                 LogPrint(BCLog::NET, "%+d  ", n); /* Continued */
#     103                 :      19992 :             }
#     104         [ +  - ]:        196 :             LogPrint(BCLog::NET, "|  "); /* Continued */
#     105         [ +  - ]:        196 :             LogPrint(BCLog::NET, "nTimeOffset = %+d  (%+d minutes)\n", nTimeOffset, nTimeOffset / 60);
#     106                 :        196 :         }
#     107                 :        196 :     }
#     108                 :        782 : }

Generated by: LCOV version 1.14