diff --git a/cmake/Hunter/config.cmake b/cmake/Hunter/config.cmake new file mode 100644 index 0000000000..f16fa826e1 --- /dev/null +++ b/cmake/Hunter/config.cmake @@ -0,0 +1 @@ +hunter_config(intx URL https://github.com/chfast/intx/archive/v0.4.0.tar.gz SHA1 8a2a0b0efa64899db972166a9b3568a6984c61bc) diff --git a/cmake/Hunter/init.cmake b/cmake/Hunter/init.cmake index 1bde32236b..4f3fd760f6 100644 --- a/cmake/Hunter/init.cmake +++ b/cmake/Hunter/init.cmake @@ -9,4 +9,5 @@ include(HunterGate) HunterGate( URL "https://github.com/ruslo/hunter/archive/v0.23.190.tar.gz" SHA1 "bc7da329d2493201de28f0c2a5fcd4de1415c477" -) \ No newline at end of file + LOCAL +) diff --git a/lib/evmone/instructions.cpp b/lib/evmone/instructions.cpp index 67ccb9bd97..f3b192c67e 100644 --- a/lib/evmone/instructions.cpp +++ b/lib/evmone/instructions.cpp @@ -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 @@ -163,7 +161,7 @@ void op_signextend(execution_state& state, instr_argument) noexcept if (ext < 31) { auto sign_bit = static_cast(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; @@ -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{}; @@ -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(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(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(state.host.get_balance(intx::be::trunc(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(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(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(state.msg->value)); } void op_calldataload(execution_state& state, instr_argument) noexcept @@ -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(data); } } @@ -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(index)]); + index = intx::be::unsafe::load(&state.memory[static_cast(index)]); } void op_mstore(execution_state& state, instr_argument) noexcept @@ -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(index)], value); + intx::be::unsafe::store(&state.memory[static_cast(index)], value); } void op_mstore8(execution_state& state, instr_argument) noexcept @@ -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( + state.host.get_storage(state.msg->destination, intx::be::store(x))); } void op_sstore(execution_state& state, instr_argument) noexcept @@ -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(state.stack.pop()); + const auto value = intx::be::store(state.stack.pop()); auto status = state.host.set_storage(state.msg->destination, key, value); int cost = 0; switch (status) @@ -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(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(x)); } void op_extcodecopy(execution_state& state, instr_argument) noexcept { - const auto addr_data = state.stack.pop(); + const auto addr = intx::be::trunc(state.stack.pop()); const auto mem_index = state.stack.pop(); const auto input_index = state.stack.pop(); const auto size = state.stack.pop(); @@ -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) @@ -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(state.host.get_code_hash(intx::be::trunc(x))); } void op_blockhash(execution_state& state, instr_argument) noexcept @@ -631,14 +599,12 @@ void op_blockhash(execution_state& state, instr_argument) noexcept const auto n = static_cast(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(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(state.host.get_tx_context().block_coinbase)); } void op_timestamp(execution_state& state, instr_argument) noexcept @@ -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(state.host.get_tx_context().block_difficulty)); } void op_gaslimit(execution_state& state, instr_argument) noexcept @@ -715,7 +681,7 @@ void op_log(execution_state& state, size_t num_topics) noexcept auto topics = std::array{}; for (size_t i = 0; i < num_topics; ++i) - intx::be::store(topics[i].bytes, state.stack.pop()); + topics[i] = intx::be::store(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); @@ -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(state.stack[1]); auto value = state.stack[2]; auto input_offset = state.stack[3]; auto input_size = state.stack[4]; @@ -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(value); auto correction = state.current_block_cost - arg.p.number; auto gas_left = state.gas_left + correction; @@ -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(value); if (size_t(input_size) > 0) { @@ -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(state.host.get_balance(state.msg->destination)); + if (balance < value) { state.gas_left += 2300; // Return unused stipend. if (state.gas_left < 0) @@ -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(state.stack[1]); auto input_offset = state.stack[2]; auto input_size = state.stack[3]; auto output_offset = state.stack[4]; @@ -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(state.stack[1]); auto input_offset = state.stack[2]; auto input_size = state.stack[3]; auto output_offset = state.stack[4]; @@ -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(state.host.get_balance(state.msg->destination)); if (balance < endowment) return; } @@ -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(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(result.create_address); if ((state.gas_left -= msg.gas - result.gas_left) < 0) return state.exit(EVMC_OUT_OF_GAS); @@ -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(state.host.get_balance(state.msg->destination)); if (balance < endowment) return; } @@ -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(salt); + msg.value = intx::be::store(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(result.create_address); if ((state.gas_left -= msg.gas - result.gas_left) < 0) return state.exit(EVMC_OUT_OF_GAS); @@ -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(state.stack[0]); if (state.rev >= EVMC_TANGERINE_WHISTLE) {