From 600f3eac8c494dfc10b628527ff87513e2381b7f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 15 Jun 2023 16:29:37 +0200 Subject: [PATCH] chore(rpc): simplify GethTrace type (#3180) --- crates/rpc/rpc-api/src/debug.rs | 6 +- .../rpc/rpc-types/src/eth/trace/geth/mod.rs | 95 +++++++++---------- .../rpc/rpc-types/src/eth/trace/geth/noop.rs | 2 + .../rpc-types/src/eth/trace/geth/pre_state.rs | 1 + crates/rpc/rpc/src/debug.rs | 19 ++-- 5 files changed, 58 insertions(+), 65 deletions(-) diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index 32c7763385..0d29042b5e 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -2,7 +2,7 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256}; use reth_rpc_types::{ trace::geth::{ - BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTraceFrame, + BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }, CallRequest, RichBlock, @@ -84,7 +84,7 @@ pub trait DebugApi { &self, tx_hash: H256, opts: Option, - ) -> RpcResult; + ) -> RpcResult; /// The `debug_traceCall` method lets you run an `eth_call` within the context of the given /// block execution using the final state of parent block as the base. @@ -101,5 +101,5 @@ pub trait DebugApi { request: CallRequest, block_number: Option, opts: Option, - ) -> RpcResult; + ) -> RpcResult; } diff --git a/crates/rpc/rpc-types/src/eth/trace/geth/mod.rs b/crates/rpc/rpc-types/src/eth/trace/geth/mod.rs index 526c9dc1fc..092efa4385 100644 --- a/crates/rpc/rpc-types/src/eth/trace/geth/mod.rs +++ b/crates/rpc/rpc-types/src/eth/trace/geth/mod.rs @@ -20,7 +20,7 @@ mod noop; mod pre_state; /// Result type for geth style transaction trace -pub type TraceResult = crate::trace::common::TraceResult; +pub type TraceResult = crate::trace::common::TraceResult; /// blockTraceResult represents the results of tracing a single block when an entire chain is being /// traced. ref @@ -34,7 +34,7 @@ pub struct BlockTraceResult { pub traces: Vec, } -/// Geth Default trace frame +/// Geth Default struct log trace frame /// /// #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] @@ -91,64 +91,55 @@ pub struct StructLog { pub error: Option, } -/// Tracing response -#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] -#[serde(untagged)] -pub enum GethTraceFrame { - Default(DefaultFrame), - NoopTracer(NoopFrame), - FourByteTracer(FourByteFrame), - CallTracer(CallFrame), - PreStateTracer(PreStateFrame), - JS(serde_json::Value), -} - -impl From for GethTraceFrame { - fn from(value: DefaultFrame) -> Self { - GethTraceFrame::Default(value) - } -} - -impl From for GethTraceFrame { - fn from(value: FourByteFrame) -> Self { - GethTraceFrame::FourByteTracer(value) - } -} - -impl From for GethTraceFrame { - fn from(value: CallFrame) -> Self { - GethTraceFrame::CallTracer(value) - } -} - -impl From for GethTraceFrame { - fn from(value: PreStateFrame) -> Self { - GethTraceFrame::PreStateTracer(value) - } -} - -impl From for GethTraceFrame { - fn from(value: NoopFrame) -> Self { - GethTraceFrame::NoopTracer(value) - } -} - +/// Tracing response objects +/// +/// Note: This deserializes untagged, so it's possible that a custom javascript tracer response +/// matches another variant, for example a js tracer that returns `{}` would be deserialized as +/// [GethTrace::NoopTracer] #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] #[serde(untagged)] pub enum GethTrace { - Known(GethTraceFrame), - Unknown(serde_json::Value), + /// The response for the default struct log tracer + Default(DefaultFrame), + /// The response for call tracer + CallTracer(CallFrame), + /// The response for four byte tracer + FourByteTracer(FourByteFrame), + /// The response for pre-state byte tracer + PreStateTracer(PreStateFrame), + /// An empty json response + NoopTracer(NoopFrame), + /// Any other trace response, such as custom javascript response objects + JS(serde_json::Value), } -impl From for GethTrace { - fn from(value: GethTraceFrame) -> Self { - GethTrace::Known(value) +impl From for GethTrace { + fn from(value: DefaultFrame) -> Self { + GethTrace::Default(value) } } -impl From for GethTrace { - fn from(value: serde_json::Value) -> Self { - GethTrace::Unknown(value) +impl From for GethTrace { + fn from(value: FourByteFrame) -> Self { + GethTrace::FourByteTracer(value) + } +} + +impl From for GethTrace { + fn from(value: CallFrame) -> Self { + GethTrace::CallTracer(value) + } +} + +impl From for GethTrace { + fn from(value: PreStateFrame) -> Self { + GethTrace::PreStateTracer(value) + } +} + +impl From for GethTrace { + fn from(value: NoopFrame) -> Self { + GethTrace::NoopTracer(value) } } diff --git a/crates/rpc/rpc-types/src/eth/trace/geth/noop.rs b/crates/rpc/rpc-types/src/eth/trace/geth/noop.rs index 003b1dcc99..a3b3f726d8 100644 --- a/crates/rpc/rpc-types/src/eth/trace/geth/noop.rs +++ b/crates/rpc/rpc-types/src/eth/trace/geth/noop.rs @@ -1,9 +1,11 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; +/// An empty frame response that's only an empty json object `{}` /// #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct NoopFrame(BTreeMap); + #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] struct Null; diff --git a/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs b/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs index fc53ecfa7b..b6301da3f2 100644 --- a/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs +++ b/crates/rpc/rpc-types/src/eth/trace/geth/pre_state.rs @@ -14,6 +14,7 @@ pub enum PreStateFrame { pub struct PreStateMode(pub BTreeMap); #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct DiffMode { pub pre: BTreeMap, pub post: BTreeMap, diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 8a44d16984..dc5a423cec 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -26,8 +26,7 @@ use reth_rpc_api::DebugApiServer; use reth_rpc_types::{ trace::geth::{ BlockTraceResult, FourByteFrame, GethDebugBuiltInTracerType, GethDebugTracerType, - GethDebugTracingCallOptions, GethDebugTracingOptions, GethTraceFrame, NoopFrame, - TraceResult, + GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, NoopFrame, TraceResult, }, BlockError, CallRequest, RichBlock, }; @@ -203,7 +202,7 @@ where &self, tx_hash: H256, opts: GethDebugTracingOptions, - ) -> EthResult { + ) -> EthResult { let (transaction, block) = match self.inner.eth_api.transaction_and_block(tx_hash).await? { None => return Err(EthApiError::TransactionNotFound), Some(res) => res, @@ -244,7 +243,7 @@ where call: CallRequest, block_id: Option, opts: GethDebugTracingCallOptions, - ) -> EthResult { + ) -> EthResult { self.on_blocking_task(|this| async move { this.try_debug_trace_call(call, block_id, opts).await }) @@ -260,7 +259,7 @@ where call: CallRequest, block_id: Option, opts: GethDebugTracingCallOptions, - ) -> EthResult { + ) -> EthResult { let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); let GethDebugTracingCallOptions { tracing_options, state_overrides, block_overrides } = opts; @@ -319,7 +318,7 @@ where let (res, env) = inspect(db, env, &mut inspector)?; let result = inspector.json_result(res, &env)?; - Ok(GethTraceFrame::JS(result)) + Ok(GethTrace::JS(result)) } } } @@ -349,7 +348,7 @@ where env: Env, at: BlockId, db: &mut SubState>, - ) -> EthResult<(GethTraceFrame, revm_primitives::State)> { + ) -> EthResult<(GethTrace, revm_primitives::State)> { let GethDebugTracingOptions { config, tracer, tracer_config, .. } = opts; if let Some(tracer) = tracer { @@ -395,7 +394,7 @@ where let state = res.state.clone(); let result = inspector.json_result(res, &env)?; - Ok((GethTraceFrame::JS(result), state)) + Ok((GethTrace::JS(result), state)) } } } @@ -598,7 +597,7 @@ where &self, tx_hash: H256, opts: Option, - ) -> RpcResult { + ) -> RpcResult { let _permit = self.acquire_trace_permit().await; Ok(DebugApi::debug_trace_transaction(self, tx_hash, opts.unwrap_or_default()).await?) } @@ -609,7 +608,7 @@ where request: CallRequest, block_number: Option, opts: Option, - ) -> RpcResult { + ) -> RpcResult { let _permit = self.acquire_trace_permit().await; Ok(DebugApi::debug_trace_call(self, request, block_number, opts.unwrap_or_default()) .await?)