Skip to content

Commit

Permalink
Use evmc::host wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Mar 15, 2019
1 parent c9f1c22 commit 45ff329
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 68 deletions.
2 changes: 1 addition & 1 deletion evmc
Submodule evmc updated 44 files
+7 −1 .bumpversion.cfg
+2 −0 .gitignore
+24 −0 .travis.yml
+15 −0 CHANGELOG.md
+14 −6 CMakeLists.txt
+5 −0 Cargo.toml
+5 −5 README.md
+3 −1 appveyor.yml
+1 −0 bindings/go/evmc/.gitignore
+3 −3 bindings/go/evmc/evmc.go
+33 −8 bindings/go/evmc/evmc_test.go
+22 −12 bindings/go/evmc/host.go
+90 −0 bindings/go/evmc/host_test.go
+3 −0 bindings/rust/evmc-sys/.gitignore
+12 −0 bindings/rust/evmc-sys/Cargo.toml
+29 −0 bindings/rust/evmc-sys/build.rs
+1 −0 bindings/rust/evmc-sys/evmc.h
+5 −0 bindings/rust/evmc-sys/src/lib.rs
+3 −0 bindings/rust/evmc-vm/.gitignore
+11 −0 bindings/rust/evmc-vm/Cargo.toml
+7 −0 bindings/rust/evmc-vm/src/lib.rs
+66 −24 circle.yml
+4 −4 cmake/HunterConfig.cmake
+0 −0 cmake/cable/toolchains/cxx14-pic.cmake
+0 −0 cmake/cable/toolchains/cxx14.cmake
+0 −0 cmake/cable/toolchains/cxx17-pic.cmake
+0 −0 cmake/cable/toolchains/cxx17.cmake
+7 −3 examples/CMakeLists.txt
+22 −2 examples/example_vm.c
+62 −11 include/evmc/evmc.h
+82 −0 include/evmc/evmc.hpp
+2 −5 lib/instructions/CMakeLists.txt
+1 −1 lib/instructions/instruction_metrics.c
+1 −1 lib/instructions/instruction_names.c
+10 −6 lib/loader/loader.c
+8 −4 test/CMakeLists.txt
+17 −13 test/integration/compilation/CMakeLists.txt
+0 −0 test/integration/compilation/compilation_test.cxx
+7 −38 test/unittests/CMakeLists.txt
+42 −0 test/unittests/loader_mock.h
+91 −176 test/unittests/test_loader.cpp
+0 −30 test/unittests/vm_mock.c
+0 −11 test/unittests/vm_mock_default.c
+3 −3 test/vmtester/tests.cpp
7 changes: 3 additions & 4 deletions lib/evmone/analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0.
#pragma once

#include <evmc/evmc.h>
#include <evmc/evmc.hpp>
#include <intx/intx.hpp>
#include <array>
#include <cstdint>
Expand All @@ -18,6 +18,7 @@ using bytes32 = std::array<uint8_t, 32>;

using bytes = std::basic_string<uint8_t>;


struct execution_state
{
bool run = true;
Expand All @@ -44,9 +45,7 @@ struct execution_state
const uint8_t* code = nullptr;
size_t code_size = 0;

evmc_context* host = nullptr;

evmc_tx_context tx_context = {};
evmc::host host = nullptr;

uint256& item(size_t index) noexcept { return stack[stack.size() - index - 1]; }
};
Expand Down
93 changes: 30 additions & 63 deletions lib/evmone/execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,14 @@ void op_balance(execution_state& state, instr_argument) noexcept
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = intx::be::uint256(state.host->host->get_balance(state.host, &addr).bytes);
x = intx::be::uint256(state.host.get_balance(addr).bytes);
}

void op_origin(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
const auto& tx_origin = state.host.get_tx_context().tx_origin;
uint8_t data[32] = {};
std::memcpy(&data[12], state.tx_context.tx_origin.bytes, sizeof(state.tx_context.tx_origin));
std::memcpy(&data[12], tx_origin.bytes, sizeof(tx_origin));
auto x = intx::be::uint256(data);
state.stack.push_back(x);
}
Expand Down Expand Up @@ -492,8 +491,7 @@ void op_sload(execution_state& state, instr_argument) noexcept
auto& x = state.item(0);
evmc_bytes32 key;
intx::be::store(key.bytes, x);
x = intx::be::uint256(
state.host->host->get_storage(state.host, &state.msg->destination, &key).bytes);
x = intx::be::uint256(state.host.get_storage(state.msg->destination, key).bytes);
}

void op_sstore(execution_state& state, instr_argument arg) noexcept
Expand All @@ -512,7 +510,7 @@ void op_sstore(execution_state& state, instr_argument arg) noexcept
intx::be::store(value.bytes, state.item(1));
state.stack.pop_back();
state.stack.pop_back();
auto status = state.host->host->set_storage(state.host, &state.msg->destination, &key, &value);
auto status = state.host.set_storage(state.msg->destination, key, value);
auto rev = static_cast<evmc_revision>(arg.number);
int cost = 0;
switch (status)
Expand Down Expand Up @@ -607,9 +605,7 @@ void op_jumpdest(execution_state&, instr_argument) noexcept

void op_gasprice(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
auto x = intx::be::uint256(state.tx_context.tx_gas_price.bytes);
auto x = intx::be::uint256(state.host.get_tx_context().tx_gas_price.bytes);
state.stack.push_back(x);
}

Expand All @@ -620,7 +616,7 @@ void op_extcodesize(execution_state& state, instr_argument) noexcept
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = state.host->host->get_code_size(state.host, &addr);
x = state.host.get_code_size(addr);
}

void op_extcodecopy(execution_state& state, instr_argument) noexcept
Expand Down Expand Up @@ -652,8 +648,7 @@ void op_extcodecopy(execution_state& state, instr_argument) noexcept
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));

auto num_bytes_copied =
state.host->host->copy_code(state.host, &addr, src, &state.memory[dst], s);
auto num_bytes_copied = state.host.copy_code(addr, src, &state.memory[dst], s);

std::memset(&state.memory[dst + num_bytes_copied], 0, s - num_bytes_copied);

Expand Down Expand Up @@ -718,67 +713,52 @@ void op_extcodehash(execution_state& state, instr_argument) noexcept
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = intx::be::uint256(state.host->host->get_code_hash(state.host, &addr).bytes);
x = intx::be::uint256(state.host.get_code_hash(addr).bytes);
}

void op_blockhash(execution_state& state, instr_argument) noexcept
{
auto& number = state.item(0);

// Load transaction context.
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);

auto upper_bound = state.tx_context.block_number;
auto upper_bound = state.host.get_tx_context().block_number;
auto lower_bound = std::max(upper_bound - 256, decltype(upper_bound){0});
auto n = static_cast<int64_t>(number);
auto header = evmc_bytes32{};
if (number < upper_bound && n >= lower_bound)
header = state.host->host->get_block_hash(state.host, n);
header = state.host.get_block_hash(n);
number = intx::be::uint256(header.bytes);
}

void op_coinbase(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
const auto& coinbase = state.host.get_tx_context().block_coinbase;
uint8_t data[32] = {};
std::memcpy(
&data[12], state.tx_context.block_coinbase.bytes, sizeof(state.tx_context.block_coinbase));
std::memcpy(&data[12], coinbase.bytes, sizeof(coinbase));
auto x = intx::be::uint256(data);
state.stack.push_back(x);
}

void op_timestamp(execution_state& state, instr_argument) noexcept
{
// TODO: Extract lazy tx context fetch.
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
auto x = intx::uint256{static_cast<uint64_t>(state.tx_context.block_timestamp)};
auto x = intx::uint256{static_cast<uint64_t>(state.host.get_tx_context().block_timestamp)};
state.stack.push_back(x);
}

void op_number(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
auto x = intx::uint256{static_cast<uint64_t>(state.tx_context.block_number)};
auto x = intx::uint256{static_cast<uint64_t>(state.host.get_tx_context().block_number)};
state.stack.push_back(x);
}

void op_difficulty(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
auto x = intx::be::uint256(state.tx_context.block_difficulty.bytes);
auto x = intx::be::uint256(state.host.get_tx_context().block_difficulty.bytes);
state.stack.push_back(x);
}

void op_gaslimit(execution_state& state, instr_argument) noexcept
{
if (state.tx_context.block_timestamp == 0)
state.tx_context = state.host->host->get_tx_context(state.host);
auto x = intx::uint256{static_cast<uint64_t>(state.tx_context.block_gas_limit)};
auto x = intx::uint256{static_cast<uint64_t>(state.host.get_tx_context().block_gas_limit)};
state.stack.push_back(x);
}

Expand Down Expand Up @@ -841,8 +821,8 @@ void op_log(execution_state& state, instr_argument arg) noexcept
state.stack.pop_back();
}

state.host->host->emit_log(state.host, &state.msg->destination, &state.memory[o], s,
topics.data(), static_cast<size_t>(arg.number));
state.host.emit_log(state.msg->destination, &state.memory[o], s, topics.data(),
static_cast<size_t>(arg.number));
}

void op_invalid(execution_state& state, instr_argument) noexcept
Expand Down Expand Up @@ -933,7 +913,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept
auto rev = EVMC_BYZANTIUM; // TODO: Support other revisions.
if (arg.call_kind == EVMC_CALL && (has_value || rev < EVMC_SPURIOUS_DRAGON))
{
if (!state.host->host->account_exists(state.host, &dst))
if (!state.host.account_exists(dst))
cost += 25000;
}

Expand Down Expand Up @@ -978,7 +958,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept

if (has_value)
{
auto balance = state.host->host->get_balance(state.host, &state.msg->destination);
auto balance = state.host.get_balance(state.msg->destination);
auto b = intx::be::uint256(balance.bytes);
if (b < value)
{
Expand All @@ -989,7 +969,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept
msg.gas += 2300; // Add stipend.
}

auto result = state.host->host->call(state.host, &msg);
auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);


Expand All @@ -1000,9 +980,6 @@ void op_call(execution_state& state, instr_argument arg) noexcept

auto gas_used = msg.gas - result.gas_left;

if (result.release)
result.release(&result);

if (has_value)
gas_used -= 2300;

Expand Down Expand Up @@ -1075,7 +1052,7 @@ void op_delegatecall(execution_state& state, instr_argument arg) noexcept
msg.input_data = &state.memory[size_t(input_offset)];
msg.input_size = size_t(input_size);

auto result = state.host->host->call(state.host, &msg);
auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);

state.item(0) = result.status_code == EVMC_SUCCESS;
Expand All @@ -1085,9 +1062,6 @@ void op_delegatecall(execution_state& state, instr_argument arg) noexcept

auto gas_used = msg.gas - result.gas_left;

if (result.release)
result.release(&result);

state.gas_left -= gas_used;
if (state.gas_left < 0)
{
Expand Down Expand Up @@ -1148,7 +1122,7 @@ void op_staticcall(execution_state& state, instr_argument arg) noexcept
msg.input_data = &state.memory[size_t(input_offset)];
msg.input_size = size_t(input_size);

auto result = state.host->host->call(state.host, &msg);
auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);
state.item(0) = result.status_code == EVMC_SUCCESS;

Expand All @@ -1157,9 +1131,6 @@ void op_staticcall(execution_state& state, instr_argument arg) noexcept

auto gas_used = msg.gas - result.gas_left;

if (result.release)
result.release(&result);

state.gas_left -= gas_used;
if (state.gas_left < 0)
{
Expand Down Expand Up @@ -1197,8 +1168,7 @@ void op_create(execution_state& state, instr_argument arg) noexcept

if (endowment != 0)
{
auto balance = intx::be::uint256(
state.host->host->get_balance(state.host, &state.msg->destination).bytes);
auto balance = intx::be::uint256(state.host.get_balance(state.msg->destination).bytes);
if (balance < endowment)
return;
}
Expand All @@ -1217,7 +1187,7 @@ void op_create(execution_state& state, instr_argument arg) noexcept
msg.depth = state.msg->depth + 1;
intx::be::store(msg.value.bytes, endowment);

auto result = state.host->host->call(state.host, &msg);
auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);
if (result.status_code == EVMC_SUCCESS)
{
Expand All @@ -1228,9 +1198,6 @@ void op_create(execution_state& state, instr_argument arg) noexcept

auto gas_used = msg.gas - result.gas_left;

if (result.release)
result.release(&result);

state.gas_left -= gas_used;
if (state.gas_left < 0)
{
Expand Down Expand Up @@ -1261,12 +1228,12 @@ void op_selfdestruct(execution_state& state, instr_argument) noexcept
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));

auto balance = state.host->host->get_balance(state.host, &state.msg->destination);
auto balance = state.host.get_balance(state.msg->destination);
if (!is_zero(balance))
{
// After EIP150 hard fork charge additional cost of sending
// ethers to non-existing account.
bool exists = state.host->host->account_exists(state.host, &addr);
bool exists = state.host.account_exists(addr);
if (!exists)
{
state.gas_left -= 25000;
Expand All @@ -1279,7 +1246,7 @@ void op_selfdestruct(execution_state& state, instr_argument) noexcept
}
}

state.host->host->selfdestruct(state.host, &state.msg->destination, &addr);
state.host.selfdestruct(state.msg->destination, addr);
state.run = false;
}

Expand Down Expand Up @@ -1406,7 +1373,7 @@ const auto op_table_initialized = []() noexcept
op_table[EVMC_SPURIOUS_DRAGON] = create_op_table_homestead();
op_table[EVMC_BYZANTIUM] = create_op_table_byzantium();
op_table[EVMC_CONSTANTINOPLE] = create_op_table_constantinople();
op_table[EVMC_CONSTANTINOPLE2] = create_op_table_petersburg();
op_table[EVMC_PETERSBURG] = create_op_table_petersburg();
return true;
}
();
Expand Down

0 comments on commit 45ff329

Please sign in to comment.