Skip to content

Commit d763a4c

Browse files
authored
rpcdaemon: SuicideAction implementation in trace API (#2111)
1 parent 6542d38 commit d763a4c

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

.github/workflows/rpc-integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Checkout RPC Tests Repository & Install Requirements
2828
run: |
2929
rm -rf ${{runner.workspace}}/rpc-tests
30-
git -c advice.detachedHead=false clone --depth 1 --branch v0.24.0 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests
30+
git -c advice.detachedHead=false clone --depth 1 --branch v0.25.3 https://github.com/erigontech/rpc-tests ${{runner.workspace}}/rpc-tests
3131
cd ${{runner.workspace}}/rpc-tests
3232
pip3 install -r requirements.txt
3333

silkworm/rpc/core/evm_trace.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ void to_json(nlohmann::json& json, const RewardAction& action) {
186186
json["value"] = to_quantity(action.value);
187187
}
188188

189+
void to_json(nlohmann::json& json, const SuicideAction& action) {
190+
json["address"] = action.address;
191+
json["balance"] = to_quantity(action.balance);
192+
json["refundAddress"] = action.refund_address;
193+
}
194+
189195
void to_json(nlohmann::json& json, const TraceResult& trace_result) {
190196
if (trace_result.address) {
191197
json["address"] = trace_result.address.value();
@@ -206,6 +212,8 @@ void to_json(nlohmann::json& json, const Trace& trace) {
206212
json["action"] = std::get<TraceAction>(trace.action);
207213
} else if (std::holds_alternative<RewardAction>(trace.action)) {
208214
json["action"] = std::get<RewardAction>(trace.action);
215+
} else if (std::holds_alternative<SuicideAction>(trace.action)) {
216+
json["action"] = std::get<SuicideAction>(trace.action);
209217
}
210218
if (trace.trace_result) {
211219
json["result"] = trace.trace_result.value();
@@ -462,6 +470,19 @@ int get_stack_count(std::uint8_t op_code) {
462470
return count;
463471
}
464472

473+
void copy_address(const evmone::uint256* stack, std::string& address) {
474+
std::string addr{"0000000000000000000000000000000000000000"};
475+
auto hex = intx::hex(stack[0]);
476+
auto pos = static_cast<int>(addr.size()) - static_cast<int>(hex.size());
477+
478+
if (pos > 0) {
479+
std::copy(hex.begin(), hex.end(), addr.begin() + pos);
480+
} else {
481+
addr = hex;
482+
}
483+
address = "0x" + addr;
484+
}
485+
465486
void copy_stack(std::uint8_t op_code, const evmone::uint256* stack, std::vector<std::string>& trace_stack) {
466487
const int top = get_stack_count(op_code);
467488
trace_stack.reserve(top > 0 ? static_cast<std::size_t>(top) : 0);
@@ -797,12 +818,41 @@ void TraceTracer::on_execution_start(evmc_revision rev, const evmc_message& msg,
797818
<< ", code: " << silkworm::to_hex(code);
798819
}
799820

800-
void TraceTracer::on_instruction_start(uint32_t pc, const intx::uint256* /*stack_top*/, const int /*stack_height*/, const int64_t gas,
821+
void TraceTracer::on_instruction_start(uint32_t pc, const intx::uint256* stack_top, const int /*stack_height*/, const int64_t gas,
801822
const evmone::ExecutionState& execution_state, const silkworm::IntraBlockState& /*intra_block_state*/) noexcept {
802823
const auto opcode = execution_state.original_code[pc];
803-
auto opcode_name = get_opcode_name(opcode_names_, opcode);
804-
805824
current_opcode_ = opcode;
825+
826+
if (opcode == OP_SELFDESTRUCT) {
827+
std::size_t idx = traces_.size();
828+
traces_.resize(traces_.size() + 1);
829+
Trace& trace = traces_[idx];
830+
trace.type = "suicide";
831+
trace.action = SuicideAction{};
832+
833+
auto index = index_stack_.top();
834+
Trace& calling_trace = traces_[index];
835+
auto& calling_action = std::get<TraceAction>(calling_trace.action);
836+
837+
auto& suicide_action = std::get<SuicideAction>(trace.action);
838+
if (calling_trace.trace_result && calling_trace.trace_result->address) {
839+
suicide_action.address = calling_trace.trace_result->address.value();
840+
} else if (calling_action.to) {
841+
suicide_action.address = calling_action.to.value();
842+
}
843+
suicide_action.balance = 0;
844+
copy_address(stack_top, suicide_action.refund_address);
845+
846+
trace.trace_address = calling_trace.trace_address;
847+
trace.trace_address.push_back(calling_trace.sub_traces);
848+
849+
calling_trace.sub_traces++;
850+
851+
nlohmann::json trace_json = trace;
852+
nlohmann::json calling_trace_json = calling_trace;
853+
}
854+
855+
auto opcode_name = get_opcode_name(opcode_names_, opcode);
806856
SILK_DEBUG << "TraceTracer::on_instruction_start:"
807857
<< " pc: " << std::dec << pc
808858
<< ", opcode: 0x" << std::hex << evmc::hex(opcode)
@@ -822,6 +872,7 @@ void TraceTracer::on_execution_end(const evmc_result& result, const silkworm::In
822872
is_precompile_ = false;
823873
return;
824874
}
875+
825876
auto index = index_stack_.top();
826877
auto start_gas = start_gas_.top();
827878

@@ -1172,8 +1223,8 @@ Task<std::vector<Trace>> TraceCallExecutor::trace_block(const BlockWithHash& blo
11721223

11731224
for (const auto& call_trace : call_traces) {
11741225
Trace trace{call_trace};
1175-
nlohmann::json json = trace;
11761226
bool skip = !(filter.from_addresses.empty() && filter.to_addresses.empty());
1227+
11771228
if (std::holds_alternative<TraceAction>(trace.action)) {
11781229
const auto& action = std::get<TraceAction>(trace.action);
11791230
if (skip && !filter.from_addresses.empty()) {
@@ -1602,6 +1653,7 @@ Task<void> TraceCallExecutor::trace_filter(const TraceFilter& trace_filter, cons
16021653
if (from_block_with_hash->block.header.number > to_block_with_hash->block.header.number) {
16031654
const Error error{-32000, "invalid parameters: fromBlock cannot be greater than toBlock"};
16041655
stream.write_json_field("error", error);
1656+
stream.write_json_field("result", nlohmann::json::value_t::null);
16051657
co_return;
16061658
}
16071659

silkworm/rpc/core/evm_trace.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void to_json(nlohmann::json& json, const TraceEx& trace_ex);
120120
void to_json(nlohmann::json& json, const TraceMemory& trace_memory);
121121
void to_json(nlohmann::json& json, const TraceStorage& trace_storage);
122122

123+
void copy_address(const evmone::uint256* stack, std::string& address);
123124
void copy_stack(std::uint8_t op_code, const evmone::uint256* stack, std::vector<std::string>& trace_stack);
124125
void copy_memory(const evmone::Memory& memory, std::optional<TraceMemory>& trace_memory);
125126
void copy_store(std::uint8_t op_code, const evmone::uint256* stack, std::optional<TraceStorage>& trace_storage);
@@ -168,7 +169,13 @@ struct RewardAction {
168169
intx::uint256 value{0};
169170
};
170171

171-
using Action = std::variant<TraceAction, RewardAction>;
172+
struct SuicideAction {
173+
evmc::address address;
174+
std::string refund_address;
175+
intx::uint256 balance{0};
176+
};
177+
178+
using Action = std::variant<TraceAction, RewardAction, SuicideAction>;
172179

173180
struct TraceResult {
174181
std::optional<evmc::address> address;
@@ -192,6 +199,7 @@ struct Trace {
192199

193200
void to_json(nlohmann::json& json, const TraceAction& action);
194201
void to_json(nlohmann::json& json, const RewardAction& action);
202+
void to_json(nlohmann::json& json, const SuicideAction& action);
195203
void to_json(nlohmann::json& json, const TraceResult& trace_result);
196204
void to_json(nlohmann::json& json, const Trace& trace);
197205

0 commit comments

Comments
 (0)