PIVX Core  5.6.99
P2P Digital Currency
timedata.cpp
Go to the documentation of this file.
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 
30 int64_t GetTimeOffset()
31 {
32  LOCK(cs_nTimeOffset);
33  return nTimeOffset;
34 }
35 
36 int64_t GetAdjustedTime()
37 {
38  return GetTime() + GetTimeOffset();
39 }
40 
41 #define BITCOIN_TIMEDATA_MAX_SAMPLES 200
42 
43 void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample, int nOffsetLimit)
44 {
45  LOCK(cs_nTimeOffset);
46  // Ignore duplicates (Except on regtest where all nodes have the same ip)
47  static std::set<CNetAddr> setKnown;
48  if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
49  return;
50  if (!Params().IsRegTestNet() && !setKnown.insert(ip).second)
51  return;
52 
53  // Add data
55  vTimeOffsets.input(nOffsetSample);
56  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  if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) {
76  int64_t nMedian = vTimeOffsets.median();
77  std::vector<int64_t> vSorted = vTimeOffsets.sorted();
78  // Only let other nodes change our time by so much
79  if (abs64(nMedian) < nOffsetLimit) {
80  nTimeOffset = nMedian;
81  SetMiscWarning("");
82  } else {
83  nTimeOffset = (nMedian > 0 ? 1 : -1) * nOffsetLimit;
84  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  SetMiscWarning(strMessage);
86  LogPrintf("*** %s\n", strMessage);
88  }
89  if (!gArgs.GetBoolArg("-shrinkdebugfile", g_logger->DefaultShrinkDebugFile())) {
90  for (int64_t n : vSorted)
91  LogPrintf("%+d ", n); /* Continued */
92  LogPrintf("| "); /* Continued */
93  }
94  LogPrintf("nTimeOffset = %+d\n", nTimeOffset);
95  }
96 }
97 
98 // Time Protocol V2
99 // Timestamp for time protocol V2: slot duration 15 seconds
100 int64_t GetTimeSlot(const int64_t nTime)
101 {
102  const int slotLen = Params().GetConsensus().nTimeSlotLength;
103  return (nTime / slotLen) * slotLen;
104 }
105 
107 {
108  return GetTimeSlot(GetAdjustedTime());
109 }
CService ip(uint32_t i)
Definition: DoS_tests.cpp:39
const CChainParams & Params()
Return the currently selected parameters.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:465
bool DefaultShrinkDebugFile() const
Definition: logging.cpp:87
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
Definition: guiinterface.h:84
Median filter over a stream of values.
Definition: timedata.h:22
std::vector< T > sorted() const
Definition: timedata.h:66
int size() const
Definition: timedata.h:61
T median() const
Definition: timedata.h:48
void input(T value)
Definition: timedata.h:36
Network address.
Definition: netaddress.h:120
CClientUIInterface uiInterface
Definition: init.cpp:109
@ LOCK
Definition: lockunlock.h:16
BCLog::Logger *const g_logger
NOTE: the logger instances is leaked on exit.
Definition: logging.cpp:26
#define PACKAGE_NAME
Definition: pivx-config.h:366
int nTimeSlotLength
Definition: params.h:194
ArgsManager gArgs
Definition: system.cpp:89
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
Definition: system.h:65
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
int64_t GetCurrentTimeSlot()
Definition: timedata.cpp:106
int64_t GetTimeOffset()
"Never go to sea with two chronometers; take one or three." Our three time sources are:
Definition: timedata.cpp:30
#define BITCOIN_TIMEDATA_MAX_SAMPLES
Definition: timedata.cpp:41
int64_t GetTimeSlot(const int64_t nTime)
Definition: timedata.cpp:100
void AddTimeData(const CNetAddr &ip, int64_t nOffsetSample, int nOffsetLimit)
Definition: timedata.cpp:43
int64_t abs64(int64_t n)
Functions to keep track of adjusted P2P time.
Definition: timedata.h:73
#define strprintf
Definition: tinyformat.h:1056
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: utiltime.cpp:27
void SetMiscWarning(const std::string &strWarning)
Definition: warnings.cpp:17