Bitcoin Core 28.99.0
P2P Digital Currency
timeoffsets.cpp
Go to the documentation of this file.
1// Copyright (c) 2024-present 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#include <logging.h>
6#include <node/timeoffsets.h>
7#include <node/warnings.h>
8#include <sync.h>
9#include <tinyformat.h>
10#include <util/time.h>
11#include <util/translation.h>
12
13#include <algorithm>
14#include <chrono>
15#include <cstdint>
16#include <deque>
17#include <limits>
18#include <optional>
19
20using namespace std::chrono_literals;
21
22void TimeOffsets::Add(std::chrono::seconds offset)
23{
25
26 if (m_offsets.size() >= MAX_SIZE) {
27 m_offsets.pop_front();
28 }
29 m_offsets.push_back(offset);
30 LogDebug(BCLog::NET, "Added time offset %+ds, total samples %d\n",
31 Ticks<std::chrono::seconds>(offset), m_offsets.size());
32}
33
34std::chrono::seconds TimeOffsets::Median() const
35{
37
38 // Only calculate the median if we have 5 or more offsets
39 if (m_offsets.size() < 5) return 0s;
40
41 auto sorted_copy = m_offsets;
42 std::sort(sorted_copy.begin(), sorted_copy.end());
43 return sorted_copy[sorted_copy.size() / 2]; // approximate median is good enough, keep it simple
44}
45
47{
48 // when median == std::numeric_limits<int64_t>::min(), calling std::chrono::abs is UB
49 auto median{std::max(Median(), std::chrono::seconds(std::numeric_limits<int64_t>::min() + 1))};
50 if (std::chrono::abs(median) <= WARN_THRESHOLD) {
52 return false;
53 }
54
56 "Your computer's date and time appear to be more than %d minutes out of sync with the network, "
57 "this may lead to consensus failure. After you've confirmed your computer's clock, this message "
58 "should no longer appear when you restart your node. Without a restart, it should stop showing "
59 "automatically after you've connected to a sufficient number of new outbound peers, which may "
60 "take some time. You can inspect the `timeoffset` field of the `getpeerinfo` and `getnetworkinfo` "
61 "RPC methods to get more info."
62 ), Ticks<std::chrono::minutes>(WARN_THRESHOLD))};
63 LogWarning("%s\n", msg.original);
65 return true;
66}
void Add(std::chrono::seconds offset) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a new time offset sample.
Definition: timeoffsets.cpp:22
static constexpr size_t MAX_SIZE
Maximum number of timeoffsets stored.
Definition: timeoffsets.h:25
node::Warnings & m_warnings
Definition: timeoffsets.h:34
bool WarnIfOutOfSync() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Raise warnings if the median time offset exceeds the warnings threshold.
Definition: timeoffsets.cpp:46
Mutex m_mutex
Definition: timeoffsets.h:29
std::chrono::seconds Median() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Compute and return the median of the collected time offset samples.
Definition: timeoffsets.cpp:34
static constexpr std::chrono::minutes WARN_THRESHOLD
Minimum difference between system and network time for a warning to be raised.
Definition: timeoffsets.h:27
bool Unset(warning_type id) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Unset a warning message.
Definition: warnings.cpp:36
bool Set(warning_type id, bilingual_str message) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Set a warning message.
Definition: warnings.cpp:29
#define LogWarning(...)
Definition: logging.h:262
#define LogDebug(category,...)
Definition: logging.h:280
@ NET
Definition: logging.h:43
Bilingual messages:
Definition: translation.h:21
#define LOCK(cs)
Definition: sync.h:257
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1165
bilingual_str _(ConstevalStringLiteral str)
Translation function.
Definition: translation.h:80