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