cfx_rpc_common_impl/trace/
conversion.rs1use cfx_parity_trace_types::{
2 ExecTrace, LocalizedTrace as PrimitiveLocalizedTrace,
3};
4use cfx_rpc_eth_types::trace::{
5 Action, ActionResult as EthRes, LocalizedTrace as EthLocalizedTrace,
6};
7use cfx_types::H256;
8
9use super::matcher::{
10 construct_parity_trace, CallCreateTraceWithPosition,
11 SelfDestructTraceWithPosition, TraceWithPosition,
12};
13
14pub fn into_eth_localized_traces(
15 tx_traces: &[ExecTrace], block_number: u64, block_hash: H256,
16 tx_hash: H256, tx_idx: usize,
17) -> Result<Vec<EthLocalizedTrace>, String> {
18 let mut eth_traces = vec![];
19 for trace_with_position in construct_parity_trace(&tx_traces)? {
20 match trace_with_position {
21 TraceWithPosition::CallCreate(CallCreateTraceWithPosition {
22 action,
23 result,
24 child_count,
25 trace_path,
26 }) => {
27 let mut eth_trace = EthLocalizedTrace {
28 action: Action::try_from(action.action.clone())?,
29 result: EthRes::None,
30 error: None,
31 trace_address: trace_path,
32 subtraces: child_count,
33 transaction_position: tx_idx,
34 transaction_hash: tx_hash,
35 block_number,
36 block_hash,
37 valid: action.valid,
39 };
40
41 eth_trace.set_result(Some(result.action.clone())).expect(
42 "`construct_parity_trace` has guarantee the consistency",
43 );
44
45 eth_traces.push(eth_trace);
46 }
47 TraceWithPosition::Suicide(SelfDestructTraceWithPosition {
48 action,
49 child_count,
50 trace_path,
51 }) => {
52 let eth_trace = EthLocalizedTrace {
53 action: Action::try_from(action.action.clone())?,
54 result: EthRes::None,
55 error: None,
56 trace_address: trace_path,
57 subtraces: child_count,
58 transaction_position: tx_idx,
59 transaction_hash: tx_hash,
60 block_number,
61 block_hash,
62 valid: action.valid,
64 };
65
66 eth_traces.push(eth_trace);
67 }
68 }
69 }
70
71 Ok(eth_traces)
72}
73
74pub fn primitive_traces_to_eth_localized_traces(
75 primitive_traces: &[PrimitiveLocalizedTrace],
76) -> Result<Vec<EthLocalizedTrace>, String> {
77 use slice_group_by::GroupBy;
78
79 let mut traces = vec![];
80 for tx_traces in
81 primitive_traces.linear_group_by_key(|x| x.transaction_hash)
82 {
83 let first_tx = tx_traces.first().unwrap();
84 let tx_exec_traces: Vec<_> = tx_traces
85 .iter()
86 .map(|x| ExecTrace {
87 action: x.action.clone(),
88 valid: x.valid,
89 })
90 .collect();
91 let eth_traces = into_eth_localized_traces(
92 &tx_exec_traces,
93 first_tx.epoch_number.as_u64(),
94 first_tx.epoch_hash,
95 first_tx.transaction_hash,
96 first_tx.transaction_position.as_usize(),
97 )?;
98 traces.extend(eth_traces);
99 }
100 Ok(traces)
101}