From cdc033945741d79ebc87a630558b4fc507a51df6 Mon Sep 17 00:00:00 2001 From: PG Herveou <pgherveou@gmail.com> Date: Mon, 24 Feb 2025 17:56:21 +0100 Subject: [PATCH] [pallet-revive] tracing should wrap around call stack execution (#7676) Fix tracing should wrap around the entire call stack execution --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- prdoc/pr_7676.prdoc | 7 ++++ substrate/frame/revive/src/exec.rs | 67 +++++++++++++++--------------- 2 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 prdoc/pr_7676.prdoc diff --git a/prdoc/pr_7676.prdoc b/prdoc/pr_7676.prdoc new file mode 100644 index 00000000000..eea0b8c749f --- /dev/null +++ b/prdoc/pr_7676.prdoc @@ -0,0 +1,7 @@ +title: '[pallet-revive] tracing should wrap around call stack execution' +doc: +- audience: Runtime Dev + description: Fix tracing should wrap around the entire call stack execution +crates: +- name: pallet-revive + bump: minor diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index 721254180bf..e13212f5e5e 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -1015,10 +1015,21 @@ where fn run(&mut self, executable: E, input_data: Vec<u8>) -> Result<(), ExecError> { let frame = self.top_frame(); let entry_point = frame.entry_point; - let is_delegate_call = frame.delegate.is_some(); let delegated_code_hash = if frame.delegate.is_some() { Some(*executable.code_hash()) } else { None }; + if_tracing(|tracer| { + tracer.enter_child_span( + self.caller().account_id().map(T::AddressMapper::to_address).unwrap_or_default(), + T::AddressMapper::to_address(&frame.account_id), + frame.delegate.is_some(), + frame.read_only, + frame.value_transferred, + &input_data, + frame.nested_gas.gas_left(), + ); + }); + // The output of the caller frame will be replaced by the output of this run. // It is also not accessible from nested frames. // Hence we drop it early to save the memory. @@ -1036,8 +1047,6 @@ where let do_transaction = || -> ExecResult { let caller = self.caller(); let frame = top_frame_mut!(self); - let read_only = frame.read_only; - let value_transferred = frame.value_transferred; let account_id = &frame.account_id.clone(); // We need to make sure that the contract's account exists before calling its @@ -1081,35 +1090,10 @@ where )?; } - let contract_address = T::AddressMapper::to_address(account_id); - let maybe_caller_address = caller.account_id().map(T::AddressMapper::to_address); let code_deposit = executable.code_info().deposit(); - - if_tracing(|tracer| { - tracer.enter_child_span( - maybe_caller_address.unwrap_or_default(), - contract_address, - is_delegate_call, - read_only, - value_transferred, - &input_data, - frame.nested_gas.gas_left(), - ); - }); - - let output = executable.execute(self, entry_point, input_data).map_err(|e| { - if_tracing(|tracer| { - tracer.exit_child_span_with_error( - e.error, - top_frame_mut!(self).nested_gas.gas_consumed(), - ); - }); - ExecError { error: e.error, origin: ErrorOrigin::Callee } - })?; - - if_tracing(|tracer| { - tracer.exit_child_span(&output, top_frame_mut!(self).nested_gas.gas_consumed()); - }); + let output = executable + .execute(self, entry_point, input_data) + .map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; // Avoid useless work that would be reverted anyways. if output.did_revert() { @@ -1157,10 +1141,27 @@ where let (success, output) = match transaction_outcome { // `with_transactional` executed successfully, and we have the expected output. - Ok((success, output)) => (success, output), + Ok((success, output)) => { + if_tracing(|tracer| { + let gas_consumed = top_frame!(self).nested_gas.gas_consumed(); + match &output { + Ok(output) => tracer.exit_child_span(&output, gas_consumed), + Err(e) => tracer.exit_child_span_with_error(e.error.into(), gas_consumed), + } + }); + + (success, output) + }, // `with_transactional` returned an error, and we propagate that error and note no state // has changed. - Err(error) => (false, Err(error.into())), + Err(error) => { + if_tracing(|tracer| { + let gas_consumed = top_frame!(self).nested_gas.gas_consumed(); + tracer.exit_child_span_with_error(error.into(), gas_consumed); + }); + + (false, Err(error.into())) + }, }; if success { -- GitLab