From b8af67eeefc9fc9622f839ec8919b7391d91bf6f Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Sun, 21 Mar 2021 10:45:17 +1000 Subject: fuzz: cleanups for versionbits fuzzer Github-Pull: #21489 Rebased-From: aa7f418fe32b3ec53285693a7731decd99be4528 --- src/test/fuzz/versionbits.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/test') diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp index 645c0d23c0..77a8d0d08f 100644 --- a/src/test/fuzz/versionbits.cpp +++ b/src/test/fuzz/versionbits.cpp @@ -52,9 +52,10 @@ public: int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, dummy_params, m_cache); } BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor(pindexPrev, dummy_params); } - bool Condition(int64_t version) const + bool Condition(int32_t version) const { - return ((version >> m_bit) & 1) != 0 && (version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; + uint32_t mask = ((uint32_t)1) << m_bit; + return (((version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (version & mask) != 0); } bool Condition(const CBlockIndex* pindex) const { return Condition(pindex->nVersion); } @@ -98,17 +99,20 @@ public: }; } // namespace +std::unique_ptr g_params; + void initialize() { - SelectParams(CBaseChainParams::MAIN); + // this is actually comparatively slow, so only do it once + g_params = CreateChainParams(ArgsManager{}, CBaseChainParams::MAIN); + assert(g_params != nullptr); } -constexpr uint32_t MAX_TIME = 4102444800; // 2100-01-01 +constexpr uint32_t MAX_START_TIME = 4102444800; // 2100-01-01 void test_one_input(const std::vector& buffer) { - const CChainParams& params = Params(); - + const CChainParams& params = *g_params; const int64_t interval = params.GetConsensus().nPowTargetSpacing; assert(interval > 1); // need to be able to halve it assert(interval < std::numeric_limits::max()); @@ -125,9 +129,9 @@ void test_one_input(const std::vector& buffer) // too many blocks at 10min each might cause uint32_t time to overflow if // block_start_time is at the end of the range above - assert(std::numeric_limits::max() - MAX_TIME > interval * max_blocks); + assert(std::numeric_limits::max() - MAX_START_TIME > interval * max_blocks); - const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange(params.GenesisBlock().nTime, MAX_TIME); + const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange(params.GenesisBlock().nTime, MAX_START_TIME); // what values for version will we use to signal / not signal? const int32_t ver_signal = fuzzed_data_provider.ConsumeIntegral(); @@ -171,8 +175,10 @@ void test_one_input(const std::vector& buffer) if (checker.Condition(ver_nosignal)) return; if (ver_nosignal < 0) return; - // TOP_BITS should ensure version will be positive + // TOP_BITS should ensure version will be positive and meet min + // version requirement assert(ver_signal > 0); + assert(ver_signal >= VERSIONBITS_LAST_OLD_BLOCK_VERSION); // Now that we have chosen time and versions, setup to mine blocks Blocks blocks(block_start_time, interval, ver_signal, ver_nosignal); @@ -201,7 +207,7 @@ void test_one_input(const std::vector& buffer) } // don't risk exceeding max_blocks or times may wrap around - if (blocks.size() + period*2 > max_blocks) break; + if (blocks.size() + 2 * period > max_blocks) break; } // NOTE: fuzzed_data_provider may be fully consumed at this point and should not be used further @@ -321,7 +327,7 @@ void test_one_input(const std::vector& buffer) assert(false); } - if (blocks.size() >= max_periods * period) { + if (blocks.size() >= period * max_periods) { // we chose the timeout (and block times) so that by the time we have this many blocks it's all over assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED); } -- cgit v1.2.3