diff --git a/src/tracing/mux.rs b/src/tracing/mux.rs index f8a62cb..481b0dd 100644 --- a/src/tracing/mux.rs +++ b/src/tracing/mux.rs @@ -1,8 +1,10 @@ use crate::tracing::{FourByteInspector, TracingInspector, TracingInspectorConfig}; use alloy_primitives::{map::HashMap, Address, Log, U256}; +use alloy_rpc_types_eth::TransactionInfo; use alloy_rpc_types_trace::geth::{ mux::{MuxConfig, MuxFrame}, - CallConfig, FourByteFrame, GethDebugBuiltInTracerType, NoopFrame, PreStateConfig, + CallConfig, FlatCallConfig, FourByteFrame, GethDebugBuiltInTracerType, NoopFrame, + PreStateConfig, }; use revm::{ interpreter::{ @@ -29,6 +31,7 @@ pub struct MuxInspector { enum TraceConfig { Call(CallConfig), PreState(PreStateConfig), + FlatCall(FlatCallConfig), Noop, } @@ -73,7 +76,13 @@ impl MuxInspector { configs.push((tracer_type, TraceConfig::Noop)); } GethDebugBuiltInTracerType::FlatCallTracer => { - return Err(Error::UnexpectedConfig(tracer_type)); + let flatcall_config = tracer_config + .ok_or(Error::MissingConfig(tracer_type))? + .into_flat_call_config()?; + + inspector_config + .merge(TracingInspectorConfig::from_flat_call_config(&flatcall_config)); + configs.push((tracer_type, TraceConfig::FlatCall(flatcall_config))); } GethDebugBuiltInTracerType::MuxTracer => { return Err(Error::UnexpectedConfig(tracer_type)); @@ -91,6 +100,7 @@ impl MuxInspector { &self, result: &ResultAndState, db: &DB, + tx_info: TransactionInfo, ) -> Result { let mut frame = HashMap::with_capacity_and_hasher(self.configs.len(), Default::default()); @@ -116,6 +126,17 @@ impl MuxInspector { continue; } } + TraceConfig::FlatCall(_flatcall_config) => { + if let Some(inspector) = &self.tracing { + inspector + .clone() + .into_parity_builder() + .into_localized_transaction_traces(tx_info) + .into() + } else { + continue; + } + } TraceConfig::Noop => NoopFrame::default().into(), }; diff --git a/tests/it/geth.rs b/tests/it/geth.rs index 7cb2617..be318cb 100644 --- a/tests/it/geth.rs +++ b/tests/it/geth.rs @@ -2,9 +2,10 @@ use crate::utils::{deploy_contract, inspect}; use alloy_primitives::{hex, map::HashMap, Address, Bytes}; +use alloy_rpc_types_eth::TransactionInfo; use alloy_rpc_types_trace::geth::{ - mux::MuxConfig, CallConfig, GethDebugBuiltInTracerType, GethDebugTracerConfig, GethTrace, - PreStateConfig, PreStateFrame, + mux::MuxConfig, CallConfig, FlatCallConfig, GethDebugBuiltInTracerType, GethDebugTracerConfig, + GethTrace, PreStateConfig, PreStateFrame, }; use revm::{ db::{CacheDB, EmptyDB}, @@ -137,6 +138,8 @@ fn test_geth_mux_tracer() { let (addr, mut evm) = deploy_contract(code.into(), deployer, SpecId::LONDON); let call_config = CallConfig { only_top_call: Some(false), with_log: Some(true) }; + let flatcall_config = + FlatCallConfig { convert_parity_errors: Some(true), include_precompiles: None }; let prestate_config = PreStateConfig { diff_mode: Some(false), ..Default::default() }; let config = MuxConfig(HashMap::from_iter([ @@ -149,6 +152,10 @@ fn test_geth_mux_tracer() { GethDebugBuiltInTracerType::PreStateTracer, Some(GethDebugTracerConfig(serde_json::to_value(prestate_config).unwrap())), ), + ( + GethDebugBuiltInTracerType::FlatCallTracer, + Some(GethDebugTracerConfig(serde_json::to_value(flatcall_config).unwrap())), + ), ])); let mut insp = MuxInspector::try_from_config(config.clone()).unwrap(); @@ -164,12 +171,13 @@ fn test_geth_mux_tracer() { let (res, _) = inspect(&mut evm.db, env, &mut insp).unwrap(); assert!(res.result.is_success()); - let frame = insp.try_into_mux_frame(&res, &evm.db).unwrap(); + let frame = insp.try_into_mux_frame(&res, &evm.db, TransactionInfo::default()).unwrap(); - assert_eq!(frame.0.len(), 3); + assert_eq!(frame.0.len(), 4); assert!(frame.0.contains_key(&GethDebugBuiltInTracerType::FourByteTracer)); assert!(frame.0.contains_key(&GethDebugBuiltInTracerType::CallTracer)); assert!(frame.0.contains_key(&GethDebugBuiltInTracerType::PreStateTracer)); + assert!(frame.0.contains_key(&GethDebugBuiltInTracerType::FlatCallTracer)); let four_byte_frame = frame.0[&GethDebugBuiltInTracerType::FourByteTracer].clone(); match four_byte_frame { @@ -203,6 +211,20 @@ fn test_geth_mux_tracer() { } _ => panic!("Expected PreStateTracer"), } + + let flatcall_frame = frame.0[&GethDebugBuiltInTracerType::FlatCallTracer].clone(); + match flatcall_frame { + GethTrace::FlatCallTracer(traces) => { + assert_eq!(traces.len(), 6); + assert!(traces[0].trace.error.is_none()); + assert!(traces[1].trace.error.is_some()); + assert!(traces[2].trace.error.is_some()); + assert!(traces[3].trace.error.is_none()); + assert!(traces[4].trace.error.is_none()); + assert!(traces[5].trace.error.is_none()); + } + _ => panic!("Expected FlatCallTracer"), + } } #[test]