[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
+19 -38
View File
@@ -1186,8 +1186,7 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
[[package]]
name = "cranelift-bforest"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3d54eab028f5805ae3b26fd60eca3f3a9cfb76b989d9bab173be3f61356cc3"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-entity",
]
@@ -1195,8 +1194,7 @@ dependencies = [
[[package]]
name = "cranelift-codegen"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2be1d5f2c3cca1efb691844bc1988b89c77291f13f778499a3f3c0cf49c0ed61"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"arrayvec 0.7.2",
"bumpalo",
@@ -1216,8 +1214,7 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9b1b1089750ce4005893af7ee00bb08a2cf1c9779999c0f7164cbc8ad2e0d2"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-codegen-shared",
]
@@ -1225,14 +1222,12 @@ dependencies = [
[[package]]
name = "cranelift-codegen-shared"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc5fbaec51de47297fd7304986fd53c8c0030abbe69728a60d72e1c63559318d"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
[[package]]
name = "cranelift-entity"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dab984c94593f876090fae92e984bdcc74d9b1acf740ab5f79036001c65cba13"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"serde",
]
@@ -1240,8 +1235,7 @@ dependencies = [
[[package]]
name = "cranelift-frontend"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e0cb3102d21a2fe5f3210af608748ddd0cd09825ac12d42dc56ed5ed8725fe0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-codegen",
"log",
@@ -1252,14 +1246,12 @@ dependencies = [
[[package]]
name = "cranelift-isle"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72101dd1f441d629735143c41e00b3428f9267738176983ef588ff43382af0a0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
[[package]]
name = "cranelift-native"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c22b0d9fcbe3fc5a1af9e7021b44ce42b930bcefac446ce22e02e8f9a0d67120"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-codegen",
"libc",
@@ -1269,8 +1261,7 @@ dependencies = [
[[package]]
name = "cranelift-wasm"
version = "0.92.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddebe32fb14fbfd9efa5f130ffb8f4665795de019928dcd7247b136c46f9249"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
@@ -11932,8 +11923,7 @@ dependencies = [
[[package]]
name = "wasmtime"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e5b183a159484980138cc05231419c536d395a7b25c1802091310ea2f74276a"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"anyhow",
"bincode",
@@ -11960,8 +11950,7 @@ dependencies = [
[[package]]
name = "wasmtime-asm-macros"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0aeb1cb256d76cf07b20264c808351c8b525ece56de1ef4d93f87a0aaf342db"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cfg-if",
]
@@ -11969,8 +11958,7 @@ dependencies = [
[[package]]
name = "wasmtime-cache"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830570847f905b8f6d2ca635c33cf42ce701dd8e4abd7d1806c631f8f06e9e4b"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -11989,8 +11977,7 @@ dependencies = [
[[package]]
name = "wasmtime-cranelift"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f7695d3814dcb508bf4d1c181a86ea6b97a209f6444478e95d86e2ffab8d1a3"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -12010,8 +11997,7 @@ dependencies = [
[[package]]
name = "wasmtime-environ"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a2a5f0fb93aa837a727a48dd1076e8a9f882cc2fee20b433c04a18740ff63b"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"anyhow",
"cranelift-entity",
@@ -12029,8 +12015,7 @@ dependencies = [
[[package]]
name = "wasmtime-jit"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01c78f9fb2922dbb5a95f009539d4badb44866caeeb53d156bf2cf4d683c3afd"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"addr2line 0.17.0",
"anyhow",
@@ -12053,8 +12038,7 @@ dependencies = [
[[package]]
name = "wasmtime-jit-debug"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67cacdb52a77b8c8e744e510beeabf0bd698b1c94c59eed33c52b3fbd19639b0"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"object 0.29.0",
"once_cell",
@@ -12064,8 +12048,7 @@ dependencies = [
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08fcba5ebd96da2a9f0747ab6337fe9788adfb3f63fa2c180520d665562d257e"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cfg-if",
"libc",
@@ -12075,8 +12058,7 @@ dependencies = [
[[package]]
name = "wasmtime-runtime"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0793210acf50d4c69182c916abaee1d423dc5d172cdfde6acfea2f9446725940"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"anyhow",
"cc",
@@ -12099,8 +12081,7 @@ dependencies = [
[[package]]
name = "wasmtime-types"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d015ba8b231248a811e323cf7a525cd3f982d4be0b9e62d27685102e5f12b1"
source = "git+https://github.com/paritytech/wasmtime.git?branch=v5.0.0_lto_fix#8a02705ad378108e43abe23c538688adf73f3b71"
dependencies = [
"cranelift-entity",
"serde",
@@ -25,7 +25,7 @@ wasmtime = { version = "5.0.0", default-features = false, features = [
"jitdump",
"parallel-compilation",
"pooling-allocator"
] }
], git = "https://github.com/paritytech/wasmtime.git", branch = "v5.0.0_lto_fix" }
anyhow = "1.0.68"
sc-allocator = { version = "4.1.0-dev", path = "../../allocator" }
sc-executor-common = { version = "0.10.0-dev", path = "../common" }
@@ -1,18 +1,28 @@
;; Emit a "Hello World!" debug message
;; Emit a debug message with an invalid utf-8 code
(module
(import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32)))
(import "env" "memory" (memory 1 1))
(data (i32.const 0) "\fc")
(func (export "call")
(call $seal_debug_message
(i32.const 0) ;; Pointer to the text buffer
(i32.const 12) ;; The size of the buffer
(func $assert_eq (param i32 i32)
(block $ok
(br_if $ok
(i32.eq (get_local 0) (get_local 1))
)
(unreachable)
)
;; the above call traps because we supplied invalid utf8
unreachable
)
(func (export "call")
(call $assert_eq
(call $seal_debug_message
(i32.const 0) ;; Pointer to the text buffer
(i32.const 12) ;; The size of the buffer
)
(i32.const 0) ;; Success return code
)
)
(func (export "deploy"))
)
@@ -20,7 +20,7 @@
(i32.const 0) ;; Pointer to the text buffer
(i32.const 12) ;; The size of the buffer
)
(i32.const 9) ;; LoggingDisabled return code
(i32.const 0) ;; Success return code
)
)
@@ -910,13 +910,12 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
// The size of the supplied message does not influence the weight because as it is never
// processed during on-chain execution: It is only ever read during debugging which happens
// when the contract is called as RPC where weights do not matter.
// Benchmark debug_message call with zero input data.
// Whereas this function is used in RPC mode only, it still should be secured
// against an excessive use.
#[pov_mode = Ignored]
seal_debug_message {
let r in 0 .. API_BENCHMARK_BATCHES;
let max_bytes = code::max_pages::<T>() * 64 * 1024;
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory { min_pages: 1, max_pages: 1 }),
imported_functions: vec![ImportedFunction {
@@ -927,15 +926,75 @@ benchmarks! {
}],
call_body: Some(body::repeated(r * API_BENCHMARK_BATCH_SIZE, &[
Instruction::I32Const(0), // value_ptr
Instruction::I32Const(max_bytes as i32), // value_len
Instruction::I32Const(0), // value_len
Instruction::Call(0),
Instruction::Drop,
])),
.. Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
}: {
<Contracts<T>>::bare_call(
instance.caller,
instance.account_id,
0u32.into(),
Weight::MAX,
None,
vec![],
true,
Determinism::Deterministic,
)
.result?;
}
seal_debug_message_per_kb {
// Vary size of input in kilobytes up to maximum allowed contract memory
// or maximum allowed debug buffer size, whichever is less.
let i in 0 .. (T::Schedule::get().limits.memory_pages * 64).min(T::MaxDebugBufferLen::get() / 1024);
// We benchmark versus messages containing printable ASCII codes.
// About 1Kb goes to the instrumented contract code instructions,
// whereas all the space left we use for the initialization of the debug messages data.
let message = (0 .. T::MaxCodeLen::get() - 1024).zip((32..127).cycle()).map(|i| i.1).collect::<Vec<_>>();
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory {
min_pages: T::Schedule::get().limits.memory_pages,
max_pages: T::Schedule::get().limits.memory_pages,
}),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "seal_debug_message",
params: vec![ValueType::I32, ValueType::I32],
return_type: Some(ValueType::I32),
}],
data_segments: vec![
DataSegment {
offset: 0,
value: message,
},
],
call_body: Some(body::plain(vec![
Instruction::I32Const(0), // value_ptr
Instruction::I32Const((i * 1024) as i32), // value_len increments by i Kb
Instruction::Call(0),
Instruction::Drop,
Instruction::End,
])),
..Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
}: {
<Contracts<T>>::bare_call(
instance.caller,
instance.account_id,
0u32.into(),
Weight::MAX,
None,
vec![],
true,
Determinism::Deterministic,
)
.result?;
}
// Only the overhead of calling the function itself with minimal arguments.
// The contract is a bit more complex because it needs to use different keys in order
+17 -34
View File
@@ -1336,31 +1336,16 @@ where
fn append_debug_buffer(&mut self, msg: &str) -> bool {
if let Some(buffer) = &mut self.debug_message {
let err_msg = scale_info::prelude::format!(
"Debug message too big (size={}) for debug buffer (bound={})",
msg.len(),
DebugBufferVec::<T>::bound(),
);
let mut msg = if msg.len() > DebugBufferVec::<T>::bound() {
err_msg.bytes()
} else {
msg.bytes()
};
let num_drain = {
let capacity = DebugBufferVec::<T>::bound().checked_sub(buffer.len()).expect(
"
`buffer` is of type `DebugBufferVec`,
`DebugBufferVec` is a `BoundedVec`,
`BoundedVec::len()` <= `BoundedVec::bound()`;
qed
",
);
msg.len().saturating_sub(capacity).min(buffer.len())
};
buffer.drain(0..num_drain);
buffer.try_extend(&mut msg).ok();
buffer
.try_extend(&mut msg.bytes())
.map_err(|_| {
log::debug!(
target: "runtime::contracts",
"Debug buffer (of {} bytes) exhausted!",
DebugBufferVec::<T>::bound(),
)
})
.ok();
true
} else {
false
@@ -2603,9 +2588,11 @@ mod tests {
exec_success()
});
// Pre-fill the buffer up to its limit
let mut debug_buffer =
DebugBufferVec::<Test>::try_from(vec![0u8; DebugBufferVec::<Test>::bound()]).unwrap();
// Pre-fill the buffer almost up to its limit, leaving not enough space to the message
let debug_buf_before =
DebugBufferVec::<Test>::try_from(vec![0u8; DebugBufferVec::<Test>::bound() - 5])
.unwrap();
let mut debug_buf_after = debug_buf_before.clone();
ExtBuilder::default().build().execute_with(|| {
let schedule: Schedule<Test> = <Test as Config>::Schedule::get();
@@ -2622,15 +2609,11 @@ mod tests {
&schedule,
0,
vec![],
Some(&mut debug_buffer),
Some(&mut debug_buf_after),
Determinism::Deterministic,
)
.unwrap();
assert_eq!(
&String::from_utf8(debug_buffer[DebugBufferVec::<Test>::bound() - 17..].to_vec())
.unwrap(),
"overflowing bytes"
);
assert_eq!(debug_buf_before, debug_buf_after);
});
}
-2
View File
@@ -912,8 +912,6 @@ pub mod pallet {
///
/// This can be triggered by a call to `seal_terminate`.
TerminatedInConstructor,
/// The debug message specified to `seal_debug_message` does contain invalid UTF-8.
DebugMessageInvalidUTF8,
/// A call tried to invoke a contract that is flagged as non-reentrant.
ReentranceDenied,
/// Origin doesn't have enough balance to pay the required storage deposits.
@@ -323,6 +323,9 @@ pub struct HostFnWeights<T: Config> {
/// Weight of calling `seal_debug_message`.
pub debug_message: Weight,
/// Weight of calling `seal_debug_message` per byte of the message.
pub debug_message_per_byte: Weight,
/// Weight of calling `seal_set_storage`.
pub set_storage: Weight,
@@ -644,6 +647,7 @@ impl<T: Config> Default for HostFnWeights<T> {
1
)),
debug_message: to_weight!(cost_batched!(seal_debug_message)),
debug_message_per_byte: to_weight!(cost_byte!(seal_debug_message_per_kb)),
set_storage: to_weight!(cost_batched!(seal_set_storage), 1024u64),
set_code_hash: to_weight!(cost_batched!(seal_set_code_hash)),
set_storage_per_new_byte: to_weight!(cost_byte_batched!(seal_set_storage_per_new_kb)),
+2 -1
View File
@@ -2714,7 +2714,8 @@ fn debug_message_invalid_utf8() {
true,
Determinism::Deterministic,
);
assert_err!(result.result, <Error<Test>>::DebugMessageInvalidUTF8);
assert_ok!(result.result);
assert!(result.debug_message.is_empty());
});
}
+2 -7
View File
@@ -2363,13 +2363,8 @@ mod tests {
"#;
let mut ext = MockExt::default();
let result = execute(CODE_DEBUG_MESSAGE_FAIL, vec![], &mut ext);
assert_eq!(
result,
Err(ExecError {
error: Error::<Test>::DebugMessageInvalidUTF8.into(),
origin: ErrorOrigin::Caller,
})
);
assert_ok!(result);
assert!(ext.debug_buffer.is_empty());
}
const CODE_CALL_RUNTIME: &str = r#"
+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.
File diff suppressed because it is too large Load Diff
@@ -18,7 +18,7 @@ codec = { package = "parity-scale-codec", version = "3.2.2", default-features =
impl-trait-for-tuples = "0.2.2"
log = { version = "0.4.17", optional = true }
wasmi = { version = "0.13", optional = true }
wasmtime = { version = "5.0.0", default-features = false, optional = true }
wasmtime = { version = "5.0.0", default-features = false, optional = true, git = "https://github.com/paritytech/wasmtime.git", branch = "v5.0.0_lto_fix" }
anyhow = { version = "1.0.68", optional = true }
sp-std = { version = "5.0.0", default-features = false, path = "../std" }