Remove timedata

With the introduction and usage of TimeOffsets, there is no more need
for this file. Remove it.
This commit is contained in:
stickies-v 2024-02-04 05:08:26 +00:00
parent 92e72b5d0d
commit c6be144c4b
No known key found for this signature in database
GPG key ID: 5CB1CE6E5E66A757
11 changed files with 1 additions and 351 deletions

View file

@ -284,7 +284,6 @@ BITCOIN_CORE_H = \
support/lockedpool.h \
sync.h \
threadsafety.h \
timedata.h \
torcontrol.h \
txdb.h \
txmempool.h \
@ -464,7 +463,6 @@ libbitcoin_node_a_SOURCES = \
rpc/txoutproof.cpp \
script/sigcache.cpp \
signet.cpp \
timedata.cpp \
torcontrol.cpp \
txdb.cpp \
txmempool.cpp \

View file

@ -151,7 +151,6 @@ BITCOIN_TESTS =\
test/streams_tests.cpp \
test/sync_tests.cpp \
test/system_tests.cpp \
test/timedata_tests.cpp \
test/timeoffsets_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
@ -382,7 +381,6 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/string.cpp \
test/fuzz/strprintf.cpp \
test/fuzz/system.cpp \
test/fuzz/timedata.cpp \
test/fuzz/timeoffsets.cpp \
test/fuzz/torcontrol.cpp \
test/fuzz/transaction.cpp \

View file

@ -11,7 +11,6 @@
#include <protocol.h>
#include <serialize.h>
#include <sync.h>
#include <timedata.h>
#include <uint256.h>
#include <util/time.h>

View file

@ -67,7 +67,6 @@
#include <scheduler.h>
#include <script/sigcache.h>
#include <sync.h>
#include <timedata.h>
#include <torcontrol.h>
#include <txdb.h>
#include <txmempool.h>
@ -523,7 +522,6 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> automatic connections to peers (default: %u). This limit does not apply to connections manually added via -addnode or the addnode RPC, which have a separate limit of %u.", DEFAULT_MAX_PEER_CONNECTIONS, MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection memory usage for the send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by outbound peers forward or backward by this amount (default: %u seconds).", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target per 24h. Limit does not apply to peers with 'download' permission or blocks created within past week. 0 = no limit (default: %s). Optional suffix units [k|K|m|M|g|G|t|T] (default: M). Lowercase is 1000 base while uppercase is 1024 base", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
#if HAVE_SOCKADDR_UN
argsman.AddArg("-onion=<ip:port|path>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy). May be a local file path prefixed with 'unix:'.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);

View file

@ -35,7 +35,6 @@
#include <scheduler.h>
#include <streams.h>
#include <sync.h>
#include <timedata.h>
#include <tinyformat.h>
#include <txmempool.h>
#include <txorphanage.h>
@ -3684,9 +3683,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
if (!pfrom.IsInboundConn()) {
// Don't use time offset samples from inbound peers to make it
// Don't use timedata samples from inbound peers to make it
// harder for others to create false warnings about our clock being out of sync.
AddTimeData(pfrom.addr, Ticks<std::chrono::seconds>(peer->m_time_offset.load()));
m_outbound_time_offsets.Add(peer->m_time_offset);
m_outbound_time_offsets.WarnIfOutOfSync();
}

View file

@ -16,7 +16,6 @@
#include <test/util/net.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <timedata.h>
#include <util/string.h>
#include <util/time.h>
#include <validation.h>
@ -72,7 +71,6 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
/*local_services=*/ServiceFlags(NODE_NETWORK | NODE_WITNESS),
/*version=*/PROTOCOL_VERSION,
/*relay_txs=*/true);
TestOnlyResetTimeData();
// This test requires that we have a chain with non-zero work.
{

View file

@ -1,31 +0,0 @@
// Copyright (c) 2020-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <timedata.h>
#include <cstdint>
#include <string>
#include <vector>
FUZZ_TARGET(timedata)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000);
// A max_size of 0 implies no limit, so cap the max number of insertions to avoid timeouts
auto max_to_insert = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 4000);
// Divide by 2 to avoid signed integer overflow in .median()
const int64_t initial_value = fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2;
CMedianFilter<int64_t> median_filter{max_size, initial_value};
while (fuzzed_data_provider.remaining_bytes() > 0 && --max_to_insert >= 0) {
(void)median_filter.median();
assert(median_filter.size() > 0);
assert(static_cast<size_t>(median_filter.size()) == median_filter.sorted().size());
assert(static_cast<unsigned int>(median_filter.size()) <= max_size || max_size == 0);
// Divide by 2 to avoid signed integer overflow in .median()
median_filter.input(fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2);
}
}

View file

@ -19,7 +19,6 @@
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <test/util/validation.h>
#include <timedata.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <validation.h>
@ -902,10 +901,6 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
chainman.ResetIbd();
m_node.args->ForceSetArg("-capturemessages", "0");
m_node.args->ForceSetArg("-bind", "");
// PeerManager::ProcessMessage() calls AddTimeData() which changes the internal state
// in timedata.cpp and later confuses the test "timedata_tests/addtimedata". Thus reset
// that state as it was before our test was run.
TestOnlyResetTimeData();
}

View file

@ -1,105 +0,0 @@
// Copyright (c) 2011-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include <netaddress.h>
#include <noui.h>
#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <timedata.h>
#include <util/string.h>
#include <util/translation.h>
#include <warnings.h>
#include <string>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
CMedianFilter<int> filter(5, 15);
BOOST_CHECK_EQUAL(filter.median(), 15);
filter.input(20); // [15 20]
BOOST_CHECK_EQUAL(filter.median(), 17);
filter.input(30); // [15 20 30]
BOOST_CHECK_EQUAL(filter.median(), 20);
filter.input(3); // [3 15 20 30]
BOOST_CHECK_EQUAL(filter.median(), 17);
filter.input(7); // [3 7 15 20 30]
BOOST_CHECK_EQUAL(filter.median(), 15);
filter.input(18); // [3 7 18 20 30]
BOOST_CHECK_EQUAL(filter.median(), 18);
filter.input(0); // [0 3 7 18 30]
BOOST_CHECK_EQUAL(filter.median(), 7);
}
static void MultiAddTimeData(int n, int64_t offset)
{
static int cnt = 0;
for (int i = 0; i < n; ++i) {
CNetAddr addr;
addr.SetInternal(ToString(++cnt));
AddTimeData(addr, offset);
}
}
BOOST_AUTO_TEST_CASE(addtimedata)
{
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
//Part 1: Add large offsets to test a warning message that our clock may be wrong.
MultiAddTimeData(3, DEFAULT_MAX_TIME_ADJUSTMENT + 1);
// Filter size is 1 + 3 = 4: It is always initialized with a single element (offset 0)
{
ASSERT_DEBUG_LOG("Please check that your computer's date and time are correct!");
MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
}
BOOST_CHECK(GetWarnings(true).original.find("clock is wrong") != std::string::npos);
// nTimeOffset is not changed if the median of offsets exceeds DEFAULT_MAX_TIME_ADJUSTMENT
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
// Part 2: Test positive and negative medians by adding more offsets
MultiAddTimeData(4, 100); // filter size 9
BOOST_CHECK_EQUAL(GetTimeOffset(), 100);
MultiAddTimeData(10, -100); //filter size 19
BOOST_CHECK_EQUAL(GetTimeOffset(), -100);
// Part 3: Test behaviour when filter has reached maximum number of offsets
const int MAX_SAMPLES = 200;
int nfill = (MAX_SAMPLES - 3 - 19) / 2; //89
MultiAddTimeData(nfill, 100);
MultiAddTimeData(nfill, -100); //filter size MAX_SAMPLES - 3
BOOST_CHECK_EQUAL(GetTimeOffset(), -100);
MultiAddTimeData(2, 100);
//filter size MAX_SAMPLES -1, median is the initial 0 offset
//since we added same number of positive/negative offsets
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
// After the number of offsets has reached MAX_SAMPLES -1 (=199), nTimeOffset will never change
// because it is only updated when the number of elements in the filter becomes odd. It was decided
// not to fix this because it prevents possible attacks. See the comment in AddTimeData() or issue #4521
// for a more detailed explanation.
MultiAddTimeData(2, 100); // filter median is 100 now, but nTimeOffset will not change
// We want this test to end with nTimeOffset==0, otherwise subsequent tests of the suite will fail.
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
TestOnlyResetTimeData();
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,116 +0,0 @@
// Copyright (c) 2014-2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <timedata.h>
#include <common/args.h>
#include <logging.h>
#include <netaddress.h>
#include <node/interface_ui.h>
#include <sync.h>
#include <tinyformat.h>
#include <util/translation.h>
#include <warnings.h>
static GlobalMutex g_timeoffset_mutex;
static int64_t nTimeOffset GUARDED_BY(g_timeoffset_mutex) = 0;
/**
* "Never go to sea with two chronometers; take one or three."
* Our three time sources are:
* - System clock
* - Median of other nodes clocks
* - The user (asking the user to fix the system clock if the first two disagree)
*/
int64_t GetTimeOffset()
{
LOCK(g_timeoffset_mutex);
return nTimeOffset;
}
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
static std::set<CNetAddr> g_sources;
static CMedianFilter<int64_t> g_time_offsets{BITCOIN_TIMEDATA_MAX_SAMPLES, 0};
static bool g_warning_emitted;
void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
LOCK(g_timeoffset_mutex);
// Ignore duplicates
if (g_sources.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
return;
if (!g_sources.insert(ip).second)
return;
// Add data
g_time_offsets.input(nOffsetSample);
LogPrint(BCLog::NET, "added time data, samples %d, offset %+d (%+d minutes)\n", g_time_offsets.size(), nOffsetSample, nOffsetSample / 60);
// There is a known issue here (see issue #4521):
//
// - The structure g_time_offsets contains up to 200 elements, after which
// any new element added to it will not increase its size, replacing the
// oldest element.
//
// - The condition to update nTimeOffset includes checking whether the
// number of elements in g_time_offsets is odd, which will never happen after
// there are 200 elements.
//
// But in this case the 'bug' is protective against some attacks, and may
// actually explain why we've never seen attacks which manipulate the
// clock offset.
//
// So we should hold off on fixing this and clean it up as part of
// a timing cleanup that strengthens it in a number of other ways.
//
if (g_time_offsets.size() >= 5 && g_time_offsets.size() % 2 == 1) {
int64_t nMedian = g_time_offsets.median();
std::vector<int64_t> vSorted = g_time_offsets.sorted();
// Only let other nodes change our time by so much
int64_t max_adjustment = std::max<int64_t>(0, gArgs.GetIntArg("-maxtimeadjustment", DEFAULT_MAX_TIME_ADJUSTMENT));
if (nMedian >= -max_adjustment && nMedian <= max_adjustment) {
nTimeOffset = nMedian;
} else {
nTimeOffset = 0;
if (!g_warning_emitted) {
// If nobody has a time different than ours but within 5 minutes of ours, give a warning
bool fMatch = false;
for (const int64_t nOffset : vSorted) {
if (nOffset != 0 && nOffset > -5 * 60 && nOffset < 5 * 60) fMatch = true;
}
if (!fMatch) {
g_warning_emitted = true;
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);
SetMiscWarning(strMessage);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
}
}
}
if (LogAcceptCategory(BCLog::NET, BCLog::Level::Debug)) {
std::string log_message{"time data samples: "};
for (const int64_t n : vSorted) {
log_message += strprintf("%+d ", n);
}
log_message += strprintf("| median offset = %+d (%+d minutes)", nTimeOffset, nTimeOffset / 60);
LogPrint(BCLog::NET, "%s\n", log_message);
}
}
}
void TestOnlyResetTimeData()
{
LOCK(g_timeoffset_mutex);
nTimeOffset = 0;
g_sources.clear();
g_time_offsets = CMedianFilter<int64_t>{BITCOIN_TIMEDATA_MAX_SAMPLES, 0};
g_warning_emitted = false;
}

View file

@ -1,82 +0,0 @@
// Copyright (c) 2014-2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TIMEDATA_H
#define BITCOIN_TIMEDATA_H
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <vector>
static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 70 * 60;
class CNetAddr;
/**
* Median filter over a stream of values.
* Returns the median of the last N numbers
*/
template <typename T>
class CMedianFilter
{
private:
std::vector<T> vValues;
std::vector<T> vSorted;
unsigned int nSize;
public:
CMedianFilter(unsigned int _size, T initial_value) : nSize(_size)
{
vValues.reserve(_size);
vValues.push_back(initial_value);
vSorted = vValues;
}
void input(T value)
{
if (vValues.size() == nSize) {
vValues.erase(vValues.begin());
}
vValues.push_back(value);
vSorted.resize(vValues.size());
std::copy(vValues.begin(), vValues.end(), vSorted.begin());
std::sort(vSorted.begin(), vSorted.end());
}
T median() const
{
int vSortedSize = vSorted.size();
assert(vSortedSize > 0);
if (vSortedSize & 1) // Odd number of elements
{
return vSorted[vSortedSize / 2];
} else // Even number of elements
{
return (vSorted[vSortedSize / 2 - 1] + vSorted[vSortedSize / 2]) / 2;
}
}
int size() const
{
return vValues.size();
}
std::vector<T> sorted() const
{
return vSorted;
}
};
/** Functions to keep track of adjusted P2P time */
int64_t GetTimeOffset();
void AddTimeData(const CNetAddr& ip, int64_t nTime);
/**
* Reset the internal state of GetTimeOffset() and AddTimeData().
*/
void TestOnlyResetTimeData();
#endif // BITCOIN_TIMEDATA_H