1use std::collections::BTreeMap;
3
4use crate::types::{Action, Bytes, Res, H160, H256, U256};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize)]
8pub enum TraceType {
10    #[serde(rename = "trace")]
12    Trace,
13    #[serde(rename = "vmTrace")]
15    VmTrace,
16    #[serde(rename = "stateDiff")]
18    StateDiff,
19}
20
21#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
22pub struct BlockTrace {
24    pub output: Bytes,
26    pub trace: Option<Vec<TransactionTrace>>,
28    #[serde(rename = "vmTrace")]
30    pub vm_trace: Option<VMTrace>,
31    #[serde(rename = "stateDiff")]
33    pub state_diff: Option<StateDiff>,
34}
35
36#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
38pub struct ChangedType<T> {
40    from: T,
41    to: T,
42}
43
44#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
45pub enum Diff<T> {
47    #[serde(rename = "=")]
48    Same,
49    #[serde(rename = "+")]
50    Born(T),
51    #[serde(rename = "-")]
52    Died(T),
53    #[serde(rename = "*")]
54    Changed(ChangedType<T>),
55}
56
57#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
58pub struct AccountDiff {
60    pub balance: Diff<U256>,
61    pub nonce: Diff<U256>,
62    pub code: Diff<Bytes>,
63    pub storage: BTreeMap<H256, Diff<H256>>,
64}
65
66#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
67pub struct StateDiff(BTreeMap<H160, AccountDiff>);
69
70#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
73pub struct TransactionTrace {
74    #[serde(rename = "traceAddress")]
76    trace_address: Vec<usize>,
77    subtraces: usize,
79    action: Action,
81    result: Option<Res>,
83}
84
85#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
87pub struct VMTrace {
89    pub code: Bytes,
91    pub ops: Vec<VMOperation>,
93}
94
95#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
96pub struct VMOperation {
98    pub pc: usize,
100    pub cost: u64,
102    pub ex: Option<VMExecutedOperation>,
104    pub sub: Option<VMTrace>,
107}
108
109#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
110pub struct VMExecutedOperation {
112    #[serde(rename = "used")]
114    pub used: u64,
115    pub push: Vec<U256>,
117    #[serde(rename = "mem")]
119    pub mem: Option<MemoryDiff>,
120    #[serde(rename = "store")]
122    pub store: Option<StorageDiff>,
123}
124
125#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
126pub struct MemoryDiff {
128    pub off: usize,
130    pub data: Bytes,
132}
133
134#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
135pub struct StorageDiff {
137    pub key: U256,
139    pub val: U256,
141}
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146    use serde_json;
147
148    const EXAMPLE_TRACE: &'static str = include!("./example-trace-str.rs");
152
153    #[test]
154    fn test_serialize_trace_type() {
155        let trace_type_str = r#"["trace","vmTrace","stateDiff"]"#;
156        let trace_type = vec![TraceType::Trace, TraceType::VmTrace, TraceType::StateDiff];
157
158        let se_trace_str: String = serde_json::to_string(&trace_type).unwrap();
159        assert_eq!(trace_type_str, se_trace_str);
160    }
161
162    #[test]
163    fn test_deserialize_blocktrace() {
164        let _trace: BlockTrace = serde_json::from_str(EXAMPLE_TRACE).unwrap();
165    }
166}