MCPcopy Create free account
hub / github.com/ElementsProject/elements / AddTimeData

Function AddTimeData

src/timedata.cpp:46–111  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

44static bool g_warning_emitted;
45
46void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
47{
48 LOCK(g_timeoffset_mutex);
49 // Ignore duplicates
50 if (g_sources.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
51 return;
52 if (!g_sources.insert(ip).second)
53 return;
54
55 // Add data
56 g_time_offsets.input(nOffsetSample);
57 LogPrint(BCLog::NET, "added time data, samples %d, offset %+d (%+d minutes)\n", g_time_offsets.size(), nOffsetSample, nOffsetSample / 60);
58
59 // There is a known issue here (see issue #4521):
60 //
61 // - The structure g_time_offsets 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 g_time_offsets 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 //
76 if (g_time_offsets.size() >= 5 && g_time_offsets.size() % 2 == 1) {
77 int64_t nMedian = g_time_offsets.median();
78 std::vector<int64_t> vSorted = g_time_offsets.sorted();
79 // Only let other nodes change our time by so much
80 int64_t max_adjustment = std::max<int64_t>(0, gArgs.GetIntArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT));
81 if (nMedian >= -max_adjustment && nMedian <= max_adjustment) {
82 nTimeOffset = nMedian;
83 } else {
84 nTimeOffset = 0;
85
86 if (!g_warning_emitted) {
87 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
88 bool fMatch = false;
89 for (const int64_t nOffset : vSorted) {
90 if (nOffset != 0 && nOffset > -5 * 60 && nOffset < 5 * 60) fMatch = true;
91 }
92
93 if (!fMatch) {
94 g_warning_emitted = true;
95 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);
96 SetMiscWarning(strMessage);
97 uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
98 }
99 }
100 }
101
102 if (LogAcceptCategory(BCLog::NET)) {
103 std::string log_message{"time data samples: "};

Callers 2

ProcessMessageMethod · 0.85
MultiAddTimeDataFunction · 0.85

Calls 10

_Function · 0.85
SetMiscWarningFunction · 0.85
LogAcceptCategoryFunction · 0.85
sortedMethod · 0.80
GetIntArgMethod · 0.80
ThreadSafeMessageBoxMethod · 0.80
sizeMethod · 0.45
insertMethod · 0.45
inputMethod · 0.45
medianMethod · 0.45

Tested by 1

MultiAddTimeDataFunction · 0.68