diff --git a/.github/workflows/rpc-integration-tests.yml b/.github/workflows/rpc-integration-tests.yml index 4ce8d476a2..8f3910d3f1 100644 --- a/.github/workflows/rpc-integration-tests.yml +++ b/.github/workflows/rpc-integration-tests.yml @@ -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.39.0 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests + git -c advice.detachedHead=false clone --depth 1 --branch v0.40.0 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests cd ${{runner.workspace}}/rpc-tests pip3 install -r requirements.txt diff --git a/silkworm/rpc/core/evm_trace.cpp b/silkworm/rpc/core/evm_trace.cpp index d39649af70..a15fed4191 100644 --- a/silkworm/rpc/core/evm_trace.cpp +++ b/silkworm/rpc/core/evm_trace.cpp @@ -856,9 +856,8 @@ void TraceTracer::on_execution_start(evmc_revision rev, const evmc_message& msg, trace_action.to = recipient; switch (msg.kind) { case evmc_call_kind::EVMC_CALL: - if (traces_.size() > 1) { - Trace& prev_trace = traces_[traces_.size() - 2]; - trace_action.call_type = prev_trace.op_code == OP_STATICCALL ? "staticcall" : "call"; + if (last_opcode_) { + trace_action.call_type = last_opcode_ == OP_STATICCALL ? "staticcall" : "call"; } else { trace_action.call_type = "call"; } @@ -870,6 +869,7 @@ void TraceTracer::on_execution_start(evmc_revision rev, const evmc_message& msg, break; case evmc_call_kind::EVMC_CALLCODE: trace_action.call_type = "callcode"; + trace_action.to = code_address; break; case evmc_call_kind::EVMC_CREATE: case evmc_call_kind::EVMC_CREATE2: @@ -906,7 +906,7 @@ void TraceTracer::on_execution_start(evmc_revision rev, const evmc_message& msg, void TraceTracer::on_instruction_start(uint32_t pc, const intx::uint256* stack_top, const int stack_height, const int64_t gas, const evmone::ExecutionState& execution_state, const silkworm::IntraBlockState& /*intra_block_state*/) noexcept { const auto opcode = execution_state.original_code[pc]; - current_opcode_ = opcode; + last_opcode_ = opcode; Trace& last_trace = traces_[traces_.size() - 1]; last_trace.stack_height = stack_height; @@ -995,7 +995,7 @@ void TraceTracer::on_execution_end(const evmc_result& result, const silkworm::In trace.trace_result.reset(); break; case evmc_status_code::EVMC_UNDEFINED_INSTRUCTION: - trace.error = "invalid opcode: opcode " + get_opcode_hex(current_opcode_.value_or(0)) + " not defined"; + trace.error = "invalid opcode: opcode " + get_opcode_hex(last_opcode_.value_or(0)) + " not defined"; trace.trace_result.reset(); break; case evmc_status_code::EVMC_INVALID_INSTRUCTION: @@ -1018,7 +1018,7 @@ void TraceTracer::on_execution_end(const evmc_result& result, const silkworm::In break; } - current_opcode_.reset(); + last_opcode_.reset(); SILK_DEBUG << "TraceTracer::on_execution_end:" << " result.status_code: " << result.status_code @@ -1907,11 +1907,14 @@ void EntryTracer::on_execution_start(evmc_revision rev, const evmc_message& msg, str_input = "0x" + silkworm::to_hex(code); result_.push_back(TraceEntry{"CREATE2", msg.depth, sender, recipient, str_value, str_input}); } else { - const bool in_static_mode = (msg.flags & evmc_flags::EVMC_STATIC) != 0; switch (msg.kind) { - case evmc_call_kind::EVMC_CALL: - in_static_mode ? result_.push_back(TraceEntry{"STATICCALL", msg.depth, sender, recipient, "", str_input}) : result_.push_back(TraceEntry{"CALL", msg.depth, sender, recipient, str_value, str_input}); - break; + case evmc_call_kind::EVMC_CALL: { + if (last_opcode_ == OP_STATICCALL) { + result_.push_back(TraceEntry{"STATICCALL", msg.depth, sender, recipient, "", str_input}); + } else { + result_.push_back(TraceEntry{"CALL", msg.depth, sender, recipient, str_value, str_input}); + } + } break; case evmc_call_kind::EVMC_DELEGATECALL: result_.push_back(TraceEntry{"DELEGATECALL", msg.depth, recipient, code_address, "", str_input}); break; @@ -1937,6 +1940,11 @@ void EntryTracer::on_execution_start(evmc_revision rev, const evmc_message& msg, << ", msg.input_data: " << to_hex(ByteView{msg.input_data, msg.input_size}); } +void EntryTracer::on_instruction_start(uint32_t pc, const intx::uint256* /* stack_top */, const int /* stack_height */, const int64_t /* gas */, + const evmone::ExecutionState& execution_state, const silkworm::IntraBlockState& /* intra_block_state */) noexcept { + last_opcode_ = execution_state.original_code[pc]; +} + void OperationTracer::on_self_destruct(const evmc::address& address, const evmc::address& beneficiary) noexcept { auto balance = initial_ibs_.get_balance(address); result_.push_back(InternalOperation{OperationType::OP_SELF_DESTRUCT, address, beneficiary, "0x" + intx::to_string(balance, 16)}); diff --git a/silkworm/rpc/core/evm_trace.hpp b/silkworm/rpc/core/evm_trace.hpp index 6f961d6bad..b101c25fe1 100644 --- a/silkworm/rpc/core/evm_trace.hpp +++ b/silkworm/rpc/core/evm_trace.hpp @@ -255,7 +255,7 @@ class TraceTracer : public silkworm::EvmTracer { bool is_precompile_{false}; std::vector& traces_; silkworm::IntraBlockState& initial_ibs_; - std::optional current_opcode_; + std::optional last_opcode_; const char* const* opcode_names_ = nullptr; int64_t initial_gas_{0}; int32_t current_depth_{-1}; @@ -427,6 +427,9 @@ class EntryTracer : public silkworm::EvmTracer { void on_execution_start(evmc_revision rev, const evmc_message& msg, evmone::bytes_view code) noexcept override; void on_execution_end(const evmc_result& result, const silkworm::IntraBlockState& intra_block_state) noexcept override; + void on_instruction_start(uint32_t pc, const intx::uint256* stack_top, int stack_height, + int64_t gas, const evmone::ExecutionState& execution_state, + const silkworm::IntraBlockState& intra_block_state) noexcept override; void on_self_destruct(const evmc::address& address, const evmc::address& beneficiary) noexcept override; TraceEntriesResult result() const { return result_; } @@ -436,6 +439,7 @@ class EntryTracer : public silkworm::EvmTracer { TraceEntriesResult result_; std::stack traces_stack_idx_; int32_t current_depth_{-1}; + std::optional last_opcode_; }; class OperationTracer : public silkworm::EvmTracer {