TLA Line data Source code
1 : // evmone: Fast Ethereum Virtual Machine implementation
2 : // Copyright 2023 The evmone Authors.
3 : // SPDX-License-Identifier: Apache-2.0
4 :
5 : #include "ethash_difficulty.hpp"
6 : #include <algorithm>
7 : #include <cassert>
8 :
9 : namespace evmone::state
10 : {
11 : namespace
12 : {
13 UBC 0 : int64_t get_bomb_delay(evmc_revision rev) noexcept
14 : {
15 0 : switch (rev)
16 : {
17 0 : default:
18 0 : return 0;
19 0 : case EVMC_BYZANTIUM:
20 0 : return 3'000'000;
21 0 : case EVMC_CONSTANTINOPLE:
22 : case EVMC_PETERSBURG:
23 : case EVMC_ISTANBUL:
24 0 : return 5'000'000;
25 0 : case EVMC_BERLIN:
26 0 : return 9'000'000;
27 0 : case EVMC_LONDON:
28 0 : return 9'700'000;
29 : }
30 : }
31 :
32 0 : int64_t calculate_difficulty_pre_byzantium(int64_t parent_difficulty, int64_t parent_timestamp,
33 : int64_t current_timestamp, int64_t block_number, evmc_revision rev)
34 : {
35 : // According to https://eips.ethereum.org/EIPS/eip-2
36 0 : const auto period_count = block_number / 100'000;
37 0 : const auto offset = parent_difficulty / 2048;
38 :
39 0 : auto diff = parent_difficulty;
40 :
41 0 : if (rev < EVMC_HOMESTEAD)
42 0 : diff += offset * (current_timestamp - parent_timestamp < 13 ? 1 : -1);
43 : else
44 0 : diff += offset * std::max(1 - (current_timestamp - parent_timestamp) / 10, int64_t{-99});
45 :
46 0 : if (period_count > 2)
47 0 : diff += 2 << (block_number / 100'000 - 3);
48 0 : else if (period_count == 2)
49 0 : diff += 1;
50 :
51 0 : return diff;
52 : }
53 :
54 0 : int64_t calculate_difficulty_since_byzantium(int64_t parent_difficulty, bool parent_has_ommers,
55 : int64_t parent_timestamp, int64_t current_timestamp, int64_t block_number,
56 : evmc_revision rev) noexcept
57 : {
58 0 : const auto delay = get_bomb_delay(rev);
59 0 : const auto fake_block_number = std::max(int64_t{0}, block_number - delay);
60 0 : const auto p = (fake_block_number / 100'000) - 2;
61 0 : assert(p < 63);
62 0 : const auto epsilon = p < 0 ? 0 : int64_t{1} << p;
63 0 : const auto y = parent_has_ommers ? 2 : 1;
64 :
65 0 : const auto timestamp_diff = current_timestamp - parent_timestamp;
66 0 : assert(timestamp_diff > 0);
67 0 : const auto sigma_2 = std::max(y - timestamp_diff / 9, int64_t{-99});
68 0 : const auto x = parent_difficulty / 2048;
69 0 : return parent_difficulty + x * sigma_2 + epsilon;
70 : }
71 : } // namespace
72 :
73 CBC 53 : int64_t calculate_difficulty(int64_t parent_difficulty, bool parent_has_ommers,
74 : int64_t parent_timestamp, int64_t current_timestamp, int64_t block_number,
75 : evmc_revision rev) noexcept
76 : {
77 : // The calculation follows Ethereum Yellow Paper section 4.3.4. "Block Header Validity".
78 : static constexpr int64_t MIN_DIFFICULTY = 0x20000;
79 :
80 53 : if (rev >= EVMC_PARIS)
81 53 : return 0; // No difficulty after the Merge.
82 :
83 : const auto difficulty =
84 UBC 0 : (rev < EVMC_BYZANTIUM) ?
85 0 : calculate_difficulty_pre_byzantium(
86 : parent_difficulty, parent_timestamp, current_timestamp, block_number, rev) :
87 0 : calculate_difficulty_since_byzantium(parent_difficulty, parent_has_ommers,
88 0 : parent_timestamp, current_timestamp, block_number, rev);
89 :
90 0 : return std::max(MIN_DIFFICULTY, difficulty);
91 : }
92 : } // namespace evmone::state
|