@@ -186,6 +186,12 @@ void to_json(nlohmann::json& json, const RewardAction& action) {
186
186
json[" value" ] = to_quantity (action.value );
187
187
}
188
188
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
+
189
195
void to_json (nlohmann::json& json, const TraceResult& trace_result) {
190
196
if (trace_result.address ) {
191
197
json[" address" ] = trace_result.address .value ();
@@ -206,6 +212,8 @@ void to_json(nlohmann::json& json, const Trace& trace) {
206
212
json[" action" ] = std::get<TraceAction>(trace.action );
207
213
} else if (std::holds_alternative<RewardAction>(trace.action )) {
208
214
json[" action" ] = std::get<RewardAction>(trace.action );
215
+ } else if (std::holds_alternative<SuicideAction>(trace.action )) {
216
+ json[" action" ] = std::get<SuicideAction>(trace.action );
209
217
}
210
218
if (trace.trace_result ) {
211
219
json[" result" ] = trace.trace_result .value ();
@@ -462,6 +470,19 @@ int get_stack_count(std::uint8_t op_code) {
462
470
return count;
463
471
}
464
472
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
+
465
486
void copy_stack (std::uint8_t op_code, const evmone::uint256* stack, std::vector<std::string>& trace_stack) {
466
487
const int top = get_stack_count (op_code);
467
488
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,
797
818
<< " , code: " << silkworm::to_hex (code);
798
819
}
799
820
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,
801
822
const evmone::ExecutionState& execution_state, const silkworm::IntraBlockState& /* intra_block_state*/ ) noexcept {
802
823
const auto opcode = execution_state.original_code [pc];
803
- auto opcode_name = get_opcode_name (opcode_names_, opcode);
804
-
805
824
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);
806
856
SILK_DEBUG << " TraceTracer::on_instruction_start:"
807
857
<< " pc: " << std::dec << pc
808
858
<< " , opcode: 0x" << std::hex << evmc::hex (opcode)
@@ -822,6 +872,7 @@ void TraceTracer::on_execution_end(const evmc_result& result, const silkworm::In
822
872
is_precompile_ = false ;
823
873
return ;
824
874
}
875
+
825
876
auto index = index_stack_.top ();
826
877
auto start_gas = start_gas_.top ();
827
878
@@ -1172,8 +1223,8 @@ Task<std::vector<Trace>> TraceCallExecutor::trace_block(const BlockWithHash& blo
1172
1223
1173
1224
for (const auto & call_trace : call_traces) {
1174
1225
Trace trace{call_trace};
1175
- nlohmann::json json = trace;
1176
1226
bool skip = !(filter.from_addresses .empty () && filter.to_addresses .empty ());
1227
+
1177
1228
if (std::holds_alternative<TraceAction>(trace.action )) {
1178
1229
const auto & action = std::get<TraceAction>(trace.action );
1179
1230
if (skip && !filter.from_addresses .empty ()) {
@@ -1602,6 +1653,7 @@ Task<void> TraceCallExecutor::trace_filter(const TraceFilter& trace_filter, cons
1602
1653
if (from_block_with_hash->block .header .number > to_block_with_hash->block .header .number ) {
1603
1654
const Error error{-32000 , " invalid parameters: fromBlock cannot be greater than toBlock" };
1604
1655
stream.write_json_field (" error" , error);
1656
+ stream.write_json_field (" result" , nlohmann::json::value_t ::null);
1605
1657
co_return ;
1606
1658
}
1607
1659
0 commit comments