Branch data Line data Source code
# 1 : : // Copyright (c) 2011-2020 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 : :
# 6 : : #include <netaddress.h>
# 7 : : #include <noui.h>
# 8 : : #include <test/util/logging.h>
# 9 : : #include <test/util/setup_common.h>
# 10 : : #include <timedata.h>
# 11 : : #include <util/string.h>
# 12 : : #include <util/translation.h>
# 13 : : #include <warnings.h>
# 14 : :
# 15 : : #include <string>
# 16 : :
# 17 : : #include <boost/test/unit_test.hpp>
# 18 : :
# 19 : : BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
# 20 : :
# 21 : : BOOST_AUTO_TEST_CASE(util_MedianFilter)
# 22 : 2 : {
# 23 : 2 : CMedianFilter<int> filter(5, 15);
# 24 : :
# 25 : 2 : BOOST_CHECK_EQUAL(filter.median(), 15);
# 26 : :
# 27 : 2 : filter.input(20); // [15 20]
# 28 : 2 : BOOST_CHECK_EQUAL(filter.median(), 17);
# 29 : :
# 30 : 2 : filter.input(30); // [15 20 30]
# 31 : 2 : BOOST_CHECK_EQUAL(filter.median(), 20);
# 32 : :
# 33 : 2 : filter.input(3); // [3 15 20 30]
# 34 : 2 : BOOST_CHECK_EQUAL(filter.median(), 17);
# 35 : :
# 36 : 2 : filter.input(7); // [3 7 15 20 30]
# 37 : 2 : BOOST_CHECK_EQUAL(filter.median(), 15);
# 38 : :
# 39 : 2 : filter.input(18); // [3 7 18 20 30]
# 40 : 2 : BOOST_CHECK_EQUAL(filter.median(), 18);
# 41 : :
# 42 : 2 : filter.input(0); // [0 3 7 18 30]
# 43 : 2 : BOOST_CHECK_EQUAL(filter.median(), 7);
# 44 : 2 : }
# 45 : :
# 46 : : static void MultiAddTimeData(int n, int64_t offset)
# 47 : 16 : {
# 48 : 16 : static int cnt = 0;
# 49 [ + + ]: 416 : for (int i = 0; i < n; ++i) {
# 50 : 400 : CNetAddr addr;
# 51 : 400 : addr.SetInternal(ToString(++cnt));
# 52 : 400 : AddTimeData(addr, offset);
# 53 : 400 : }
# 54 : 16 : }
# 55 : :
# 56 : :
# 57 : : BOOST_AUTO_TEST_CASE(addtimedata)
# 58 : 2 : {
# 59 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
# 60 : :
# 61 : : //Part 1: Add large offsets to test a warning message that our clock may be wrong.
# 62 : 2 : MultiAddTimeData(3, DEFAULT_MAX_TIME_ADJUSTMENT + 1);
# 63 : : // Filter size is 1 + 3 = 4: It is always initialized with a single element (offset 0)
# 64 : :
# 65 : 2 : {
# 66 : 2 : ASSERT_DEBUG_LOG("Please check that your computer's date and time are correct!");
# 67 : 2 : MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
# 68 : 2 : }
# 69 : :
# 70 : 2 : BOOST_CHECK(GetWarnings(true).original.find("clock is wrong") != std::string::npos);
# 71 : :
# 72 : : // nTimeOffset is not changed if the median of offsets exceeds DEFAULT_MAX_TIME_ADJUSTMENT
# 73 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
# 74 : :
# 75 : : // Part 2: Test positive and negative medians by adding more offsets
# 76 : 2 : MultiAddTimeData(4, 100); // filter size 9
# 77 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), 100);
# 78 : 2 : MultiAddTimeData(10, -100); //filter size 19
# 79 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), -100);
# 80 : :
# 81 : : // Part 3: Test behaviour when filter has reached maximum number of offsets
# 82 : 2 : const int MAX_SAMPLES = 200;
# 83 : 2 : int nfill = (MAX_SAMPLES - 3 - 19) / 2; //89
# 84 : 2 : MultiAddTimeData(nfill, 100);
# 85 : 2 : MultiAddTimeData(nfill, -100); //filter size MAX_SAMPLES - 3
# 86 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), -100);
# 87 : :
# 88 : 2 : MultiAddTimeData(2, 100);
# 89 : : //filter size MAX_SAMPLES -1, median is the initial 0 offset
# 90 : : //since we added same number of positive/negative offsets
# 91 : :
# 92 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
# 93 : :
# 94 : : // After the number of offsets has reached MAX_SAMPLES -1 (=199), nTimeOffset will never change
# 95 : : // because it is only updated when the number of elements in the filter becomes odd. It was decided
# 96 : : // not to fix this because it prevents possible attacks. See the comment in AddTimeData() or issue #4521
# 97 : : // for a more detailed explanation.
# 98 : 2 : MultiAddTimeData(2, 100); // filter median is 100 now, but nTimeOffset will not change
# 99 : 2 : BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
# 100 : :
# 101 : : // We want this test to end with nTimeOffset==0, otherwise subsequent tests of the suite will fail.
# 102 : 2 : }
# 103 : :
# 104 : : BOOST_AUTO_TEST_SUITE_END()
|