From ff87573a204f4e5caa536a7d3a7ddfe39a83a957 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 14 Sep 2024 18:23:58 +0200 Subject: [PATCH] feat: add types for flat call tracer --- crates/rpc-types-trace/src/geth/call.rs | 33 +++++++++++++++++++++++ crates/rpc-types-trace/src/geth/mod.rs | 36 ++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-trace/src/geth/call.rs b/crates/rpc-types-trace/src/geth/call.rs index 5555b9acba5..5a1cb126ea3 100644 --- a/crates/rpc-types-trace/src/geth/call.rs +++ b/crates/rpc-types-trace/src/geth/call.rs @@ -1,5 +1,6 @@ //! Geth call tracer types. +use crate::parity::LocalizedTransactionTrace; use alloy_primitives::{Address, Bytes, B256, U256}; use serde::{Deserialize, Serialize}; @@ -88,6 +89,38 @@ impl CallConfig { } } +/// The response object for `debug_traceTransaction` with `"tracer": "flatCallTracer"`. +/// +/// That is equivalent to parity's [`LocalizedTransactionTrace`] +/// +pub type FlatCallFrame = LocalizedTransactionTrace; + +/// The configuration for the flat call tracer. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FlatCallConfig { + /// If true, call tracer converts errors to parity format + #[serde(default, skip_serializing_if = "Option::is_none")] + pub convert_parity_errors: Option, + /// If true, call tracer includes calls to precompiled contracts + #[serde(default, skip_serializing_if = "Option::is_none")] + pub include_precompiles: Option, +} + +impl FlatCallConfig { + /// Converts errors to parity format. + pub const fn parity_errors(mut self) -> Self { + self.convert_parity_errors = Some(true); + self + } + + /// Include calls to precompiled contracts. + pub const fn with_precompiles(mut self) -> Self { + self.include_precompiles = Some(true); + self + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc-types-trace/src/geth/mod.rs b/crates/rpc-types-trace/src/geth/mod.rs index ea8c94026d5..9b64b642052 100644 --- a/crates/rpc-types-trace/src/geth/mod.rs +++ b/crates/rpc-types-trace/src/geth/mod.rs @@ -1,14 +1,16 @@ //! Geth tracing types. -use crate::geth::mux::{MuxConfig, MuxFrame}; +use crate::geth::{ + call::FlatCallFrame, + mux::{MuxConfig, MuxFrame}, +}; use alloy_primitives::{Bytes, B256, U256}; use alloy_rpc_types_eth::{state::StateOverride, BlockOverrides}; use serde::{de::DeserializeOwned, ser::SerializeMap, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, time::Duration}; - // re-exports pub use self::{ - call::{CallConfig, CallFrame, CallLogFrame}, + call::{CallConfig, CallFrame, CallLogFrame, FlatCallConfig}, four_byte::FourByteFrame, noop::NoopFrame, pre_state::{ @@ -118,6 +120,8 @@ pub enum GethTrace { Default(DefaultFrame), /// The response for call tracer CallTracer(CallFrame), + /// The response for the flat call tracer + FlatCallTracer(FlatCallFrame), /// The response for four byte tracer FourByteTracer(FourByteFrame), /// The response for pre-state byte tracer @@ -147,6 +151,14 @@ impl GethTrace { } } + /// Try to convert the inner tracer to [FlatCallFrame] + pub fn try_into_flat_call_frame(self) -> Result { + match self { + Self::FlatCallTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + /// Try to convert the inner tracer to [FourByteFrame] pub fn try_into_four_byte_frame(self) -> Result { match self { @@ -212,6 +224,12 @@ impl From for GethTrace { } } +impl From for GethTrace { + fn from(value: FlatCallFrame) -> Self { + Self::FlatCallTracer(value) + } +} + impl From for GethTrace { fn from(value: PreStateFrame) -> Self { Self::PreStateTracer(value) @@ -246,6 +264,10 @@ pub enum GethDebugBuiltInTracerType { /// with the top-level call at root and sub-calls as children of the higher levels. #[serde(rename = "callTracer")] CallTracer, + /// Tracks all call frames of a transaction and returns them in a flat format, i.e. as opposed + /// to the nested format of `callTracer`. + #[serde(rename = "flatCallTracer")] + FlatCallTracer, /// The prestate tracer has two modes: prestate and diff. The prestate mode returns the /// accounts necessary to execute a given transaction. diff mode returns the differences /// between the transaction's pre and post-state (i.e. what changed because the transaction @@ -311,6 +333,14 @@ impl GethDebugTracerConfig { self.from_value() } + /// Returns the [FlatCallConfig] if it is a call config. + pub fn into_flat_call_config(self) -> Result { + if self.0.is_null() { + return Ok(Default::default()); + } + self.from_value() + } + /// Returns the raw json value pub fn into_json(self) -> serde_json::Value { self.0