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

Commit 8d20ed5

Browse files
agryaznovathei
andauthored
[contracts] Make debug buffer work like a FIFO pipe (#12953)
* make debug buffer work like a FIFO pipe * remove unused Error type * Remove panics * Update frame/contracts/src/exec.rs Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> Co-authored-by: Alexander Theißen <alex.theissen@me.com>
1 parent 6fe8cd4 commit 8d20ed5

File tree

4 files changed

+52
-43
lines changed

4 files changed

+52
-43
lines changed

frame/contracts/src/exec.rs

+48-36
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ pub trait Ext: sealing::Sealed {
279279
/// when the code is executing on-chain.
280280
///
281281
/// Returns `true` if debug message recording is enabled. Otherwise `false` is returned.
282-
fn append_debug_buffer(&mut self, msg: &str) -> Result<bool, DispatchError>;
282+
fn append_debug_buffer(&mut self, msg: &str) -> bool;
283283

284284
/// Call some dispatchable and return the result.
285285
fn call_runtime(&self, call: <Self::T as Config>::RuntimeCall) -> DispatchResultWithPostInfo;
@@ -1334,16 +1334,34 @@ where
13341334
&mut self.top_frame_mut().nested_gas
13351335
}
13361336

1337-
fn append_debug_buffer(&mut self, msg: &str) -> Result<bool, DispatchError> {
1337+
fn append_debug_buffer(&mut self, msg: &str) -> bool {
13381338
if let Some(buffer) = &mut self.debug_message {
1339-
if !msg.is_empty() {
1340-
buffer
1341-
.try_extend(&mut msg.bytes())
1342-
.map_err(|_| Error::<T>::DebugBufferExhausted)?;
1343-
}
1344-
Ok(true)
1339+
let mut msg = msg.bytes();
1340+
let num_drain = {
1341+
let capacity = DebugBufferVec::<T>::bound().checked_sub(buffer.len()).expect(
1342+
"
1343+
`buffer` is of type `DebugBufferVec`,
1344+
`DebugBufferVec` is a `BoundedVec`,
1345+
`BoundedVec::len()` <= `BoundedVec::bound()`;
1346+
qed
1347+
",
1348+
);
1349+
msg.len().saturating_sub(capacity).min(buffer.len())
1350+
};
1351+
buffer.drain(0..num_drain);
1352+
buffer
1353+
.try_extend(&mut msg)
1354+
.map_err(|_| {
1355+
log::debug!(
1356+
target: "runtime::contracts",
1357+
"Debug message to big (size={}) for debug buffer (bound={})",
1358+
msg.len(), DebugBufferVec::<T>::bound(),
1359+
);
1360+
})
1361+
.ok();
1362+
true
13451363
} else {
1346-
Ok(false)
1364+
false
13471365
}
13481366
}
13491367

@@ -2511,12 +2529,8 @@ mod tests {
25112529
#[test]
25122530
fn printing_works() {
25132531
let code_hash = MockLoader::insert(Call, |ctx, _| {
2514-
ctx.ext
2515-
.append_debug_buffer("This is a test")
2516-
.expect("Maximum allowed debug buffer size exhausted!");
2517-
ctx.ext
2518-
.append_debug_buffer("More text")
2519-
.expect("Maximum allowed debug buffer size exhausted!");
2532+
ctx.ext.append_debug_buffer("This is a test");
2533+
ctx.ext.append_debug_buffer("More text");
25202534
exec_success()
25212535
});
25222536

@@ -2549,12 +2563,8 @@ mod tests {
25492563
#[test]
25502564
fn printing_works_on_fail() {
25512565
let code_hash = MockLoader::insert(Call, |ctx, _| {
2552-
ctx.ext
2553-
.append_debug_buffer("This is a test")
2554-
.expect("Maximum allowed debug buffer size exhausted!");
2555-
ctx.ext
2556-
.append_debug_buffer("More text")
2557-
.expect("Maximum allowed debug buffer size exhausted!");
2566+
ctx.ext.append_debug_buffer("This is a test");
2567+
ctx.ext.append_debug_buffer("More text");
25582568
exec_trapped()
25592569
});
25602570

@@ -2587,7 +2597,7 @@ mod tests {
25872597
#[test]
25882598
fn debug_buffer_is_limited() {
25892599
let code_hash = MockLoader::insert(Call, move |ctx, _| {
2590-
ctx.ext.append_debug_buffer("overflowing bytes")?;
2600+
ctx.ext.append_debug_buffer("overflowing bytes");
25912601
exec_success()
25922602
});
25932603

@@ -2602,20 +2612,22 @@ mod tests {
26022612
set_balance(&ALICE, min_balance * 10);
26032613
place_contract(&BOB, code_hash);
26042614
let mut storage_meter = storage::meter::Meter::new(&ALICE, Some(0), 0).unwrap();
2605-
assert_err!(
2606-
MockStack::run_call(
2607-
ALICE,
2608-
BOB,
2609-
&mut gas_meter,
2610-
&mut storage_meter,
2611-
&schedule,
2612-
0,
2613-
vec![],
2614-
Some(&mut debug_buffer),
2615-
Determinism::Deterministic,
2616-
)
2617-
.map_err(|e| e.error),
2618-
Error::<Test>::DebugBufferExhausted
2615+
MockStack::run_call(
2616+
ALICE,
2617+
BOB,
2618+
&mut gas_meter,
2619+
&mut storage_meter,
2620+
&schedule,
2621+
0,
2622+
vec![],
2623+
Some(&mut debug_buffer),
2624+
Determinism::Deterministic,
2625+
)
2626+
.unwrap();
2627+
assert_eq!(
2628+
&String::from_utf8(debug_buffer[DebugBufferVec::<Test>::bound() - 17..].to_vec())
2629+
.unwrap(),
2630+
"overflowing bytes"
26192631
);
26202632
});
26212633
}

frame/contracts/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -857,9 +857,6 @@ pub mod pallet {
857857
CodeRejected,
858858
/// An indetermistic code was used in a context where this is not permitted.
859859
Indeterministic,
860-
/// The debug buffer size used during contract execution exceeded the limit determined by
861-
/// the `MaxDebugBufferLen` pallet config parameter.
862-
DebugBufferExhausted,
863860
}
864861

865862
/// A mapping from an original code hash to the original code, untouched by instrumentation.

frame/contracts/src/wasm/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,9 @@ mod tests {
588588
fn gas_meter(&mut self) -> &mut GasMeter<Self::T> {
589589
&mut self.gas_meter
590590
}
591-
fn append_debug_buffer(&mut self, msg: &str) -> Result<bool, DispatchError> {
591+
fn append_debug_buffer(&mut self, msg: &str) -> bool {
592592
self.debug_buffer.extend(msg.as_bytes());
593-
Ok(true)
593+
true
594594
}
595595
fn call_runtime(
596596
&self,

frame/contracts/src/wasm/runtime.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2380,11 +2380,11 @@ pub mod env {
23802380
str_len: u32,
23812381
) -> Result<ReturnCode, TrapReason> {
23822382
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
2383-
if ctx.ext.append_debug_buffer("")? {
2383+
if ctx.ext.append_debug_buffer("") {
23842384
let data = ctx.read_sandbox_memory(memory, str_ptr, str_len)?;
23852385
let msg =
23862386
core::str::from_utf8(&data).map_err(|_| <Error<E::T>>::DebugMessageInvalidUTF8)?;
2387-
ctx.ext.append_debug_buffer(msg)?;
2387+
ctx.ext.append_debug_buffer(msg);
23882388
return Ok(ReturnCode::Success)
23892389
}
23902390
Ok(ReturnCode::LoggingDisabled)

0 commit comments

Comments
 (0)