Skip to content

Commit

Permalink
sc-executor-polkavm: Migrate into PolkaVM 0.18.0 (#6533)
Browse files Browse the repository at this point in the history
Bump `polkavm` to 0.18.0, and update `sc-polkavm-executor` to be
compatible with the API changes. In addition, bump also `polkavm-derive`
and `polkavm-linker` in order to make sure that the all parts of the
Polkadot SDK use the exact same ABI for `.polkavm` binaries.

Purely relying on RV32E/RV64E ABI is not possible, as PolkaVM uses a
RISCV-V alike ISA, which is derived from RV32E/RV64E but it is still its
own microarchitecture, i.e. not fully binary compatible.

---------

Signed-off-by: Jarkko Sakkinen <[email protected]>
Co-authored-by: Koute <[email protected]>
Co-authored-by: Alexander Theißen <[email protected]>
  • Loading branch information
3 people authored Dec 14, 2024
1 parent ec69b61 commit bd2c35f
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 103 deletions.
95 changes: 90 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1089,9 +1089,9 @@ polkadot-subsystem-bench = { path = "polkadot/node/subsystem-bench" }
polkadot-test-client = { path = "polkadot/node/test/client" }
polkadot-test-runtime = { path = "polkadot/runtime/test-runtime" }
polkadot-test-service = { path = "polkadot/node/test/service" }
polkavm = { version = "0.9.3", default-features = false }
polkavm-derive = "0.17.0"
polkavm-linker = "0.17.1"
polkavm = { version = "0.18.0", default-features = false }
polkavm-derive = "0.18.0"
polkavm-linker = "0.18.0"
portpicker = { version = "0.1.1" }
pretty_assertions = { version = "1.3.0" }
primitive-types = { version = "0.13.1", default-features = false, features = [
Expand Down
11 changes: 11 additions & 0 deletions polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
// `construct_runtime!` does a lot of recursion and requires us to increase the limit.
#![recursion_limit = "512"]

#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_feature = "e"))]
// Allocate 2 MiB stack.
//
// TODO: A workaround. Invoke polkavm_derive::min_stack_size!() instead
// later on.
::core::arch::global_asm!(
".pushsection .polkavm_min_stack_size,\"R\",@note\n",
".4byte 2097152",
".popsection\n",
);

extern crate alloc;

use alloc::{
Expand Down
20 changes: 20 additions & 0 deletions prdoc/pr_6533.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
title: "Migrate executor into PolkaVM 0.18.0"
doc:
- audience: Runtime Dev
description: |
Bump `polkavm` to 0.18.0, and update `sc-polkavm-executor` to be
compatible with the API changes. In addition, bump also `polkavm-derive`
and `polkavm-linker` in order to make sure that the all parts of the
Polkadot SDK use the exact same ABI for `.polkavm` binaries.

Purely relying on RV32E/RV64E ABI is not possible, as PolkaVM uses a
RISCV-V alike ISA, which is derived from RV32E/RV64E but it is still its
own microarchitecture, i.e. not fully binary compatible.

crates:
- name: sc-executor-common
bump: major
- name: sc-executor-polkavm
bump: minor
- name: substrate-wasm-builder
bump: minor
4 changes: 2 additions & 2 deletions substrate/client/executor/common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ pub enum WasmError {
Other(String),
}

impl From<polkavm::ProgramParseError> for WasmError {
fn from(error: polkavm::ProgramParseError) -> Self {
impl From<polkavm::program::ProgramParseError> for WasmError {
fn from(error: polkavm::program::ProgramParseError) -> Self {
WasmError::Other(error.to_string())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{error::WasmError, wasm_runtime::HeapAllocStrategy};
use polkavm::ArcBytes;
use wasm_instrument::parity_wasm::elements::{
deserialize_buffer, serialize, ExportEntry, External, Internal, MemorySection, MemoryType,
Module, Section,
Expand All @@ -29,7 +30,7 @@ pub struct RuntimeBlob(BlobKind);
#[derive(Clone)]
enum BlobKind {
WebAssembly(Module),
PolkaVM(polkavm::ProgramBlob<'static>),
PolkaVM((polkavm::ProgramBlob, ArcBytes)),
}

impl RuntimeBlob {
Expand All @@ -52,9 +53,9 @@ impl RuntimeBlob {
pub fn new(raw_blob: &[u8]) -> Result<Self, WasmError> {
if raw_blob.starts_with(b"PVM\0") {
if crate::is_polkavm_enabled() {
return Ok(Self(BlobKind::PolkaVM(
polkavm::ProgramBlob::parse(raw_blob)?.into_owned(),
)));
let raw = ArcBytes::from(raw_blob);
let blob = polkavm::ProgramBlob::parse(raw.clone())?;
return Ok(Self(BlobKind::PolkaVM((blob, raw))));
} else {
return Err(WasmError::Other("expected a WASM runtime blob, found a PolkaVM runtime blob; set the 'SUBSTRATE_ENABLE_POLKAVM' environment variable to enable the experimental PolkaVM-based executor".to_string()));
}
Expand Down Expand Up @@ -192,7 +193,7 @@ impl RuntimeBlob {
match self.0 {
BlobKind::WebAssembly(raw_module) =>
serialize(raw_module).expect("serializing into a vec should succeed; qed"),
BlobKind::PolkaVM(ref blob) => blob.as_bytes().to_vec(),
BlobKind::PolkaVM(ref blob) => blob.1.to_vec(),
}
}

Expand Down Expand Up @@ -227,7 +228,7 @@ impl RuntimeBlob {
pub fn as_polkavm_blob(&self) -> Option<&polkavm::ProgramBlob> {
match self.0 {
BlobKind::WebAssembly(..) => None,
BlobKind::PolkaVM(ref blob) => Some(blob),
BlobKind::PolkaVM((ref blob, _)) => Some(blob),
}
}
}
Loading

0 comments on commit bd2c35f

Please sign in to comment.