diff --git a/include/evmc/evmc.h b/include/evmc/evmc.h index e0c88fe71..22b064bb9 100644 --- a/include/evmc/evmc.h +++ b/include/evmc/evmc.h @@ -40,7 +40,7 @@ extern "C" { enum { /** The EVMC ABI version number of the interface declared in this file. */ - EVMC_ABI_VERSION = 1 + EVMC_ABI_VERSION = 2 }; /** @@ -68,9 +68,11 @@ struct evmc_address enum evmc_call_kind { EVMC_CALL = 0, /**< Request CALL. */ - EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. The value param ignored. */ + EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. Valid since Homestead. + The value param ignored. */ EVMC_CALLCODE = 2, /**< Request CALLCODE. */ - EVMC_CREATE = 3 /**< Request CREATE. Semantic of some params changes. */ + EVMC_CREATE = 3, /**< Request CREATE. */ + EVMC_CREATE2 = 4 /**< Request CREATE2. Valid since Constantinople.*/ }; /** The flags for ::evmc_message. */ @@ -116,6 +118,13 @@ struct evmc_message */ struct evmc_uint256be code_hash; + /** + * The optional value used in new contract address construction. + * + * Ignored unless kind is EVMC_CREATE2. + */ + struct evmc_uint256be create2_salt; + /** The amount of gas for message execution. */ int64_t gas; diff --git a/include/evmc/instructions.h b/include/evmc/instructions.h index a86cf9d67..d11edc82f 100644 --- a/include/evmc/instructions.h +++ b/include/evmc/instructions.h @@ -166,6 +166,7 @@ enum evmc_opcode OP_CALLCODE = 0xf2, OP_RETURN = 0xf3, OP_DELEGATECALL = 0xf4, + OP_CREATE2 = 0xf5, OP_STATICCALL = 0xfa, diff --git a/lib/instructions/instruction_metrics.c b/lib/instructions/instruction_metrics.c index a1f0a9e47..b8fe69780 100644 --- a/lib/instructions/instruction_metrics.c +++ b/lib/instructions/instruction_metrics.c @@ -267,7 +267,7 @@ static struct evmc_instruction_metrics constantinople_metrics[256] = { /* CALLCODE = 0xf2 */ {700, 7, 1}, /* RETURN = 0xf3 */ {ZERO, 2, 0}, /* DELEGATECALL = 0xf4 */ {700, 6, 1}, - /* = 0xf5 */ {UNDEFINED, 0, 0}, + /* CREATE2 = 0xf5 */ {32000, 4, 1}, /* = 0xf6 */ {UNDEFINED, 0, 0}, /* = 0xf7 */ {UNDEFINED, 0, 0}, /* = 0xf8 */ {UNDEFINED, 0, 0}, diff --git a/lib/instructions/instruction_names.c b/lib/instructions/instruction_names.c index d2b29ea9c..e182d590b 100644 --- a/lib/instructions/instruction_names.c +++ b/lib/instructions/instruction_names.c @@ -251,7 +251,7 @@ static const char* constantinople_names[256] = { /* 0xf2 */ "CALLCODE", /* 0xf3 */ "RETURN", /* 0xf4 */ "DELEGATECALL", - /* 0xf5 */ NULL, + /* 0xf5 */ "CREATE2", /* 0xf6 */ NULL, /* 0xf7 */ NULL, /* 0xf8 */ NULL, diff --git a/test/unittests/test_instructions.cpp b/test/unittests/test_instructions.cpp index 3a8691689..8e5884946 100644 --- a/test/unittests/test_instructions.cpp +++ b/test/unittests/test_instructions.cpp @@ -88,6 +88,22 @@ TEST(instructions, byzantium_hard_fork) EXPECT_EQ(sdn[OP_STATICCALL], nullptr); } +TEST(instructions, constantinople_hard_fork) +{ + const auto c = evmc_get_instruction_metrics_table(EVMC_CONSTANTINOPLE); + const auto b = evmc_get_instruction_metrics_table(EVMC_BYZANTIUM); + const auto cn = evmc_get_instruction_names_table(EVMC_CONSTANTINOPLE); + const auto bn = evmc_get_instruction_names_table(EVMC_BYZANTIUM); + + EXPECT_EQ(c[OP_CREATE2].gas_cost, 32000); + EXPECT_EQ(c[OP_CREATE2].num_stack_arguments, 4); + EXPECT_EQ(c[OP_CREATE2].num_stack_returned_items, 1); + EXPECT_EQ(b[OP_CREATE2].gas_cost, -1); + EXPECT_EQ(cn[OP_CREATE2], std::string{"CREATE2"}); + EXPECT_EQ(bn[OP_CREATE2], nullptr); +} + + TEST(instructions, name_gas_cost_equivalence) { for (auto rev = EVMC_FRONTIER; rev <= EVMC_LATEST_REVISION; diff --git a/test/vmtester/tests.cpp b/test/vmtester/tests.cpp index a284412b1..744c97bd9 100644 --- a/test/vmtester/tests.cpp +++ b/test/vmtester/tests.cpp @@ -12,7 +12,6 @@ static_assert(sizeof(evmc_uint256be) == 32, "evmc_uint256be is too big"); static_assert(sizeof(evmc_address) == 20, "evmc_address is too big"); static_assert(sizeof(evmc_result) <= 64, "evmc_result does not fit cache line"); static_assert(sizeof(evmc_instance) <= 64, "evmc_instance does not fit cache line"); -static_assert(sizeof(evmc_message) <= 18 * 8, "evmc_message not optimally packed"); static_assert(offsetof(evmc_message, code_hash) % 8 == 0, "evmc_message.code_hash not aligned"); // Check enums match int size.