diff --git a/include/evmc/evmc.h b/include/evmc/evmc.h index fae53b84f..20d053194 100644 --- a/include/evmc/evmc.h +++ b/include/evmc/evmc.h @@ -832,8 +832,15 @@ enum evmc_revision */ EVMC_LONDON = 9, + /** + * The Shanghai revision. + * + * https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md + */ + EVMC_SHANGHAI = 10, + /** The maximum EVM revision supported. */ - EVMC_MAX_REVISION = EVMC_LONDON + EVMC_MAX_REVISION = EVMC_SHANGHAI }; diff --git a/include/evmc/helpers.h b/include/evmc/helpers.h index 5ada94a77..21f2ad011 100644 --- a/include/evmc/helpers.h +++ b/include/evmc/helpers.h @@ -285,6 +285,8 @@ static inline const char* evmc_revision_to_string(enum evmc_revision rev) return "Berlin"; case EVMC_LONDON: return "London"; + case EVMC_SHANGHAI: + return "Shanghai"; } return ""; } diff --git a/lib/instructions/instruction_metrics.c b/lib/instructions/instruction_metrics.c index 0357b8b89..4325f94bd 100644 --- a/lib/instructions/instruction_metrics.c +++ b/lib/instructions/instruction_metrics.c @@ -2108,6 +2108,7 @@ const struct evmc_instruction_metrics* evmc_get_instruction_metrics_table( { switch (revision) { + case EVMC_SHANGHAI: case EVMC_LONDON: return london_metrics; case EVMC_BERLIN: diff --git a/lib/instructions/instruction_names.c b/lib/instructions/instruction_names.c index 62245f70d..6fd8294ec 100644 --- a/lib/instructions/instruction_names.c +++ b/lib/instructions/instruction_names.c @@ -1563,6 +1563,7 @@ const char* const* evmc_get_instruction_names_table(enum evmc_revision revision) { switch (revision) { + case EVMC_SHANGHAI: case EVMC_LONDON: return london_names; case EVMC_BERLIN: diff --git a/test/unittests/cpp_test.cpp b/test/unittests/cpp_test.cpp index 0de09218e..ec292e8c9 100644 --- a/test/unittests/cpp_test.cpp +++ b/test/unittests/cpp_test.cpp @@ -848,6 +848,7 @@ TEST(cpp, revision_to_string) TEST_CASE(EVMC_ISTANBUL), TEST_CASE(EVMC_BERLIN), TEST_CASE(EVMC_LONDON), + TEST_CASE(EVMC_SHANGHAI), }; #undef TEST_CASE diff --git a/test/unittests/instructions_test.cpp b/test/unittests/instructions_test.cpp index e56a5050d..0535e4c89 100644 --- a/test/unittests/instructions_test.cpp +++ b/test/unittests/instructions_test.cpp @@ -3,7 +3,6 @@ // Licensed under the Apache License, Version 2.0. #include - #include inline bool operator==(const evmc_instruction_metrics& a, @@ -41,7 +40,7 @@ TEST(instructions, homestead_hard_fork) const auto fn = evmc_get_instruction_names_table(EVMC_FRONTIER); const auto hn = evmc_get_instruction_names_table(EVMC_HOMESTEAD); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) // NOLINT { @@ -67,7 +66,7 @@ TEST(instructions, tangerine_whistle_hard_fork) const auto hn = evmc_get_instruction_names_table(EVMC_HOMESTEAD); const auto twn = evmc_get_instruction_names_table(EVMC_TANGERINE_WHISTLE); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) { @@ -119,7 +118,7 @@ TEST(instructions, spurious_dragon_hard_fork) const auto sdn = evmc_get_instruction_names_table(EVMC_SPURIOUS_DRAGON); const auto twn = evmc_get_instruction_names_table(EVMC_TANGERINE_WHISTLE); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) // NOLINT { @@ -143,7 +142,7 @@ TEST(instructions, byzantium_hard_fork) const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM); const auto sdn = evmc_get_instruction_names_table(EVMC_SPURIOUS_DRAGON); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) { @@ -189,7 +188,7 @@ TEST(instructions, constantinople_hard_fork) const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE); const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) { @@ -236,7 +235,7 @@ TEST(instructions, petersburg_hard_fork) const auto pn = evmc_get_instruction_names_table(EVMC_PETERSBURG); const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { EXPECT_EQ(p[op], c[op]) << op; EXPECT_STREQ(pn[op], cn[op]) << op; @@ -250,7 +249,7 @@ TEST(instructions, istanbul_hard_fork) const auto in = evmc_get_instruction_names_table(EVMC_ISTANBUL); const auto pn = evmc_get_instruction_names_table(EVMC_PETERSBURG); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { switch (op) { @@ -294,7 +293,7 @@ TEST(instructions, berlin_hard_fork) const auto bn = evmc_get_instruction_names_table(EVMC_BERLIN); const auto in = evmc_get_instruction_names_table(EVMC_ISTANBUL); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { EXPECT_STREQ(bn[op], in[op]) << op; @@ -335,7 +334,7 @@ TEST(instructions, london_hard_fork) const auto ln = evmc_get_instruction_names_table(EVMC_LONDON); const auto bn = evmc_get_instruction_names_table(EVMC_BERLIN); - for (int op{OP_STOP}; op <= OP_SELFDESTRUCT; ++op) + for (int op = 0x00; op <= 0xff; ++op) { if (op == OP_BASEFEE) continue; @@ -352,3 +351,17 @@ TEST(instructions, london_hard_fork) EXPECT_EQ(ln[OP_BASEFEE], std::string{"BASEFEE"}); EXPECT_TRUE(bn[OP_BASEFEE] == nullptr); } + +TEST(instructions, shanghai_hard_fork) +{ + const auto s = evmc_get_instruction_metrics_table(EVMC_SHANGHAI); + const auto l = evmc_get_instruction_metrics_table(EVMC_LONDON); + const auto sn = evmc_get_instruction_names_table(EVMC_SHANGHAI); + const auto ln = evmc_get_instruction_names_table(EVMC_LONDON); + + for (int op = 0x00; op <= 0xff; ++op) + { + EXPECT_EQ(s[op], l[op]) << op; + EXPECT_STREQ(sn[op], ln[op]) << op; + } +}