Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change RJUMPV immediate argument to max_index #640

Merged
merged 2 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ jobs:
bin/evmone-statetest ~/tests/GeneralStateTests ~/tests/LegacyTests/Constantinople/GeneralStateTests
- download_execution_tests:
repo: ipsilon/tests
rev: eof-prague-20230803
rev: eof-rjumpv-20230803
legacy: false
- run:
name: "State tests (EOF)"
Expand Down
16 changes: 6 additions & 10 deletions lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,8 @@ EOFValidationError validate_instructions(

if (op == OP_RJUMPV)
{
const auto count = code[i + 1];
if (count < 1)
return EOFValidationError::invalid_rjumpv_count;
i += static_cast<size_t>(1 /* count */ + count * 2 /* tbl */);
const auto count = code[i + 1] + 1;
i += static_cast<size_t>(1 /* max_index */ + count * 2 /* tbl */);
if (i >= code.size())
return EOFValidationError::truncated_instruction;
}
Expand Down Expand Up @@ -292,7 +290,7 @@ bool validate_rjump_destinations(bytes_view code) noexcept
}
else if (op == OP_RJUMPV)
{
const auto count = code[i + 1];
const auto count = size_t{code[i + 1]} + 1;
imm_size += count * REL_OFFSET_SIZE /* tbl */;
const size_t post_pos = i + 1 + imm_size;

Expand Down Expand Up @@ -362,7 +360,7 @@ std::variant<EOFValidationError, int32_t> validate_max_stack_height(

// Determine size of immediate, including the special case of RJUMPV.
const size_t imm_size = (opcode == OP_RJUMPV) ?
(1 + /*count*/ size_t{code[i + 1]} * REL_OFFSET_SIZE) :
(1 + /*count*/ (size_t{code[i + 1]} + 1) * REL_OFFSET_SIZE) :
instr::traits[opcode].immediate_size;

// Mark immediate locations.
Expand Down Expand Up @@ -403,10 +401,10 @@ std::variant<EOFValidationError, int32_t> validate_max_stack_height(
}
else if (opcode == OP_RJUMPV)
{
const auto count = code[i + 1];
const auto max_index = code[i + 1];

// Insert all jump targets.
for (size_t k = 0; k < count; ++k)
for (size_t k = 0; k <= max_index; ++k)
{
const auto target_rel_offset = read_int16_be(&code[i + k * REL_OFFSET_SIZE + 2]);
const auto target = static_cast<int32_t>(next) + target_rel_offset;
Expand Down Expand Up @@ -602,8 +600,6 @@ std::string_view get_error_message(EOFValidationError err) noexcept
return "undefined_instruction";
case EOFValidationError::truncated_instruction:
return "truncated_instruction";
case EOFValidationError::invalid_rjumpv_count:
return "invalid_rjumpv_count";
case EOFValidationError::invalid_rjump_destination:
return "invalid_rjump_destination";
case EOFValidationError::too_many_code_sections:
Expand Down
1 change: 0 additions & 1 deletion lib/evmone/eof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ enum class EOFValidationError
invalid_section_bodies_size,
undefined_instruction,
truncated_instruction,
invalid_rjumpv_count,
invalid_rjump_destination,
too_many_code_sections,
invalid_type_section_size,
Expand Down
6 changes: 3 additions & 3 deletions lib/evmone/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,10 @@ inline code_iterator rjumpv(StackTop stack, ExecutionState& /*state*/, code_iter
constexpr auto REL_OFFSET_SIZE = sizeof(int16_t);
const auto case_ = stack.pop();

const auto count = pc[1];
const auto pc_post = pc + 1 + 1 /* count */ + count * REL_OFFSET_SIZE /* tbl */;
const auto max_index = pc[1];
const auto pc_post = pc + 1 + 1 /* max_index */ + (max_index + 1) * REL_OFFSET_SIZE /* tbl */;

if (case_ >= count)
if (case_ > max_index)
{
return pc_post;
}
Expand Down
45 changes: 19 additions & 26 deletions test/unittests/eof_validation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,22 @@ TEST(eof_validation, EOF1_valid_rjumpi)
TEST(eof_validation, EOF1_valid_rjumpv)
{
// table = [0] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 040000 00 00000001 6000E2010000600100"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 040000 00 00000001 6000E2000000600100"),
EOFValidationError::success);

// table = [0,3] case = 0
EXPECT_EQ(
validate_eof("EF0001 010004 020001000E 040000 00 00000001 6000E20200000003600100600200"),
validate_eof("EF0001 010004 020001000E 040000 00 00000001 6000E20100000003600100600200"),
EOFValidationError::success);

// table = [0,3] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000E 040000 00 00000001 6002E20200000003600100600200"),
validate_eof("EF0001 010004 020001000E 040000 00 00000001 6002E20100000003600100600200"),
EOFValidationError::success);

// table = [0,3,-10] case = 2
EXPECT_EQ(validate_eof(
"EF0001 010004 0200010010 040000 00 00000001 6002E20300000003FFF6600100600200"),
"EF0001 010004 0200010010 040000 00 00000001 6002E20200000003FFF6600100600200"),
EOFValidationError::success);
}

Expand All @@ -464,29 +464,22 @@ TEST(eof_validation, EOF1_rjumpi_truncated)
TEST(eof_validation, EOF1_rjumpv_truncated)
{
// table = [0] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010005 040000 00 00000000 6000E20100"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010005 040000 00 00000000 6000E20000"),
EOFValidationError::truncated_instruction);

// table = [0,3] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010007 040000 00 00000000 6000E202000000"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010007 040000 00 00000000 6000E201000000"),
EOFValidationError::truncated_instruction);

// table = [0,3] case = 2
EXPECT_EQ(validate_eof("EF0001 010004 0200010006 040000 00 00000000 6002E2020000"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010006 040000 00 00000000 6002E2010000"),
EOFValidationError::truncated_instruction);

// table = [0,3,-10] case = 2
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 040000 00 00000000 6002E20300000003FF"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010009 040000 00 00000000 6002E20200000003FF"),
EOFValidationError::truncated_instruction);
}

TEST(eof_validation, EOF1_rjumpv_0_count)
{
auto code = eof1_bytecode(rjumpv({}, 0) + OP_STOP, 1);

EXPECT_EQ(validate_eof(code), EOFValidationError::invalid_rjumpv_count);
}

TEST(eof_validation, EOF1_rjump_invalid_destination)
{
// Into header (offset = -5)
Expand Down Expand Up @@ -544,49 +537,49 @@ TEST(eof_validation, EOF1_rjumpi_invalid_destination)
TEST(eof_validation, EOF1_rjumpv_invalid_destination)
{
// table = [-23] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E201FFE96001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E200FFE96001"),
EOFValidationError::invalid_rjump_destination);

// table = [-8] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E201FFF86001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E200FFF86001"),
EOFValidationError::invalid_rjump_destination);

// table = [-1] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E201FFFF6001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E200FFFF6001"),
EOFValidationError::invalid_rjump_destination);

// table = [2] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E20100026001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E20000026001"),
EOFValidationError::invalid_rjump_destination);

// table = [3] case = 0
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E20100036001"),
EXPECT_EQ(validate_eof("EF0001 010004 0200010008 040000 00 00000000 6000E20000036001"),
EOFValidationError::invalid_rjump_destination);


// table = [0,3,-27] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20300000003FFE56001006002"),
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20200000003FFE56001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,-12] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20300000003FFF46001006002"),
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20200000003FFF46001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,-1] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20300000003FFFF6001006002"),
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E20200000003FFFF6001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,5] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E2030000000300056001006002"),
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E2020000000300056001006002"),
EOFValidationError::invalid_rjump_destination);

// table = [0,3,6] case = 2
EXPECT_EQ(
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E2030000000300066001006002"),
validate_eof("EF0001 010004 020001000F 040000 00 00000000 6002E2020000000300066001006002"),
EOFValidationError::invalid_rjump_destination);
}

Expand Down Expand Up @@ -662,7 +655,7 @@ TEST(eof_validation, max_arguments_count)
}
}

TEST(eof_validation, max_stack_heigh)
TEST(eof_validation, max_stack_height)
{
{
auto code = bytecode{"EF0001 010008 02000200010BFE 040000 00 00000000 000003FF"} + OP_RETF +
Expand Down
3 changes: 2 additions & 1 deletion test/utils/bytecode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ inline bytecode rjumpi(int16_t offset, bytecode condition)

inline bytecode rjumpv(const std::initializer_list<int16_t> offsets, bytecode condition)
{
bytecode ret = condition + OP_RJUMPV + static_cast<Opcode>(offsets.size());
assert(offsets.size() > 0);
bytecode ret = condition + OP_RJUMPV + static_cast<Opcode>(offsets.size() - 1);
for (const auto offset : offsets)
ret += bytecode{big_endian(offset)};
return ret;
Expand Down