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

Support CREATE2 opcode in Constantinople #45

Merged
merged 3 commits into from
Jul 25, 2018
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
15 changes: 12 additions & 3 deletions include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

/**
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions include/evmc/instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ enum evmc_opcode
OP_CALLCODE = 0xf2,
OP_RETURN = 0xf3,
OP_DELEGATECALL = 0xf4,
OP_CREATE2 = 0xf5,

OP_STATICCALL = 0xfa,

Expand Down
2 changes: 1 addition & 1 deletion lib/instructions/instruction_metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
2 changes: 1 addition & 1 deletion lib/instructions/instruction_names.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions test/unittests/test_instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion test/vmtester/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be kept with an updated size?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not anything useful. I was just checking obvious struct fields alignment.

static_assert(offsetof(evmc_message, code_hash) % 8 == 0, "evmc_message.code_hash not aligned");

// Check enums match int size.
Expand Down