use crate::types::{Action, ActionType, Bytes, Res, H160, H256, U256};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
#[derive(Debug, Clone, Serialize)]
pub enum TraceType {
#[serde(rename = "trace")]
Trace,
#[serde(rename = "vmTrace")]
VmTrace,
#[serde(rename = "stateDiff")]
StateDiff,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct BlockTrace {
pub output: Bytes,
pub trace: Option<Vec<TransactionTrace>>,
#[serde(rename = "vmTrace")]
pub vm_trace: Option<VMTrace>,
#[serde(rename = "stateDiff")]
pub state_diff: Option<StateDiff>,
#[serde(rename = "transactionHash")]
pub transaction_hash: Option<H256>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct ChangedType<T> {
pub from: T,
pub to: T,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub enum Diff<T> {
#[serde(rename = "=")]
Same,
#[serde(rename = "+")]
Born(T),
#[serde(rename = "-")]
Died(T),
#[serde(rename = "*")]
Changed(ChangedType<T>),
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct AccountDiff {
pub balance: Diff<U256>,
pub nonce: Diff<U256>,
pub code: Diff<Bytes>,
pub storage: BTreeMap<H256, Diff<H256>>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct StateDiff(pub BTreeMap<H160, AccountDiff>);
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct TransactionTrace {
#[serde(rename = "traceAddress")]
pub trace_address: Vec<usize>,
pub subtraces: usize,
pub action: Action,
#[serde(rename = "type")]
pub action_type: ActionType,
pub result: Option<Res>,
pub error: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct VMTrace {
pub code: Bytes,
pub ops: Vec<VMOperation>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct VMOperation {
pub pc: usize,
pub cost: u64,
pub ex: Option<VMExecutedOperation>,
pub sub: Option<VMTrace>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct VMExecutedOperation {
#[serde(rename = "used")]
pub used: u64,
pub push: Vec<U256>,
#[serde(rename = "mem")]
pub mem: Option<MemoryDiff>,
#[serde(rename = "store")]
pub store: Option<StorageDiff>,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct MemoryDiff {
pub off: usize,
pub data: Bytes,
}
#[derive(Debug, Clone, PartialEq, Default, Deserialize, Serialize)]
pub struct StorageDiff {
pub key: U256,
pub val: U256,
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE_TRACE: &str = include!("./example-trace-str.rs");
const EXAMPLE_TRACES: &str = include!("./example-traces-str.rs");
#[test]
fn test_serialize_trace_type() {
let trace_type_str = r#"["trace","vmTrace","stateDiff"]"#;
let trace_type = vec![TraceType::Trace, TraceType::VmTrace, TraceType::StateDiff];
let se_trace_str: String = serde_json::to_string(&trace_type).unwrap();
assert_eq!(trace_type_str, se_trace_str);
}
#[test]
fn test_deserialize_blocktrace() {
let _trace: BlockTrace = serde_json::from_str(EXAMPLE_TRACE).unwrap();
}
#[test]
fn test_deserialize_blocktraces() {
let _traces: Vec<BlockTrace> = serde_json::from_str(EXAMPLE_TRACES).unwrap();
}
}