diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/pow.cpp | 37 | ||||
-rw-r--r-- | src/test/pow_tests.cpp | 27 |
2 files changed, 60 insertions, 4 deletions
diff --git a/src/test/fuzz/pow.cpp b/src/test/fuzz/pow.cpp index 0004d82d66..507ce57ec0 100644 --- a/src/test/fuzz/pow.cpp +++ b/src/test/fuzz/pow.cpp @@ -83,3 +83,40 @@ FUZZ_TARGET_INIT(pow, initialize_pow) } } } + + +FUZZ_TARGET_INIT(pow_transition, initialize_pow) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + const Consensus::Params& consensus_params{Params().GetConsensus()}; + std::vector<std::unique_ptr<CBlockIndex>> blocks; + + const uint32_t old_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; + const uint32_t new_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; + const int32_t version{fuzzed_data_provider.ConsumeIntegral<int32_t>()}; + uint32_t nbits{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}; + + const arith_uint256 pow_limit = UintToArith256(consensus_params.powLimit); + arith_uint256 old_target; + old_target.SetCompact(nbits); + if (old_target > pow_limit) { + nbits = pow_limit.GetCompact(); + } + // Create one difficulty adjustment period worth of headers + for (int height = 0; height < consensus_params.DifficultyAdjustmentInterval(); ++height) { + CBlockHeader header; + header.nVersion = version; + header.nTime = old_time; + header.nBits = nbits; + if (height == consensus_params.DifficultyAdjustmentInterval() - 1) { + header.nTime = new_time; + } + auto current_block{std::make_unique<CBlockIndex>(header)}; + current_block->pprev = blocks.empty() ? nullptr : blocks.back().get(); + current_block->nHeight = height; + blocks.emplace_back(std::move(current_block)).get(); + } + auto last_block{blocks.back().get()}; + unsigned int new_nbits{GetNextWorkRequired(last_block, nullptr, consensus_params)}; + Assert(PermittedDifficultyTransition(consensus_params, last_block->nHeight + 1, last_block->nBits, new_nbits)); +} diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 2f43ae52f7..3695ea9d16 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -20,7 +20,14 @@ BOOST_AUTO_TEST_CASE(get_next_work) pindexLast.nHeight = 32255; pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86aU); + + // Here (and below): expected_nbits is calculated in + // CalculateNextWorkRequired(); redoing the calculation here would be just + // reimplementing the same code that is written in pow.cpp. Rather than + // copy that code, we just hardcode the expected result. + unsigned int expected_nbits = 0x1d00d86aU; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), expected_nbits); + BOOST_CHECK(PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, expected_nbits)); } /* Test the constraint on the upper bound for next work */ @@ -32,7 +39,9 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) pindexLast.nHeight = 2015; pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffffU); + unsigned int expected_nbits = 0x1d00ffffU; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), expected_nbits); + BOOST_CHECK(PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, expected_nbits)); } /* Test the constraint on the lower bound for actual time taken */ @@ -44,7 +53,12 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) pindexLast.nHeight = 68543; pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fdU); + unsigned int expected_nbits = 0x1c0168fdU; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), expected_nbits); + BOOST_CHECK(PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, expected_nbits)); + // Test that reducing nbits further would not be a PermittedDifficultyTransition. + unsigned int invalid_nbits = expected_nbits-1; + BOOST_CHECK(!PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, invalid_nbits)); } /* Test the constraint on the upper bound for actual time taken */ @@ -56,7 +70,12 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) pindexLast.nHeight = 46367; pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fdU); + unsigned int expected_nbits = 0x1d00e1fdU; + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), expected_nbits); + BOOST_CHECK(PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, expected_nbits)); + // Test that increasing nbits further would not be a PermittedDifficultyTransition. + unsigned int invalid_nbits = expected_nbits+1; + BOOST_CHECK(!PermittedDifficultyTransition(chainParams->GetConsensus(), pindexLast.nHeight+1, pindexLast.nBits, invalid_nbits)); } BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target) |