cfx_parity_trace_types/
trace_types.rs

1// Copyright 2020 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5use super::{action_types::Action, filter::TraceFilter};
6use cfx_bytes::Bytes;
7use cfx_internal_common::{DatabaseDecodable, DatabaseEncodable};
8use cfx_types::{Bloom, Space, H256, U256, U64};
9use malloc_size_of_derive::MallocSizeOf;
10use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
11use rlp_derive::{RlpDecodable, RlpEncodable};
12
13/// Trace localized in vector of traces produced by a single transaction.
14///
15/// Parent and children indexes refer to positions in this vector.
16#[derive(Debug, PartialEq, Clone, MallocSizeOf)]
17pub struct ExecTrace {
18    #[ignore_malloc_size_of = "ignored for performance reason"]
19    /// Type of action performed by a transaction.
20    pub action: Action,
21    pub valid: bool,
22}
23
24impl ExecTrace {
25    /// Returns bloom of the trace.
26    pub fn bloom(&self) -> Bloom { self.action.bloom() }
27}
28
29impl Encodable for ExecTrace {
30    fn rlp_append(&self, s: &mut RlpStream) {
31        s.begin_list(2);
32        s.append(&self.action);
33        s.append(&self.valid);
34    }
35}
36
37impl Decodable for ExecTrace {
38    fn decode(d: &Rlp) -> Result<Self, DecoderError> {
39        match d.item_count()? {
40            1 => Ok(ExecTrace {
41                action: d.val_at(0)?,
42                valid: true,
43            }),
44            2 => Ok(ExecTrace {
45                action: d.val_at(0)?,
46                valid: d.val_at(1)?,
47            }),
48            _ => Err(DecoderError::RlpInvalidLength),
49        }
50    }
51}
52
53pub struct LocalizedTrace {
54    pub action: Action,
55    pub valid: bool,
56    /// Epoch hash.
57    pub epoch_hash: H256,
58    /// Epoch number.
59    pub epoch_number: U256,
60    /// Block hash.
61    pub block_hash: H256,
62    /// Transaction position.
63    pub transaction_position: U64,
64    /// Signed transaction hash.
65    pub transaction_hash: H256,
66}
67
68/// Represents all traces produced by a single transaction.
69#[derive(Debug, PartialEq, Clone, RlpEncodable, RlpDecodable, MallocSizeOf)]
70pub struct TransactionExecTraces(pub Vec<ExecTrace>);
71
72impl From<Vec<ExecTrace>> for TransactionExecTraces {
73    fn from(v: Vec<ExecTrace>) -> Self { TransactionExecTraces(v) }
74}
75
76impl TransactionExecTraces {
77    /// Returns bloom of all traces in the collection.
78    pub fn bloom(&self) -> Bloom {
79        self.0
80            .iter()
81            .fold(Default::default(), |bloom, trace| bloom | trace.bloom())
82    }
83
84    pub fn filter_space(self, space: Space) -> Self {
85        // `unwrap` here should always succeed.
86        // `vec![]` is just added in case.
87        Self(
88            TraceFilter::space_filter(space)
89                .filter_traces(self)
90                .unwrap_or(vec![]),
91        )
92    }
93}
94
95impl Into<Vec<ExecTrace>> for TransactionExecTraces {
96    fn into(self) -> Vec<ExecTrace> { self.0 }
97}
98
99/// Represents all traces produced by transactions in a single block.
100#[derive(
101    Debug, PartialEq, Clone, Default, RlpEncodable, RlpDecodable, MallocSizeOf,
102)]
103pub struct BlockExecTraces(pub Vec<TransactionExecTraces>);
104
105impl From<Vec<TransactionExecTraces>> for BlockExecTraces {
106    fn from(v: Vec<TransactionExecTraces>) -> Self { BlockExecTraces(v) }
107}
108
109impl BlockExecTraces {
110    /// Returns bloom of all traces in the block.
111    pub fn bloom(&self) -> Bloom {
112        self.0.iter().fold(Default::default(), |bloom, tx_traces| {
113            bloom | tx_traces.bloom()
114        })
115    }
116
117    pub fn filter_space(self, space: Space) -> Self {
118        Self(
119            self.0
120                .into_iter()
121                .map(|tx_trace| tx_trace.filter_space(space))
122                .collect(),
123        )
124    }
125}
126
127impl Into<Vec<TransactionExecTraces>> for BlockExecTraces {
128    fn into(self) -> Vec<TransactionExecTraces> { self.0 }
129}
130
131impl DatabaseDecodable for BlockExecTraces {
132    fn db_decode(bytes: &[u8]) -> Result<Self, DecoderError> {
133        rlp::decode(bytes)
134    }
135}
136
137impl DatabaseEncodable for BlockExecTraces {
138    fn db_encode(&self) -> Bytes { rlp::encode(self) }
139}