diff --git a/include/evmc/instructions.h b/include/evmc/instructions.h index 1c22f848b..d2bfbbc47 100644 --- a/include/evmc/instructions.h +++ b/include/evmc/instructions.h @@ -93,6 +93,9 @@ enum evmc_opcode OP_MSIZE = 0x59, OP_GAS = 0x5a, OP_JUMPDEST = 0x5b, + OP_RJUMP = 0x5c, + OP_RJUMPI = 0x5d, +// OP_RJUMPTABLE = 0x5e, OP_PUSH0 = 0x5f, OP_PUSH1 = 0x60, diff --git a/lib/instructions/instruction_metrics.c b/lib/instructions/instruction_metrics.c index ea9aea96e..cc2b0f54c 100644 --- a/lib/instructions/instruction_metrics.c +++ b/lib/instructions/instruction_metrics.c @@ -124,8 +124,8 @@ static struct evmc_instruction_metrics cancun_metrics[256] = { /* MSIZE = 0x59 */ {BASE, 0, 1}, /* GAS = 0x5a */ {BASE, 0, 1}, /* JUMPDEST = 0x5b */ {1, 0, 0}, - /* = 0x5c */ {UNDEFINED, 0, 0}, - /* = 0x5d */ {UNDEFINED, 0, 0}, + /* RJUMP = 0x5c */ {LOW, 0, 0}, + /* RJUMPI = 0x5d */ {7, 1, -1}, /* = 0x5e */ {UNDEFINED, 0, 0}, /* PUSH0 = 0x5f */ {BASE, 0, 1}, /* PUSH1 = 0x60 */ {VERYLOW, 0, 1}, diff --git a/lib/instructions/instruction_names.c b/lib/instructions/instruction_names.c index 64a21592d..21ae38e79 100644 --- a/lib/instructions/instruction_names.c +++ b/lib/instructions/instruction_names.c @@ -97,8 +97,8 @@ static const char* cancun_names[256] = { /* 0x59 */ "MSIZE", /* 0x5a */ "GAS", /* 0x5b */ "JUMPDEST", - /* 0x5c */ NULL, - /* 0x5d */ NULL, + /* 0x5c */ "RJUMP", + /* 0x5d */ "RJUMPI", /* 0x5e */ NULL, /* 0x5f */ "PUSH0", /* 0x60 */ "PUSH1", diff --git a/test/unittests/instructions_test.cpp b/test/unittests/instructions_test.cpp index a4216be4c..02213ac51 100644 --- a/test/unittests/instructions_test.cpp +++ b/test/unittests/instructions_test.cpp @@ -394,3 +394,33 @@ TEST(instructions, shanghai_hard_fork) EXPECT_EQ(sn[OP_PUSH0], std::string{"PUSH0"}); EXPECT_TRUE(pn[OP_PUSH0] == nullptr); } + +TEST(instructions, cancun_hard_fork) +{ + const auto c = evmc_get_instruction_metrics_table(EVMC_CANCUN); + const auto s = evmc_get_instruction_metrics_table(EVMC_SHANGHAI); + const auto cn = evmc_get_instruction_names_table(EVMC_CANCUN); + const auto sn = evmc_get_instruction_names_table(EVMC_SHANGHAI); + + for (int op = 0x00; op <= 0xff; ++op) + { + if (op == OP_RJUMP || op == OP_RJUMPI) + continue; + EXPECT_EQ(c[op], s[op]) << op; + EXPECT_STREQ(cn[op], sn[op]) << op; + } + + // EIP-4200: Static relative jumps + EXPECT_EQ(c[OP_RJUMP].gas_cost, 5); + EXPECT_EQ(c[OP_RJUMP].stack_height_required, 0); + EXPECT_EQ(c[OP_RJUMP].stack_height_change, 0); + EXPECT_EQ(s[OP_RJUMP].gas_cost, 0); + EXPECT_EQ(cn[OP_RJUMP], std::string{"RJUMP"}); + EXPECT_TRUE(sn[OP_RJUMP] == nullptr); + EXPECT_EQ(c[OP_RJUMPI].gas_cost, 7); + EXPECT_EQ(c[OP_RJUMPI].stack_height_required, 1); + EXPECT_EQ(c[OP_RJUMPI].stack_height_change, -1); + EXPECT_EQ(s[OP_RJUMPI].gas_cost, 0); + EXPECT_EQ(cn[OP_RJUMPI], std::string{"RJUMPI"}); + EXPECT_TRUE(sn[OP_RJUMPI] == nullptr); +}