From 996d37b5aa0d2cdb69bc451cdbcba844b0b25796 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 28 Nov 2022 12:23:19 +0100 Subject: [PATCH] baseline: Implement EIP-663 --- lib/evmone/advanced_instructions.cpp | 3 +++ lib/evmone/instructions.hpp | 34 ++++++++++++++++++++++++++ lib/evmone/instructions_traits.hpp | 5 ++++ lib/evmone/instructions_xmacro.hpp | 4 +-- test/unittests/eof_validation_test.cpp | 2 +- test/unittests/instructions_test.cpp | 2 ++ 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/lib/evmone/advanced_instructions.cpp b/lib/evmone/advanced_instructions.cpp index 3ee9e02315..3a9940835f 100644 --- a/lib/evmone/advanced_instructions.cpp +++ b/lib/evmone/advanced_instructions.cpp @@ -246,6 +246,9 @@ constexpr std::array instruction_implementations = []( table[OP_CREATE2] = op_create; table[OP_STATICCALL] = op_call; + table[OP_DUPN] = op_undefined; + table[OP_SWAPN] = op_undefined; + return table; }(); } // namespace diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index e80d64f118..3e5a955e14 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -820,6 +820,40 @@ inline void swap(StackTop stack) noexcept a[3] = t3; } +inline code_iterator dupn(StackTop stack, ExecutionState& state, code_iterator pos) noexcept +{ + const auto n = pos[1] + 17 - 1; + + const auto stack_size = &stack.top() - state.stack_space.bottom(); + + if (stack_size <= n) + { + state.status = EVMC_STACK_UNDERFLOW; + return nullptr; + } + + stack.push(stack[n]); + + return pos + 2; +} + +inline code_iterator swapn(StackTop stack, ExecutionState& state, code_iterator pos) noexcept +{ + const auto n = pos[1] + 17; + + const auto stack_size = &stack.top() - state.stack_space.bottom(); + + if (stack_size <= n) + { + state.status = EVMC_STACK_UNDERFLOW; + return nullptr; + } + + std::swap(stack.top(), stack[n]); + + return pos + 2; +} + template inline evmc_status_code log(StackTop stack, ExecutionState& state) noexcept { diff --git a/lib/evmone/instructions_traits.hpp b/lib/evmone/instructions_traits.hpp index 8599476e01..edc37584c0 100644 --- a/lib/evmone/instructions_traits.hpp +++ b/lib/evmone/instructions_traits.hpp @@ -164,6 +164,8 @@ constexpr inline GasCostTable gas_costs = []() noexcept { table[EVMC_SHANGHAI][OP_PUSH0] = 2; table[EVMC_CANCUN] = table[EVMC_SHANGHAI]; + table[EVMC_CANCUN][OP_DUPN] = 3; + table[EVMC_CANCUN][OP_SWAPN] = 3; return table; }(); @@ -360,6 +362,9 @@ constexpr inline std::array traits = []() noexcept { table[OP_LOG3] = {"LOG3", 0, false, 5, -5, EVMC_FRONTIER}; table[OP_LOG4] = {"LOG4", 0, false, 6, -6, EVMC_FRONTIER}; + table[OP_DUPN] = {"DUPN", 1, false, 0, 1, EVMC_CANCUN}; + table[OP_SWAPN] = {"SWAPN", 1, false, 0, 0, EVMC_CANCUN}; + table[OP_CREATE] = {"CREATE", 0, false, 3, -2, EVMC_FRONTIER}; table[OP_CALL] = {"CALL", 0, false, 7, -6, EVMC_FRONTIER}; table[OP_CALLCODE] = {"CALLCODE", 0, false, 7, -6, EVMC_FRONTIER}; diff --git a/lib/evmone/instructions_xmacro.hpp b/lib/evmone/instructions_xmacro.hpp index 1f7b135caf..29238333be 100644 --- a/lib/evmone/instructions_xmacro.hpp +++ b/lib/evmone/instructions_xmacro.hpp @@ -221,8 +221,8 @@ \ ON_OPCODE_UNDEFINED(0xb0) \ ON_OPCODE_UNDEFINED(0xb1) \ - ON_OPCODE_UNDEFINED(0xb2) \ - ON_OPCODE_UNDEFINED(0xb3) \ + ON_OPCODE_IDENTIFIER(OP_DUPN, dupn) \ + ON_OPCODE_IDENTIFIER(OP_SWAPN, swapn) \ ON_OPCODE_UNDEFINED(0xb4) \ ON_OPCODE_UNDEFINED(0xb5) \ ON_OPCODE_UNDEFINED(0xb6) \ diff --git a/test/unittests/eof_validation_test.cpp b/test/unittests/eof_validation_test.cpp index e55ee49a0a..1c87956ce9 100644 --- a/test/unittests/eof_validation_test.cpp +++ b/test/unittests/eof_validation_test.cpp @@ -230,6 +230,6 @@ TEST(eof_validation, EOF1_terminating_instructions) opcode == OP_INVALID || opcode == OP_SELFDESTRUCT) ? EOFValidationError::success : EOFValidationError::missing_terminating_instruction); - EXPECT_EQ(validate_eof(container), expected) << hex(code); + EXPECT_EQ(validate_eof(container, EVMC_CANCUN), expected) << hex(code); } } diff --git a/test/unittests/instructions_test.cpp b/test/unittests/instructions_test.cpp index 478f01e40f..235b1b3aa0 100644 --- a/test/unittests/instructions_test.cpp +++ b/test/unittests/instructions_test.cpp @@ -49,6 +49,8 @@ constexpr void validate_traits_of() noexcept // immediate_size if constexpr (Op >= OP_PUSH1 && Op <= OP_PUSH32) static_assert(tr.immediate_size == Op - OP_PUSH1 + 1); + else if constexpr (Op == OP_DUPN || Op == OP_SWAPN) + static_assert(tr.immediate_size == 1); else static_assert(tr.immediate_size == 0);