mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 16:47:57 +00:00
b0f34e4b29
This PR adds a new PolkaVM-based executor to Substrate. - The executor can now be used to actually run a PolkaVM-based runtime, and successfully produces blocks. - The executor is always compiled-in, but is disabled by default. - The `SUBSTRATE_ENABLE_POLKAVM` environment variable must be set to `1` to enable the executor, in which case the node will accept both WASM and PolkaVM program blobs (otherwise it'll default to WASM-only). This is deliberately undocumented and not explicitly exposed anywhere (e.g. in the command line arguments, or in the API) to disincentivize anyone from enabling it in production. If/when we'll move this into production usage I'll remove the environment variable and do it "properly". - I did not use our legacy runtime allocator for the PolkaVM executor, so currently every allocation inside of the runtime will leak guest memory until that particular instance is destroyed. The idea here is that I will work on the https://github.com/polkadot-fellows/RFCs/pull/4 which will remove the need for the legacy allocator under WASM, and that will also allow us to use a proper non-leaking allocator under PolkaVM. - I also did some minor cleanups of the WASM executor and deleted some dead code. No prdocs included since this is not intended to be an end-user feature, but an unofficial experiment, and shouldn't affect any current production user. Once this is production-ready a full Polkadot Fellowship RFC will be necessary anyway.
99 lines
3.2 KiB
Rust
99 lines
3.2 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
|
|
//! Definitions for a wasm runtime.
|
|
|
|
use crate::error::Error;
|
|
|
|
pub use sc_allocator::AllocationStats;
|
|
|
|
/// Default heap allocation strategy.
|
|
pub const DEFAULT_HEAP_ALLOC_STRATEGY: HeapAllocStrategy =
|
|
HeapAllocStrategy::Static { extra_pages: DEFAULT_HEAP_ALLOC_PAGES };
|
|
|
|
/// Default heap allocation pages.
|
|
pub const DEFAULT_HEAP_ALLOC_PAGES: u32 = 2048;
|
|
|
|
/// A trait that defines an abstract WASM runtime module.
|
|
///
|
|
/// This can be implemented by an execution engine.
|
|
pub trait WasmModule: Sync + Send {
|
|
/// Create a new instance.
|
|
fn new_instance(&self) -> Result<Box<dyn WasmInstance>, Error>;
|
|
}
|
|
|
|
/// A trait that defines an abstract wasm module instance.
|
|
///
|
|
/// This can be implemented by an execution engine.
|
|
pub trait WasmInstance: Send {
|
|
/// Call a method on this WASM instance.
|
|
///
|
|
/// Before execution, instance is reset.
|
|
///
|
|
/// Returns the encoded result on success.
|
|
fn call(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
|
|
self.call_with_allocation_stats(method, data).0
|
|
}
|
|
|
|
/// Call a method on this WASM instance.
|
|
///
|
|
/// Before execution, instance is reset.
|
|
///
|
|
/// Returns the encoded result on success.
|
|
fn call_with_allocation_stats(
|
|
&mut self,
|
|
method: &str,
|
|
data: &[u8],
|
|
) -> (Result<Vec<u8>, Error>, Option<AllocationStats>);
|
|
|
|
/// Call an exported method on this WASM instance.
|
|
///
|
|
/// Before execution, instance is reset.
|
|
///
|
|
/// Returns the encoded result on success.
|
|
fn call_export(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
|
|
self.call(method.into(), data)
|
|
}
|
|
}
|
|
|
|
/// Defines the heap pages allocation strategy the wasm runtime should use.
|
|
///
|
|
/// A heap page is defined as 64KiB of memory.
|
|
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
|
|
pub enum HeapAllocStrategy {
|
|
/// Allocate a static number of heap pages.
|
|
///
|
|
/// The total number of allocated heap pages is the initial number of heap pages requested by
|
|
/// the wasm file plus the `extra_pages`.
|
|
Static {
|
|
/// The number of pages that will be added on top of the initial heap pages requested by
|
|
/// the wasm file.
|
|
extra_pages: u32,
|
|
},
|
|
/// Allocate the initial heap pages as requested by the wasm file and then allow it to grow
|
|
/// dynamically.
|
|
Dynamic {
|
|
/// The absolute maximum size of the linear memory (in pages).
|
|
///
|
|
/// When `Some(_)` the linear memory will be allowed to grow up to this limit.
|
|
/// When `None` the linear memory will be allowed to grow up to the maximum limit supported
|
|
/// by WASM (4GB).
|
|
maximum_pages: Option<u32>,
|
|
},
|
|
}
|