diff --git a/circle.yml b/circle.yml index e4312be3ab..5ed32911fb 100644 --- a/circle.yml +++ b/circle.yml @@ -19,7 +19,7 @@ commands: steps: - restore_cache: name: "Restore Silkworm cache" - key: &silkworm-cache-key silkworm-20210413 + key: &silkworm-cache-key silkworm-eip-3198-20210529 - run: name: "Check Silkworm cache" command: | @@ -38,8 +38,8 @@ commands: working_directory: ~/silkworm/src command: | [ "$SILKWORM_BUILD" = true ] || exit 0 - git clone --no-checkout --single-branch https://github.com/torquem-ch/silkworm.git . - git checkout 3388d3ef7ba37ca440707a96a7d2886989073a59 + git clone --no-checkout --single-branch https://github.com/torquem-ch/silkworm.git . --branch eip-3198 + git checkout 07a4b7ab2849dc759249b204a455e309ab096412 git submodule update --init --recursive --depth=1 --progress - run: name: "Configure Silkworm" diff --git a/evmc b/evmc index 53f1fea70f..17fd712701 160000 --- a/evmc +++ b/evmc @@ -1 +1 @@ -Subproject commit 53f1fea70ff9e04887b11e34cdf7baab0d4be46c +Subproject commit 17fd712701502ffe0588df34f006a7ef3d2f954e diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index e9b5f5dcc1..5bce7a8b89 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -345,6 +345,9 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana case OP_SELFBALANCE: selfbalance(state); break; + case OP_BASEFEE: + basefee(state); + break; case OP_POP: pop(state.stack); diff --git a/lib/evmone/instruction_traits.hpp b/lib/evmone/instruction_traits.hpp index f2b094c36a..53044c7025 100644 --- a/lib/evmone/instruction_traits.hpp +++ b/lib/evmone/instruction_traits.hpp @@ -94,6 +94,7 @@ constexpr inline std::array traits = []() noexcept { table[OP_GASLIMIT] = {"GASLIMIT", 0, 1}; table[OP_CHAINID] = {"CHAINID", 0, 1}; table[OP_SELFBALANCE] = {"SELFBALANCE", 0, 1}; + table[OP_BASEFEE] = {"BASEFEE", 0, 1}; table[OP_POP] = {"POP", 1, -1}; table[OP_MLOAD] = {"MLOAD", 1, 0}; @@ -365,6 +366,7 @@ constexpr inline std::array gas_costs = []() noexcept template <> constexpr inline std::array gas_costs = []() noexcept { auto table = gas_costs; + table[OP_BASEFEE] = 2; return table; }(); diff --git a/lib/evmone/instructions.cpp b/lib/evmone/instructions.cpp index f44539614a..302f7d5bb9 100644 --- a/lib/evmone/instructions.cpp +++ b/lib/evmone/instructions.cpp @@ -253,6 +253,7 @@ constexpr std::array instruction_implementations = []( table[OP_GASLIMIT] = op; table[OP_CHAINID] = op; table[OP_SELFBALANCE] = op; + table[OP_BASEFEE] = op; table[OP_POP] = op; table[OP_MLOAD] = op; diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 3003de1bec..10fb59cb76 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -403,6 +403,11 @@ inline void gasprice(ExecutionState& state) noexcept state.stack.push(intx::be::load(state.host.get_tx_context().tx_gas_price)); } +inline void basefee(ExecutionState& state) noexcept +{ + state.stack.push(intx::be::load(state.host.get_tx_context().block_base_fee)); +} + inline evmc_status_code extcodesize(ExecutionState& state) noexcept { auto& x = state.stack.top(); diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index 54940c2b56..a7e60aa506 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(evmone-unittests evm_test.cpp evm_calls_test.cpp evm_eip2929_test.cpp + evm_eip3198_basefee_test.cpp evm_state_test.cpp evm_other_test.cpp evmone_test.cpp diff --git a/test/unittests/evm_eip3198_basefee_test.cpp b/test/unittests/evm_eip3198_basefee_test.cpp new file mode 100644 index 0000000000..74607b489c --- /dev/null +++ b/test/unittests/evm_eip3198_basefee_test.cpp @@ -0,0 +1,34 @@ +// evmone: Fast Ethereum Virtual Machine implementation +// Copyright 2021 The evmone Authors. +// SPDX-License-Identifier: Apache-2.0 + +/// This file contains EVM unit tests for EIP-3198 "BASEFEE opcode" +/// https://eips.ethereum.org/EIPS/eip-3198 + +#include "evm_fixture.hpp" + +using namespace evmc::literals; +using evmone::test::evm; + +TEST_P(evm, basefee_pre_london) +{ + rev = EVMC_BERLIN; + const auto code = bytecode{OP_BASEFEE}; + + execute(code); + EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION); +} + +TEST_P(evm, basefee_nominal_case) +{ + // https://eips.ethereum.org/EIPS/eip-3198#nominal-case + rev = EVMC_LONDON; + host.tx_context.block_base_fee = evmc::bytes32{7}; + + execute(bytecode{} + OP_BASEFEE + OP_STOP); + EXPECT_GAS_USED(EVMC_SUCCESS, 2); + + execute(bytecode{} + OP_BASEFEE + ret_top()); + EXPECT_GAS_USED(EVMC_SUCCESS, 17); + EXPECT_OUTPUT_INT(7); +}