diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 979ce5770d..9e5d64e8d5 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -781,6 +781,11 @@ inline void gas(StackTop stack, ExecutionState& state) noexcept stack.push(state.gas_left); } +inline void push0(StackTop stack) noexcept +{ + stack.push({}); +} + template inline uint64_t load_partial_push_data(code_iterator pos) noexcept diff --git a/lib/evmone/instructions_xmacro.hpp b/lib/evmone/instructions_xmacro.hpp index 28256c82f3..f536fc41ad 100644 --- a/lib/evmone/instructions_xmacro.hpp +++ b/lib/evmone/instructions_xmacro.hpp @@ -68,6 +68,7 @@ X(OP_MSIZE, msize) \ X(OP_GAS, gas) \ X(OP_JUMPDEST, jumpdest) \ + X(OP_PUSH0, push0) \ X(OP_PUSH1, push<1>) \ X(OP_PUSH2, push<2>) \ X(OP_PUSH3, push<3>) \ diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index b32e81e6e5..4d66f453e8 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(evmone-unittests evm_calls_test.cpp evm_eip2929_test.cpp evm_eip3198_basefee_test.cpp + evm_eip3855_push0_test.cpp evm_memory_test.cpp evm_state_test.cpp evm_other_test.cpp diff --git a/test/unittests/evm_eip3855_push0_test.cpp b/test/unittests/evm_eip3855_push0_test.cpp new file mode 100644 index 0000000000..77caac312b --- /dev/null +++ b/test/unittests/evm_eip3855_push0_test.cpp @@ -0,0 +1,50 @@ +// evmone: Fast Ethereum Virtual Machine implementation +// Copyright 2022 The evmone Authors. +// SPDX-License-Identifier: Apache-2.0 + +/// This file contains EVM unit tests for EIP-3855 "PUSH0 instruction" +/// https://eips.ethereum.org/EIPS/eip-3855 + +#include "evm_fixture.hpp" + +using namespace evmc::literals; +using evmone::test::evm; + +TEST_P(evm, push0_pre_shanghai) +{ + rev = EVMC_PARIS; + const auto code = bytecode{OP_PUSH0}; + + execute(code); + EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION); +} + +TEST_P(evm, push0) +{ + rev = EVMC_SHANGHAI; + execute(OP_PUSH0 + ret_top()); + EXPECT_GAS_USED(EVMC_SUCCESS, 17); + EXPECT_OUTPUT_INT(0); +} + +TEST_P(evm, push0_return_empty) +{ + rev = EVMC_SHANGHAI; + execute(bytecode{} + OP_PUSH0 + OP_PUSH0 + OP_RETURN); + EXPECT_GAS_USED(EVMC_SUCCESS, 4); + EXPECT_EQ(result.output_size, 0); +} + +TEST_P(evm, push0_full_stack) +{ + rev = EVMC_SHANGHAI; + execute(1024 * bytecode{OP_PUSH0}); + EXPECT_GAS_USED(EVMC_SUCCESS, 1024 * 2); +} + +TEST_P(evm, push0_stack_overflow) +{ + rev = EVMC_SHANGHAI; + execute(1025 * bytecode{OP_PUSH0}); + EXPECT_STATUS(EVMC_STACK_OVERFLOW); +}