Skip to content

Commit

Permalink
EOF execution unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Jun 1, 2021
1 parent 772fc36 commit 9233479
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_executable(evmone-unittests
evm_calls_test.cpp
evm_eip2929_test.cpp
evm_eip3198_basefee_test.cpp
evm_eof_test.cpp
evm_state_test.cpp
evm_other_test.cpp
evmone_test.cpp
Expand Down
163 changes: 163 additions & 0 deletions test/unittests/evm_eof_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2021 The evmone Authors.
// SPDX-License-Identifier: Apache-2.0

#include "evm_fixture.hpp"

using evmone::test::evm;

TEST_P(evm, eof_execution)
{
const auto code = eof_bytecode(OP_STOP);

rev = EVMC_LONDON;
execute(code);
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);

rev = EVMC_SHANGHAI;
execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
}

TEST_P(evm, eof_execution_with_data_section)
{
rev = EVMC_SHANGHAI;
// data section contains ret(0, 1)
const auto code = eof_bytecode(mstore8(0, 1), ret(0, 1));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(result.output_size, 0);
}

TEST_P(evm, eof_pc)
{
rev = EVMC_SHANGHAI;
const auto code = eof_bytecode(OP_PC + mstore8(0) + ret(0, 1));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 8);
}

TEST_P(evm, eof_jump_inside_code_section)
{
rev = EVMC_SHANGHAI;
auto code = eof_bytecode(jump(12) + OP_INVALID + OP_JUMPDEST + mstore8(0, 1) + ret(0, 1));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 1);

code =
eof_bytecode(jump(15) + OP_INVALID + OP_JUMPDEST + mstore8(0, 1) + ret(0, 1), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 1);
}

TEST_P(evm, eof_jump_into_header)
{
rev = EVMC_SHANGHAI;
// data section is of size 0x5b = OP_JUMPDEST
const auto code = eof_bytecode(jump(9), 0x5b * bytecode{0});

execute(code);
EXPECT_STATUS(EVMC_BAD_JUMP_DESTINATION);
}

TEST_P(evm, eof_jump_into_data_section)
{
rev = EVMC_SHANGHAI;
// data section contains OP_JUMPDEST + mstore8(0, 1) + ret(0, 1)
const auto code = eof_bytecode(jump(15), OP_JUMPDEST + mstore8(0, 1) + ret(0, 1));

execute(code);
EXPECT_STATUS(EVMC_BAD_JUMP_DESTINATION);
}

TEST_P(evm, eof_codesize)
{
rev = EVMC_SHANGHAI;
auto code = eof_bytecode(mstore8(0, OP_CODESIZE) + ret(0, 1));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 17);

code = eof_bytecode(mstore8(0, OP_CODESIZE) + ret(0, 1), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
ASSERT_EQ(result.output_size, 1);
EXPECT_EQ(result.output_data[0], 24);
}

TEST_P(evm, eof_codecopy_full)
{
rev = EVMC_SHANGHAI;
auto code = eof_bytecode(bytecode{20} + 0 + 0 + OP_CODECOPY + ret(0, 20));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(bytes_view(result.output_data, result.output_size),
from_hex("efcafe0101000c006014600060003960146000f3"));

code = eof_bytecode(bytecode{27} + 0 + 0 + OP_CODECOPY + ret(0, 27), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(bytes_view(result.output_data, result.output_size),
from_hex("efcafe0101000c02000400601b6000600039601b6000f3deadbeef"));
}

TEST_P(evm, eof_codecopy_header)
{
rev = EVMC_SHANGHAI;
auto code = eof_bytecode(bytecode{8} + 0 + 0 + OP_CODECOPY + ret(0, 8));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(bytes_view(result.output_data, result.output_size), from_hex("efcafe0101000c00"));

code = eof_bytecode(bytecode{11} + 0 + 0 + OP_CODECOPY + ret(0, 11), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(
bytes_view(result.output_data, result.output_size), from_hex("efcafe0101000c02000400"));
}

TEST_P(evm, eof_codecopy_code)
{
rev = EVMC_SHANGHAI;
auto code = eof_bytecode(bytecode{12} + 8 + 0 + OP_CODECOPY + ret(0, 12));

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(
bytes_view(result.output_data, result.output_size), from_hex("600c6008600039600c6000f3"));

code = eof_bytecode(bytecode{12} + 11 + 0 + OP_CODECOPY + ret(0, 12), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(
bytes_view(result.output_data, result.output_size), from_hex("600c600b600039600c6000f3"));
}

TEST_P(evm, eof_codecopy_data)
{
rev = EVMC_SHANGHAI;

const auto code = eof_bytecode(bytecode{4} + 23 + 0 + OP_CODECOPY + ret(0, 4), "deadbeef");

execute(code);
EXPECT_STATUS(EVMC_SUCCESS);
EXPECT_EQ(bytes_view(result.output_data, result.output_size), from_hex("deadbeef"));
}
19 changes: 19 additions & 0 deletions test/utils/bytecode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ inline bytecode operator*(int n, evmc_opcode op)
return n * bytecode{op};
}

inline bytecode eof_header(uint16_t code_size, uint16_t data_size = 0)
{
bytecode out{"efcafe0101"};
out += bytecode{static_cast<evmc_opcode>(code_size >> 8)} +
static_cast<evmc_opcode>(code_size & 0xff);
if (data_size != 0)
{
out += "02" + bytecode{static_cast<evmc_opcode>(data_size >> 8)} +
static_cast<evmc_opcode>(data_size & 0xff);
}
out += "00";
return out;
}

inline bytecode eof_bytecode(bytecode code, bytecode data = {})
{
return eof_header(static_cast<uint16_t>(code.size()), static_cast<uint16_t>(data.size())) +
code + data;
}

inline bytecode push(bytes_view data)
{
Expand Down

0 comments on commit 9233479

Please sign in to comment.