diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 02b85a0d96913..e7aa118dfd6ac 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -42,4 +42,5 @@ full_crypto = [ # Don't add `panic_handler` and `alloc_error_handler` since they are expected to be provided # by the user anyway. "sp-io/disable_panic_handler", + "sp-io/disable_oom", ] diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 2cb3a6e5a3464..e56bfcf56041a 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -64,11 +64,12 @@ with-tracing = [ "sp-tracing/with-tracing" ] -# These two features are used for `no_std` builds for the environments which -# already provides `#[panic_handler]` and `#[global_allocator]`. +# These two features are used for `no_std` builds for the environments which already provides +# `#[panic_handler]`, `#[alloc_error_handler]` and `#[global_allocator]`. # # For the regular wasm runtime builds those are not used. disable_panic_handler = [] +disable_oom = [] disable_allocator = [] # This feature flag controls the runtime's behavior when encountering @@ -82,7 +83,8 @@ disable_allocator = [] # logs, with the caller receving a generic "wasm `unreachable` instruction executed" # error message. # -# This has no effect if `disable_panic_handler` is enabled. +# This has no effect if both `disable_panic_handler` and `disable_oom` +# are enabled. # # WARNING: Enabling this feature flag requires the `PanicHandler::abort_on_panic` # host function to be supported by the host. Do *not* enable it for your diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 8d8ea9ca171f5..8c3cdc668cba3 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -19,10 +19,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr( - all(not(feature = "disable_panic_handler"), not(feature = "std")), - feature(panic_oom_payload) -)] +#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))] #![cfg_attr( feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library." @@ -1643,34 +1640,33 @@ mod allocator_impl { #[panic_handler] #[no_mangle] pub fn panic(info: &core::panic::PanicInfo) -> ! { - use sp_std::alloc::{alloc::AllocErrorPanicPayload, format, string::String}; - - let improved_panic_error_reporting = match () { - #[cfg(feature = "improved_panic_error_reporting")] - () => true, - #[cfg(not(feature = "improved_panic_error_reporting"))] - () => false, - }; - - let message = info - .payload() - .downcast_ref::() - .map(|_| { - let msg = improved_panic_error_reporting - .then_some("Runtime memory exhausted.") - .unwrap_or("Runtime memory exhausted. Aborting"); - String::from(msg) - }) - .unwrap_or_else(|| format!("{info}")); - - if improved_panic_error_reporting { + let message = sp_std::alloc::format!("{}", info); + #[cfg(feature = "improved_panic_error_reporting")] + { panic_handler::abort_on_panic(&message); - } else { + } + #[cfg(not(feature = "improved_panic_error_reporting"))] + { logging::log(LogLevel::Error, "runtime", message.as_bytes()); core::arch::wasm32::unreachable(); } } +/// A default OOM handler for WASM environment. +#[cfg(all(not(feature = "disable_oom"), not(feature = "std")))] +#[alloc_error_handler] +pub fn oom(_: core::alloc::Layout) -> ! { + #[cfg(feature = "improved_panic_error_reporting")] + { + panic_handler::abort_on_panic("Runtime memory exhausted."); + } + #[cfg(not(feature = "improved_panic_error_reporting"))] + { + logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); + core::arch::wasm32::unreachable(); + } +} + /// Type alias for Externalities implementation used in tests. #[cfg(feature = "std")] pub type TestExternalities = sp_state_machine::TestExternalities; diff --git a/primitives/state-machine/src/overlayed_changes/mod.rs b/primitives/state-machine/src/overlayed_changes/mod.rs index b32df635b177c..3acf927da69cc 100644 --- a/primitives/state-machine/src/overlayed_changes/mod.rs +++ b/primitives/state-machine/src/overlayed_changes/mod.rs @@ -177,6 +177,7 @@ impl StorageChanges { /// Storage transactions are calculated as part of the `storage_root`. /// These transactions can be reused for importing the block into the /// storage. So, we cache them to not require a recomputation of those transactions. +#[derive(Clone)] pub struct StorageTransactionCache { /// Contains the changes for the main and the child storages as one transaction. pub(crate) transaction: Option, diff --git a/primitives/wasm-interface-common/src/lib.rs b/primitives/wasm-interface-common/src/lib.rs index 6d021a1e3553a..18d5a97592039 100644 --- a/primitives/wasm-interface-common/src/lib.rs +++ b/primitives/wasm-interface-common/src/lib.rs @@ -22,6 +22,8 @@ use sp_std::borrow::Cow; use core::{mem, marker::PhantomData}; +pub mod util; + #[cfg(feature = "wasmi")] pub use wasmi; diff --git a/primitives/wasm-interface-common/src/util.rs b/primitives/wasm-interface-common/src/util.rs new file mode 100644 index 0000000000000..2b4ebd6e66517 --- /dev/null +++ b/primitives/wasm-interface-common/src/util.rs @@ -0,0 +1,26 @@ +// This file is part of Gear. +// +// Copyright (C) 2021-2023 Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use core::ops::Range; + +/// Construct a range from an offset to a data length after the offset. +/// Returns None if the end of the range would exceed some maximum offset. +pub fn checked_range(offset: usize, len: usize, max: usize) -> Option> { + let end = offset.checked_add(len)?; + (end <= max).then(|| offset..end) +} diff --git a/primitives/wasm-interface/src/util.rs b/primitives/wasm-interface/src/util.rs index 52a59cc2ae8c1..72969b0c716c4 100644 --- a/primitives/wasm-interface/src/util.rs +++ b/primitives/wasm-interface/src/util.rs @@ -17,14 +17,7 @@ use super::*; use wasmtime::{AsContext, AsContextMut}; -use sp_std::ops::Range; - -/// Construct a range from an offset to a data length after the offset. -/// Returns None if the end of the range would exceed some maximum offset. -pub fn checked_range(offset: usize, len: usize, max: usize) -> Option> { - let end = offset.checked_add(len)?; - (end <= max).then(|| offset..end) -} +pub use sp_wasm_interface_common::util::checked_range; pub fn write_memory_from( mut ctx: impl AsContextMut,