]> Git Repo - VerusCoin.git/blame - src/timedata.cpp
Merge pull request #5170
[VerusCoin.git] / src / timedata.cpp
CommitLineData
14f888ca
WL
1// Copyright (c) 2014 The Bitcoin 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 "timedata.h"
6
7#include "netbase.h"
8#include "sync.h"
9#include "ui_interface.h"
10#include "util.h"
ad49c256 11#include "utilstrencodings.h"
14f888ca
WL
12
13#include <boost/foreach.hpp>
14
15using namespace std;
16
17static CCriticalSection cs_nTimeOffset;
18static int64_t nTimeOffset = 0;
19
20//
21// "Never go to sea with two chronometers; take one or three."
22// Our three time sources are:
23// - System clock
24// - Median of other nodes clocks
25// - The user (asking the user to fix the system clock if the first two disagree)
26//
27//
28int64_t GetTimeOffset()
29{
30 LOCK(cs_nTimeOffset);
31 return nTimeOffset;
32}
33
34int64_t GetAdjustedTime()
35{
36 return GetTime() + GetTimeOffset();
37}
38
ad49c256
WL
39static int64_t abs64(int64_t n)
40{
41 return (n >= 0 ? n : -n);
42}
43
14f888ca
WL
44void AddTimeData(const CNetAddr& ip, int64_t nTime)
45{
46 int64_t nOffsetSample = nTime - GetTime();
47
48 LOCK(cs_nTimeOffset);
49 // Ignore duplicates
50 static set<CNetAddr> setKnown;
51 if (!setKnown.insert(ip).second)
52 return;
53
54 // Add data
55 static CMedianFilter<int64_t> vTimeOffsets(200,0);
56 vTimeOffsets.input(nOffsetSample);
57 LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
93659379
WL
58
59 // There is a known issue here (see issue #4521):
60 //
61 // - The structure vTimeOffsets contains up to 200 elements, after which
62 // any new element added to it will not increase its size, replacing the
63 // oldest element.
64 //
65 // - The condition to update nTimeOffset includes checking whether the
66 // number of elements in vTimeOffsets is odd, which will never happen after
67 // there are 200 elements.
68 //
69 // But in this case the 'bug' is protective against some attacks, and may
70 // actually explain why we've never seen attacks which manipulate the
71 // clock offset.
72 //
73 // So we should hold off on fixing this and clean it up as part of
74 // a timing cleanup that strengthens it in a number of other ways.
75 //
14f888ca
WL
76 if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
77 {
78 int64_t nMedian = vTimeOffsets.median();
79 std::vector<int64_t> vSorted = vTimeOffsets.sorted();
80 // Only let other nodes change our time by so much
81 if (abs64(nMedian) < 70 * 60)
82 {
83 nTimeOffset = nMedian;
84 }
85 else
86 {
87 nTimeOffset = 0;
88
89 static bool fDone;
90 if (!fDone)
91 {
92 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
93 bool fMatch = false;
94 BOOST_FOREACH(int64_t nOffset, vSorted)
95 if (nOffset != 0 && abs64(nOffset) < 5 * 60)
96 fMatch = true;
97
98 if (!fMatch)
99 {
100 fDone = true;
2b410c2f 101 string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.");
14f888ca
WL
102 strMiscWarning = strMessage;
103 LogPrintf("*** %s\n", strMessage);
104 uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
105 }
106 }
107 }
108 if (fDebug) {
109 BOOST_FOREACH(int64_t n, vSorted)
110 LogPrintf("%+d ", n);
111 LogPrintf("| ");
112 }
113 LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
114 }
115}
This page took 0.069288 seconds and 4 git commands to generate.