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

Use new BE API from intx #131

Merged
merged 3 commits into from
Aug 27, 2019
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
1 change: 1 addition & 0 deletions cmake/Hunter/config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hunter_config(intx URL https://github.com/chfast/intx/archive/v0.4.0.tar.gz SHA1 8a2a0b0efa64899db972166a9b3568a6984c61bc)
3 changes: 2 additions & 1 deletion cmake/Hunter/init.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ include(HunterGate)
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.23.190.tar.gz"
SHA1 "bc7da329d2493201de28f0c2a5fcd4de1415c477"
)
LOCAL
)
144 changes: 43 additions & 101 deletions lib/evmone/instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,20 @@ void op_smod(execution_state& state, instr_argument) noexcept

void op_addmod(execution_state& state, instr_argument) noexcept
{
using intx::uint512;
const auto x = state.stack.pop();
const auto y = state.stack.pop();
auto& m = state.stack.top();

m = m != 0 ? ((uint512{x} + uint512{y}) % uint512{m}).lo : 0;
m = m != 0 ? intx::addmod(x, y, m) : 0;
}

void op_mulmod(execution_state& state, instr_argument) noexcept
{
using intx::uint512;
const auto x = state.stack.pop();
const auto y = state.stack.pop();
auto& m = state.stack.top();

m = m != 0 ? ((uint512{x} * uint512{y}) % uint512{m}).lo : 0;
m = m != 0 ? intx::mulmod(x, y, m) : 0;
}

void op_exp(execution_state& state, instr_argument) noexcept
Expand All @@ -163,7 +161,7 @@ void op_signextend(execution_state& state, instr_argument) noexcept
if (ext < 31)
{
auto sign_bit = static_cast<int>(ext) * 8 + 7;
auto sign_mask = intx::uint256{1} << sign_bit;
auto sign_mask = uint256{1} << sign_bit;
auto value_mask = sign_mask - 1;
auto is_neg = (x & sign_mask) != 0;
x = is_neg ? x | ~value_mask : x & value_mask;
Expand Down Expand Up @@ -261,7 +259,7 @@ void op_shr(execution_state& state, instr_argument) noexcept

void op_sar(execution_state& state, instr_argument arg) noexcept
{
if ((state.stack[1] & (intx::uint256{1} << 255)) == 0)
if ((state.stack[1] & (uint256{1} << 255)) == 0)
return op_shr(state, arg);

constexpr auto allones = ~uint256{};
Expand Down Expand Up @@ -293,47 +291,35 @@ void op_sha3(execution_state& state, instr_argument) noexcept
return state.exit(EVMC_OUT_OF_GAS);

auto data = s != 0 ? &state.memory[i] : nullptr;
auto h = ethash::keccak256(data, s);

size = intx::be::uint256(h.bytes);
size = intx::be::load<uint256>(ethash::keccak256(data, s));
}

void op_address(execution_state& state, instr_argument) noexcept
{
// TODO: Might be generalized using pointers to class member.
uint8_t data[32] = {};
std::memcpy(&data[12], state.msg->destination.bytes, sizeof(state.msg->destination));
state.stack.push(intx::be::uint256(data));
state.stack.push(intx::be::load<uint256>(state.msg->destination));
}

void op_balance(execution_state& state, instr_argument) noexcept
{
auto& x = state.stack.top();
uint8_t data[32];
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = intx::be::uint256(state.host.get_balance(addr).bytes);
x = intx::be::load<uint256>(state.host.get_balance(intx::be::trunc<evmc::address>(x)));
}

void op_origin(execution_state& state, instr_argument) noexcept
{
uint8_t data[32] = {};
std::memcpy(&data[12], state.host.get_tx_context().tx_origin.bytes, sizeof(evmc_address));
state.stack.push(intx::be::uint256(data));
state.stack.push(intx::be::load<uint256>(state.host.get_tx_context().tx_origin));
}

void op_caller(execution_state& state, instr_argument) noexcept
{
// TODO: Might be generalized using pointers to class member.
uint8_t data[32] = {};
std::memcpy(&data[12], state.msg->sender.bytes, sizeof(state.msg->sender));
state.stack.push(intx::be::uint256(data));
state.stack.push(intx::be::load<uint256>(state.msg->sender));
}

void op_callvalue(execution_state& state, instr_argument) noexcept
{
state.stack.push(intx::be::uint256(state.msg->value.bytes));
state.stack.push(intx::be::load<uint256>(state.msg->value));
}

void op_calldataload(execution_state& state, instr_argument) noexcept
Expand All @@ -351,7 +337,7 @@ void op_calldataload(execution_state& state, instr_argument) noexcept
for (size_t i = 0; i < (end - begin); ++i)
data[i] = state.msg->input_data[begin + i];

index = intx::be::uint256(data);
index = intx::be::load<uint256>(data);
}
}

Expand Down Expand Up @@ -426,7 +412,7 @@ void op_mload(execution_state& state, instr_argument) noexcept
if (!check_memory(state, index, 32))
return;

index = intx::be::uint256(&state.memory[static_cast<size_t>(index)]);
index = intx::be::unsafe::load<uint256>(&state.memory[static_cast<size_t>(index)]);
}

void op_mstore(execution_state& state, instr_argument) noexcept
Expand All @@ -437,7 +423,7 @@ void op_mstore(execution_state& state, instr_argument) noexcept
if (!check_memory(state, index, 32))
return;

intx::be::store(&state.memory[static_cast<size_t>(index)], value);
intx::be::unsafe::store(&state.memory[static_cast<size_t>(index)], value);
}

void op_mstore8(execution_state& state, instr_argument) noexcept
Expand All @@ -454,9 +440,8 @@ void op_mstore8(execution_state& state, instr_argument) noexcept
void op_sload(execution_state& state, instr_argument) noexcept
{
auto& x = state.stack.top();
evmc_bytes32 key;
intx::be::store(key.bytes, x);
x = intx::be::uint256(state.host.get_storage(state.msg->destination, key).bytes);
x = intx::be::load<uint256>(
state.host.get_storage(state.msg->destination, intx::be::store<evmc::bytes32>(x)));
}

void op_sstore(execution_state& state, instr_argument) noexcept
Expand All @@ -465,10 +450,8 @@ void op_sstore(execution_state& state, instr_argument) noexcept
if (state.msg->flags & EVMC_STATIC)
return state.exit(EVMC_STATIC_MODE_VIOLATION);

evmc_bytes32 key;
evmc_bytes32 value;
intx::be::store(key.bytes, state.stack.pop());
intx::be::store(value.bytes, state.stack.pop());
const auto key = intx::be::store<evmc::bytes32>(state.stack.pop());
const auto value = intx::be::store<evmc::bytes32>(state.stack.pop());
auto status = state.host.set_storage(state.msg->destination, key, value);
int cost = 0;
switch (status)
Expand Down Expand Up @@ -536,22 +519,18 @@ void op_gas(execution_state& state, instr_argument arg) noexcept

void op_gasprice(execution_state& state, instr_argument) noexcept
{
state.stack.push(intx::be::uint256(state.host.get_tx_context().tx_gas_price.bytes));
state.stack.push(intx::be::load<uint256>(state.host.get_tx_context().tx_gas_price));
}

void op_extcodesize(execution_state& state, instr_argument) noexcept
{
auto& x = state.stack.top();
uint8_t data[32];
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = state.host.get_code_size(addr);
x = state.host.get_code_size(intx::be::trunc<evmc::address>(x));
}

void op_extcodecopy(execution_state& state, instr_argument) noexcept
{
const auto addr_data = state.stack.pop();
const auto addr = intx::be::trunc<evmc::address>(state.stack.pop());
const auto mem_index = state.stack.pop();
const auto input_index = state.stack.pop();
const auto size = state.stack.pop();
Expand All @@ -567,13 +546,6 @@ void op_extcodecopy(execution_state& state, instr_argument) noexcept
if ((state.gas_left -= copy_cost) < 0)
return state.exit(EVMC_OUT_OF_GAS);

evmc_address addr;
{
uint8_t tmp[32];
intx::be::store(tmp, addr_data);
std::memcpy(addr.bytes, &tmp[12], sizeof(addr));
}

auto data = s != 0 ? &state.memory[dst] : nullptr;
auto num_bytes_copied = state.host.copy_code(addr, src, data, s);
if (s - num_bytes_copied > 0)
Expand Down Expand Up @@ -615,11 +587,7 @@ void op_returndatacopy(execution_state& state, instr_argument) noexcept
void op_extcodehash(execution_state& state, instr_argument) noexcept
{
auto& x = state.stack.top();
uint8_t data[32];
intx::be::store(data, x);
evmc_address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
x = intx::be::uint256(state.host.get_code_hash(addr).bytes);
x = intx::be::load<uint256>(state.host.get_code_hash(intx::be::trunc<evmc::address>(x)));
}

void op_blockhash(execution_state& state, instr_argument) noexcept
Expand All @@ -631,14 +599,12 @@ void op_blockhash(execution_state& state, instr_argument) noexcept
const auto n = static_cast<int64_t>(number);
const auto header =
(number < upper_bound && n >= lower_bound) ? state.host.get_block_hash(n) : evmc::bytes32{};
number = intx::be::uint256(header.bytes);
number = intx::be::load<uint256>(header);
}

void op_coinbase(execution_state& state, instr_argument) noexcept
{
uint8_t data[32] = {};
std::memcpy(&data[12], state.host.get_tx_context().block_coinbase.bytes, sizeof(evmc_address));
state.stack.push(intx::be::uint256(data));
state.stack.push(intx::be::load<uint256>(state.host.get_tx_context().block_coinbase));
}

void op_timestamp(execution_state& state, instr_argument) noexcept
Expand All @@ -657,7 +623,7 @@ void op_number(execution_state& state, instr_argument) noexcept

void op_difficulty(execution_state& state, instr_argument) noexcept
{
state.stack.push(intx::be::uint256(state.host.get_tx_context().block_difficulty.bytes));
state.stack.push(intx::be::load<uint256>(state.host.get_tx_context().block_difficulty));
}

void op_gaslimit(execution_state& state, instr_argument) noexcept
Expand Down Expand Up @@ -715,7 +681,7 @@ void op_log(execution_state& state, size_t num_topics) noexcept

auto topics = std::array<evmc::bytes32, 4>{};
for (size_t i = 0; i < num_topics; ++i)
intx::be::store(topics[i].bytes, state.stack.pop());
topics[i] = intx::be::store<evmc::bytes32>(state.stack.pop());

const auto data = s != 0 ? &state.memory[o] : nullptr;
state.host.emit_log(state.msg->destination, data, s, topics.data(), num_topics);
Expand Down Expand Up @@ -762,12 +728,7 @@ void op_revert(execution_state& state, instr_argument) noexcept
void op_call(execution_state& state, instr_argument arg) noexcept
{
auto gas = state.stack[0];

uint8_t data[32];
intx::be::store(data, state.stack[1]);
auto dst = evmc_address{};
std::memcpy(dst.bytes, &data[12], sizeof(dst));

const auto dst = intx::be::trunc<evmc::address>(state.stack[1]);
auto value = state.stack[2];
auto input_offset = state.stack[3];
auto input_size = state.stack[4];
Expand All @@ -792,7 +753,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept
auto msg = evmc_message{};
msg.kind = arg.p.call_kind;
msg.flags = state.msg->flags;
intx::be::store(msg.value.bytes, value);
msg.value = intx::be::store<evmc::uint256be>(value);

auto correction = state.current_block_cost - arg.p.number;
auto gas_left = state.gas_left + correction;
Expand Down Expand Up @@ -838,7 +799,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept

msg.destination = dst;
msg.sender = state.msg->destination;
intx::be::store(msg.value.bytes, value);
msg.value = intx::be::store<evmc::uint256be>(value);

if (size_t(input_size) > 0)
{
Expand All @@ -850,9 +811,9 @@ void op_call(execution_state& state, instr_argument arg) noexcept

if (has_value)
{
auto balance = state.host.get_balance(state.msg->destination);
auto b = intx::be::uint256(balance.bytes);
if (b < value)
const auto balance =
intx::be::load<uint256>(state.host.get_balance(state.msg->destination));
if (balance < value)
{
state.gas_left += 2300; // Return unused stipend.
if (state.gas_left < 0)
Expand Down Expand Up @@ -884,12 +845,7 @@ void op_call(execution_state& state, instr_argument arg) noexcept
void op_delegatecall(execution_state& state, instr_argument arg) noexcept
{
auto gas = state.stack[0];

uint8_t data[32];
intx::be::store(data, state.stack[1]);
auto dst = evmc_address{};
std::memcpy(dst.bytes, &data[12], sizeof(dst));

const auto dst = intx::be::trunc<evmc::address>(state.stack[1]);
auto input_offset = state.stack[2];
auto input_size = state.stack[3];
auto output_offset = state.stack[4];
Expand Down Expand Up @@ -956,12 +912,7 @@ void op_delegatecall(execution_state& state, instr_argument arg) noexcept
void op_staticcall(execution_state& state, instr_argument arg) noexcept
{
auto gas = state.stack[0];

uint8_t data[32];
intx::be::store(data, state.stack[1]);
auto dst = evmc_address{};
std::memcpy(dst.bytes, &data[12], sizeof(dst));

const auto dst = intx::be::trunc<evmc::address>(state.stack[1]);
auto input_offset = state.stack[2];
auto input_size = state.stack[3];
auto output_offset = state.stack[4];
Expand Down Expand Up @@ -1043,7 +994,8 @@ void op_create(execution_state& state, instr_argument arg) noexcept

if (endowment != 0)
{
auto balance = intx::be::uint256(state.host.get_balance(state.msg->destination).bytes);
const auto balance =
intx::be::load<uint256>(state.host.get_balance(state.msg->destination));
if (balance < endowment)
return;
}
Expand All @@ -1065,16 +1017,12 @@ void op_create(execution_state& state, instr_argument arg) noexcept

msg.sender = state.msg->destination;
msg.depth = state.msg->depth + 1;
intx::be::store(msg.value.bytes, endowment);
msg.value = intx::be::store<evmc::uint256be>(endowment);

auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);
if (result.status_code == EVMC_SUCCESS)
{
uint8_t data[32] = {};
std::memcpy(&data[12], &result.create_address, sizeof(result.create_address));
state.stack[0] = intx::be::uint256(data);
}
state.stack[0] = intx::be::load<uint256>(result.create_address);

if ((state.gas_left -= msg.gas - result.gas_left) < 0)
return state.exit(EVMC_OUT_OF_GAS);
Expand Down Expand Up @@ -1110,7 +1058,8 @@ void op_create2(execution_state& state, instr_argument arg) noexcept

if (endowment != 0)
{
auto balance = intx::be::uint256(state.host.get_balance(state.msg->destination).bytes);
const auto balance =
intx::be::load<uint256>(state.host.get_balance(state.msg->destination));
if (balance < endowment)
return;
}
Expand All @@ -1129,17 +1078,13 @@ void op_create2(execution_state& state, instr_argument arg) noexcept
}
msg.sender = state.msg->destination;
msg.depth = state.msg->depth + 1;
intx::be::store(msg.create2_salt.bytes, salt);
intx::be::store(msg.value.bytes, endowment);
msg.create2_salt = intx::be::store<evmc::bytes32>(salt);
msg.value = intx::be::store<evmc::uint256be>(endowment);

auto result = state.host.call(msg);
state.return_data.assign(result.output_data, result.output_size);
if (result.status_code == EVMC_SUCCESS)
{
uint8_t data[32] = {};
std::memcpy(&data[12], &result.create_address, sizeof(result.create_address));
state.stack[0] = intx::be::uint256(data);
}
state.stack[0] = intx::be::load<uint256>(result.create_address);

if ((state.gas_left -= msg.gas - result.gas_left) < 0)
return state.exit(EVMC_OUT_OF_GAS);
Expand All @@ -1155,10 +1100,7 @@ void op_selfdestruct(execution_state& state, instr_argument) noexcept
if (state.msg->flags & EVMC_STATIC)
return state.exit(EVMC_STATIC_MODE_VIOLATION);

uint8_t data[32];
intx::be::store(data, state.stack[0]);
evmc::address addr;
std::memcpy(addr.bytes, &data[12], sizeof(addr));
const auto addr = intx::be::trunc<evmc::address>(state.stack[0]);

if (state.rev >= EVMC_TANGERINE_WHISTLE)
{
Expand Down