Skip to content

Commit

Permalink
Introduce particle gas costs for Istanbul
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Jul 24, 2019
1 parent bcdb16c commit cb4e20a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
15 changes: 13 additions & 2 deletions lib/evmone/analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ evmc_call_kind op2call_kind(uint8_t opcode) noexcept
code_analysis analyze(
const exec_fn_table& fns, evmc_revision rev, const uint8_t* code, size_t code_size) noexcept
{
// FIXME: change to an if outside
static auto to_gas_cost = [&](int64_t gas_cost)
{
if (rev >= EVMC_ISTANBUL)
return static_cast<int>(gas_cost / particles_per_gas);
else
return static_cast<int>(gas_cost);
};

code_analysis analysis;
// TODO: Check if final result exceeds the reservation.
analysis.instrs.reserve(code_size + 1);
Expand Down Expand Up @@ -113,11 +122,13 @@ code_analysis analyze(
else if (c >= OP_SWAP1 && c <= OP_SWAP16)
instr.arg.p.number = c - OP_SWAP1 + 1;
else if (c == OP_GAS)
instr.arg.p.number = static_cast<int>(block->gas_cost);
{
instr.arg.p.number = to_gas_cost(block->gas_cost);
}
else if (c == OP_DELEGATECALL || c == OP_CALL || c == OP_CALLCODE || c == OP_STATICCALL ||
c == OP_CREATE || c == OP_CREATE2)
{
instr.arg.p.number = static_cast<int>(block->gas_cost);
instr.arg.p.number = to_gas_cost(block->gas_cost);
instr.arg.p.call_kind = op2call_kind(c == OP_STATICCALL ? uint8_t{OP_CALL} : c);
}
else if (c == OP_PC)
Expand Down
2 changes: 2 additions & 0 deletions lib/evmone/analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ static_assert(continue_status == 0, "The 'continue' status is not 0");
/// The EVMC_INTERNAL_ERROR MUST NOT be used in evmone for any other case.
constexpr auto stop_status = EVMC_INTERNAL_ERROR;

constexpr unsigned particles_per_gas = 1000;

/// The stack for 256-bit EVM words.
///
/// This implementation reserves memory inplace for all possible stack items (1024),
Expand Down
6 changes: 6 additions & 0 deletions lib/evmone/execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ evmc_result execute(evmc_instance*, evmc_context* ctx, evmc_revision rev, const
state->host = evmc::HostContext{ctx};
state->gas_left = msg->gas;
state->rev = rev;
if (rev >= EVMC_ISTANBUL)
state->gas_left *= particles_per_gas;
while (state->status == continue_status)
{
auto& instr = analysis.instrs[state->pc];
Expand All @@ -44,7 +46,11 @@ evmc_result execute(evmc_instance*, evmc_context* ctx, evmc_revision rev, const
result.status_code = state->status != stop_status ? state->status : continue_status;

if (result.status_code == EVMC_SUCCESS || result.status_code == EVMC_REVERT)
{
result.gas_left = state->gas_left;
if (rev >= EVMC_ISTANBUL)
result.gas_left /= particles_per_gas;
}

if (state->output_size > 0)
{
Expand Down
8 changes: 6 additions & 2 deletions lib/evmone/instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ bool check_memory(execution_state& state, const uint256& offset, const uint256&
const auto new_size = o + s;
if (m < new_size)
{
auto cost_per_word = (state.rev >= EVMC_ISTANBUL) ? 3 : 3 * particles_per_gas;
auto w = (new_size + 31) / 32;
auto new_cost = 3 * w + w * w / 512;
auto new_cost = cost_per_word * w + w * w / 512;
auto cost = new_cost - state.memory_prev_cost;
state.memory_prev_cost = new_cost;

Expand Down Expand Up @@ -514,7 +515,10 @@ void op_gas(execution_state& state, instr_argument arg) noexcept
{
const auto correction = state.current_block_cost - arg.p.number;
const auto gas = static_cast<uint64_t>(state.gas_left + correction);
state.stack.push(gas);
if (state.rev >= EVMC_ISTANBUL)
state.stack.push(gas / particles_per_gas);
else
state.stack.push(gas);
}

void op_gasprice(execution_state& state, instr_argument) noexcept
Expand Down

0 comments on commit cb4e20a

Please sign in to comment.