diff --git a/prdoc/pr_9736.prdoc b/prdoc/pr_9736.prdoc new file mode 100644 index 0000000000000..82cee4495bdb3 --- /dev/null +++ b/prdoc/pr_9736.prdoc @@ -0,0 +1,12 @@ +title: '[pallet-revive] fix tracing collect' +doc: +- audience: Runtime Dev + description: |- + Fix tracing collection + + collect_trace should take `self` instead of `&mut self`, to avoid reusing the tracer state when tracing multiple transactions in a block. + + Fix https://github.com/paritytech/contract-issues/issues/156https://github.com/paritytech/contract-issues/issues/156 +crates: +- name: pallet-revive + bump: patch diff --git a/substrate/frame/revive/src/evm/api/debug_rpc_types.rs b/substrate/frame/revive/src/evm/api/debug_rpc_types.rs index 7dbfc254a769a..b3a547c59eaf4 100644 --- a/substrate/frame/revive/src/evm/api/debug_rpc_types.rs +++ b/substrate/frame/revive/src/evm/api/debug_rpc_types.rs @@ -291,6 +291,9 @@ pub struct CallTrace { /// Type of call. #[serde(rename = "type")] pub call_type: CallType, + /// Number of child calls entered (for log position calculation) + #[serde(skip)] + pub child_call_count: u32, } /// A log emitted during a call. diff --git a/substrate/frame/revive/src/evm/tracing.rs b/substrate/frame/revive/src/evm/tracing.rs index 10dbcdde10313..dc235ede4784e 100644 --- a/substrate/frame/revive/src/evm/tracing.rs +++ b/substrate/frame/revive/src/evm/tracing.rs @@ -60,7 +60,7 @@ where } /// Collect the traces and return them. - pub fn collect_trace(&mut self) -> Option { + pub fn collect_trace(self) -> Option { match self { Tracer::CallTracer(inner) => inner.collect_trace().map(Trace::Call), Tracer::PrestateTracer(inner) => Some(inner.collect_trace().into()), diff --git a/substrate/frame/revive/src/evm/tracing/call_tracing.rs b/substrate/frame/revive/src/evm/tracing/call_tracing.rs index 5eff16e0ce4c9..9392dcb8fb3e5 100644 --- a/substrate/frame/revive/src/evm/tracing/call_tracing.rs +++ b/substrate/frame/revive/src/evm/tracing/call_tracing.rs @@ -51,8 +51,8 @@ impl CallTracer { } /// Collect the traces and return them. - pub fn collect_trace(&mut self) -> Option> { - core::mem::take(&mut self.traces).pop() + pub fn collect_trace(mut self) -> Option> { + self.traces.pop() } } @@ -71,6 +71,13 @@ impl Gas> Tracing for CallTracer ( @@ -121,12 +128,17 @@ impl Gas> Tracing for CallTracer PrestateTrace { - let trace = core::mem::take(&mut self.trace); - let (mut pre, mut post) = trace; + pub fn collect_trace(self) -> PrestateTrace { + let (mut pre, mut post) = self.trace; let include_code = !self.config.disable_code; let is_empty = |info: &PrestateTraceInfo| { diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index 9ed4e02dee25d..d5da246058944 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -2059,11 +2059,11 @@ macro_rules! impl_runtime_apis_plus_revive { tracer_type: $crate::evm::TracerType, ) -> Vec<(u32, $crate::evm::Trace)> { use $crate::{sp_runtime::traits::Block, tracing::trace}; - let mut tracer = $crate::Pallet::::evm_tracer(tracer_type); let mut traces = vec![]; let (header, extrinsics) = block.deconstruct(); <$Executive>::initialize_block(&header); for (index, ext) in extrinsics.into_iter().enumerate() { + let mut tracer = $crate::Pallet::::evm_tracer(tracer_type.clone()); let t = tracer.as_tracing(); let _ = trace(t, || <$Executive>::apply_extrinsic(ext)); @@ -2104,7 +2104,7 @@ macro_rules! impl_runtime_apis_plus_revive { tracer_type: $crate::evm::TracerType, ) -> Result<$crate::evm::Trace, $crate::EthTransactError> { use $crate::tracing::trace; - let mut tracer = $crate::Pallet::::evm_tracer(tracer_type); + let mut tracer = $crate::Pallet::::evm_tracer(tracer_type.clone()); let t = tracer.as_tracing(); t.watch_address(&tx.from.unwrap_or_default()); @@ -2116,7 +2116,7 @@ macro_rules! impl_runtime_apis_plus_revive { } else if let Err(err) = result { Err(err) } else { - Ok(tracer.empty_trace()) + Ok($crate::Pallet::::evm_tracer(tracer_type).empty_trace()) } } diff --git a/substrate/frame/revive/src/tests/pvm.rs b/substrate/frame/revive/src/tests/pvm.rs index d25060322699a..a75332dffa28e 100644 --- a/substrate/frame/revive/src/tests/pvm.rs +++ b/substrate/frame/revive/src/tests/pvm.rs @@ -4051,8 +4051,9 @@ fn call_tracing_works() { let tracer_configs = vec![ CallTracerConfig{ with_logs: false, only_top_call: false}, - CallTracerConfig{ with_logs: false, only_top_call: false}, + CallTracerConfig{ with_logs: true, only_top_call: false}, CallTracerConfig{ with_logs: false, only_top_call: true}, + CallTracerConfig{ with_logs: true, only_top_call: true}, ]; // Verify that the first trace report the same weight reported by bare_call @@ -4154,12 +4155,15 @@ fn call_tracing_works() { ..Default::default() } ], + child_call_count: 1, ..Default::default() }, ], + child_call_count: 2, ..Default::default() }, ], + child_call_count: 2, ..Default::default() }, ] @@ -4179,6 +4183,7 @@ fn call_tracing_works() { logs: logs.clone(), value: Some(U256::from(0)), calls: calls, + child_call_count: 2, ..Default::default() }; @@ -4244,6 +4249,7 @@ fn create_call_tracing_works() { call_type: CallType::Create2, ..Default::default() },], + child_call_count: 1, ..Default::default() } );