#include #include #include #include #include #include namespace xrpl { namespace test { class LedgerTiming_test : public beast::unit_test::suite { void testGetNextLedgerTimeResolution() { // helper to iteratively call into getNextLedgerTimeResolution struct test_res { std::uint32_t decrease = 0; std::uint32_t equal = 0; std::uint32_t increase = 0; static test_res run(bool previousAgree, std::uint32_t rounds) { test_res res; auto closeResolution = ledgerDefaultTimeResolution; auto nextCloseResolution = closeResolution; std::uint32_t round = 0; do { nextCloseResolution = getNextLedgerTimeResolution(closeResolution, previousAgree, ++round); if (nextCloseResolution < closeResolution) { ++res.decrease; } else if (nextCloseResolution > closeResolution) { ++res.increase; } else { ++res.equal; } std::swap(nextCloseResolution, closeResolution); } while (round < rounds); return res; } }; // If we never agree on close time, only can increase resolution // until hit the max auto decreases = test_res::run(false, 10); BEAST_EXPECT(decreases.increase == 3); BEAST_EXPECT(decreases.decrease == 0); BEAST_EXPECT(decreases.equal == 7); // If we always agree on close time, only can decrease resolution // until hit the min auto increases = test_res::run(false, 100); BEAST_EXPECT(increases.increase == 3); BEAST_EXPECT(increases.decrease == 0); BEAST_EXPECT(increases.equal == 97); } void testRoundCloseTime() { using namespace std::chrono_literals; // A closeTime equal to the epoch is not modified using tp = NetClock::time_point; tp const def; BEAST_EXPECT(def == roundCloseTime(def, 30s)); // Otherwise, the closeTime is rounded to the nearest // rounding up on ties BEAST_EXPECT(tp{0s} == roundCloseTime(tp{29s}, 60s)); BEAST_EXPECT(tp{30s} == roundCloseTime(tp{30s}, 1s)); BEAST_EXPECT(tp{60s} == roundCloseTime(tp{31s}, 60s)); BEAST_EXPECT(tp{60s} == roundCloseTime(tp{30s}, 60s)); BEAST_EXPECT(tp{60s} == roundCloseTime(tp{59s}, 60s)); BEAST_EXPECT(tp{60s} == roundCloseTime(tp{60s}, 60s)); BEAST_EXPECT(tp{60s} == roundCloseTime(tp{61s}, 60s)); } void testEffCloseTime() { using namespace std::chrono_literals; using tp = NetClock::time_point; tp close = effCloseTime(tp{10s}, 30s, tp{0s}); BEAST_EXPECT(close == tp{1s}); close = effCloseTime(tp{16s}, 30s, tp{0s}); BEAST_EXPECT(close == tp{30s}); close = effCloseTime(tp{16s}, 30s, tp{30s}); BEAST_EXPECT(close == tp{31s}); close = effCloseTime(tp{16s}, 30s, tp{60s}); BEAST_EXPECT(close == tp{61s}); close = effCloseTime(tp{31s}, 30s, tp{0s}); BEAST_EXPECT(close == tp{30s}); } void run() override { testGetNextLedgerTimeResolution(); testRoundCloseTime(); testEffCloseTime(); } }; BEAST_DEFINE_TESTSUITE(LedgerTiming, consensus, xrpl); } // namespace test } // namespace xrpl