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.
This commit is contained in:
Vasil Dimov 2021-01-18 14:27:00 +01:00
parent 08bcfa2767
commit 60da1eaa11
No known key found for this signature in database
GPG key ID: 54DF06F64B55CBBF
3 changed files with 20 additions and 4 deletions

View file

@ -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()

View file

@ -39,18 +39,20 @@ int64_t GetAdjustedTime()
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
static std::set<CNetAddr> setKnown;
static CMedianFilter<int64_t> 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<CNetAddr> setKnown;
if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
return;
if (!setKnown.insert(ip).second)
return;
// Add data
static CMedianFilter<int64_t> 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<int64_t>(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
fDone = false;
}

View file

@ -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