diff --git a/cmd/state-transition/state_transition.cpp b/cmd/state-transition/state_transition.cpp index a9563866..bcee7c5d 100644 --- a/cmd/state-transition/state_transition.cpp +++ b/cmd/state-transition/state_transition.cpp @@ -106,12 +106,12 @@ Block StateTransition::get_block(InMemoryState& state, ChainConfig& chain_config block.header.prev_randao = to_bytes32(from_hex(get_env("currentRandom")).value_or(Bytes{})); } - const evmc_revision rev{chain_config.revision(block.header.number, block.header.timestamp)}; + const evmc_revision rev{chain_config.revision(block.header)}; // set difficulty only for revisions before The Merge // current block difficulty cannot fall below miniumum: https://eips.ethereum.org/EIPS/eip-2 static constexpr uint64_t kMinDifficulty{0x20000}; - if (!chain_config.terminal_total_difficulty.has_value()) { + if (!chain_config.terminal_total_difficulty().has_value()) { block.header.difficulty = intx::from_string(get_env("currentDifficulty")); if (block.header.difficulty < kMinDifficulty && rev <= EVMC_LONDON) { block.header.difficulty = kMinDifficulty; @@ -330,7 +330,7 @@ void StateTransition::run() { ExecutionProcessor processor{block, *ruleSet, *state, config}; Receipt receipt; - const evmc_revision rev{config.revision(block.header.number, block.header.timestamp)}; + const evmc_revision rev{config.revision(block.header)}; auto pre_block_validation = ruleSet->pre_validate_block_body(block, *state); auto block_validation = ruleSet->validate_block_header(block.header, *state, true); diff --git a/cmd/test/ethereum.cpp b/cmd/test/ethereum.cpp index 943e1464..42aa1e43 100644 --- a/cmd/test/ethereum.cpp +++ b/cmd/test/ethereum.cpp @@ -359,7 +359,7 @@ RunResults transaction_test(const nlohmann::json& j) { } const ChainConfig& config{silkworm::test::kNetworkConfig.at(entry.key())}; - const evmc_revision rev{config.revision(/*block_number=*/0, /*block_time=*/0)}; + const evmc_revision rev{config.revision(BlockHeader{.number=0,.timestamp=0})}; /* pre_validate_transaction checks for invalid signature only if from is empty, which means sender recovery * phase (which btw also verifies signature) was not triggered yet. In the context of tests, instead, from is @@ -438,7 +438,7 @@ Status individual_difficulty_test(const nlohmann::json& j, const ChainConfig& co } } - intx::uint256 calculated_difficulty{EthashRuleSet::difficulty(block_number, current_timestamp, parent_difficulty, + intx::uint256 calculated_difficulty{EthashRuleSet::difficulty(BlockHeader{.number=block_number, .timestamp=current_timestamp}, parent_difficulty, parent_timestamp, parent_has_uncles, config)}; if (calculated_difficulty == current_difficulty) { return Status::kPassed; diff --git a/eosevm/block_mapping.hpp b/eosevm/block_mapping.hpp index e7b70d27..d401d09b 100644 --- a/eosevm/block_mapping.hpp +++ b/eosevm/block_mapping.hpp @@ -1,7 +1,9 @@ +#pragma once #include #include #include +#include namespace eosevm { struct block_mapping @@ -61,13 +63,15 @@ struct block_mapping inline void prepare_block_header(silkworm::BlockHeader& header, const block_mapping& bm, uint64_t evm_contract_name, - uint32_t evm_block_num) + uint32_t evm_block_num, + uint64_t version) { header.beneficiary = silkworm::make_reserved_address(evm_contract_name); header.difficulty = 1; header.number = evm_block_num; header.gas_limit = 0x7ffffffffff; header.timestamp = bm.evm_block_num_to_evm_timestamp(header.number); + header.nonce = eosevm::version_to_nonce(version); } diff --git a/eosevm/version.hpp b/eosevm/version.hpp new file mode 100644 index 00000000..5e027b54 --- /dev/null +++ b/eosevm/version.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +namespace eosevm { + +using NonceType=silkworm::BlockHeader::NonceType; + +inline NonceType version_to_nonce(uint64_t version) { + NonceType nonce; + silkworm::endian::store_big_u64(nonce.data(), version); + return nonce; +} + +inline uint64_t nonce_to_version(const NonceType& nonce) { + // The nonce will be treated as big-endian number for now. + return silkworm::endian::load_big_u64(nonce.data()); +} + +inline evmc_revision version_to_evmc_revision(uint64_t version) { + switch (version) { + case 0: return EVMC_ISTANBUL; + case 1: return EVMC_ISTANBUL; + default: return EVMC_ISTANBUL; + } +} + +} // namespace eosevm \ No newline at end of file diff --git a/silkworm/core/chain/config.cpp b/silkworm/core/chain/config.cpp index 1d16fd38..d3cb53c9 100644 --- a/silkworm/core/chain/config.cpp +++ b/silkworm/core/chain/config.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include namespace silkworm { @@ -74,33 +76,35 @@ nlohmann::json ChainConfig::to_json() const noexcept { break; } - member_to_json(ret, "homesteadBlock", homestead_block); - member_to_json(ret, "daoForkBlock", dao_block); - member_to_json(ret, "eip150Block", tangerine_whistle_block); - member_to_json(ret, "eip155Block", spurious_dragon_block); - member_to_json(ret, "byzantiumBlock", byzantium_block); - member_to_json(ret, "constantinopleBlock", constantinople_block); - member_to_json(ret, "petersburgBlock", petersburg_block); - member_to_json(ret, "istanbulBlock", istanbul_block); - member_to_json(ret, "muirGlacierBlock", muir_glacier_block); - member_to_json(ret, "berlinBlock", berlin_block); - member_to_json(ret, "londonBlock", london_block); - member_to_json(ret, "arrowGlacierBlock", arrow_glacier_block); - member_to_json(ret, "grayGlacierBlock", gray_glacier_block); - - if (terminal_total_difficulty) { + member_to_json(ret, "homesteadBlock", _homestead_block); + member_to_json(ret, "daoForkBlock", _dao_block); + member_to_json(ret, "eip150Block", _tangerine_whistle_block); + member_to_json(ret, "eip155Block", _spurious_dragon_block); + member_to_json(ret, "byzantiumBlock", _byzantium_block); + member_to_json(ret, "constantinopleBlock", _constantinople_block); + member_to_json(ret, "petersburgBlock", _petersburg_block); + member_to_json(ret, "istanbulBlock", _istanbul_block); + member_to_json(ret, "muirGlacierBlock", _muir_glacier_block); + member_to_json(ret, "berlinBlock", _berlin_block); + member_to_json(ret, "londonBlock", _london_block); + member_to_json(ret, "arrowGlacierBlock", _arrow_glacier_block); + member_to_json(ret, "grayGlacierBlock", _gray_glacier_block); + + if (_terminal_total_difficulty) { // TODO (Andrew) geth probably treats terminalTotalDifficulty as a JSON number - ret[kTerminalTotalDifficulty] = to_string(*terminal_total_difficulty); + ret[kTerminalTotalDifficulty] = to_string(*_terminal_total_difficulty); } - member_to_json(ret, "mergeNetsplitBlock", merge_netsplit_block); - member_to_json(ret, "shanghaiTime", shanghai_time); - member_to_json(ret, "cancunTime", cancun_time); + member_to_json(ret, "mergeNetsplitBlock", _merge_netsplit_block); + member_to_json(ret, "shanghaiTime", _shanghai_time); + member_to_json(ret, "cancunTime", _cancun_time); if (genesis_hash.has_value()) { ret["genesisBlockHash"] = to_hex(*genesis_hash, /*with_prefix=*/true); } + member_to_json(ret, "version", _version); + return ret; } @@ -124,42 +128,44 @@ std::optional ChainConfig::from_json(const nlohmann::json& json) no config.protocol_rule_set = protocol::RuleSetType::kNoProof; } - read_json_config_member(json, "homesteadBlock", config.homestead_block); - read_json_config_member(json, "daoForkBlock", config.dao_block); - read_json_config_member(json, "eip150Block", config.tangerine_whistle_block); - read_json_config_member(json, "eip155Block", config.spurious_dragon_block); - read_json_config_member(json, "byzantiumBlock", config.byzantium_block); - read_json_config_member(json, "constantinopleBlock", config.constantinople_block); - read_json_config_member(json, "petersburgBlock", config.petersburg_block); - read_json_config_member(json, "istanbulBlock", config.istanbul_block); - read_json_config_member(json, "muirGlacierBlock", config.muir_glacier_block); - read_json_config_member(json, "berlinBlock", config.berlin_block); - read_json_config_member(json, "londonBlock", config.london_block); - read_json_config_member(json, "arrowGlacierBlock", config.arrow_glacier_block); - read_json_config_member(json, "grayGlacierBlock", config.gray_glacier_block); + read_json_config_member(json, "homesteadBlock", config._homestead_block); + read_json_config_member(json, "daoForkBlock", config._dao_block); + read_json_config_member(json, "eip150Block", config._tangerine_whistle_block); + read_json_config_member(json, "eip155Block", config._spurious_dragon_block); + read_json_config_member(json, "byzantiumBlock", config._byzantium_block); + read_json_config_member(json, "constantinopleBlock", config._constantinople_block); + read_json_config_member(json, "petersburgBlock", config._petersburg_block); + read_json_config_member(json, "istanbulBlock", config._istanbul_block); + read_json_config_member(json, "muirGlacierBlock", config._muir_glacier_block); + read_json_config_member(json, "berlinBlock", config._berlin_block); + read_json_config_member(json, "londonBlock", config._london_block); + read_json_config_member(json, "arrowGlacierBlock", config._arrow_glacier_block); + read_json_config_member(json, "grayGlacierBlock", config._gray_glacier_block); if (json.contains(kTerminalTotalDifficulty)) { // We handle terminalTotalDifficulty serialized both as JSON string *and* as JSON number if (json[kTerminalTotalDifficulty].is_string()) { /* This is still present to maintain compatibility with previous Silkworm format */ - config.terminal_total_difficulty = + config._terminal_total_difficulty = intx::from_string(json[kTerminalTotalDifficulty].get()); } else if (json[kTerminalTotalDifficulty].is_number()) { /* This is for compatibility with Erigon that uses a JSON number */ // nlohmann::json treats JSON numbers that overflow 64-bit unsigned integer as floating-point numbers and // intx::uint256 cannot currently be constructed from a floating-point number or string in scientific notation - config.terminal_total_difficulty = + config._terminal_total_difficulty = from_string_sci(json[kTerminalTotalDifficulty].dump().c_str()); } } - read_json_config_member(json, "mergeNetsplitBlock", config.merge_netsplit_block); - read_json_config_member(json, "shanghaiTime", config.shanghai_time); - read_json_config_member(json, "cancunTime", config.cancun_time); + read_json_config_member(json, "mergeNetsplitBlock", config._merge_netsplit_block); + read_json_config_member(json, "shanghaiTime", config._shanghai_time); + read_json_config_member(json, "cancunTime", config._cancun_time); /* Note ! genesis_hash is purposely omitted. It must be loaded from db after the * effective genesis block has been persisted */ + read_json_config_member(json, "version", config._version); + return config; } @@ -169,41 +175,54 @@ std::ostream& operator<<(std::ostream& out, const ChainConfig& obj) { return out #endif -evmc_revision ChainConfig::revision(uint64_t block_number, uint64_t block_time) const noexcept { - if (cancun_time && block_time >= cancun_time) return EVMC_CANCUN; - if (shanghai_time && block_time >= shanghai_time) return EVMC_SHANGHAI; +evmc_revision ChainConfig::determine_revision_by_block(uint64_t block_number, uint64_t block_time) const noexcept { + if (_cancun_time && block_time >= _cancun_time) return EVMC_CANCUN; + if (_shanghai_time && block_time >= _shanghai_time) return EVMC_SHANGHAI; - if (london_block && block_number >= london_block) return EVMC_LONDON; - if (berlin_block && block_number >= berlin_block) return EVMC_BERLIN; - if (istanbul_block && block_number >= istanbul_block) return EVMC_ISTANBUL; - if (petersburg_block && block_number >= petersburg_block) return EVMC_PETERSBURG; - if (constantinople_block && block_number >= constantinople_block) return EVMC_CONSTANTINOPLE; - if (byzantium_block && block_number >= byzantium_block) return EVMC_BYZANTIUM; - if (spurious_dragon_block && block_number >= spurious_dragon_block) return EVMC_SPURIOUS_DRAGON; - if (tangerine_whistle_block && block_number >= tangerine_whistle_block) return EVMC_TANGERINE_WHISTLE; - if (homestead_block && block_number >= homestead_block) return EVMC_HOMESTEAD; + if (_london_block && block_number >= _london_block) return EVMC_LONDON; + if (_berlin_block && block_number >= _berlin_block) return EVMC_BERLIN; + if (_istanbul_block && block_number >= _istanbul_block) return EVMC_ISTANBUL; + if (_petersburg_block && block_number >= _petersburg_block) return EVMC_PETERSBURG; + if (_constantinople_block && block_number >= _constantinople_block) return EVMC_CONSTANTINOPLE; + if (_byzantium_block && block_number >= _byzantium_block) return EVMC_BYZANTIUM; + if (_spurious_dragon_block && block_number >= _spurious_dragon_block) return EVMC_SPURIOUS_DRAGON; + if (_tangerine_whistle_block && block_number >= _tangerine_whistle_block) return EVMC_TANGERINE_WHISTLE; + if (_homestead_block && block_number >= _homestead_block) return EVMC_HOMESTEAD; return EVMC_FRONTIER; } +evmc_revision ChainConfig::revision(const BlockHeader& header) const noexcept { + if(protocol_rule_set != protocol::RuleSetType::kTrust) { + return determine_revision_by_block(header.number, header.timestamp); + } + uint64_t evm_version = 0; + if(header.number == 0) { + evm_version = _version.has_value() ? *_version : 0; + } else { + evm_version = eosevm::nonce_to_version(header.nonce); + } + return eosevm::version_to_evmc_revision(evm_version); +} + std::vector ChainConfig::distinct_fork_numbers() const { std::set ret; // Add forks identified by *block number* in ascending order - ret.insert(homestead_block.value_or(0)); - ret.insert(dao_block.value_or(0)); - ret.insert(tangerine_whistle_block.value_or(0)); - ret.insert(spurious_dragon_block.value_or(0)); - ret.insert(byzantium_block.value_or(0)); - ret.insert(constantinople_block.value_or(0)); - ret.insert(petersburg_block.value_or(0)); - ret.insert(istanbul_block.value_or(0)); - ret.insert(muir_glacier_block.value_or(0)); - ret.insert(berlin_block.value_or(0)); - ret.insert(london_block.value_or(0)); - ret.insert(arrow_glacier_block.value_or(0)); - ret.insert(gray_glacier_block.value_or(0)); - ret.insert(merge_netsplit_block.value_or(0)); + ret.insert(_homestead_block.value_or(0)); + ret.insert(_dao_block.value_or(0)); + ret.insert(_tangerine_whistle_block.value_or(0)); + ret.insert(_spurious_dragon_block.value_or(0)); + ret.insert(_byzantium_block.value_or(0)); + ret.insert(_constantinople_block.value_or(0)); + ret.insert(_petersburg_block.value_or(0)); + ret.insert(_istanbul_block.value_or(0)); + ret.insert(_muir_glacier_block.value_or(0)); + ret.insert(_berlin_block.value_or(0)); + ret.insert(_london_block.value_or(0)); + ret.insert(_arrow_glacier_block.value_or(0)); + ret.insert(_gray_glacier_block.value_or(0)); + ret.insert(_merge_netsplit_block.value_or(0)); ret.erase(0); // Block 0 is not a fork number return {ret.cbegin(), ret.cend()}; @@ -213,8 +232,8 @@ std::vector ChainConfig::distinct_fork_times() const { std::set ret; // Add forks identified by *block timestamp* in ascending order - ret.insert(shanghai_time.value_or(0)); - ret.insert(cancun_time.value_or(0)); + ret.insert(_shanghai_time.value_or(0)); + ret.insert(_cancun_time.value_or(0)); ret.erase(0); // Block 0 is not a fork timestamp return {ret.cbegin(), ret.cend()}; diff --git a/silkworm/core/chain/config.hpp b/silkworm/core/chain/config.hpp index 529e59bb..f6575ac7 100644 --- a/silkworm/core/chain/config.hpp +++ b/silkworm/core/chain/config.hpp @@ -30,7 +30,8 @@ #endif #include - +#include +#include namespace silkworm { namespace protocol { @@ -57,34 +58,124 @@ struct ChainConfig { //! \brief Returns the type of the (pre-Merge) protocol rule set protocol::RuleSetType protocol_rule_set{protocol::RuleSetType::kNoProof}; + const std::optional& homestead_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _homestead_block; + } + + const std::optional& dao_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _dao_block; + } + + const std::optional& tangerine_whistle_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _tangerine_whistle_block; + } + + const std::optional& spurious_dragon_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _spurious_dragon_block; + } + + const std::optional& byzantium_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _byzantium_block; + } + + const std::optional& constantinople_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _constantinople_block; + } + + const std::optional& petersburg_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _petersburg_block; + } + + const std::optional& istanbul_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _istanbul_block; + } + + const std::optional& muir_glacier_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _muir_glacier_block; + } + + const std::optional& berlin_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _berlin_block; + } + + const std::optional& london_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _london_block; + } + + const std::optional& arrow_glacier_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _arrow_glacier_block; + } + + const std::optional& gray_glacier_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _gray_glacier_block; + } + + const std::optional& terminal_total_difficulty() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _terminal_total_difficulty; + } + + const std::optional& shanghai_time() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _shanghai_time; + } + + const std::optional& cancun_time() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _cancun_time; + } + + const std::optional& merge_netsplit_block() const{ + SILKWORM_ASSERT(protocol_rule_set != protocol::RuleSetType::kTrust); + return _merge_netsplit_block; + } + // https://github.com/ethereum/execution-specs/tree/master/network-upgrades/mainnet-upgrades - std::optional homestead_block{std::nullopt}; - std::optional dao_block{std::nullopt}; - std::optional tangerine_whistle_block{std::nullopt}; - std::optional spurious_dragon_block{std::nullopt}; - std::optional byzantium_block{std::nullopt}; - std::optional constantinople_block{std::nullopt}; - std::optional petersburg_block{std::nullopt}; - std::optional istanbul_block{std::nullopt}; - std::optional muir_glacier_block{std::nullopt}; - std::optional berlin_block{std::nullopt}; - std::optional london_block{std::nullopt}; - std::optional arrow_glacier_block{std::nullopt}; - std::optional gray_glacier_block{std::nullopt}; + std::optional _homestead_block{std::nullopt}; + std::optional _dao_block{std::nullopt}; + std::optional _tangerine_whistle_block{std::nullopt}; + std::optional _spurious_dragon_block{std::nullopt}; + std::optional _byzantium_block{std::nullopt}; + std::optional _constantinople_block{std::nullopt}; + std::optional _petersburg_block{std::nullopt}; + std::optional _istanbul_block{std::nullopt}; + std::optional _muir_glacier_block{std::nullopt}; + std::optional _berlin_block{std::nullopt}; + std::optional _london_block{std::nullopt}; + std::optional _arrow_glacier_block{std::nullopt}; + std::optional _gray_glacier_block{std::nullopt}; //! \brief PoW to PoS switch //! \see EIP-3675: Upgrade consensus to Proof-of-Stake - std::optional terminal_total_difficulty{std::nullopt}; - std::optional merge_netsplit_block{std::nullopt}; // FORK_NEXT_VALUE in EIP-3675 + std::optional _terminal_total_difficulty{std::nullopt}; + std::optional _merge_netsplit_block{std::nullopt}; // FORK_NEXT_VALUE in EIP-3675 // Starting from Shanghai, forks are triggered by block time rather than number - std::optional shanghai_time{std::nullopt}; - std::optional cancun_time{std::nullopt}; + std::optional _shanghai_time{std::nullopt}; + std::optional _cancun_time{std::nullopt}; + + // EOSEVM version + std::optional _version{std::nullopt}; //! \brief Returns the revision level at given block number //! \details In other words, on behalf of Json chain config data //! returns whether specific HF have occurred - [[nodiscard]] evmc_revision revision(uint64_t block_number, uint64_t block_time) const noexcept; + [[nodiscard]] evmc_revision determine_revision_by_block(uint64_t block_number, uint64_t block_time) const noexcept; + + [[nodiscard]] evmc_revision revision(const BlockHeader& header) const noexcept; [[nodiscard]] std::vector distinct_fork_numbers() const; [[nodiscard]] std::vector distinct_fork_times() const; @@ -124,110 +215,110 @@ std::ostream& operator<<(std::ostream& out, const ChainConfig& obj); inline constexpr ChainConfig kEOSEVMMainnetConfig{ .chain_id = 17777, .protocol_rule_set = protocol::RuleSetType::kTrust, - .homestead_block = 0, - .dao_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, + ._homestead_block = 0, + ._dao_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, }; inline constexpr ChainConfig kEOSEVMOldTestnetConfig{ .chain_id = 15555, .protocol_rule_set = protocol::RuleSetType::kTrust, - .homestead_block = 0, - .dao_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, + ._homestead_block = 0, + ._dao_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, }; inline constexpr ChainConfig kEOSEVMTestnetConfig{ .chain_id = 15557, .protocol_rule_set = protocol::RuleSetType::kTrust, - .homestead_block = 0, - .dao_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, + ._homestead_block = 0, + ._dao_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, }; inline constexpr ChainConfig kEOSEVMLocalTestnetConfig{ .chain_id = 25555, .protocol_rule_set = protocol::RuleSetType::kTrust, - .homestead_block = 0, - .dao_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, + ._homestead_block = 0, + ._dao_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, }; inline constexpr evmc::bytes32 kMainnetGenesisHash{0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3_bytes32}; inline constexpr ChainConfig kMainnetConfig{ .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kEthash, - .homestead_block = 1'150'000, - .dao_block = 1'920'000, - .tangerine_whistle_block = 2'463'000, - .spurious_dragon_block = 2'675'000, - .byzantium_block = 4'370'000, - .constantinople_block = 7'280'000, - .petersburg_block = 7'280'000, - .istanbul_block = 9'069'000, - .muir_glacier_block = 9'200'000, - .berlin_block = 12'244'000, - .london_block = 12'965'000, - .arrow_glacier_block = 13'773'000, - .gray_glacier_block = 15'050'000, - .terminal_total_difficulty = intx::from_string("58750000000000000000000"), - .shanghai_time = 1681338455, + ._homestead_block = 1'150'000, + ._dao_block = 1'920'000, + ._tangerine_whistle_block = 2'463'000, + ._spurious_dragon_block = 2'675'000, + ._byzantium_block = 4'370'000, + ._constantinople_block = 7'280'000, + ._petersburg_block = 7'280'000, + ._istanbul_block = 9'069'000, + ._muir_glacier_block = 9'200'000, + ._berlin_block = 12'244'000, + ._london_block = 12'965'000, + ._arrow_glacier_block = 13'773'000, + ._gray_glacier_block = 15'050'000, + ._terminal_total_difficulty = intx::from_string("58750000000000000000000"), + ._shanghai_time = 1681338455, }; inline constexpr evmc::bytes32 kGoerliGenesisHash{0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a_bytes32}; inline constexpr ChainConfig kGoerliConfig{ .chain_id = 5, .protocol_rule_set = protocol::RuleSetType::kClique, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 1'561'651, - .berlin_block = 4'460'644, - .london_block = 5'062'605, - .terminal_total_difficulty = 10790000, - .shanghai_time = 1678832736, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 1'561'651, + ._berlin_block = 4'460'644, + ._london_block = 5'062'605, + ._terminal_total_difficulty = 10790000, + ._shanghai_time = 1678832736, }; inline constexpr evmc::bytes32 kSepoliaGenesisHash{0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9_bytes32}; inline constexpr ChainConfig kSepoliaConfig{ .chain_id = 11155111, .protocol_rule_set = protocol::RuleSetType::kEthash, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .muir_glacier_block = 0, - .berlin_block = 0, - .london_block = 0, - .terminal_total_difficulty = 17000000000000000, - .merge_netsplit_block = 1'735'371, - .shanghai_time = 1677557088, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._muir_glacier_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._terminal_total_difficulty = 17000000000000000, + ._merge_netsplit_block = 1'735'371, + ._shanghai_time = 1677557088, }; //! \brief Looks up a known chain config provided its chain ID diff --git a/silkworm/core/chain/config_test.cpp b/silkworm/core/chain/config_test.cpp index eee945d3..5ff3b916 100644 --- a/silkworm/core/chain/config_test.cpp +++ b/silkworm/core/chain/config_test.cpp @@ -47,62 +47,66 @@ TEST_CASE("Config lookup") { } TEST_CASE("Config revision") { - CHECK(kMainnetConfig.revision(0, 0) == EVMC_FRONTIER); - CHECK(kMainnetConfig.revision(1, 1438269988) == EVMC_FRONTIER); - CHECK(kMainnetConfig.revision(200'000, 1441661589) == EVMC_FRONTIER); - CHECK(kMainnetConfig.revision(1'000'000, 1455404053) == EVMC_FRONTIER); - CHECK(kMainnetConfig.revision(1'149'999, 1457981342) == EVMC_FRONTIER); - CHECK(kMainnetConfig.revision(1'150'000, 1457981393) == EVMC_HOMESTEAD); - CHECK(kMainnetConfig.revision(1'150'001, 1457981402) == EVMC_HOMESTEAD); - CHECK(kMainnetConfig.revision(1'920'000, 1469020840) == EVMC_HOMESTEAD); // DAO fork doesn't have an evmc_revision - CHECK(kMainnetConfig.revision(2'000'000, 1470173578) == EVMC_HOMESTEAD); - CHECK(kMainnetConfig.revision(2'462'999, 1476796747) == EVMC_HOMESTEAD); - CHECK(kMainnetConfig.revision(2'463'000, 1476796771) == EVMC_TANGERINE_WHISTLE); - CHECK(kMainnetConfig.revision(2'463'001, 1476796812) == EVMC_TANGERINE_WHISTLE); - CHECK(kMainnetConfig.revision(2'674'999, 1479831337) == EVMC_TANGERINE_WHISTLE); - CHECK(kMainnetConfig.revision(2'675'000, 1479831344) == EVMC_SPURIOUS_DRAGON); - CHECK(kMainnetConfig.revision(2'675'001, 1479831347) == EVMC_SPURIOUS_DRAGON); - CHECK(kMainnetConfig.revision(3'000'000, 1484475035) == EVMC_SPURIOUS_DRAGON); - CHECK(kMainnetConfig.revision(4'000'000, 1499633567) == EVMC_SPURIOUS_DRAGON); - CHECK(kMainnetConfig.revision(4'369'999, 1508131303) == EVMC_SPURIOUS_DRAGON); - CHECK(kMainnetConfig.revision(4'370'000, 1508131331) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(4'370'001, 1508131362) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(5'000'000, 1517319693) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(6'000'000, 1532118564) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(7'000'000, 1546466952) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(7'279'999, 1551383501) == EVMC_BYZANTIUM); - CHECK(kMainnetConfig.revision(7'280'000, 1551383524) == EVMC_PETERSBURG); - CHECK(kMainnetConfig.revision(7'280'001, 1551383544) == EVMC_PETERSBURG); - CHECK(kMainnetConfig.revision(8'000'000, 1561100149) == EVMC_PETERSBURG); - CHECK(kMainnetConfig.revision(9'000'000, 1574706444) == EVMC_PETERSBURG); - CHECK(kMainnetConfig.revision(9'068'999, 1575764708) == EVMC_PETERSBURG); - CHECK(kMainnetConfig.revision(9'069'000, 1575764709) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(9'069'001, 1575764711) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(9'200'000, 1577953849) == EVMC_ISTANBUL); // Muir Glacier doesn't have an evmc_revision - CHECK(kMainnetConfig.revision(10'000'000, 1588598533) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(11'000'000, 1601957824) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(12'000'000, 1615234816) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(12'243'999, 1618481214) == EVMC_ISTANBUL); - CHECK(kMainnetConfig.revision(12'244'000, 1618481223) == EVMC_BERLIN); - CHECK(kMainnetConfig.revision(12'244'001, 1618481230) == EVMC_BERLIN); - CHECK(kMainnetConfig.revision(12'964'999, 1628166812) == EVMC_BERLIN); - CHECK(kMainnetConfig.revision(12'965'000, 1628166822) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(12'965'001, 1628166835) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(13'000'000, 1628632419) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(13'773'000, 1639079723) == EVMC_LONDON); // Arrow Glacier doesn't have an evmc_revision - CHECK(kMainnetConfig.revision(14'000'000, 1642114795) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(15'000'000, 1655778535) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(15'050'000, 1656586444) == EVMC_LONDON); // Gray Glacier doesn't have an evmc_revision - CHECK(kMainnetConfig.revision(15'537'393, 1663224162) == EVMC_LONDON); // We still use EVMC_LONDON for The Merge, though formally it should be EVMC_PARIS - CHECK(kMainnetConfig.revision(16'000'000, 1668811907) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(17'000'000, 1680911891) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(17'034'869, 1681338443) == EVMC_LONDON); - CHECK(kMainnetConfig.revision(17'034'870, 1681338479) == EVMC_SHANGHAI); - CHECK(kMainnetConfig.revision(17'034'871, 1681338503) == EVMC_SHANGHAI); - CHECK(kMainnetConfig.revision(100'000'000, 3000000000) == EVMC_SHANGHAI); - - CHECK(test::kLondonConfig.revision(0, 0) == EVMC_LONDON); - CHECK(test::kShanghaiConfig.revision(0, 0) == EVMC_SHANGHAI); + auto build_header = [&](uint64_t number, uint64_t ts) { + return BlockHeader{.number=number, .timestamp=ts}; + }; + + CHECK(kMainnetConfig.revision(build_header(0, 0)) == EVMC_FRONTIER); + CHECK(kMainnetConfig.revision(build_header(1, 1438269988)) == EVMC_FRONTIER); + CHECK(kMainnetConfig.revision(build_header(200'000, 1441661589)) == EVMC_FRONTIER); + CHECK(kMainnetConfig.revision(build_header(1'000'000, 1455404053)) == EVMC_FRONTIER); + CHECK(kMainnetConfig.revision(build_header(1'149'999, 1457981342)) == EVMC_FRONTIER); + CHECK(kMainnetConfig.revision(build_header(1'150'000, 1457981393)) == EVMC_HOMESTEAD); + CHECK(kMainnetConfig.revision(build_header(1'150'001, 1457981402)) == EVMC_HOMESTEAD); + CHECK(kMainnetConfig.revision(build_header(1'920'000, 1469020840)) == EVMC_HOMESTEAD); // DAO fork doesn't) have an evmc_revision + CHECK(kMainnetConfig.revision(build_header(2'000'000, 1470173578)) == EVMC_HOMESTEAD); + CHECK(kMainnetConfig.revision(build_header(2'462'999, 1476796747)) == EVMC_HOMESTEAD); + CHECK(kMainnetConfig.revision(build_header(2'463'000, 1476796771)) == EVMC_TANGERINE_WHISTLE); + CHECK(kMainnetConfig.revision(build_header(2'463'001, 1476796812)) == EVMC_TANGERINE_WHISTLE); + CHECK(kMainnetConfig.revision(build_header(2'674'999, 1479831337)) == EVMC_TANGERINE_WHISTLE); + CHECK(kMainnetConfig.revision(build_header(2'675'000, 1479831344)) == EVMC_SPURIOUS_DRAGON); + CHECK(kMainnetConfig.revision(build_header(2'675'001, 1479831347)) == EVMC_SPURIOUS_DRAGON); + CHECK(kMainnetConfig.revision(build_header(3'000'000, 1484475035)) == EVMC_SPURIOUS_DRAGON); + CHECK(kMainnetConfig.revision(build_header(4'000'000, 1499633567)) == EVMC_SPURIOUS_DRAGON); + CHECK(kMainnetConfig.revision(build_header(4'369'999, 1508131303)) == EVMC_SPURIOUS_DRAGON); + CHECK(kMainnetConfig.revision(build_header(4'370'000, 1508131331)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(4'370'001, 1508131362)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(5'000'000, 1517319693)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(6'000'000, 1532118564)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(7'000'000, 1546466952)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(7'279'999, 1551383501)) == EVMC_BYZANTIUM); + CHECK(kMainnetConfig.revision(build_header(7'280'000, 1551383524)) == EVMC_PETERSBURG); + CHECK(kMainnetConfig.revision(build_header(7'280'001, 1551383544)) == EVMC_PETERSBURG); + CHECK(kMainnetConfig.revision(build_header(8'000'000, 1561100149)) == EVMC_PETERSBURG); + CHECK(kMainnetConfig.revision(build_header(9'000'000, 1574706444)) == EVMC_PETERSBURG); + CHECK(kMainnetConfig.revision(build_header(9'068'999, 1575764708)) == EVMC_PETERSBURG); + CHECK(kMainnetConfig.revision(build_header(9'069'000, 1575764709)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(9'069'001, 1575764711)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(9'200'000, 1577953849)) == EVMC_ISTANBUL); // Muir Glacier doesn't) have an evmc_revision + CHECK(kMainnetConfig.revision(build_header(10'000'000, 1588598533)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(11'000'000, 1601957824)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(12'000'000, 1615234816)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(12'243'999, 1618481214)) == EVMC_ISTANBUL); + CHECK(kMainnetConfig.revision(build_header(12'244'000, 1618481223)) == EVMC_BERLIN); + CHECK(kMainnetConfig.revision(build_header(12'244'001, 1618481230)) == EVMC_BERLIN); + CHECK(kMainnetConfig.revision(build_header(12'964'999, 1628166812)) == EVMC_BERLIN); + CHECK(kMainnetConfig.revision(build_header(12'965'000, 1628166822)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(12'965'001, 1628166835)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(13'000'000, 1628632419)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(13'773'000, 1639079723)) == EVMC_LONDON); // Arrow Glacier doesn't) have an evmc_revision + CHECK(kMainnetConfig.revision(build_header(14'000'000, 1642114795)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(15'000'000, 1655778535)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(15'050'000, 1656586444)) == EVMC_LONDON); // Gray Glacier doesn't) have an evmc_revision + CHECK(kMainnetConfig.revision(build_header(15'537'393, 1663224162)) == EVMC_LONDON); // We still use EVMC_LONDON for The Merge, though formally it) should be EVMC_PARIS + CHECK(kMainnetConfig.revision(build_header(16'000'000, 1668811907)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(17'000'000, 1680911891)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(17'034'869, 1681338443)) == EVMC_LONDON); + CHECK(kMainnetConfig.revision(build_header(17'034'870, 1681338479)) == EVMC_SHANGHAI); + CHECK(kMainnetConfig.revision(build_header(17'034'871, 1681338503)) == EVMC_SHANGHAI); + CHECK(kMainnetConfig.revision(build_header(100'000'000, 3000000000)) == EVMC_SHANGHAI); + + CHECK(test::kLondonConfig.revision(build_header(0, 0)) == EVMC_LONDON); + CHECK(test::kShanghaiConfig.revision(build_header(0, 0)) == EVMC_SHANGHAI); } TEST_CASE("distinct_fork_points") { @@ -202,8 +206,8 @@ TEST_CASE("JSON serialization") { const std::optional config2{ChainConfig::from_json(merge_test_json)}; REQUIRE(config2); - CHECK(config2->terminal_total_difficulty == intx::from_string("39387012740608862000000")); - CHECK(config2->merge_netsplit_block == 10000); + CHECK(config2->terminal_total_difficulty() == intx::from_string("39387012740608862000000")); + CHECK(config2->merge_netsplit_block() == 10000); CHECK(config2->to_json() == merge_test_json); } @@ -234,7 +238,7 @@ TEST_CASE("terminalTotalDifficulty as JSON number (Erigon compatibility)") { REQUIRE(config1); CHECK(config1 == kMainnetConfig); CHECK(config1->to_json() != mainnet_json_ttd_number); // "58750000000000000000000" vs 5.875e+22 - CHECK(config1->terminal_total_difficulty == intx::from_string("58750000000000000000000")); + CHECK(config1->terminal_total_difficulty() == intx::from_string("58750000000000000000000")); const auto goerli_json_ttd_number = nlohmann::json::parse(R"({ "chainId":5, @@ -257,7 +261,7 @@ TEST_CASE("terminalTotalDifficulty as JSON number (Erigon compatibility)") { REQUIRE(config2); CHECK(config2 == kGoerliConfig); CHECK(config2->to_json() != goerli_json_ttd_number); // "10790000" vs 10790000 - CHECK(config2->terminal_total_difficulty == intx::from_string("10790000")); + CHECK(config2->terminal_total_difficulty() == intx::from_string("10790000")); const auto sepolia_json_ttd_number = nlohmann::json::parse(R"({ "chainId":11155111, @@ -282,7 +286,7 @@ TEST_CASE("terminalTotalDifficulty as JSON number (Erigon compatibility)") { REQUIRE(config3); CHECK(config3 == kSepoliaConfig); CHECK(config3->to_json() != sepolia_json_ttd_number); // "17000000000000000" vs 17000000000000000 - CHECK(config3->terminal_total_difficulty == intx::from_string("17000000000000000")); + CHECK(config3->terminal_total_difficulty() == intx::from_string("17000000000000000")); } } // namespace silkworm diff --git a/silkworm/core/chain/genesis.cpp b/silkworm/core/chain/genesis.cpp index c507c9d9..c3b75553 100644 --- a/silkworm/core/chain/genesis.cpp +++ b/silkworm/core/chain/genesis.cpp @@ -87,7 +87,7 @@ BlockHeader read_genesis_header(const nlohmann::json& genesis_json, const evmc:: const std::optional chain_config{ChainConfig::from_json(genesis_json["config"])}; SILKWORM_ASSERT(chain_config.has_value()); - if (chain_config->revision(0, header.timestamp) >= EVMC_LONDON) { + if (chain_config->revision(header) >= EVMC_LONDON) { header.base_fee_per_gas = protocol::kInitialBaseFee; } diff --git a/silkworm/core/common/test_util.hpp b/silkworm/core/common/test_util.hpp index 65745f3e..ffd43cc1 100644 --- a/silkworm/core/common/test_util.hpp +++ b/silkworm/core/common/test_util.hpp @@ -33,32 +33,32 @@ inline constexpr ChainConfig kFrontierConfig{ inline constexpr ChainConfig kLondonConfig{ .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, }; //! Enables Shanghai from genesis. inline constexpr ChainConfig kShanghaiConfig{ .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .terminal_total_difficulty = 0, - .shanghai_time = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._terminal_total_difficulty = 0, + ._shanghai_time = 0, }; static const std::map kNetworkConfig{ @@ -67,225 +67,225 @@ static const std::map kNetworkConfig{ { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, + ._homestead_block = 0, }}, {"FrontierToHomesteadAt5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 5, + ._homestead_block = 5, }}, {"HomesteadToDaoAt5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .dao_block = 5, + ._homestead_block = 0, + ._dao_block = 5, }}, {"EIP150", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, }}, {"HomesteadToEIP150At5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 5, + ._homestead_block = 0, + ._tangerine_whistle_block = 5, }}, {"EIP158", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, }}, {"Byzantium", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, }}, {"EIP158ToByzantiumAt5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 5, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 5, }}, {"Constantinople", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, }}, {"ConstantinopleFix", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, }}, {"ByzantiumToConstantinopleFixAt5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 5, - .petersburg_block = 5, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 5, + ._petersburg_block = 5, }}, {"Istanbul", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, }}, {"EIP2384", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .muir_glacier_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._muir_glacier_block = 0, }}, {"Berlin", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .muir_glacier_block = 0, - .berlin_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._muir_glacier_block = 0, + ._berlin_block = 0, }}, {"London", test::kLondonConfig}, {"BerlinToLondonAt5", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .muir_glacier_block = 0, - .berlin_block = 0, - .london_block = 5, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._muir_glacier_block = 0, + ._berlin_block = 0, + ._london_block = 5, }}, {"ArrowGlacier", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .arrow_glacier_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._arrow_glacier_block = 0, }}, {"GrayGlacier", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .gray_glacier_block = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._gray_glacier_block = 0, }}, {"Merge", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .terminal_total_difficulty = 0, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._terminal_total_difficulty = 0, }}, {"ArrowGlacierToMergeAtDiffC0000", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .arrow_glacier_block = 0, - .terminal_total_difficulty = 0xC0000, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._arrow_glacier_block = 0, + ._terminal_total_difficulty = 0xC0000, }}, {"Shanghai", test::kShanghaiConfig}, {"MergeToShanghaiAtTime15k", { .chain_id = 1, .protocol_rule_set = protocol::RuleSetType::kNoProof, - .homestead_block = 0, - .tangerine_whistle_block = 0, - .spurious_dragon_block = 0, - .byzantium_block = 0, - .constantinople_block = 0, - .petersburg_block = 0, - .istanbul_block = 0, - .berlin_block = 0, - .london_block = 0, - .terminal_total_difficulty = 0, - .shanghai_time = 15'000, + ._homestead_block = 0, + ._tangerine_whistle_block = 0, + ._spurious_dragon_block = 0, + ._byzantium_block = 0, + ._constantinople_block = 0, + ._petersburg_block = 0, + ._istanbul_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._terminal_total_difficulty = 0, + ._shanghai_time = 15'000, }}, }; diff --git a/silkworm/core/execution/evm.cpp b/silkworm/core/execution/evm.cpp index 81651dac..ea8d7bcf 100644 --- a/silkworm/core/execution/evm.cpp +++ b/silkworm/core/execution/evm.cpp @@ -331,7 +331,7 @@ evmc_result EVM::execute_with_baseline_interpreter(evmc_revision rev, const evmc } evmc_revision EVM::revision() const noexcept { - return config().revision(block_.header.number, block_.header.timestamp); + return config().revision(block_.header); } void EVM::add_tracer(EvmTracer& tracer) noexcept { diff --git a/silkworm/core/execution/evm_test.cpp b/silkworm/core/execution/evm_test.cpp index f7208e10..941bf09c 100644 --- a/silkworm/core/execution/evm_test.cpp +++ b/silkworm/core/execution/evm_test.cpp @@ -339,7 +339,7 @@ TEST_CASE("EIP-3541: Reject new contracts starting with the 0xEF byte") { Block block; block.header.number = 13'500'000; - REQUIRE(config.revision(block.header.number, block.header.timestamp) == EVMC_LONDON); + REQUIRE(config.revision(block.header) == EVMC_LONDON); InMemoryState db; IntraBlockState state{db}; diff --git a/silkworm/core/execution/processor.cpp b/silkworm/core/execution/processor.cpp index d1377c62..14858322 100644 --- a/silkworm/core/execution/processor.cpp +++ b/silkworm/core/execution/processor.cpp @@ -120,7 +120,8 @@ uint64_t ExecutionProcessor::refund_gas(const Transaction& txn, uint64_t gas_lef ValidationResult ExecutionProcessor::execute_block_no_post_validation(std::vector& receipts) noexcept { const Block& block{evm_.block()}; - if (block.header.number == evm_.config().dao_block) { + // Avoid calling dao_block() when the ruleset is kTrust to prevent triggering an assertion in the dao_block function + if (evm_.config().protocol_rule_set != protocol::RuleSetType::kTrust && block.header.number == evm_.config().dao_block()) { dao::transfer_balances(state_); } diff --git a/silkworm/core/protocol/base_rule_set.cpp b/silkworm/core/protocol/base_rule_set.cpp index 67b829c4..83f94ade 100644 --- a/silkworm/core/protocol/base_rule_set.cpp +++ b/silkworm/core/protocol/base_rule_set.cpp @@ -25,7 +25,7 @@ namespace silkworm::protocol { ValidationResult BaseRuleSet::pre_validate_block_body(const Block& block, const BlockState& state) { const BlockHeader& header{block.header}; - const evmc_revision rev{chain_config_.revision(header.number, header.timestamp)}; + const evmc_revision rev{chain_config_.revision(header)}; const evmc::bytes32 txn_root{compute_transaction_root(block)}; if (txn_root != header.transactions_root) { @@ -152,7 +152,7 @@ ValidationResult BaseRuleSet::validate_block_header(const BlockHeader& header, c } uint64_t parent_gas_limit{parent->gas_limit}; - if (header.number == chain_config_.london_block) { + if (header.number == chain_config_.london_block()) { parent_gas_limit = parent->gas_limit * kElasticityMultiplier; // EIP-1559 } @@ -167,15 +167,16 @@ ValidationResult BaseRuleSet::validate_block_header(const BlockHeader& header, c } // https://eips.ethereum.org/EIPS/eip-779 - if (chain_config_.dao_block.has_value() && chain_config_.dao_block.value() <= header.number && - header.number <= chain_config_.dao_block.value() + 9) { + // Avoid calling dao_block() when the ruleset is kTrust to prevent triggering an assertion in the dao_block function + if (chain_config_.protocol_rule_set != RuleSetType::kTrust && chain_config_.dao_block().has_value() && chain_config_.dao_block().value() <= header.number && + header.number <= chain_config_.dao_block().value() + 9) { static const Bytes kDaoExtraData{*from_hex("0x64616f2d686172642d666f726b")}; if (header.extra_data != kDaoExtraData) { return ValidationResult::kWrongDaoExtraData; } } - const evmc_revision rev{chain_config_.revision(header.number, header.timestamp)}; + const evmc_revision rev{chain_config_.revision(header)}; if (header.base_fee_per_gas != expected_base_fee_per_gas(*parent, rev)) { return ValidationResult::kWrongBaseFee; diff --git a/silkworm/core/protocol/ethash_rule_set.cpp b/silkworm/core/protocol/ethash_rule_set.cpp index 4b568c53..5b3a8bbc 100644 --- a/silkworm/core/protocol/ethash_rule_set.cpp +++ b/silkworm/core/protocol/ethash_rule_set.cpp @@ -42,7 +42,7 @@ ValidationResult EthashRuleSet::validate_seal(const BlockHeader& header) { intx::uint256 EthashRuleSet::difficulty(const BlockHeader& header, const BlockHeader& parent) { const bool parent_has_uncles{parent.ommers_hash != kEmptyListHash}; - return difficulty(header.number, header.timestamp, parent.difficulty, + return difficulty(header, parent.difficulty, parent.timestamp, parent_has_uncles, chain_config_); } @@ -65,7 +65,7 @@ static intx::uint256 block_reward_base(const evmc_revision rev) { BlockReward EthashRuleSet::compute_reward(const ChainConfig& config, const Block& block) { const BlockNum block_number{block.header.number}; - const evmc_revision rev{config.revision(block_number, block.header.timestamp)}; + const evmc_revision rev{config.revision(block.header)}; const intx::uint256 base{block_reward_base(rev)}; intx::uint256 miner_reward{base}; @@ -81,11 +81,12 @@ BlockReward EthashRuleSet::compute_reward(const ChainConfig& config, const Block return {miner_reward, ommer_rewards}; } -intx::uint256 EthashRuleSet::difficulty(uint64_t block_number, const uint64_t block_timestamp, +intx::uint256 EthashRuleSet::difficulty(const BlockHeader& header, const intx::uint256& parent_difficulty, const uint64_t parent_timestamp, const bool parent_has_uncles, const ChainConfig& config) { - const evmc_revision rev{config.revision(block_number, block_timestamp)}; - + auto block_timestamp = header.timestamp; + auto block_number = header.number; + const evmc_revision rev{config.revision(header)}; intx::uint256 difficulty{parent_difficulty}; const intx::uint256 x{parent_difficulty >> 11}; // parent_difficulty / 2048; @@ -115,16 +116,16 @@ intx::uint256 EthashRuleSet::difficulty(uint64_t block_number, const uint64_t bl } uint64_t bomb_delay{0}; - if (config.gray_glacier_block.has_value() && block_number >= config.gray_glacier_block) { + if (config.gray_glacier_block().has_value() && block_number >= config.gray_glacier_block()) { // https://eips.ethereum.org/EIPS/eip-5133 bomb_delay = 11'400'000; - } else if (config.arrow_glacier_block.has_value() && block_number >= config.arrow_glacier_block) { + } else if (config.arrow_glacier_block().has_value() && block_number >= config.arrow_glacier_block()) { // https://eips.ethereum.org/EIPS/eip-4345 bomb_delay = 10'700'000; } else if (rev >= EVMC_LONDON) { // https://eips.ethereum.org/EIPS/eip-3554 bomb_delay = 9'700'000; - } else if (config.muir_glacier_block.has_value() && block_number >= config.muir_glacier_block) { + } else if (config.muir_glacier_block().has_value() && block_number >= config.muir_glacier_block()) { // https://eips.ethereum.org/EIPS/eip-2384 bomb_delay = 9'000'000; } else if (rev >= EVMC_CONSTANTINOPLE) { diff --git a/silkworm/core/protocol/ethash_rule_set.hpp b/silkworm/core/protocol/ethash_rule_set.hpp index 49782cb2..b0eac230 100644 --- a/silkworm/core/protocol/ethash_rule_set.hpp +++ b/silkworm/core/protocol/ethash_rule_set.hpp @@ -47,7 +47,7 @@ class EthashRuleSet : public BaseRuleSet { // Canonical difficulty of a Proof-of-Work block header. // See Section 4.3.4 "Block Header Validity" of the Yellow Paper and also // EIP-2, EIP-100, EIP-649, EIP-1234, EIP-2384, EIP-3554, EIP-4345. - static intx::uint256 difficulty(uint64_t block_number, uint64_t block_timestamp, + static intx::uint256 difficulty(const BlockHeader& header, const intx::uint256& parent_difficulty, uint64_t parent_timestamp, bool parent_has_uncles, const ChainConfig& config); diff --git a/silkworm/core/protocol/ethash_rule_set_test.cpp b/silkworm/core/protocol/ethash_rule_set_test.cpp index 5711828e..f5949dee 100644 --- a/silkworm/core/protocol/ethash_rule_set_test.cpp +++ b/silkworm/core/protocol/ethash_rule_set_test.cpp @@ -27,7 +27,7 @@ TEST_CASE("DifficultyTest34") { uint64_t parent_timestamp{0x04bdbdaf}; bool parent_has_uncles{false}; - intx::uint256 difficulty{EthashRuleSet::difficulty(block_number, block_timestamp, parent_difficulty, parent_timestamp, + intx::uint256 difficulty{EthashRuleSet::difficulty(BlockHeader{.number=block_number,.timestamp=block_timestamp}, parent_difficulty, parent_timestamp, parent_has_uncles, kMainnetConfig)}; CHECK(difficulty == 0x72772897b619876a); } diff --git a/silkworm/core/protocol/merge_rule_set.cpp b/silkworm/core/protocol/merge_rule_set.cpp index b3fd92f8..19255d15 100644 --- a/silkworm/core/protocol/merge_rule_set.cpp +++ b/silkworm/core/protocol/merge_rule_set.cpp @@ -23,7 +23,7 @@ namespace silkworm::protocol { MergeRuleSet::MergeRuleSet(RuleSetPtr pre_merge_rule_set, const ChainConfig& chain_config) : BaseRuleSet{chain_config, /*prohibit_ommers=*/true}, - terminal_total_difficulty_{*chain_config.terminal_total_difficulty}, + terminal_total_difficulty_{*chain_config.terminal_total_difficulty()}, pre_merge_rule_set_{std::move(pre_merge_rule_set)} {} ValidationResult MergeRuleSet::pre_validate_block_body(const Block& block, const BlockState& state) { diff --git a/silkworm/core/protocol/merge_rule_set_test.cpp b/silkworm/core/protocol/merge_rule_set_test.cpp index 225f7e4e..f0274f33 100644 --- a/silkworm/core/protocol/merge_rule_set_test.cpp +++ b/silkworm/core/protocol/merge_rule_set_test.cpp @@ -47,7 +47,7 @@ TEST_CASE("Proof-of-Stake RuleSet") { parent.header.difficulty = 1000; ChainConfig config{kMainnetConfig}; - config.terminal_total_difficulty = parent.header.difficulty; + config._terminal_total_difficulty = parent.header.difficulty; MergeRuleSet rule_set{std::make_unique(config), config}; diff --git a/silkworm/core/protocol/rule_set.cpp b/silkworm/core/protocol/rule_set.cpp index efb36927..e8fa0b19 100644 --- a/silkworm/core/protocol/rule_set.cpp +++ b/silkworm/core/protocol/rule_set.cpp @@ -45,7 +45,7 @@ RuleSetPtr rule_set_factory(const ChainConfig& chain_config) { return nullptr; } - if (chain_config.terminal_total_difficulty) { + if (chain_config.protocol_rule_set != protocol::RuleSetType::kTrust && chain_config.terminal_total_difficulty()) { rule_set = std::make_unique(std::move(rule_set), chain_config); } return rule_set; diff --git a/silkworm/core/protocol/validation.cpp b/silkworm/core/protocol/validation.cpp index 87103af7..8ce40137 100644 --- a/silkworm/core/protocol/validation.cpp +++ b/silkworm/core/protocol/validation.cpp @@ -145,7 +145,7 @@ ValidationResult validate_transaction(const Transaction& txn, const IntraBlockSt ValidationResult pre_validate_transactions(const Block& block, const ChainConfig& config) { const BlockHeader& header{block.header}; - const evmc_revision rev{config.revision(header.number, header.timestamp)}; + const evmc_revision rev{config.revision(header)}; const std::optional data_gas_price{header.data_gas_price()}; for (const Transaction& txn : block.transactions) { diff --git a/silkworm/core/protocol/validation.hpp b/silkworm/core/protocol/validation.hpp index ac6a966c..575fdf4c 100644 --- a/silkworm/core/protocol/validation.hpp +++ b/silkworm/core/protocol/validation.hpp @@ -20,8 +20,8 @@ #include +#include #include -#include #include namespace silkworm { diff --git a/silkworm/core/types/block.hpp b/silkworm/core/types/block.hpp index f5cc3ac0..74e97a96 100644 --- a/silkworm/core/types/block.hpp +++ b/silkworm/core/types/block.hpp @@ -24,7 +24,7 @@ #include #include -#include +//#include #include #include #include diff --git a/silkworm/node/stagedsync/stages/_test.cpp b/silkworm/node/stagedsync/stages/_test.cpp index 7dc5455c..1d070e30 100644 --- a/silkworm/node/stagedsync/stages/_test.cpp +++ b/silkworm/node/stagedsync/stages/_test.cpp @@ -139,10 +139,16 @@ TEST_CASE("Sync Stages") { } SECTION("Senders") { - std::vector block_hashes{ - 0x3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb_bytes32, - 0xb5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510_bytes32, - 0x0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2_bytes32}; + std::vector block_hashes{}; + + auto block_hash = db::write_header_ex(txn, BlockHeader{.number=1}, true); + block_hashes.push_back(block_hash); + + block_hash = db::write_header_ex(txn, BlockHeader{.number=2}, true); + block_hashes.push_back(block_hash); + + block_hash = db::write_header_ex(txn, BlockHeader{.number=3}, true); + block_hashes.push_back(block_hash); auto sample_transactions{test::sample_transactions()}; diff --git a/silkworm/node/stagedsync/stages/stage_senders.cpp b/silkworm/node/stagedsync/stages/stage_senders.cpp index 935245be..1a757225 100644 --- a/silkworm/node/stagedsync/stages/stage_senders.cpp +++ b/silkworm/node/stagedsync/stages/stage_senders.cpp @@ -294,6 +294,11 @@ Stage::Result Senders::parallel_recover(db::RWTxn& txn) { auto current_hash = db::read_canonical_hash(txn, current_block_num); if (!current_hash) throw StageError(Stage::Result::kBadChainSequence, "Canonical hash at height " + std::to_string(current_block_num) + " not found"); + + auto header = db::read_header(txn, current_block_num, *current_hash); + if (!header) throw StageError(Stage::Result::kBadChainSequence, + "Canonical header at height " + std::to_string(current_block_num) + " not found"); + BlockBody block_body; auto found = data_model.read_body(*current_hash, current_block_num, block_body); if (!found) throw StageError(Stage::Result::kBadChainSequence, @@ -308,7 +313,7 @@ Stage::Result Senders::parallel_recover(db::RWTxn& txn) { if (block_body.transactions.empty()) continue; total_collected_senders += block_body.transactions.size(); - success_or_throw(add_to_batch(current_block_num, *current_hash, std::move(block_body.transactions))); + success_or_throw(add_to_batch(*header, current_block_num, *current_hash, std::move(block_body.transactions))); // Process batch in parallel if max size has been reached if (batch_->size() >= max_batch_size_) { @@ -356,13 +361,13 @@ Stage::Result Senders::parallel_recover(db::RWTxn& txn) { return ret; } -Stage::Result Senders::add_to_batch(BlockNum block_num, Hash block_hash, std::vector&& transactions) { +Stage::Result Senders::add_to_batch(const BlockHeader& header, BlockNum block_num, Hash block_hash, std::vector&& transactions) { if (is_stopping()) { return Stage::Result::kAborted; } // We're only interested in revisions up to London, so it's OK to not detect time-based forks. - const evmc_revision rev{node_settings_->chain_config->revision(block_num, /*block_time=*/0)}; + const evmc_revision rev{node_settings_->chain_config->revision(header)}; const bool has_homestead{rev >= EVMC_HOMESTEAD}; const bool has_spurious_dragon{rev >= EVMC_SPURIOUS_DRAGON}; diff --git a/silkworm/node/stagedsync/stages/stage_senders.hpp b/silkworm/node/stagedsync/stages/stage_senders.hpp index 6bf32695..6cb9c33e 100644 --- a/silkworm/node/stagedsync/stages/stage_senders.hpp +++ b/silkworm/node/stagedsync/stages/stage_senders.hpp @@ -58,7 +58,7 @@ class Senders final : public Stage { private: Stage::Result parallel_recover(db::RWTxn& txn); - Stage::Result add_to_batch(BlockNum block_num, Hash block_hash, std::vector&& transactions); + Stage::Result add_to_batch(const BlockHeader& header, BlockNum block_num, Hash block_hash, std::vector&& transactions); void recover_batch(ThreadPool& worker_pool, secp256k1_context* context); void collect_senders(); void collect_senders(std::shared_ptr& batch); diff --git a/silkworm/silkrpc/commands/engine_api.cpp b/silkworm/silkrpc/commands/engine_api.cpp index a6137259..aeb4f701 100644 --- a/silkworm/silkrpc/commands/engine_api.cpp +++ b/silkworm/silkrpc/commands/engine_api.cpp @@ -262,17 +262,17 @@ awaitable EngineRpcApi::handle_engine_new_payload_v2(const nlohmann::json& const auto config = silkworm::ChainConfig::from_json(chain_config.config); ensure(config.has_value(), "execution layer has invalid configuration"); - ensure(config->shanghai_time.has_value(), "execution layer has no Shanghai timestamp in configuration"); + ensure(config->shanghai_time().has_value(), "execution layer has no Shanghai timestamp in configuration"); // We MUST check that CL has sent the expected ExecutionPayload version [Specification for params] - if (payload.timestamp < config->shanghai_time and payload.version != ExecutionPayload::V1) { + if (payload.timestamp < config->shanghai_time() and payload.version != ExecutionPayload::V1) { const auto error_msg = "consensus layer must use ExecutionPayloadV1 if timestamp lower than Shanghai"; SILK_ERROR << error_msg; reply = make_json_error(request.at("id"), kInvalidParams, error_msg); co_await tx->close(); co_return; } - if (payload.timestamp >= config->shanghai_time and payload.version != ExecutionPayload::V2) { + if (payload.timestamp >= config->shanghai_time() and payload.version != ExecutionPayload::V2) { const auto error_msg = "consensus layer must use ExecutionPayloadV2 if timestamp greater or equal to Shanghai"; SILK_ERROR << error_msg; reply = make_json_error(request.at("id"), kInvalidParams, error_msg); @@ -383,16 +383,16 @@ awaitable EngineRpcApi::handle_engine_forkchoice_updated_v2(const nlohmann const auto config = silkworm::ChainConfig::from_json(chain_config.config); ensure(config.has_value(), "execution layer has invalid configuration"); - ensure(config->shanghai_time.has_value(), "execution layer has no Shanghai timestamp in configuration"); + ensure(config->shanghai_time().has_value(), "execution layer has no Shanghai timestamp in configuration"); // We MUST check that CL has sent the expected PayloadAttributes version [Specification for params] - if (attributes.timestamp < config->shanghai_time and attributes.version != PayloadAttributes::V1) { + if (attributes.timestamp < config->shanghai_time() and attributes.version != PayloadAttributes::V1) { const auto error_msg = "consensus layer must use PayloadAttributesV1 if timestamp lower than Shanghai"; SILK_ERROR << error_msg; reply = make_json_error(request.at("id"), kInvalidParams, error_msg); co_return; } - if (attributes.timestamp >= config->shanghai_time and attributes.version != PayloadAttributes::V2) { + if (attributes.timestamp >= config->shanghai_time() and attributes.version != PayloadAttributes::V2) { const auto error_msg = "consensus layer must use PayloadAttributesV2 if timestamp greater or equal to Shanghai"; SILK_ERROR << error_msg; reply = make_json_error(request.at("id"), kInvalidParams, error_msg); @@ -437,12 +437,12 @@ awaitable EngineRpcApi::handle_engine_exchange_transition_configuration_v1 SILK_DEBUG << "chain config: " << chain_config; const auto config = silkworm::ChainConfig::from_json(chain_config.config); ensure(config.has_value(), "execution layer has invalid configuration"); - ensure(config->terminal_total_difficulty.has_value(), "execution layer does not have terminal total difficulty"); + ensure(config->terminal_total_difficulty().has_value(), "execution layer does not have terminal total difficulty"); // We SHOULD check for any configuration mismatch except `terminalBlockNumber` [Specification 2.] - if (config->terminal_total_difficulty != cl_configuration.terminal_total_difficulty) { + if (config->terminal_total_difficulty() != cl_configuration.terminal_total_difficulty) { SILK_ERROR << "execution layer has the incorrect terminal total difficulty, expected: " - << cl_configuration.terminal_total_difficulty << " got: " << config->terminal_total_difficulty.value(); + << cl_configuration.terminal_total_difficulty << " got: " << config->terminal_total_difficulty().value(); reply = make_json_error(request.at("id"), kInvalidParams, "consensus layer terminal total difficulty does not match"); co_await tx->close(); co_return; @@ -457,7 +457,7 @@ awaitable EngineRpcApi::handle_engine_exchange_transition_configuration_v1 // We MUST respond with configurable setting values set according to EIP-3675 [Specification 1.] const TransitionConfiguration transition_configuration{ - .terminal_total_difficulty = config->terminal_total_difficulty.value(), + .terminal_total_difficulty = config->terminal_total_difficulty().value(), .terminal_block_hash = kZeroHash, // terminal_block_hash removed from chain_config, return zero .terminal_block_number = 0 // terminal_block_number removed from chain_config, return zero }; diff --git a/silkworm/silkrpc/commands/ots_api.cpp b/silkworm/silkrpc/commands/ots_api.cpp index 0a266698..22e213e5 100644 --- a/silkworm/silkrpc/commands/ots_api.cpp +++ b/silkworm/silkrpc/commands/ots_api.cpp @@ -663,7 +663,7 @@ intx::uint256 OtsRpcApi::get_block_fees(const ChainConfig& chain_config, const s auto txn = block.block.transactions[receipt.tx_index]; intx::uint256 effective_gas_price; - if (config.london_block && block_number >= config.london_block.value()) { + if (config.london_block() && block_number >= config.london_block().value()) { intx::uint256 base_fee = block.block.header.base_fee_per_gas.value_or(0); intx::uint256 gas_price = txn.effective_gas_price(base_fee); effective_gas_price = base_fee + gas_price; diff --git a/silkworm/silkrpc/core/fee_history_oracle.cpp b/silkworm/silkrpc/core/fee_history_oracle.cpp index b9b8f61f..da63d656 100644 --- a/silkworm/silkrpc/core/fee_history_oracle.cpp +++ b/silkworm/silkrpc/core/fee_history_oracle.cpp @@ -149,7 +149,7 @@ boost::asio::awaitable FeeHistoryOracle::process_block(BlockFees& block_fe const auto parent_block = co_await block_provider_(header.number - 1); - const auto evmc_revision = config_.revision(parent_block->block.header.number, parent_block->block.header.timestamp); + const auto evmc_revision = config_.revision(parent_block->block.header); block_fees.next_base_fee = protocol::expected_base_fee_per_gas(parent_block->block.header, evmc_revision).value_or(0); if (reward_percentile.size() == 0) { diff --git a/silkworm/sync/internals/chain_fork_view.cpp b/silkworm/sync/internals/chain_fork_view.cpp index e500eb2f..cbab5c16 100644 --- a/silkworm/sync/internals/chain_fork_view.cpp +++ b/silkworm/sync/internals/chain_fork_view.cpp @@ -33,7 +33,7 @@ void ChainForkView::reset_head(ChainHead new_head) { td_cache_.put(current_head_.hash, current_head_.total_difficulty); } -ChainHead ChainForkView::head_at_genesis(const ChainConfig& chain_config) { +ChainHead ChainForkView::head_at_genesis(const silkworm::ChainConfig& chain_config) { bool allow_exceptions = false; auto source_data = read_genesis_data(chain_config.chain_id); auto genesis_json = nlohmann::json::parse(source_data, nullptr, allow_exceptions); diff --git a/silkworm/sync/internals/chain_fork_view.hpp b/silkworm/sync/internals/chain_fork_view.hpp index b3f312f7..8bce9558 100644 --- a/silkworm/sync/internals/chain_fork_view.hpp +++ b/silkworm/sync/internals/chain_fork_view.hpp @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -51,7 +52,7 @@ class ChainForkView { std::optional get_total_difficulty(const Hash& hash); std::optional get_total_difficulty(BlockNum height, const Hash& hash); - static ChainHead head_at_genesis(const ChainConfig& chain_config); + static ChainHead head_at_genesis(const silkworm::ChainConfig& chain_config); private: ChainHead initial_head_{}; diff --git a/silkworm/sync/sync.cpp b/silkworm/sync/sync.cpp index 99eb48b3..5e4b6f09 100644 --- a/silkworm/sync/sync.cpp +++ b/silkworm/sync/sync.cpp @@ -33,7 +33,7 @@ Sync::Sync(boost::asio::io_context& io_context, : sync_sentry_client_{io_context, sentry_client}, block_exchange_{sync_sentry_client_, db::ROAccess{chaindata_env}, config} { // If terminal total difficulty is present in chain config, the network will use Proof-of-Stake sooner or later - if (config.terminal_total_difficulty) { + if (config.terminal_total_difficulty()) { // Configure and activate the Execution Layer Engine API RPC server rpc::DaemonSettings engine_rpc_settings{ .log_settings = { diff --git a/silkworm/sync/sync_pos.cpp b/silkworm/sync/sync_pos.cpp index 22666df2..d0f22cbf 100644 --- a/silkworm/sync/sync_pos.cpp +++ b/silkworm/sync/sync_pos.cpp @@ -156,7 +156,7 @@ std::shared_ptr PoSSync::make_execution_block(const rpc::ExecutionPayload } void PoSSync::do_sanity_checks(const BlockHeader&, /*const BlockHeader& parent,*/ TotalDifficulty parent_td) { - auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty; + auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty(); if (parent_td < terminal_total_difficulty) throw PayloadValidationError("ignoring pre-merge payload"); @@ -177,7 +177,7 @@ auto PoSSync::new_payload(const rpc::ExecutionPayload& payload) -> asio::awaitab // Implementation of engine_new_payloadVx method using namespace execution; constexpr evmc::bytes32 kZeroHash = 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32; - auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty; + auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty(); auto no_latest_valid_hash = std::nullopt; try { @@ -265,7 +265,7 @@ auto PoSSync::fork_choice_update(const rpc::ForkChoiceState& state, // Implementation of engine_forkchoiceUpdatedVx method using namespace execution; constexpr evmc::bytes32 kZeroHash = 0x0000000000000000000000000000000000000000000000000000000000000000_bytes32; - auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty; + auto terminal_total_difficulty = block_exchange_.chain_config().terminal_total_difficulty(); auto no_latest_valid_hash = std::nullopt; auto no_payload_id = std::nullopt; try {