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
This commit is contained in:
PG Herveou
2023-08-24 09:56:28 +02:00
committed by GitHub
parent 8b9455465b
commit cd464f9cfd
10 changed files with 97 additions and 89 deletions
@@ -0,0 +1,145 @@
use super::*;
use crate::debug::{CallSpan, ExportedFunction, Tracing};
use frame_support::traits::Currency;
use pallet_contracts_primitives::ExecReturnValue;
use pretty_assertions::assert_eq;
use std::cell::RefCell;
#[derive(Clone, PartialEq, Eq, Debug)]
struct DebugFrame {
code_hash: CodeHash<Test>,
call: ExportedFunction,
input: Vec<u8>,
result: Option<Vec<u8>>,
}
thread_local! {
static DEBUG_EXECUTION_TRACE: RefCell<Vec<DebugFrame>> = RefCell::new(Vec::new());
}
pub struct TestDebug;
pub struct TestCallSpan {
code_hash: CodeHash<Test>,
call: ExportedFunction,
input: Vec<u8>,
}
impl Tracing<Test> for TestDebug {
type CallSpan = TestCallSpan;
fn new_call_span(
code_hash: &CodeHash<Test>,
entry_point: ExportedFunction,
input_data: &[u8],
) -> TestCallSpan {
DEBUG_EXECUTION_TRACE.with(|d| {
d.borrow_mut().push(DebugFrame {
code_hash: *code_hash,
call: entry_point,
input: input_data.to_vec(),
result: None,
})
});
TestCallSpan { code_hash: *code_hash, call: entry_point, input: input_data.to_vec() }
}
}
impl CallSpan for TestCallSpan {
fn after_call(self, output: &ExecReturnValue) {
DEBUG_EXECUTION_TRACE.with(|d| {
d.borrow_mut().push(DebugFrame {
code_hash: self.code_hash,
call: self.call,
input: self.input,
result: Some(output.data.clone()),
})
});
}
}
#[test]
fn unsafe_debugging_works() {
let (wasm_caller, code_hash_caller) = compile_module::<Test>("call").unwrap();
let (wasm_callee, code_hash_callee) = compile_module::<Test>("store_call").unwrap();
fn current_stack() -> Vec<DebugFrame> {
DEBUG_EXECUTION_TRACE.with(|stack| stack.borrow().clone())
}
fn deploy(wasm: Vec<u8>) -> AccountId32 {
Contracts::bare_instantiate(
ALICE,
0,
GAS_LIMIT,
None,
Code::Upload(wasm),
vec![],
vec![],
DebugInfo::Skip,
CollectEvents::Skip,
)
.result
.unwrap()
.account_id
}
fn constructor_frame(hash: CodeHash<Test>, after: bool) -> DebugFrame {
DebugFrame {
code_hash: hash,
call: ExportedFunction::Constructor,
input: vec![],
result: if after { Some(vec![]) } else { None },
}
}
fn call_frame(hash: CodeHash<Test>, args: Vec<u8>, after: bool) -> DebugFrame {
DebugFrame {
code_hash: hash,
call: ExportedFunction::Call,
input: args,
result: if after { Some(vec![]) } else { None },
}
}
ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
assert_eq!(current_stack(), vec![]);
let addr_caller = deploy(wasm_caller);
let addr_callee = deploy(wasm_callee);
assert_eq!(
current_stack(),
vec![
constructor_frame(code_hash_caller, false),
constructor_frame(code_hash_caller, true),
constructor_frame(code_hash_callee, false),
constructor_frame(code_hash_callee, true),
]
);
let main_args = (100u32, &addr_callee).encode();
let inner_args = (100u32).encode();
assert_ok!(Contracts::call(
RuntimeOrigin::signed(ALICE),
addr_caller,
0,
GAS_LIMIT,
None,
main_args.clone()
));
let stack_top = current_stack()[4..].to_vec();
assert_eq!(
stack_top,
vec![
call_frame(code_hash_caller, main_args.clone(), false),
call_frame(code_hash_callee, inner_args.clone(), false),
call_frame(code_hash_callee, inner_args, true),
call_frame(code_hash_caller, main_args, true),
]
);
});
}