diff --git a/include/evm_runtime/test/block_info.hpp b/include/evm_runtime/test/block_info.hpp index ed4fc936..abc97cfb 100644 --- a/include/evm_runtime/test/block_info.hpp +++ b/include/evm_runtime/test/block_info.hpp @@ -16,7 +16,8 @@ struct block_info { uint64_t gasLimit; uint64_t number; uint64_t timestamp; - //std::optional base_fee_per_gas; + std::optional base_fee_per_gas; + bytes mixhash; BlockHeader get_block_header()const { address beneficiary; @@ -30,13 +31,15 @@ struct block_info { res.number = number; res.timestamp = timestamp; - //if(base_fee_per_gas.has_value()) res.base_fee_per_gas = to_uint256(*base_fee_per_gas); + check(mixhash.size() == 32, "invalid mixhash"); + memcpy(res.prev_randao.bytes, mixhash.data(), mixhash.size()); + + if(base_fee_per_gas.has_value()) res.base_fee_per_gas = to_uint256(*base_fee_per_gas); return res; } - //EOSLIB_SERIALIZE(block_info,(coinbase)(difficulty)(gasLimit)(number)(timestamp)(base_fee_per_gas)) - EOSLIB_SERIALIZE(block_info,(coinbase)(difficulty)(gasLimit)(number)(timestamp)) + EOSLIB_SERIALIZE(block_info,(coinbase)(difficulty)(gasLimit)(number)(timestamp)(base_fee_per_gas)(mixhash)) }; } //namespace test diff --git a/include/evm_runtime/test/config.hpp b/include/evm_runtime/test/config.hpp index bf8af1c0..8699ba8c 100644 --- a/include/evm_runtime/test/config.hpp +++ b/include/evm_runtime/test/config.hpp @@ -15,6 +15,13 @@ inline constexpr ChainConfig kTestNetwork{ ._constantinople_block = 0, ._petersburg_block = 0, ._istanbul_block = 0, + ._muir_glacier_block = 0, + ._berlin_block = 0, + ._london_block = 0, + ._arrow_glacier_block = 0, + ._gray_glacier_block = 0, + ._terminal_total_difficulty = 0, + ._shanghai_time = 0 }; } //namespace test diff --git a/include/evm_runtime/test/engine.hpp b/include/evm_runtime/test/engine.hpp index 866ccf59..1ff65d91 100644 --- a/include/evm_runtime/test/engine.hpp +++ b/include/evm_runtime/test/engine.hpp @@ -36,8 +36,10 @@ class engine : public silkworm::protocol::IRuleSet { miner_reward += block_reward / 32; } - eosio::print("add balance to beneficiary\n"); - state.add_to_balance(block.header.beneficiary, miner_reward); + if(revision < EVMC_PARIS) { + eosio::print("add balance to beneficiary\n"); + state.add_to_balance(block.header.beneficiary, miner_reward); + } } //! \brief Performs validation of block body that can be done prior to sender recovery and execution. diff --git a/tests/evm_runtime_tests.cpp b/tests/evm_runtime_tests.cpp index edbf20eb..be21574c 100644 --- a/tests/evm_runtime_tests.cpp +++ b/tests/evm_runtime_tests.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,8 @@ #include #include +#include + using namespace eosio_system; using namespace eosio; using namespace std; @@ -231,7 +234,8 @@ struct block_info { uint64_t gasLimit; uint64_t number; uint64_t timestamp; - //fc::optional base_fee_per_gas; + std::optional base_fee_per_gas; + bytes mixhash; static block_info create(const Block& block) { block_info bi; @@ -240,15 +244,15 @@ struct block_info { bi.gasLimit = block.header.gas_limit; bi.number = block.header.number; bi.timestamp = block.header.timestamp; + bi.mixhash = to_bytes(block.header.prev_randao); - // if(block.header.base_fee_per_gas.has_value()) - // bi.base_fee_per_gas = to_bytes(*block.header.base_fee_per_gas); + if(block.header.base_fee_per_gas.has_value()) + bi.base_fee_per_gas = to_bytes(*block.header.base_fee_per_gas); return bi; } }; -//FC_REFLECT(block_info, (coinbase)(difficulty)(gasLimit)(number)(timestamp)(base_fee_per_gas)); -FC_REFLECT(block_info, (coinbase)(difficulty)(gasLimit)(number)(timestamp)); +FC_REFLECT(block_info, (coinbase)(difficulty)(gasLimit)(number)(timestamp)(base_fee_per_gas)(mixhash)); struct account { uint64_t id; @@ -398,8 +402,42 @@ struct assert_message_check { } }; +namespace silkworm { namespace rlp { +DecodingResult decode_legacy(ByteView& from, Block& to, Leftover mode=silkworm::rlp::Leftover::kProhibit) noexcept { + const auto rlp_head{decode_header(from)}; + if (!rlp_head) { + return tl::unexpected{rlp_head.error()}; + } + if (!rlp_head->list) { + return tl::unexpected{DecodingError::kUnexpectedString}; + } + const uint64_t leftover{from.length() - rlp_head->payload_length}; + if (mode != Leftover::kAllow && leftover) { + return tl::unexpected{DecodingError::kInputTooLong}; + } + + if (DecodingResult res{silkworm::rlp::decode_items(from, to.header, to.transactions, to.ommers)}; !res) { + return res; + } + + to.withdrawals = std::nullopt; + if (from.length() > leftover) { + std::vector withdrawals; + if (DecodingResult res{silkworm::rlp::decode(from, withdrawals, Leftover::kAllow)}; !res) { + return res; + } + to.withdrawals = withdrawals; + } + + if (from.length() != leftover) { + return tl::unexpected{DecodingError::kUnexpectedListElements}; + } + return {}; +} +}} + struct evm_runtime_tester : eosio_system_tester, silkworm::State { - + abi_serializer evm_runtime_abi; std::map< name, private_key> key_map; bool is_verbose = false; @@ -884,7 +922,7 @@ struct evm_runtime_tester : eosio_system_tester, silkworm::State { Block block; ByteView view{*rlp}; - if (!rlp::decode(view, block) || !view.empty()) { + if (!rlp::decode_legacy(view, block) || !view.empty()) { if (invalid) { dlog("invalid=kPassed 2"); return Status::kPassed; @@ -946,6 +984,7 @@ struct evm_runtime_tester : eosio_system_tester, silkworm::State { } bool post_check(const nlohmann::json& expected) { + if (number_of_accounts() != expected.size()) { std::cout << "Account number mismatch: " << number_of_accounts() << " != " << expected.size() << std::endl; @@ -1019,10 +1058,10 @@ struct evm_runtime_tester : eosio_system_tester, silkworm::State { RunResults blockchain_test(const std::string& test_name, const nlohmann::json& json_test) { //mod_exp restriction: exponent bit size cannot exceed bit size of either base or modulus - if( test_name == "modexp_d27g0v0_Istanbul" || - test_name == "modexp_d27g1v0_Istanbul" || - test_name == "modexp_d27g2v0_Istanbul" || - test_name == "modexp_d27g3v0_Istanbul" ) { + if( test_name == "modexp_d27g0v0_Shanghai" || + test_name == "modexp_d27g1v0_Shanghai" || + test_name == "modexp_d27g2v0_Shanghai" || + test_name == "modexp_d27g3v0_Shanghai" ) { return Status::kSkipped; } @@ -1069,7 +1108,7 @@ struct evm_runtime_tester : eosio_system_tester, silkworm::State { std::string network{json_test["network"].get()}; //Only Istanbul - if(network != "Istanbul") continue; + if(network != "Shanghai") continue; const RunResults r{(*this.*runner)(test.key(), json_test)}; total += r; diff --git a/tests/skip_list.txt b/tests/skip_list.txt index 7ab69ab5..0720ac91 100644 --- a/tests/skip_list.txt +++ b/tests/skip_list.txt @@ -59,4 +59,8 @@ #BlockchainTests/GeneralStateTests/stZeroKnowledge #BlockchainTests/GeneralStateTests/stAttackTest #BlockchainTests/GeneralStateTests/stEIP1559 -#BlockchainTests/GeneralStateTests/stMemoryStressTest \ No newline at end of file +#BlockchainTests/GeneralStateTests/stMemoryStressTest +#BlockchainTests/GeneralStateTests/Shanghai +#BlockchainTests/GeneralStateTests/Shanghai/stEIP3651-warmcoinbase +#BlockchainTests/GeneralStateTests/Shanghai/stEIP3860-limitmeterinitcode +#BlockchainTests/GeneralStateTests/Shanghai/stEIP3855-push0