From 60da1eaa1113e7318e273144e7ef9c8895d7ed54 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 18 Jan 2021 14:27:00 +0100 Subject: timedata: make it possible to reset the state Add a new function `TestOnlyResetTimeData()` which would reset the internal state used by `GetTimeOffset()`, `GetAdjustedTime()` and `AddTimeData()`. This is needed so that unit tests that call `AddTimeData()` can restore the state in order not to confuse other tests that rely on it. Currently `timedata_tests/addtimedata` is the only test that modifies the state (via `AddTimeData()`) and also the only test that relies on that state. --- src/test/timedata_tests.cpp | 3 ++- src/timedata.cpp | 16 +++++++++++++--- src/timedata.h | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 1dcee23bbb..478d61d5e2 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -96,9 +96,10 @@ BOOST_AUTO_TEST_CASE(addtimedata) // 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); - // We want this test to end with nTimeOffset==0, otherwise subsequent tests of the suite will fail. + TestOnlyResetTimeData(); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/timedata.cpp b/src/timedata.cpp index 541580b3ff..ed651e3e9e 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -39,18 +39,20 @@ int64_t GetAdjustedTime() #define BITCOIN_TIMEDATA_MAX_SAMPLES 200 +static std::set setKnown; +static CMedianFilter vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); +static bool fDone; + void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) { LOCK(g_timeoffset_mutex); // Ignore duplicates - static std::set setKnown; if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES) return; if (!setKnown.insert(ip).second) return; // Add data - static CMedianFilter vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); vTimeOffsets.input(nOffsetSample); LogPrint(BCLog::NET, "added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample / 60); @@ -81,7 +83,6 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) } else { nTimeOffset = 0; - static bool fDone; if (!fDone) { // If nobody has a time different than ours but within 5 minutes of ours, give a warning bool fMatch = false; @@ -108,3 +109,12 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) } } } + +void TestOnlyResetTimeData() +{ + LOCK(g_timeoffset_mutex); + nTimeOffset = 0; + setKnown.clear(); + vTimeOffsets = CMedianFilter(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); + fDone = false; +} diff --git a/src/timedata.h b/src/timedata.h index b165ecde26..2f039d5465 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -75,4 +75,9 @@ int64_t GetTimeOffset(); int64_t GetAdjustedTime(); void AddTimeData(const CNetAddr& ip, int64_t nTime); +/** + * Reset the internal state of GetTimeOffset(), GetAdjustedTime() and AddTimeData(). + */ +void TestOnlyResetTimeData(); + #endif // BITCOIN_TIMEDATA_H -- cgit v1.2.3