Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions prdoc/pr_9736.prdoc
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions substrate/frame/revive/src/evm/api/debug_rpc_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ pub struct CallTrace<Gas = U256> {
/// 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.
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/src/evm/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ where
}

/// Collect the traces and return them.
pub fn collect_trace(&mut self) -> Option<Trace> {
pub fn collect_trace(self) -> Option<Trace> {
match self {
Tracer::CallTracer(inner) => inner.collect_trace().map(Trace::Call),
Tracer::PrestateTracer(inner) => Some(inner.collect_trace().into()),
Expand Down
26 changes: 19 additions & 7 deletions substrate/frame/revive/src/evm/tracing/call_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ impl<Gas, GasMapper> CallTracer<Gas, GasMapper> {
}

/// Collect the traces and return them.
pub fn collect_trace(&mut self) -> Option<CallTrace<Gas>> {
core::mem::take(&mut self.traces).pop()
pub fn collect_trace(mut self) -> Option<CallTrace<Gas>> {
self.traces.pop()
}
}

Expand All @@ -71,6 +71,13 @@ impl<Gas: Default, GasMapper: Fn(Weight) -> Gas> Tracing for CallTracer<Gas, Gas
input: &[u8],
gas_left: Weight,
) {
// Increment parent's child call count.
if let Some(&index) = self.current_stack.last() {
if let Some(trace) = self.traces.get_mut(index) {
trace.child_call_count += 1;
}
}

if self.traces.is_empty() || !self.config.only_top_call {
let (call_type, input) = match self.code_with_salt.take() {
Some((Code::Upload(v), salt)) => (
Expand Down Expand Up @@ -121,12 +128,17 @@ impl<Gas: Default, GasMapper: Fn(Weight) -> Gas> Tracing for CallTracer<Gas, Gas
}

let current_index = self.current_stack.last().unwrap();
let position = self.traces[*current_index].calls.len() as u32;
let log =
CallLog { address, topics: topics.to_vec(), data: data.to_vec().into(), position };

let current_index = *self.current_stack.last().unwrap();
self.traces[current_index].logs.push(log);
if let Some(trace) = self.traces.get_mut(*current_index) {
let log = CallLog {
address,
topics: topics.to_vec(),
data: data.to_vec().into(),
position: trace.child_call_count,
};

trace.logs.push(log);
}
}

fn exit_child_span(&mut self, output: &ExecReturnValue, gas_used: Weight) {
Expand Down
5 changes: 2 additions & 3 deletions substrate/frame/revive/src/evm/tracing/prestate_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ where
}

/// Collect the traces and return them.
pub fn collect_trace(&mut self) -> 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| {
Expand Down
6 changes: 3 additions & 3 deletions substrate/frame/revive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Self>::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::<Self>::evm_tracer(tracer_type.clone());
let t = tracer.as_tracing();
let _ = trace(t, || <$Executive>::apply_extrinsic(ext));

Expand Down Expand Up @@ -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::<Self>::evm_tracer(tracer_type);
let mut tracer = $crate::Pallet::<Self>::evm_tracer(tracer_type.clone());
let t = tracer.as_tracing();

t.watch_address(&tx.from.unwrap_or_default());
Expand All @@ -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::<Self>::evm_tracer(tracer_type).empty_trace())
}
}

Expand Down
8 changes: 7 additions & 1 deletion substrate/frame/revive/src/tests/pvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
},
]
Expand All @@ -4179,6 +4183,7 @@ fn call_tracing_works() {
logs: logs.clone(),
value: Some(U256::from(0)),
calls: calls,
child_call_count: 2,
..Default::default()
};

Expand Down Expand Up @@ -4244,6 +4249,7 @@ fn create_call_tracing_works() {
call_type: CallType::Create2,
..Default::default()
},],
child_call_count: 1,
..Default::default()
}
);
Expand Down
Loading