From e4bcf7c2e7fd0b43b1f4a2a0114dffc0fddea574 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 5 Feb 2024 17:19:51 +0300 Subject: [PATCH] test: Adjust difficulty if below minimum `0x20000` (#803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applies the minimum difficulty cap also to pre-Byzantium difficulty calculations. Fixes https://github.com/ethereum/evmone/issues/752. Co-authored-by: Paweł Bylica --- test/state/ethash_difficulty.cpp | 39 +++++++++++++--------- test/unittests/state_difficulty_test.cpp | 41 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/test/state/ethash_difficulty.cpp b/test/state/ethash_difficulty.cpp index 0d9bb0d51a..73633980b7 100644 --- a/test/state/ethash_difficulty.cpp +++ b/test/state/ethash_difficulty.cpp @@ -51,23 +51,10 @@ int64_t calculate_difficulty_pre_byzantium(int64_t parent_difficulty, int64_t pa return diff; } -} // namespace - -int64_t calculate_difficulty(int64_t parent_difficulty, bool parent_has_ommers, +int64_t calculate_difficulty_since_byzantium(int64_t parent_difficulty, bool parent_has_ommers, int64_t parent_timestamp, int64_t current_timestamp, int64_t block_number, evmc_revision rev) noexcept { - // The calculation follows Ethereum Yellow Paper section 4.3.4. "Block Header Validity". - - if (rev >= EVMC_PARIS) - return 0; // No difficulty after the Merge. - - if (rev < EVMC_BYZANTIUM) - return calculate_difficulty_pre_byzantium( - parent_difficulty, parent_timestamp, current_timestamp, block_number, rev); - - static constexpr auto min_difficulty = int64_t{1} << 17; - const auto delay = get_bomb_delay(rev); const auto fake_block_number = std::max(int64_t{0}, block_number - delay); const auto p = (fake_block_number / 100'000) - 2; @@ -79,7 +66,27 @@ int64_t calculate_difficulty(int64_t parent_difficulty, bool parent_has_ommers, assert(timestamp_diff > 0); const auto sigma_2 = std::max(y - timestamp_diff / 9, int64_t{-99}); const auto x = parent_difficulty / 2048; - const auto difficulty = parent_difficulty + x * sigma_2 + epsilon; - return std::max(min_difficulty, difficulty); + return parent_difficulty + x * sigma_2 + epsilon; +} +} // namespace + +int64_t calculate_difficulty(int64_t parent_difficulty, bool parent_has_ommers, + int64_t parent_timestamp, int64_t current_timestamp, int64_t block_number, + evmc_revision rev) noexcept +{ + // The calculation follows Ethereum Yellow Paper section 4.3.4. "Block Header Validity". + static constexpr int64_t MIN_DIFFICULTY = 0x20000; + + if (rev >= EVMC_PARIS) + return 0; // No difficulty after the Merge. + + const auto difficulty = + (rev < EVMC_BYZANTIUM) ? + calculate_difficulty_pre_byzantium( + parent_difficulty, parent_timestamp, current_timestamp, block_number, rev) : + calculate_difficulty_since_byzantium(parent_difficulty, parent_has_ommers, + parent_timestamp, current_timestamp, block_number, rev); + + return std::max(MIN_DIFFICULTY, difficulty); } } // namespace evmone::state diff --git a/test/unittests/state_difficulty_test.cpp b/test/unittests/state_difficulty_test.cpp index 8c8ae5950f..e661301324 100644 --- a/test/unittests/state_difficulty_test.cpp +++ b/test/unittests/state_difficulty_test.cpp @@ -122,6 +122,47 @@ static constexpr DifficultyTest tests[] = { 0x617ec9fb8, true, }, + { + EVMC_FRONTIER, + "min_difficulty_frontier", + 1, + 0x20000, + 1100, + 0x20000, + 1000, + false, + }, + { + EVMC_HOMESTEAD, + "min_difficulty_homestead", + 1, + 0x20000, + 2000, + 0x21999, + 1000, + false, + }, + { + EVMC_BYZANTIUM, + "min_difficulty_byzantium", + 3'000'001, + 0x20000, + 10060, + 0x20139, + 10000, + false, + }, + { + // Calculated difficulty is exactly 0x20000 without min cap. + EVMC_BYZANTIUM, + "min_difficulty_byzantium2", + 3'000'001, + 0x20000, + 10060, + 0x20140, + 10000, + false, + }, }; TEST(state_difficulty, tests)