feat: add support for Geth built-in tracer and config (#2121)
* feat: add 4byteTracer * feat: add prestateTracer * feat: add noopTracer * refactor: geth tracer layout * feat: call tracer config * fix: compatible with legacy call trace * feat: pre state tracer config * test: serialize/deserialize tracer * refactor: deserialize type * style: update refs * chore: update CHANGELOG.md * style: json string to object
This commit is contained in:
parent
e5e4da07c5
commit
14be402f40
|
@ -13,6 +13,7 @@
|
||||||
- Add abigen support for hardhat generated bytecode json format [#2012](https://github.com/gakonst/ethers-rs/pull/2012)
|
- Add abigen support for hardhat generated bytecode json format [#2012](https://github.com/gakonst/ethers-rs/pull/2012)
|
||||||
- Fix typo in `RwClient` docs for `write_client` method.
|
- Fix typo in `RwClient` docs for `write_client` method.
|
||||||
- Add support for Geth `debug_traceCall` [#1949](https://github.com/gakonst/ethers-rs/pull/1949)
|
- Add support for Geth `debug_traceCall` [#1949](https://github.com/gakonst/ethers-rs/pull/1949)
|
||||||
|
- Add support for Geth built-in tracer and config [#2121](https://github.com/gakonst/ethers-rs/pull/2121)
|
||||||
- Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815)
|
- Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815)
|
||||||
- `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers.
|
- `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers.
|
||||||
- An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract.
|
- An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract.
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
|
mod call;
|
||||||
|
mod four_byte;
|
||||||
|
mod noop;
|
||||||
|
mod pre_state;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
call::{CallConfig, CallFrame},
|
||||||
|
four_byte::FourByteFrame,
|
||||||
|
noop::NoopFrame,
|
||||||
|
pre_state::{PreStateConfig, PreStateFrame},
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Address, Bytes, NameOrAddress, H256, U256},
|
types::{Bytes, H256, U256},
|
||||||
utils::from_int_or_hex,
|
utils::from_int_or_hex,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -40,34 +51,14 @@ pub struct StructLog {
|
||||||
pub storage: Option<BTreeMap<H256, H256>>,
|
pub storage: Option<BTreeMap<H256, H256>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/ethereum/go-ethereum/blob/a9ef135e2dd53682d106c6a2aede9187026cc1de/eth/tracers/native/call.go#L37
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct CallFrame {
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub typ: String,
|
|
||||||
pub from: Address,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub to: Option<NameOrAddress>,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub value: Option<U256>,
|
|
||||||
#[serde(deserialize_with = "from_int_or_hex")]
|
|
||||||
pub gas: U256,
|
|
||||||
#[serde(deserialize_with = "from_int_or_hex", rename = "gasUsed")]
|
|
||||||
pub gas_used: U256,
|
|
||||||
pub input: Bytes,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub output: Option<Bytes>,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub error: Option<String>,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub calls: Option<Vec<CallFrame>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum GethTraceFrame {
|
pub enum GethTraceFrame {
|
||||||
Default(DefaultFrame),
|
Default(DefaultFrame),
|
||||||
|
NoopTracer(NoopFrame),
|
||||||
|
FourByteTracer(FourByteFrame),
|
||||||
CallTracer(CallFrame),
|
CallTracer(CallFrame),
|
||||||
|
PreStateTracer(PreStateFrame),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DefaultFrame> for GethTraceFrame {
|
impl From<DefaultFrame> for GethTraceFrame {
|
||||||
|
@ -76,12 +67,30 @@ impl From<DefaultFrame> for GethTraceFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FourByteFrame> for GethTraceFrame {
|
||||||
|
fn from(value: FourByteFrame) -> Self {
|
||||||
|
GethTraceFrame::FourByteTracer(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<CallFrame> for GethTraceFrame {
|
impl From<CallFrame> for GethTraceFrame {
|
||||||
fn from(value: CallFrame) -> Self {
|
fn from(value: CallFrame) -> Self {
|
||||||
GethTraceFrame::CallTracer(value)
|
GethTraceFrame::CallTracer(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PreStateFrame> for GethTraceFrame {
|
||||||
|
fn from(value: PreStateFrame) -> Self {
|
||||||
|
GethTraceFrame::PreStateTracer(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NoopFrame> for GethTraceFrame {
|
||||||
|
fn from(value: NoopFrame) -> Self {
|
||||||
|
GethTraceFrame::NoopTracer(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum GethTrace {
|
pub enum GethTrace {
|
||||||
|
@ -106,8 +115,21 @@ impl From<Value> for GethTrace {
|
||||||
/// See <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers>
|
/// See <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers>
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
pub enum GethDebugBuiltInTracerType {
|
pub enum GethDebugBuiltInTracerType {
|
||||||
|
#[serde(rename = "4byteTracer")]
|
||||||
|
FourByteTracer,
|
||||||
#[serde(rename = "callTracer")]
|
#[serde(rename = "callTracer")]
|
||||||
CallTracer,
|
CallTracer,
|
||||||
|
#[serde(rename = "prestateTracer")]
|
||||||
|
PreStateTracer,
|
||||||
|
#[serde(rename = "noopTracer")]
|
||||||
|
NoopTracer,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum GethDebugBuiltInTracerConfig {
|
||||||
|
CallTracer(CallConfig),
|
||||||
|
PreStateTracer(PreStateConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Available tracers
|
/// Available tracers
|
||||||
|
@ -123,6 +145,16 @@ pub enum GethDebugTracerType {
|
||||||
JsTracer(String),
|
JsTracer(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum GethDebugTracerConfig {
|
||||||
|
/// built-in tracer
|
||||||
|
BuiltInTracer(GethDebugBuiltInTracerConfig),
|
||||||
|
|
||||||
|
/// custom JS tracer
|
||||||
|
JsTracer(Value),
|
||||||
|
}
|
||||||
|
|
||||||
/// Bindings for additional `debug_traceTransaction` options
|
/// Bindings for additional `debug_traceTransaction` options
|
||||||
///
|
///
|
||||||
/// See <https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction>
|
/// See <https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction>
|
||||||
|
@ -139,6 +171,10 @@ pub struct GethDebugTracingOptions {
|
||||||
pub enable_return_data: Option<bool>,
|
pub enable_return_data: Option<bool>,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub tracer: Option<GethDebugTracerType>,
|
pub tracer: Option<GethDebugTracerType>,
|
||||||
|
/// tracerConfig is slated for Geth v1.11.0
|
||||||
|
/// See <https://github.com/ethereum/go-ethereum/issues/26513>
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tracer_config: Option<GethDebugTracerConfig>,
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub timeout: Option<String>,
|
pub timeout: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
use crate::{
|
||||||
|
types::{Address, Bytes, NameOrAddress, H256, U256},
|
||||||
|
utils::from_int_or_hex,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/call.go#L44
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct CallFrame {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub typ: String,
|
||||||
|
pub from: Address,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub to: Option<NameOrAddress>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub value: Option<U256>,
|
||||||
|
#[serde(default, deserialize_with = "from_int_or_hex")]
|
||||||
|
pub gas: U256,
|
||||||
|
#[serde(default, deserialize_with = "from_int_or_hex", rename = "gasUsed")]
|
||||||
|
pub gas_used: U256,
|
||||||
|
pub input: Bytes,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub output: Option<Bytes>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub error: Option<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub calls: Option<Vec<CallFrame>>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub logs: Option<Vec<CallLogFrame>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct CallLogFrame {
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
address: Option<Address>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
topics: Option<Vec<H256>>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
data: Option<Bytes>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CallConfig {
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub only_top_call: Option<bool>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub with_log: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
// See <https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracetest/testdata>
|
||||||
|
const DEFAULT: &str = include_str!("./test_data/call_tracer/default.json");
|
||||||
|
const LEGACY: &str = include_str!("./test_data/call_tracer/legacy.json");
|
||||||
|
const ONLY_TOP_CALL: &str = include_str!("./test_data/call_tracer/only_top_call.json");
|
||||||
|
const WITH_LOG: &str = include_str!("./test_data/call_tracer/with_log.json");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_call_trace() {
|
||||||
|
let mut opts = GethDebugTracingCallOptions::default();
|
||||||
|
opts.tracing_options.disable_storage = Some(false);
|
||||||
|
opts.tracing_options.tracer =
|
||||||
|
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::CallTracer));
|
||||||
|
opts.tracing_options.tracer_config =
|
||||||
|
Some(GethDebugTracerConfig::BuiltInTracer(GethDebugBuiltInTracerConfig::CallTracer(
|
||||||
|
CallConfig { only_top_call: Some(true), with_log: Some(true) },
|
||||||
|
)));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&opts).unwrap(),
|
||||||
|
r#"{"disableStorage":false,"tracer":"callTracer","tracerConfig":{"onlyTopCall":true,"withLog":true}}"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize_call_trace() {
|
||||||
|
let _trace: CallFrame = serde_json::from_str(DEFAULT).unwrap();
|
||||||
|
let _trace: CallFrame = serde_json::from_str(LEGACY).unwrap();
|
||||||
|
let _trace: CallFrame = serde_json::from_str(ONLY_TOP_CALL).unwrap();
|
||||||
|
let trace: CallFrame = serde_json::from_str(WITH_LOG).unwrap();
|
||||||
|
let _logs = trace.logs.unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/4byte.go#L48
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct FourByteFrame(pub BTreeMap<String, u64>);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
const DEFAULT: &str = r#"{
|
||||||
|
"0x27dc297e-128": 1,
|
||||||
|
"0x38cc4831-0": 2,
|
||||||
|
"0x524f3889-96": 1,
|
||||||
|
"0xadf59f99-288": 1,
|
||||||
|
"0xc281d19e-0": 1
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_four_byte_trace() {
|
||||||
|
let mut opts = GethDebugTracingCallOptions::default();
|
||||||
|
opts.tracing_options.tracer =
|
||||||
|
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::FourByteTracer));
|
||||||
|
|
||||||
|
assert_eq!(serde_json::to_string(&opts).unwrap(), r#"{"tracer":"4byteTracer"}"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize_four_byte_trace() {
|
||||||
|
let _trace: FourByteFrame = serde_json::from_str(DEFAULT).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/noop.go#L34
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct NoopFrame(BTreeMap<Null, Null>);
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
|
||||||
|
struct Null;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
const DEFAULT: &str = r#"{}"#;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_noop_trace() {
|
||||||
|
let mut opts = GethDebugTracingCallOptions::default();
|
||||||
|
opts.tracing_options.tracer =
|
||||||
|
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::NoopTracer));
|
||||||
|
|
||||||
|
assert_eq!(serde_json::to_string(&opts).unwrap(), r#"{"tracer":"noopTracer"}"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize_noop_trace() {
|
||||||
|
let _trace: NoopFrame = serde_json::from_str(DEFAULT).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
use crate::{
|
||||||
|
types::{Address, H256, U256},
|
||||||
|
utils::from_int_or_hex_opt,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/prestate.go#L38
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum PreStateFrame {
|
||||||
|
Default(PreStateMode),
|
||||||
|
Diff(DiffMode),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct PreStateMode(pub BTreeMap<Address, AccountState>);
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct DiffMode {
|
||||||
|
pub pre: BTreeMap<Address, AccountState>,
|
||||||
|
pub post: BTreeMap<Address, AccountState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct AccountState {
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
deserialize_with = "from_int_or_hex_opt",
|
||||||
|
skip_serializing_if = "Option::is_none"
|
||||||
|
)]
|
||||||
|
pub balance: Option<U256>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub code: Option<String>,
|
||||||
|
#[serde(
|
||||||
|
default,
|
||||||
|
deserialize_with = "from_int_or_hex_opt",
|
||||||
|
skip_serializing_if = "Option::is_none"
|
||||||
|
)]
|
||||||
|
pub nonce: Option<U256>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub storage: Option<BTreeMap<H256, H256>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PreStateConfig {
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub diff_mode: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
// See <https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracetest/testdata>
|
||||||
|
const DEFAULT: &str = include_str!("./test_data/pre_state_tracer/default.json");
|
||||||
|
const LEGACY: &str = include_str!("./test_data/pre_state_tracer/legacy.json");
|
||||||
|
const DIFF_MODE: &str = include_str!("./test_data/pre_state_tracer/diff_mode.json");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_pre_state_trace() {
|
||||||
|
let mut opts = GethDebugTracingCallOptions::default();
|
||||||
|
opts.tracing_options.disable_storage = Some(false);
|
||||||
|
opts.tracing_options.tracer =
|
||||||
|
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::PreStateTracer));
|
||||||
|
opts.tracing_options.tracer_config = Some(GethDebugTracerConfig::BuiltInTracer(
|
||||||
|
GethDebugBuiltInTracerConfig::PreStateTracer(PreStateConfig { diff_mode: Some(true) }),
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&opts).unwrap(),
|
||||||
|
r#"{"disableStorage":false,"tracer":"prestateTracer","tracerConfig":{"diffMode":true}}"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize_pre_state_trace() {
|
||||||
|
let trace: PreStateFrame = serde_json::from_str(DEFAULT).unwrap();
|
||||||
|
match trace {
|
||||||
|
PreStateFrame::Default(PreStateMode(_)) => {}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
let _trace: PreStateFrame = serde_json::from_str(LEGACY).unwrap();
|
||||||
|
let trace: PreStateFrame = serde_json::from_str(DIFF_MODE).unwrap();
|
||||||
|
match trace {
|
||||||
|
PreStateFrame::Diff(DiffMode { pre: _pre, post: _post }) => {}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"calls": [
|
||||||
|
{
|
||||||
|
"from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
|
||||||
|
"gas": "0x6d05",
|
||||||
|
"gasUsed": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
|
||||||
|
"type": "CALL",
|
||||||
|
"value": "0x6f05b59d3b20000"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
|
||||||
|
"gas": "0x10738",
|
||||||
|
"gasUsed": "0x9751",
|
||||||
|
"input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
|
||||||
|
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
"to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
|
||||||
|
"type": "CALL",
|
||||||
|
"value": "0x0"
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"calls": [
|
||||||
|
{
|
||||||
|
"from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
|
||||||
|
"input": "0x",
|
||||||
|
"to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
|
||||||
|
"type": "CALL",
|
||||||
|
"value": "0x6f05b59d3b20000"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
|
||||||
|
"gas": "0x10738",
|
||||||
|
"gasUsed": "0x9751",
|
||||||
|
"input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
|
||||||
|
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
"to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
|
||||||
|
"type": "CALL",
|
||||||
|
"value": "0x0"
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5",
|
||||||
|
"gas": "0x2dced",
|
||||||
|
"gasUsed": "0x1a9e5",
|
||||||
|
"to": "0x200edd17f30485a8735878661960cd7a9a95733f",
|
||||||
|
"input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"output": "0xba51a6df00000000000000000000000000000000000000000000000000000000",
|
||||||
|
"value": "0x8ac7230489e80000",
|
||||||
|
"type": "CALL"
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"from": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
|
||||||
|
"gas": "0x1f36d",
|
||||||
|
"gasUsed": "0xc6a5",
|
||||||
|
"to": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
|
||||||
|
"input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680",
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
|
||||||
|
"topics": [
|
||||||
|
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
|
||||||
|
"0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
|
||||||
|
"0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
|
||||||
|
],
|
||||||
|
"data": "0x0000000000000000000000000000000000000000000000000000000000989680"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value": "0x0",
|
||||||
|
"type": "CALL"
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
|
||||||
|
"balance": "0xc820f93200f4000",
|
||||||
|
"nonce": 94
|
||||||
|
},
|
||||||
|
"0x332b656504f4eabb44c8617a42af37461a34e9dc": {
|
||||||
|
"balance": "0x11faea4f35e5af80000",
|
||||||
|
"storage": {
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
|
||||||
|
"balance": "0xbf681825be002ac452",
|
||||||
|
"nonce": 28922
|
||||||
|
},
|
||||||
|
"0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
|
||||||
|
"balance": "0xb3d0ac5cb94df6f6b0",
|
||||||
|
"nonce": 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"pre": {
|
||||||
|
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"nonce": 22
|
||||||
|
},
|
||||||
|
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
|
||||||
|
"balance": "0x0"
|
||||||
|
},
|
||||||
|
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
|
||||||
|
"balance": "0x4d87094125a369d9bd5",
|
||||||
|
"nonce": 1,
|
||||||
|
"code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
|
||||||
|
"storage": {
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
|
||||||
|
"balance": "0x1780d77678137ac1b775",
|
||||||
|
"nonce": 29072
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
|
||||||
|
"balance": "0x6f05b59d3b20000"
|
||||||
|
},
|
||||||
|
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
|
||||||
|
"balance": "0x420eed1bd6c00"
|
||||||
|
},
|
||||||
|
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
|
||||||
|
"balance": "0x4d869a3b70062eb9bd5",
|
||||||
|
"storage": {
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b95e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
|
||||||
|
"balance": "0x1780d7725724a9044b75",
|
||||||
|
"nonce": 29073
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
|
||||||
|
"balance": "0x0",
|
||||||
|
"code": "0x",
|
||||||
|
"nonce": 22,
|
||||||
|
"storage": {}
|
||||||
|
},
|
||||||
|
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
|
||||||
|
"balance": "0x4d87094125a369d9bd5",
|
||||||
|
"code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
|
||||||
|
"nonce": 1,
|
||||||
|
"storage": {
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
|
||||||
|
"balance": "0x1780d77678137ac1b775",
|
||||||
|
"code": "0x",
|
||||||
|
"nonce": 29072,
|
||||||
|
"storage": {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue