Skip to content

Commit

Permalink
rpcdaemon: fix debug/trace API family gas cost step 2 (#2172)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sixtysixter authored Jul 18, 2024
1 parent 63cfdfd commit 9e15853
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/rpc-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Checkout RPC Tests Repository & Install Requirements
run: |
rm -rf ${{runner.workspace}}/rpc-tests
git -c advice.detachedHead=false clone --depth 1 --branch v0.31.0 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests
git -c advice.detachedHead=false clone --depth 1 --branch v0.32.0 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests
cd ${{runner.workspace}}/rpc-tests
pip3 install -r requirements.txt
Expand Down
71 changes: 55 additions & 16 deletions silkworm/rpc/core/evm_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ void DebugTracer::on_execution_start(evmc_revision rev, const evmc_message& msg,
const evmc::address recipient(msg.recipient);
const evmc::address sender(msg.sender);

SILK_DEBUG << "on_execution_start: gas: " << std::dec << msg.gas
SILK_DEBUG << "on_execution_start:"
<< " rev: " << rev
<< " gas: " << std::dec << msg.gas
<< " depth: " << msg.depth
<< " recipient: " << recipient
<< " sender: " << sender
Expand Down Expand Up @@ -160,8 +162,8 @@ void DebugTracer::on_instruction_start(uint32_t pc, const intx::uint256* stack_t
if (call_fixes_) { // previuos opcodw was a CALL*
if (execution_state.msg->depth == call_fixes_->depth) {
if (call_fixes_->gas_cost) {
log.gas_cost = call_fixes_->gas_cost;
} else {
log.gas_cost = call_fixes_->gas_cost + call_fixes_->code_cost;
} else if (!call_fixes_->precompiled) {
log.gas_cost = log.gas - gas + call_fixes_->stipend;
}
} else {
Expand All @@ -183,14 +185,7 @@ void DebugTracer::on_instruction_start(uint32_t pc, const intx::uint256* stack_t
logs_.erase(logs_.begin());
}

if (opcode == OP_CALL || opcode == OP_CALLCODE || opcode == OP_STATICCALL || opcode == OP_DELEGATECALL || opcode == OP_CREATE || opcode == OP_CREATE2) {
call_fixes_ = std::make_unique<CallFixes>(CallFixes{execution_state.msg->depth, 0, metrics_[opcode].gas_cost});
if (opcode == OP_CALL && stack_height >= 7 && stack_top[-2] != 0) {
call_fixes_->stipend = 2300; // for CALLs with value, include stipend
}

call_fixes_->code_cost = metrics_[opcode].gas_cost;
}
evaluate_call_fixes(opcode, execution_state, stack_top, stack_height, intra_block_state);

DebugLog log;
log.pc = pc;
Expand Down Expand Up @@ -222,7 +217,9 @@ void DebugTracer::on_precompiled_run(const evmc_result& result, int64_t gas, con
<< ", gas: " << std::dec << gas;

if (call_fixes_) {
call_fixes_->gas_cost = gas + call_fixes_->code_cost;
call_fixes_->gas_cost += gas + call_fixes_->code_cost;
call_fixes_->code_cost = 0;
call_fixes_->precompiled = true;
}
}

Expand All @@ -233,10 +230,6 @@ void DebugTracer::on_execution_end(const evmc_result& result, const silkworm::In
if (!logs_.empty()) {
auto& log = logs_[logs_.size() - 1];

if (call_fixes_) {
log.gas_cost += call_fixes_->stipend;
}

insert_error(log, result.status_code);

switch (result.status_code) {
Expand All @@ -247,7 +240,26 @@ void DebugTracer::on_execution_end(const evmc_result& result, const silkworm::In
log.gas_cost = 0;
break;

case evmc_status_code::EVMC_OUT_OF_GAS:
if (call_fixes_) {
log.gas_cost += call_fixes_->gas_cost;
}
break;

default:
if (call_fixes_) {
if (result.gas_left == 0 && !call_fixes_->precompiled) {
log.gas_cost = call_fixes_->stipend + call_fixes_->gas_cost;
} else if (!call_fixes_->precompiled) {
log.gas_cost = result.gas_left + call_fixes_->gas_cost + call_fixes_->code_cost;
call_fixes_->gas_cost = 0;
} else if (call_fixes_->precompiled) {
log.gas_cost = call_fixes_->gas_cost;
call_fixes_->gas_cost = 0;
} else {
call_fixes_->gas_cost = 0;
}
}
break;
}
}
Expand All @@ -270,6 +282,33 @@ void DebugTracer::flush_logs() {
}
}

void DebugTracer::evaluate_call_fixes(unsigned char opcode, const evmone::ExecutionState& execution_state, const intx::uint256* stack_top, const int stack_height, const silkworm::IntraBlockState& intra_block_state) {
if (opcode == OP_CALL || opcode == OP_CALLCODE || opcode == OP_STATICCALL || opcode == OP_DELEGATECALL || opcode == OP_CREATE || opcode == OP_CREATE2) {
call_fixes_ = std::make_unique<CallFixes>(CallFixes{execution_state.msg->depth, 0, metrics_[opcode].gas_cost});
const auto value = stack_top[-2]; // value
if (value != 0) {
call_fixes_->gas_cost += 9000;
}
if (opcode == OP_CALL) {
if (opcode == OP_CALL && stack_height >= 7 && value != 0) {
call_fixes_->stipend = 2300; // for CALLs with value, include stipend
}
const auto call_gas = stack_top[0]; // gas
const auto dst = intx::be::trunc<evmc::address>(stack_top[-1]); // dst

if ((value != 0 || execution_state.rev < EVMC_SPURIOUS_DRAGON) && !intra_block_state.exists(dst)) {
call_fixes_->gas_cost += 25000;
}
SILK_DEBUG << "DebugTracer::evaluate_call_fixes:"
<< " call_gas: " << call_gas
<< " dst: " << dst
<< " value: " << value
<< " gas_cost: " << call_fixes_->gas_cost
<< " stipend: " << call_fixes_->stipend;
}
}
}

void AccountTracer::on_execution_end(const evmc_result& /*result*/, const silkworm::IntraBlockState& intra_block_state) noexcept {
nonce = intra_block_state.get_nonce(address_);
balance = intra_block_state.get_balance(address_);
Expand Down
2 changes: 2 additions & 0 deletions silkworm/rpc/core/evm_debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct CallFixes {
int64_t stipend{0};
int16_t code_cost{0};
int64_t gas_cost{0};
bool precompiled{false};
};

class DebugTracer : public EvmTracer {
Expand All @@ -97,6 +98,7 @@ class DebugTracer : public EvmTracer {

private:
void write_log(const DebugLog& log);
void evaluate_call_fixes(unsigned char opcode, const evmone::ExecutionState& execution_state, const intx::uint256* stack_top, const int stack_height, const silkworm::IntraBlockState& intra_block_state);

json::Stream& stream_;
const DebugConfig& config_;
Expand Down

0 comments on commit 9e15853

Please sign in to comment.