Skip to content

Commit 2458e0c

Browse files
ascjonesRobbepop
andauthored
Implement seal_debug_message (#792)
* Implement `seal_debug_message` * Update docs * Fmt * Fix debug_print macro * review: use newline char Co-authored-by: Robin Freyler <[email protected]> * Fix example * Revert to newline string * Fmt * Single call to debug_print for debug_println! * Add missing ReturnCode, still need to handle it * Inline debug_println! * If logging is disabled then subsequent calls will be a no-op * Fmt * Fix missing error match in experimental off-chain * Add safety comment to debug_message * Only re-export ink_prelude::format, and explain * Satisfy clippy * Encapsulate DEBUG_ENABLED global in module * Move seal_denug_message to unstable module * Update unstable and safety comments * Add more comments about the required features to be enabled on the node runtime * Add `ink-debug` feature, make debug messages a noop if not enabled * Fmt * Noop macro formatting * Enable debug printing for std * Comment formatting * Encapsulate static variable inside the function * Fmt * Remove debug_assert!(true) for disabled macros Co-authored-by: Robin Freyler <[email protected]>
1 parent d4fd3f7 commit 2458e0c

File tree

19 files changed

+192
-99
lines changed

19 files changed

+192
-99
lines changed

crates/engine/src/ext.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ define_error_codes! {
9191
CodeNotFound = 7,
9292
/// The account that was called is either no contract (e.g. user account) or is a tombstone.
9393
NotCallable = 8,
94+
/// The call to `seal_debug_message` had no effect because debug message
95+
/// recording was disabled.
96+
LoggingDisabled = 9,
9497
}
9598

9699
/// The raw return code returned by the host side.
@@ -317,10 +320,10 @@ impl Engine {
317320
unimplemented!("off-chain environment does not yet support `restore_to`");
318321
}
319322

320-
/// Prints the given contents to the console log.
321-
pub fn println(&mut self, content: &str) {
322-
self.debug_info.record_println(String::from(content));
323-
println!("{}", content);
323+
/// Records the given debug message and appends to stdout.
324+
pub fn debug_message(&mut self, message: &str) {
325+
self.debug_info.record_debug_message(String::from(message));
326+
print!("{}", message);
324327
}
325328

326329
/// Conduct the BLAKE-2 256-bit hash and place the result into `output`.

crates/engine/src/test_api.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -33,41 +33,41 @@ pub struct EmittedEvent {
3333
}
3434

3535
#[derive(Clone)]
36-
pub struct RecordedPrintlns {
37-
printlns: Vec<String>,
36+
pub struct RecordedDebugMessages {
37+
debug_messages: Vec<String>,
3838
}
3939

40-
impl RecordedPrintlns {
40+
impl RecordedDebugMessages {
4141
// Creates a new `Engine instance.
4242
pub fn new() -> Self {
4343
Self {
44-
printlns: Vec::new(),
44+
debug_messages: Vec::new(),
4545
}
4646
}
4747

48-
// Records a new println.
49-
pub fn record(&mut self, println: String) {
50-
self.printlns.push(println);
48+
// Records a new debug message.
49+
pub fn record(&mut self, message: String) {
50+
self.debug_messages.push(message);
5151
}
5252

53-
// Clears all recorded printlns.
53+
// Clears all recorded debug messages.
5454
pub fn clear(&mut self) {
55-
self.printlns.clear();
55+
self.debug_messages.clear();
5656
}
5757
}
5858

59-
impl Default for RecordedPrintlns {
59+
impl Default for RecordedDebugMessages {
6060
fn default() -> Self {
6161
Self::new()
6262
}
6363
}
6464

65-
impl IntoIterator for RecordedPrintlns {
65+
impl IntoIterator for RecordedDebugMessages {
6666
type Item = String;
6767
type IntoIter = std::vec::IntoIter<Self::Item>;
6868

6969
fn into_iter(self) -> Self::IntoIter {
70-
self.printlns.into_iter()
70+
self.debug_messages.into_iter()
7171
}
7272
}
7373

@@ -76,7 +76,7 @@ pub struct DebugInfo {
7676
/// Emitted events recorder.
7777
emitted_events: Vec<EmittedEvent>,
7878
/// Emitted print messages recorder.
79-
emitted_printlns: RecordedPrintlns,
79+
emitted_debug_messages: RecordedDebugMessages,
8080
/// The total number of reads to the storage.
8181
count_reads: HashMap<AccountId, usize>,
8282
/// The total number of writes to the storage.
@@ -96,7 +96,7 @@ impl DebugInfo {
9696
pub fn new() -> Self {
9797
Self {
9898
emitted_events: Vec::new(),
99-
emitted_printlns: RecordedPrintlns::new(),
99+
emitted_debug_messages: RecordedDebugMessages::new(),
100100
count_reads: HashMap::new(),
101101
count_writes: HashMap::new(),
102102
cells_per_account: HashMap::new(),
@@ -108,7 +108,7 @@ impl DebugInfo {
108108
self.count_reads.clear();
109109
self.count_writes.clear();
110110
self.emitted_events.clear();
111-
self.emitted_printlns.clear();
111+
self.emitted_debug_messages.clear();
112112
self.cells_per_account.clear();
113113
}
114114

@@ -159,9 +159,9 @@ impl DebugInfo {
159159
.unwrap_or(None)
160160
}
161161

162-
/// Records a println.
163-
pub fn record_println(&mut self, println: String) {
164-
self.emitted_printlns.record(println);
162+
/// Records a debug message.
163+
pub fn record_debug_message(&mut self, message: String) {
164+
self.emitted_debug_messages.record(message);
165165
}
166166

167167
/// Records an event.
@@ -215,9 +215,9 @@ impl Engine {
215215
self.exec_context.callee()
216216
}
217217

218-
/// Returns the contents of the past performed environmental `println` in order.
219-
pub fn get_recorded_printlns(&self) -> RecordedPrintlns {
220-
self.debug_info.emitted_printlns.clone()
218+
/// Returns the contents of the past performed environmental `debug_message` in order.
219+
pub fn get_emitted_debug_messages(&self) -> RecordedDebugMessages {
220+
self.debug_info.emitted_debug_messages.clone()
221221
}
222222

223223
/// Returns the recorded emitted events in order.

crates/engine/src/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ fn transfer() {
115115
}
116116

117117
#[test]
118-
fn printlns() {
118+
fn debug_messages() {
119119
let mut engine = Engine::new();
120-
engine.println("foobar");
121-
let mut recorded = engine.get_recorded_printlns().into_iter();
120+
engine.debug_message("foobar");
121+
let mut recorded = engine.get_emitted_debug_messages().into_iter();
122122
assert_eq!(recorded.next(), Some("foobar".into()));
123123
assert_eq!(recorded.next(), None);
124124
}

crates/env/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@ std = [
6262
"sha3",
6363
"blake2",
6464
]
65+
# Enable contract debug messages via `debug_print!` and `debug_println!`.
66+
ink-debug = []
6567
ink-experimental-engine = ["ink_engine"]

crates/env/src/api.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,10 @@ where
553553
})
554554
}
555555

556-
/// Prints the given contents to the environmental log.
557-
pub fn debug_println(content: &str) {
556+
/// Appends the given message to the debug message buffer.
557+
pub fn debug_message(message: &str) {
558558
<EnvInstance as OnInstance>::on_instance(|instance| {
559-
EnvBackend::println(instance, content)
559+
EnvBackend::debug_message(instance, message)
560560
})
561561
}
562562

crates/env/src/backend.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,15 @@ pub trait EnvBackend {
119119
where
120120
R: scale::Encode;
121121

122-
/// Prints the given contents to the console log.
123-
fn println(&mut self, content: &str);
122+
/// Emit a custom debug message.
123+
///
124+
/// The message is appended to the debug buffer which is then supplied to the calling RPC
125+
/// client. This buffer is also printed as a debug message to the node console if the
126+
/// `debug` log level is enabled for the `runtime::contracts` target.
127+
///
128+
/// If debug message recording is disabled in the contracts pallet, which is always the case
129+
/// when the code is executing on-chain, then this will have no effect.
130+
fn debug_message(&mut self, content: &str);
124131

125132
/// Conducts the crypto hash of the given input and stores the result in `output`.
126133
fn hash_bytes<H>(&mut self, input: &[u8], output: &mut <H as HashOutput>::Type)

crates/env/src/engine/experimental_off_chain/impls.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ impl From<ext::Error> for crate::Error {
111111
ext::Error::NewContractNotFunded => Self::NewContractNotFunded,
112112
ext::Error::CodeNotFound => Self::CodeNotFound,
113113
ext::Error::NotCallable => Self::NotCallable,
114+
ext::Error::LoggingDisabled => Self::LoggingDisabled,
114115
}
115116
}
116117
}
@@ -227,8 +228,8 @@ impl EnvBackend for EnvInstance {
227228
)
228229
}
229230

230-
fn println(&mut self, content: &str) {
231-
self.engine.println(content)
231+
fn debug_message(&mut self, message: &str) {
232+
self.engine.debug_message(message)
232233
}
233234

234235
fn hash_bytes<H>(&mut self, input: &[u8], output: &mut <H as HashOutput>::Type)

crates/env/src/engine/experimental_off_chain/test_api.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{
2323
Result,
2424
};
2525
use core::fmt::Debug;
26-
use ink_engine::test_api::RecordedPrintlns;
26+
use ink_engine::test_api::RecordedDebugMessages;
2727
use std::panic::UnwindSafe;
2828

2929
/// Record for an emitted event.
@@ -129,10 +129,10 @@ where
129129
unimplemented!("off-chain environment does not yet support `set_block_entropy`");
130130
}
131131

132-
/// Returns the contents of the past performed environmental `println` in order.
133-
pub fn recorded_printlns() -> RecordedPrintlns {
132+
/// Returns the contents of the past performed environmental debug messages in order.
133+
pub fn recorded_debug_messages() -> RecordedDebugMessages {
134134
<EnvInstance as OnInstance>::on_instance(|instance| {
135-
instance.engine.get_recorded_printlns()
135+
instance.engine.get_emitted_debug_messages()
136136
})
137137
}
138138

crates/env/src/engine/off_chain/db/console.rs crates/env/src/engine/off_chain/db/debug_buf.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -14,67 +14,67 @@
1414

1515
use ink_prelude::string::String;
1616

17-
/// A debug console used to print console contents and store them.
18-
pub struct Console {
19-
/// The buffer to store the already pasted contents.
20-
past_prints: Vec<String>,
17+
/// A debug buffer used to store debug messages and print them to stdout.
18+
pub struct DebugBuffer {
19+
/// The buffer to store the emitted debug messages.
20+
past_debug_messages: Vec<String>,
2121
}
2222

23-
impl Console {
23+
impl DebugBuffer {
2424
/// Creates a new empty console.
2525
pub fn new() -> Self {
2626
Self {
27-
past_prints: Vec::new(),
27+
past_debug_messages: Vec::new(),
2828
}
2929
}
3030

31-
/// Resets the console to uninitialized state.
31+
/// Resets the debug buffer to uninitialized state.
3232
pub fn reset(&mut self) {
33-
self.past_prints.clear();
33+
self.past_debug_messages.clear();
3434
}
3535

36-
/// Prints the contents to the actual console and stores them.
37-
pub fn println(&mut self, contents: &str) {
38-
self.past_prints.push(contents.to_string());
39-
println!("{}", contents);
36+
/// Prints the message to stdout and stores it.
37+
pub fn debug_message(&mut self, message: &str) {
38+
self.past_debug_messages.push(message.to_string());
39+
print!("{}", message);
4040
}
4141

42-
/// Returns an iterator over the past console prints.
43-
pub fn past_prints(&self) -> PastPrints {
44-
PastPrints::new(self)
42+
/// Returns an iterator over the past debug messages.
43+
pub fn past_debug_messages(&self) -> DebugMessages {
44+
DebugMessages::new(self)
4545
}
4646
}
4747

48-
/// Iterator over the past prints to the console.
49-
pub struct PastPrints<'a> {
50-
/// Iterator over the past printlns.
48+
/// Iterator over the past debug messages.
49+
pub struct DebugMessages<'a> {
50+
/// Iterator over the past debug messages.
5151
iter: core::slice::Iter<'a, String>,
5252
}
5353

54-
impl<'a> PastPrints<'a> {
55-
/// Creates a new iterator over the past console prints.
56-
fn new(console: &'a Console) -> Self {
54+
impl<'a> DebugMessages<'a> {
55+
/// Creates a new iterator over the past debug messages.
56+
fn new(console: &'a DebugBuffer) -> Self {
5757
Self {
58-
iter: console.past_prints.iter(),
58+
iter: console.past_debug_messages.iter(),
5959
}
6060
}
6161
}
6262

63-
impl<'a> Iterator for PastPrints<'a> {
63+
impl<'a> Iterator for DebugMessages<'a> {
6464
type Item = &'a str;
6565

6666
fn next(&mut self) -> Option<Self::Item> {
6767
self.iter.next().map(AsRef::as_ref)
6868
}
6969
}
7070

71-
impl<'a> ExactSizeIterator for PastPrints<'a> {
71+
impl<'a> ExactSizeIterator for DebugMessages<'a> {
7272
fn len(&self) -> usize {
7373
self.iter.len()
7474
}
7575
}
7676

77-
impl<'a> DoubleEndedIterator for PastPrints<'a> {
77+
impl<'a> DoubleEndedIterator for DebugMessages<'a> {
7878
fn next_back(&mut self) -> Option<Self::Item> {
7979
self.iter.next_back().map(AsRef::as_ref)
8080
}

crates/env/src/engine/off_chain/db/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
mod accounts;
1616
mod block;
1717
mod chain_spec;
18-
mod console;
18+
mod debug_buf;
1919
mod events;
2020
mod exec_context;
2121

@@ -30,9 +30,9 @@ pub use self::{
3030
},
3131
block::Block,
3232
chain_spec::ChainSpec,
33-
console::{
34-
Console,
35-
PastPrints,
33+
debug_buf::{
34+
DebugBuffer,
35+
DebugMessages,
3636
},
3737
events::{
3838
EmittedEvent,

crates/env/src/engine/off_chain/impls.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ impl EnvBackend for EnvInstance {
175175
std::process::exit(flags.into_u32() as i32)
176176
}
177177

178-
fn println(&mut self, content: &str) {
179-
self.console.println(content)
178+
fn debug_message(&mut self, message: &str) {
179+
self.debug_buf.debug_message(message)
180180
}
181181

182182
fn hash_bytes<H>(&mut self, input: &[u8], output: &mut <H as HashOutput>::Type)

0 commit comments

Comments
 (0)