Skip to content

Commit

Permalink
Merge pull request #131 from ethereum/intx
Browse files Browse the repository at this point in the history
Use new BE API from intx
  • Loading branch information
chfast authored Aug 27, 2019
2 parents 197e560 + 327cda3 commit b6da2b3
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 102 deletions.
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

0 comments on commit b6da2b3

Please sign in to comment.