Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit bdee519

Browse files
authored
Contracts: Update Config::Debug (#14789)
* Update Debug trait * Rename * tweak * fmt * Better namings * rm unsafe-debug * rework doc * nit * fix comment * clippy * update naming * Rename file * fmt fixes * rename * Move tracing behind umbrella Debugging trait * fix * fix comment * reorder imports * comment * update doc * add missing doc * add missing doc * Update Debugging -> Debugger * Update bin/node/runtime/Cargo.toml
1 parent b7c18f1 commit bdee519

File tree

10 files changed

+97
-89
lines changed

10 files changed

+97
-89
lines changed

bin/node/runtime/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,3 @@ try-runtime = [
373373
"pallet-whitelist/try-runtime",
374374
"sp-runtime/try-runtime",
375375
]
376-
unsafe-debug = [ "pallet-contracts/unsafe-debug" ]

bin/node/runtime/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,6 @@ impl pallet_contracts::Config for Runtime {
12641264
type Migrations = pallet_contracts::migration::codegen::BenchMigrations;
12651265
type MaxDelegateDependencies = ConstU32<32>;
12661266
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
1267-
#[cfg(feature = "unsafe-debug")]
12681267
type Debug = ();
12691268
type Environment = ();
12701269
}

frame/contracts/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,3 @@ try-runtime = [
114114
"pallet-utility/try-runtime",
115115
"sp-runtime/try-runtime",
116116
]
117-
unsafe-debug = []

frame/contracts/src/debug.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
pub use crate::exec::ExportedFunction;
2+
use crate::{CodeHash, Config, LOG_TARGET};
3+
use pallet_contracts_primitives::ExecReturnValue;
4+
5+
/// Umbrella trait for all interfaces that serves for debugging.
6+
pub trait Debugger<T: Config>: Tracing<T> {}
7+
8+
impl<T: Config, V> Debugger<T> for V where V: Tracing<T> {}
9+
10+
/// Defines methods to capture contract calls, enabling external observers to
11+
/// measure, trace, and react to contract interactions.
12+
pub trait Tracing<T: Config> {
13+
/// The type of [`CallSpan`] that is created by this trait.
14+
type CallSpan: CallSpan;
15+
16+
/// Creates a new call span to encompass the upcoming contract execution.
17+
///
18+
/// This method should be invoked just before the execution of a contract and
19+
/// marks the beginning of a traceable span of execution.
20+
///
21+
/// # Arguments
22+
///
23+
/// * `code_hash` - The code hash of the contract being called.
24+
/// * `entry_point` - Describes whether the call is the constructor or a regular call.
25+
/// * `input_data` - The raw input data of the call.
26+
fn new_call_span(
27+
code_hash: &CodeHash<T>,
28+
entry_point: ExportedFunction,
29+
input_data: &[u8],
30+
) -> Self::CallSpan;
31+
}
32+
33+
/// Defines a span of execution for a contract call.
34+
pub trait CallSpan {
35+
/// Called just after the execution of a contract.
36+
///
37+
/// # Arguments
38+
///
39+
/// * `output` - The raw output of the call.
40+
fn after_call(self, output: &ExecReturnValue);
41+
}
42+
43+
impl<T: Config> Tracing<T> for () {
44+
type CallSpan = ();
45+
46+
fn new_call_span(code_hash: &CodeHash<T>, entry_point: ExportedFunction, input_data: &[u8]) {
47+
log::trace!(target: LOG_TARGET, "call {entry_point:?} hash: {code_hash:?}, input_data: {input_data:?}")
48+
}
49+
}
50+
51+
impl CallSpan for () {
52+
fn after_call(self, output: &ExecReturnValue) {
53+
log::trace!(target: LOG_TARGET, "call result {output:?}")
54+
}
55+
}

frame/contracts/src/exec.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717

18-
#[cfg(feature = "unsafe-debug")]
19-
use crate::unsafe_debug::ExecutionObserver;
2018
use crate::{
19+
debug::{CallSpan, Tracing},
2120
gas::GasMeter,
2221
storage::{self, meter::Diff, WriteOutcome},
2322
BalanceOf, CodeHash, CodeInfo, CodeInfoOf, Config, ContractInfo, ContractInfoOf,
@@ -908,20 +907,15 @@ where
908907
// Every non delegate call or instantiate also optionally transfers the balance.
909908
self.initial_transfer()?;
910909

911-
#[cfg(feature = "unsafe-debug")]
912-
let (code_hash, input_clone) = {
913-
let code_hash = *executable.code_hash();
914-
T::Debug::before_call(&code_hash, entry_point, &input_data);
915-
(code_hash, input_data.clone())
916-
};
910+
let call_span =
911+
T::Debug::new_call_span(executable.code_hash(), entry_point, &input_data);
917912

918913
// Call into the Wasm blob.
919914
let output = executable
920915
.execute(self, &entry_point, input_data)
921916
.map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?;
922917

923-
#[cfg(feature = "unsafe-debug")]
924-
T::Debug::after_call(&code_hash, entry_point, input_clone, &output);
918+
call_span.after_call(&output);
925919

926920
// Avoid useless work that would be reverted anyways.
927921
if output.did_revert() {

frame/contracts/src/lib.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ mod storage;
9696
mod wasm;
9797

9898
pub mod chain_extension;
99+
pub mod debug;
99100
pub mod migration;
100-
pub mod unsafe_debug;
101101
pub mod weights;
102102

103103
#[cfg(test)]
@@ -144,6 +144,7 @@ use sp_std::{fmt::Debug, prelude::*};
144144

145145
pub use crate::{
146146
address::{AddressGenerator, DefaultAddressGenerator},
147+
debug::Tracing,
147148
exec::Frame,
148149
migration::{MigrateSequence, Migration, NoopMigration},
149150
pallet::*,
@@ -219,6 +220,7 @@ pub struct Environment<T: Config> {
219220
#[frame_support::pallet]
220221
pub mod pallet {
221222
use super::*;
223+
use crate::debug::Debugger;
222224
use frame_support::pallet_prelude::*;
223225
use frame_system::pallet_prelude::*;
224226
use sp_runtime::Perbill;
@@ -390,13 +392,11 @@ pub mod pallet {
390392
/// ```
391393
type Migrations: MigrateSequence;
392394

393-
/// Type that provides debug handling for the contract execution process.
394-
///
395-
/// # Warning
396-
///
397-
/// Do **not** use it in a production environment or for benchmarking purposes.
398-
#[cfg(feature = "unsafe-debug")]
399-
type Debug: unsafe_debug::UnsafeDebug<Self>;
395+
/// # Note
396+
/// For most production chains, it's recommended to use the `()` implementation of this
397+
/// trait. This implementation offers additional logging when the log target
398+
/// "runtime::contracts" is set to trace.
399+
type Debug: Debugger<Self>;
400400

401401
/// Type that bundles together all the runtime configurable interface types.
402402
///

frame/contracts/src/tests.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
// limitations under the License.
1717

1818
mod pallet_dummy;
19-
mod unsafe_debug;
19+
mod test_debug;
2020

21-
use self::test_utils::{ensure_stored, expected_deposit, hash};
21+
use self::{
22+
test_debug::TestDebug,
23+
test_utils::{ensure_stored, expected_deposit, hash},
24+
};
2225
use crate::{
2326
self as pallet_contracts,
2427
chain_extension::{
@@ -479,8 +482,7 @@ impl Config for Test {
479482
type Migrations = crate::migration::codegen::BenchMigrations;
480483
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
481484
type MaxDelegateDependencies = MaxDelegateDependencies;
482-
#[cfg(feature = "unsafe-debug")]
483-
type Debug = unsafe_debug::TestDebugger;
485+
type Debug = TestDebug;
484486
type Environment = ();
485487
}
486488

frame/contracts/src/tests/unsafe_debug.rs renamed to frame/contracts/src/tests/test_debug.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
#![cfg(feature = "unsafe-debug")]
2-
31
use super::*;
4-
use crate::unsafe_debug::{ExecutionObserver, ExportedFunction};
2+
use crate::debug::{CallSpan, ExportedFunction, Tracing};
53
use frame_support::traits::Currency;
64
use pallet_contracts_primitives::ExecReturnValue;
75
use pretty_assertions::assert_eq;
@@ -19,31 +17,40 @@ thread_local! {
1917
static DEBUG_EXECUTION_TRACE: RefCell<Vec<DebugFrame>> = RefCell::new(Vec::new());
2018
}
2119

22-
pub struct TestDebugger;
20+
pub struct TestDebug;
21+
pub struct TestCallSpan {
22+
code_hash: CodeHash<Test>,
23+
call: ExportedFunction,
24+
input: Vec<u8>,
25+
}
26+
27+
impl Tracing<Test> for TestDebug {
28+
type CallSpan = TestCallSpan;
2329

24-
impl ExecutionObserver<CodeHash<Test>> for TestDebugger {
25-
fn before_call(code_hash: &CodeHash<Test>, entry_point: ExportedFunction, input_data: &[u8]) {
30+
fn new_call_span(
31+
code_hash: &CodeHash<Test>,
32+
entry_point: ExportedFunction,
33+
input_data: &[u8],
34+
) -> TestCallSpan {
2635
DEBUG_EXECUTION_TRACE.with(|d| {
2736
d.borrow_mut().push(DebugFrame {
28-
code_hash: code_hash.clone(),
37+
code_hash: *code_hash,
2938
call: entry_point,
3039
input: input_data.to_vec(),
3140
result: None,
3241
})
3342
});
43+
TestCallSpan { code_hash: *code_hash, call: entry_point, input: input_data.to_vec() }
3444
}
45+
}
3546

36-
fn after_call(
37-
code_hash: &CodeHash<Test>,
38-
entry_point: ExportedFunction,
39-
input_data: Vec<u8>,
40-
output: &ExecReturnValue,
41-
) {
47+
impl CallSpan for TestCallSpan {
48+
fn after_call(self, output: &ExecReturnValue) {
4249
DEBUG_EXECUTION_TRACE.with(|d| {
4350
d.borrow_mut().push(DebugFrame {
44-
code_hash: code_hash.clone(),
45-
call: entry_point,
46-
input: input_data,
51+
code_hash: self.code_hash,
52+
call: self.call,
53+
input: self.input,
4754
result: Some(output.data.clone()),
4855
})
4956
});

frame/contracts/src/unsafe_debug.rs

-47
This file was deleted.

scripts/ci/gitlab/pipeline/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ test-linux-stable:
234234
--locked
235235
--release
236236
--verbose
237-
--features runtime-benchmarks,try-runtime,experimental,unsafe-debug
237+
--features runtime-benchmarks,try-runtime,experimental
238238
--manifest-path ./bin/node/cli/Cargo.toml
239239
--partition count:${CI_NODE_INDEX}/${CI_NODE_TOTAL}
240240
# we need to update cache only from one job

0 commit comments

Comments
 (0)