Skip to content

Commit

Permalink
Move code reference to message
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Mar 13, 2024
1 parent 0e0172d commit c3499c2
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 58 deletions.
4 changes: 3 additions & 1 deletion examples/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ int main(int argc, char* argv[])
.input_size = sizeof(input),
.gas = gas,
.depth = 0,
.code = code,
.code_size = code_size,
};
struct evmc_result result = evmc_execute(vm, host, ctx, EVMC_HOMESTEAD, &msg, code, code_size);
struct evmc_result result = evmc_execute(vm, host, ctx, EVMC_HOMESTEAD, &msg);
printf("Execution result:\n");
int exit_code = 0;
if (result.status_code != EVMC_SUCCESS)
Expand Down
4 changes: 1 addition & 3 deletions examples/example_precompiles_vm/example_precompiles_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ evmc_result execute(evmc_vm* /*vm*/,
const evmc_host_interface* /*host*/,
evmc_host_context* /*context*/,
enum evmc_revision rev,
const evmc_message* msg,
const uint8_t* /*code*/,
size_t /*code_size*/)
const evmc_message* msg)
{
// The EIP-1352 (https://eips.ethereum.org/EIPS/eip-1352) defines
// the range 0 - 0xffff (2 bytes) of addresses reserved for precompiled contracts.
Expand Down
12 changes: 5 additions & 7 deletions examples/example_vm/example_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,7 @@ evmc_result execute(evmc_vm* instance,
const evmc_host_interface* host,
evmc_host_context* context,
enum evmc_revision rev,
const evmc_message* msg,
const uint8_t* code,
size_t code_size)
const evmc_message* msg)
{
auto* vm = static_cast<ExampleVM*>(instance);

Expand All @@ -176,14 +174,14 @@ evmc_result execute(evmc_vm* instance,
Stack stack;
Memory memory;

for (size_t pc = 0; pc < code_size; ++pc)
for (size_t pc = 0; pc < msg->code_size; ++pc)
{
// Check remaining gas, assume each instruction costs 1.
gas_left -= 1;
if (gas_left < 0)
return evmc_make_result(EVMC_OUT_OF_GAS, 0, 0, nullptr, 0);

switch (code[pc])
switch (msg->code[pc])
{
default:
return evmc_make_result(EVMC_UNDEFINED_INSTRUCTION, 0, 0, nullptr, 0);
Expand Down Expand Up @@ -296,9 +294,9 @@ evmc_result execute(evmc_vm* instance,
case OP_PUSH32:
{
evmc_uint256be value = {};
size_t num_push_bytes = size_t{code[pc]} - OP_PUSH1 + 1;
size_t num_push_bytes = size_t{msg->code[pc]} - OP_PUSH1 + 1;
size_t offset = sizeof(value) - num_push_bytes;
std::memcpy(&value.bytes[offset], &code[pc + 1], num_push_bytes);
std::memcpy(&value.bytes[offset], &msg->code[pc + 1], num_push_bytes);
pc += num_push_bytes;
stack.push(value);
break;
Expand Down
4 changes: 1 addition & 3 deletions include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1064,9 +1064,7 @@ typedef struct evmc_result (*evmc_execute_fn)(struct evmc_vm* vm,
const struct evmc_host_interface* host,
struct evmc_host_context* context,
enum evmc_revision rev,
const struct evmc_message* msg,
uint8_t const* code,
size_t code_size);
const struct evmc_message* msg);

/**
* Possible capabilities of a VM.
Expand Down
22 changes: 6 additions & 16 deletions include/evmc/evmc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,21 +720,15 @@ class VM
Result execute(const evmc_host_interface& host,
evmc_host_context* ctx,
evmc_revision rev,
const evmc_message& msg,
const uint8_t* code,
size_t code_size) noexcept
const evmc_message& msg) noexcept
{
return Result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)};
return Result{m_instance->execute(m_instance, &host, ctx, rev, &msg)};
}

/// Convenient variant of the VM::execute() that takes reference to evmc::Host class.
Result execute(Host& host,
evmc_revision rev,
const evmc_message& msg,
const uint8_t* code,
size_t code_size) noexcept
Result execute(Host& host, evmc_revision rev, const evmc_message& msg) noexcept
{
return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size);
return execute(Host::get_interface(), host.to_context(), rev, msg);
}

/// Executes code without the Host context.
Expand All @@ -745,13 +739,9 @@ class VM
/// but without providing the Host context and interface.
/// This method is for experimental precompiles support where execution is
/// guaranteed not to require any Host access.
Result execute(evmc_revision rev,
const evmc_message& msg,
const uint8_t* code,
size_t code_size) noexcept
Result execute(evmc_revision rev, const evmc_message& msg) noexcept
{
return Result{
m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)};
return Result{m_instance->execute(m_instance, nullptr, nullptr, rev, &msg)};
}

/// Returns the pointer to C EVMC struct representing the VM.
Expand Down
6 changes: 2 additions & 4 deletions include/evmc/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,9 @@ static inline struct evmc_result evmc_execute(struct evmc_vm* vm,
const struct evmc_host_interface* host,
struct evmc_host_context* context,
enum evmc_revision rev,
const struct evmc_message* msg,
uint8_t const* code,
size_t code_size)
const struct evmc_message* msg)
{
return vm->execute(vm, host, context, rev, msg, code, code_size);
return vm->execute(vm, host, context, rev, msg);
}

/// The evmc_result release function using free() for releasing the memory.
Expand Down
19 changes: 11 additions & 8 deletions lib/tooling/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ auto bench(MockedHost& host,
evmc::VM& vm,
evmc_revision rev,
const evmc_message& msg,
bytes_view code,
const evmc::Result& expected_result,
std::ostream& out)
{
Expand All @@ -37,7 +36,7 @@ auto bench(MockedHost& host,

// Probe run: execute once again the already warm code to estimate a single run time.
const auto probe_start = clock::now();
const auto result = vm.execute(host, rev, msg, code.data(), code.size());
const auto result = vm.execute(host, rev, msg);
const auto bench_start = clock::now();
const auto probe_time = bench_start - probe_start;

Expand All @@ -50,7 +49,7 @@ auto bench(MockedHost& host,
// Benchmark loop.
const auto num_iterations = std::max(static_cast<int>(target_bench_time / probe_time), 1);
for (int i = 0; i < num_iterations; ++i)
vm.execute(host, rev, msg, code.data(), code.size());
vm.execute(host, rev, msg);
const auto bench_time = (clock::now() - bench_start) / num_iterations;

out << "Time: " << std::chrono::duration_cast<unit>(bench_time).count() << unit_name
Expand All @@ -77,16 +76,19 @@ int run(VM& vm,
msg.gas = gas;
msg.input_data = input.data();
msg.input_size = input.size();
msg.code = code.data();
msg.code_size = code.size();

bytes_view exec_code = code;
if (create)
{
evmc_message create_msg{};
create_msg.kind = EVMC_CREATE;
create_msg.recipient = create_address;
create_msg.gas = create_gas;
create_msg.code = code.data();
create_msg.code_size = code.size();

const auto create_result = vm.execute(host, rev, create_msg, code.data(), code.size());
const auto create_result = vm.execute(host, rev, create_msg);
if (create_result.status_code != EVMC_SUCCESS)
{
out << "Contract creation failed: " << create_result.status_code << "\n";
Expand All @@ -97,14 +99,15 @@ int run(VM& vm,
created_account.code = bytes(create_result.output_data, create_result.output_size);

msg.recipient = create_address;
exec_code = created_account.code;
msg.code = created_account.code.data();
msg.code_size = created_account.code.size();
}
out << "\n";

const auto result = vm.execute(host, rev, msg, exec_code.data(), exec_code.size());
const auto result = vm.execute(host, rev, msg);

if (bench)
tooling::bench(host, vm, rev, msg, exec_code, result, out);
tooling::bench(host, vm, rev, msg, result, out);

const auto gas_used = msg.gas - result.gas_left;
out << "Result: " << result.status_code << "\nGas used: " << gas_used << "\n";
Expand Down
6 changes: 3 additions & 3 deletions test/unittests/cpp_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ TEST(cpp, vm)
const auto host = evmc_host_interface{};
auto msg = evmc_message{};
msg.gas = 1;
auto res = vm.execute(host, nullptr, EVMC_MAX_REVISION, msg, nullptr, 0);
auto res = vm.execute(host, nullptr, EVMC_MAX_REVISION, msg);
EXPECT_EQ(res.status_code, EVMC_SUCCESS);
EXPECT_EQ(res.gas_left, 1);
}
Expand Down Expand Up @@ -616,7 +616,7 @@ TEST(cpp, vm_execute_precompiles)
msg.input_size = input.size();
msg.gas = 18;

auto res = vm.execute(EVMC_MAX_REVISION, msg, nullptr, 0);
auto res = vm.execute(EVMC_MAX_REVISION, msg);
EXPECT_EQ(res.status_code, EVMC_SUCCESS);
EXPECT_EQ(res.gas_left, 0);
ASSERT_EQ(res.output_size, input.size());
Expand All @@ -632,7 +632,7 @@ TEST(cpp, vm_execute_with_null_host)

auto vm = evmc::VM{evmc_create_example_vm()};
const evmc_message msg{};
auto res = vm.execute(host, EVMC_FRONTIER, msg, nullptr, 0);
auto res = vm.execute(host, EVMC_FRONTIER, msg);
EXPECT_EQ(res.status_code, EVMC_SUCCESS);
EXPECT_EQ(res.gas_left, 0);
}
Expand Down
4 changes: 3 additions & 1 deletion test/unittests/example_vm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ class example_vm : public testing::Test
msg.gas = gas;
msg.input_data = input.data();
msg.input_size = input.size();
msg.code = code.data();
msg.code_size = code.size();

return vm.execute(host, rev, msg, code.data(), code.size());
return vm.execute(host, rev, msg);
}
};

Expand Down
23 changes: 11 additions & 12 deletions tools/vmtester/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ TEST_F(evmc_vm_test, capabilities)
TEST_F(evmc_vm_test, execute_call)
{
evmc::MockedHost mockedHost;
const evmc_message msg{};
evmc_message msg{};
std::array<uint8_t, 2> code = {{0xfe, 0x00}};
msg.code = code.data();
msg.code_size = code.size();

const evmc_result result =
vm->execute(vm, &evmc::MockedHost::get_interface(), mockedHost.to_context(),
EVMC_MAX_REVISION, &msg, code.data(), code.size());
const evmc_result result = vm->execute(vm, &evmc::MockedHost::get_interface(),
mockedHost.to_context(), EVMC_MAX_REVISION, &msg);

// Validate some constraints
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_REVERT)
Expand All @@ -86,6 +87,7 @@ TEST_F(evmc_vm_test, execute_call)

TEST_F(evmc_vm_test, execute_create)
{
std::array<uint8_t, 2> code = {{0xfe, 0x00}};
evmc::MockedHost mockedHost;
const evmc_message msg{EVMC_CREATE,
0,
Expand All @@ -98,13 +100,11 @@ TEST_F(evmc_vm_test, execute_create)
evmc_uint256be{},
evmc_bytes32{},
evmc_address{},
nullptr,
0};
std::array<uint8_t, 2> code = {{0xfe, 0x00}};
code.data(),
code.size()};

const evmc_result result =
vm->execute(vm, &evmc::MockedHost::get_interface(), mockedHost.to_context(),
EVMC_MAX_REVISION, &msg, code.data(), code.size());
const evmc_result result = vm->execute(vm, &evmc::MockedHost::get_interface(),
mockedHost.to_context(), EVMC_MAX_REVISION, &msg);

// Validate some constraints
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_REVERT)
Expand Down Expand Up @@ -194,8 +194,7 @@ TEST_F(evmc_vm_test, precompile_test)
nullptr,
0};

const evmc_result result =
vm->execute(vm, nullptr, nullptr, EVMC_MAX_REVISION, &msg, nullptr, 0);
const evmc_result result = vm->execute(vm, nullptr, nullptr, EVMC_MAX_REVISION, &msg);

// Validate some constraints

Expand Down

0 comments on commit c3499c2

Please sign in to comment.