[contracts] make debug_message execution outcome invariant to node debug logging setting (#13197)

* update benchmark for seal_debug_message

* add seal_debug_message_per_kb benchmark

* un-fallable debug buffer: silently drops excessive and wrong utf-8 encoded messages

* charge debug_message per byte of the message

* improved benchmark

* cap debug_message

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* fix applied buggy suggestion

* make sure i*1024 < MaxDebugBufferLen

* fix schedule for our non-batched benchmark

* Switch to a `wasmtime` fork with LTO linking failure workaround

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts

---------

Co-authored-by: command-bot <>
Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Co-authored-by: Jan Bujak <jan@parity.io>
This commit is contained in:
Sasha Gryaznov
2023-02-14 20:28:34 +02:00
committed by GitHub
parent df24729d74
commit 53b7778599
13 changed files with 1373 additions and 1065 deletions
+17 -18
View File
@@ -21,7 +21,7 @@ use crate::{
exec::{ExecError, ExecResult, Ext, FixSizedKey, TopicOf, VarSizedKey},
gas::{ChargedAmount, Token},
schedule::HostFnWeights,
BalanceOf, CodeHash, Config, Error, SENTINEL,
BalanceOf, CodeHash, Config, DebugBufferVec, Error, SENTINEL,
};
use bitflags::bitflags;
@@ -114,9 +114,6 @@ pub enum ReturnCode {
CodeNotFound = 7,
/// The contract that was called is no contract (a plain account).
NotCallable = 8,
/// The call to `seal_debug_message` had no effect because debug message
/// recording was disabled.
LoggingDisabled = 9,
/// The call dispatched by `seal_call_runtime` was executed but returned an error.
CallRuntimeReturnedError = 10,
/// ECDSA pubkey recovery failed (most probably wrong recovery id or signature), or
@@ -229,8 +226,8 @@ pub enum RuntimeCosts {
Random,
/// Weight of calling `seal_deposit_event` with the given number of topics and event size.
DepositEvent { num_topic: u32, len: u32 },
/// Weight of calling `seal_debug_message`.
DebugMessage,
/// Weight of calling `seal_debug_message` per byte of passed message.
DebugMessage(u32),
/// Weight of calling `seal_set_storage` for the given storage item sizes.
SetStorage { old_bytes: u32, new_bytes: u32 },
/// Weight of calling `seal_clear_storage` per cleared byte.
@@ -309,7 +306,9 @@ impl RuntimeCosts {
.deposit_event
.saturating_add(s.deposit_event_per_topic.saturating_mul(num_topic.into()))
.saturating_add(s.deposit_event_per_byte.saturating_mul(len.into())),
DebugMessage => s.debug_message,
DebugMessage(len) => s
.debug_message
.saturating_add(s.deposit_event_per_byte.saturating_mul(len.into())),
SetStorage { new_bytes, old_bytes } => s
.set_storage
.saturating_add(s.set_storage_per_new_byte.saturating_mul(new_bytes.into()))
@@ -2054,7 +2053,7 @@ pub mod env {
_delta_ptr: u32,
_delta_count: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
Ok(())
}
@@ -2076,7 +2075,7 @@ pub mod env {
_delta_ptr: u32,
_delta_count: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
Ok(())
}
@@ -2094,7 +2093,7 @@ pub mod env {
_value_ptr: u32,
_value_len: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
Ok(())
}
@@ -2108,7 +2107,7 @@ pub mod env {
#[prefixed_alias]
#[deprecated]
fn set_rent_allowance(ctx: _, _memory: _, _value_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
Ok(())
}
@@ -2362,7 +2361,7 @@ pub mod env {
/// Emit a custom debug message.
///
/// No newlines are added to the supplied message.
/// Specifying invalid UTF-8 triggers a trap.
/// Specifying invalid UTF-8 just drops the message with no trap.
///
/// This is a no-op if debug message recording is disabled which is always the case
/// when the code is executing on-chain. The message is interpreted as UTF-8 and
@@ -2383,15 +2382,15 @@ pub mod env {
str_ptr: u32,
str_len: u32,
) -> Result<ReturnCode, TrapReason> {
ctx.charge_gas(RuntimeCosts::DebugMessage)?;
let str_len = str_len.min(DebugBufferVec::<E::T>::bound() as u32);
ctx.charge_gas(RuntimeCosts::DebugMessage(str_len))?;
if ctx.ext.append_debug_buffer("") {
let data = ctx.read_sandbox_memory(memory, str_ptr, str_len)?;
let msg =
core::str::from_utf8(&data).map_err(|_| <Error<E::T>>::DebugMessageInvalidUTF8)?;
ctx.ext.append_debug_buffer(msg);
return Ok(ReturnCode::Success)
if let Some(msg) = core::str::from_utf8(&data).ok() {
ctx.ext.append_debug_buffer(msg);
}
}
Ok(ReturnCode::LoggingDisabled)
Ok(ReturnCode::Success)
}
/// Call some dispatchable of the runtime.