Coverage Report

Created: 2026-04-29 19:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/node/timeoffsets.cpp
Line
Count
Source
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
20
using namespace std::chrono_literals;
21
22
void TimeOffsets::Add(std::chrono::seconds offset)
23
711
{
24
711
    LOCK(m_mutex);
25
26
711
    if (m_offsets.size() >= MAX_SIZE) {
27
75
        m_offsets.pop_front();
28
75
    }
29
711
    m_offsets.push_back(offset);
30
711
    LogDebug(BCLog::NET, "Added time offset %+ds, total samples %d\n",
31
711
             Ticks<std::chrono::seconds>(offset), m_offsets.size());
32
711
}
33
34
std::chrono::seconds TimeOffsets::Median() const
35
1.43k
{
36
1.43k
    LOCK(m_mutex);
37
38
    // Only calculate the median if we have 5 or more offsets
39
1.43k
    if (m_offsets.size() < 5) return 0s;
40
41
126
    auto sorted_copy = m_offsets;
42
126
    std::sort(sorted_copy.begin(), sorted_copy.end());
43
126
    return sorted_copy[sorted_copy.size() / 2];  // approximate median is good enough, keep it simple
44
1.43k
}
45
46
bool TimeOffsets::WarnIfOutOfSync() const
47
526
{
48
    // when median == std::numeric_limits<int64_t>::min(), calling std::chrono::abs is UB
49
526
    auto median{std::max(Median(), std::chrono::seconds(std::numeric_limits<int64_t>::min() + 1))};
50
526
    if (std::chrono::abs(median) <= WARN_THRESHOLD) {
51
515
        m_warnings.Unset(node::Warning::CLOCK_OUT_OF_SYNC);
52
515
        return false;
53
515
    }
54
55
11
    bilingual_str msg{strprintf(_(
56
11
        "Your computer's date and time appear to be more than %d minutes out of sync with the network, "
57
11
        "this may lead to consensus failure. After you've confirmed your computer's clock, this message "
58
11
        "should no longer appear when you restart your node. Without a restart, it should stop showing "
59
11
        "automatically after you've connected to a sufficient number of new outbound peers, which may "
60
11
        "take some time. You can inspect the `timeoffset` field of the `getpeerinfo` and `getnetworkinfo` "
61
11
        "RPC methods to get more info."
62
11
    ), Ticks<std::chrono::minutes>(WARN_THRESHOLD))};
63
11
    LogWarning("%s\n", msg.original);
64
11
    m_warnings.Set(node::Warning::CLOCK_OUT_OF_SYNC, msg);
65
11
    return true;
66
526
}