Skip to content

Commit

Permalink
Merge pull request #2 from moonbeam-foundation/crystalin-runtime-wasm
Browse files Browse the repository at this point in the history
Fix allow_missing_func_imports
  • Loading branch information
crystalin committed Sep 28, 2023
2 parents 1ed54ff + a9953bd commit b07b47e
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 33 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

14 changes: 8 additions & 6 deletions substrate/client/chain-spec/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@

//! Tool for creating the genesis block.

use std::{collections::hash_map::DefaultHasher, marker::PhantomData, sync::Arc};
use std::{marker::PhantomData, sync::Arc};

use sc_client_api::{backend::Backend, BlockImportOperation};
use sc_executor::RuntimeVersionOf;
use sp_core::storage::{well_known_keys, StateVersion, Storage};
use sp_core::{
storage::{well_known_keys, StateVersion, Storage},
Blake2Hasher,
};

use sp_runtime::{
traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero},
BuildStorage,
Expand All @@ -44,10 +48,8 @@ where
code_fetcher: &code_fetcher,
heap_pages: None,
hash: {
use std::hash::{Hash, Hasher};
let mut state = DefaultHasher::new();
wasm.hash(&mut state);
state.finish().to_le_bytes().to_vec()
use sp_core::Hasher;
Blake2Hasher::hash(&wasm.to_vec()).as_ref().to_vec()
},
};
let runtime_version = RuntimeVersionOf::runtime_version(executor, &mut ext, &runtime_code)
Expand Down
15 changes: 7 additions & 8 deletions substrate/client/cli/src/commands/precompile_wasm_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ use crate::{

use clap::Parser;
use sc_client_api::{Backend, HeaderBackend};
use sp_core::traits::RuntimeCode;
use sc_executor::{
precompile_and_serialize_versioned_wasm_runtime, HeapAllocStrategy, DEFAULT_HEAP_ALLOC_PAGES,
};
use sp_runtime::traits::Block as BlockT;
use sc_service::ChainSpec;
use sp_core::traits::RuntimeCode;
use sp_runtime::traits::Block as BlockT;
use sp_state_machine::backend::BackendRuntimeCode;
use std::{fmt::Debug, path::PathBuf, sync::Arc};

Expand Down Expand Up @@ -81,7 +81,7 @@ pub struct PrecompileWasmCmd {

impl PrecompileWasmCmd {
/// Run the precompile-wasm command
pub async fn run<B, BA>(&self, backend: Arc<BA>, spec: Box<dyn ChainSpec>,) -> error::Result<()>
pub async fn run<B, BA>(&self, backend: Arc<BA>, spec: Box<dyn ChainSpec>) -> error::Result<()>
where
B: BlockT,
BA: Backend<B>,
Expand All @@ -92,9 +92,8 @@ impl PrecompileWasmCmd {

if backend.have_state_at(blockchain_info.finalized_hash, blockchain_info.finalized_number) {
let state = backend.state_at(backend.blockchain().info().finalized_hash)?;

precompile_and_serialize_versioned_wasm_runtime(
true,
HeapAllocStrategy::Static { extra_pages: heap_pages },
&BackendRuntimeCode::new(&state).runtime_code()?,
execution_method_from_cli(
Expand All @@ -108,12 +107,13 @@ impl PrecompileWasmCmd {
let storage = spec.as_storage_builder().build_storage()?;
if let Some(wasm_bytecode) = storage.top.get(sp_storage::well_known_keys::CODE) {
let runtime_code = RuntimeCode {
code_fetcher: &sp_core::traits::WrappedRuntimeCode(wasm_bytecode.as_slice().into()),
code_fetcher: &sp_core::traits::WrappedRuntimeCode(
wasm_bytecode.as_slice().into(),
),
hash: sp_core::blake2_256(&wasm_bytecode).to_vec(),
heap_pages: Some(heap_pages as u64),
};
precompile_and_serialize_versioned_wasm_runtime(
true,
HeapAllocStrategy::Static { extra_pages: heap_pages },
&runtime_code,
execution_method_from_cli(
Expand All @@ -126,7 +126,6 @@ impl PrecompileWasmCmd {
}
}


Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions substrate/client/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"]
parking_lot = "0.12.1"
schnellru = "0.2.1"
tracing = "0.1.29"
log = "0.4.17"

codec = { package = "parity-scale-codec", version = "3.6.1" }
sc-executor-common = { path = "common" }
Expand Down
51 changes: 34 additions & 17 deletions substrate/client/executor/src/wasm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,42 +321,50 @@ where
return Err(WasmError::Instantiation(format!(
"--wasmtime-precompiled is not a directory: {}",
wasmtime_precompiled_dir.display()
)))
)));
}
let handle_err = |e: std::io::Error| -> WasmError {
return WasmError::Instantiation(format!(
"Io error when loading wasmtime precompiled folder ({}): {}",
wasmtime_precompiled_dir.display(),
e
))
));
};
let mut maybe_compiled_artifact = None;

let artifact_version =
compute_artifact_version(allow_missing_func_imports, code_hash, &semantics);
log::debug!(
target: "wasmtime-runtime",
"Searching for wasm hash: {}",
artifact_version.clone()
);

for entry in std::fs::read_dir(wasmtime_precompiled_dir).map_err(handle_err)? {
let entry = entry.map_err(handle_err)?;
if let Some(file_name) = entry.file_name().to_str() {
let artifact_version = compute_artifact_version(
allow_missing_func_imports,
code_hash,
&semantics,
);

// We check that the artifact was generated for this specific artifact
// version and with the same wasm interface version and configuration.
if file_name.contains(&artifact_version) {
if file_name.contains(&artifact_version.clone()) {
log::info!(
target: "wasmtime-runtime",
"Found precompiled wasm: {}",
file_name
);
// We change the version check strategy to make sure that the file
// content was serialized with the exact same config as well
maybe_compiled_artifact = Some((
entry.path(),
sc_executor_wasmtime::ModuleVersionStrategy::Custom(
artifact_version,
artifact_version.clone(),
),
));
}
} else {
return Err(WasmError::Instantiation(
"wasmtime precompiled folder contain a file with invalid utf8 name"
.to_owned(),
))
));
}
}

Expand Down Expand Up @@ -410,14 +418,13 @@ where

/// Create and serialize a precompiled artifact of a wasm runtime with the given `code`.
pub fn precompile_and_serialize_versioned_wasm_runtime<'c>(
allow_missing_func_imports: bool,
heap_alloc_strategy: HeapAllocStrategy,
runtime_code: &'c RuntimeCode<'c>,
wasm_method: WasmExecutionMethod,
wasmtime_precompiled_path: &Path,
) -> Result<(), WasmError> {
let semantics = match wasm_method {
WasmExecutionMethod::Compiled { instantiation_strategy } =>
WasmExecutionMethod::Compiled { instantiation_strategy } => {
sc_executor_wasmtime::Semantics {
heap_alloc_strategy,
instantiation_strategy,
Expand All @@ -428,13 +435,18 @@ pub fn precompile_and_serialize_versioned_wasm_runtime<'c>(
wasm_bulk_memory: false,
wasm_reference_types: false,
wasm_simd: false,
},
}
},
};

let code_hash = &runtime_code.hash;

let artifact_version =
compute_artifact_version(allow_missing_func_imports, code_hash, &semantics);
let artifact_version = compute_artifact_version(false, code_hash, &semantics);
log::debug!(
target: "wasmtime-runtime",
"Generated precompiled wasm hash: {}",
artifact_version.clone()
);

let code = runtime_code.fetch_runtime_code().ok_or(WasmError::CodeNotFound)?;

Expand All @@ -450,7 +462,7 @@ pub fn precompile_and_serialize_versioned_wasm_runtime<'c>(

// Write in a file
let mut file = std::fs::File::create(
wasmtime_precompiled_path.join(format!("precompiled_wasm_0x{}", &artifact_version)),
wasmtime_precompiled_path.join(format!("precompiled_wasm_{}", &artifact_version)),
)
.map_err(|e| {
WasmError::Other(format!(
Expand All @@ -472,6 +484,11 @@ fn compute_artifact_version(
code_hash: &[u8],
semantics: &sc_executor_wasmtime::Semantics,
) -> String {
log::trace!(
target: "wasmtime-runtime",
"Computing wasm runtime hash [allow_missing_func_imports: {}, code_hash: {}, semantics: {:?}]",
allow_missing_func_imports, sp_core::bytes::to_hex(&code_hash, false), semantics
);
let mut buffer = Vec::new();
buffer.extend_from_slice(code_hash);
buffer.extend_from_slice(sp_wasm_interface::VERSION.as_bytes());
Expand Down
4 changes: 2 additions & 2 deletions substrate/client/executor/wasmtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ fn common_config(semantics: &Semantics) -> std::result::Result<wasmtime::Config,
/// See [here][stack_height] for more details of the instrumentation
///
/// [stack_height]: https://github.com/paritytech/wasm-utils/blob/d9432baf/src/stack_height/mod.rs#L1-L50
#[derive(Clone, codec::Encode)]
#[derive(Debug, Clone, codec::Encode)]
pub struct DeterministicStackLimit {
/// A number of logical "values" that can be pushed on the wasm stack. A trap will be triggered
/// if exceeded.
Expand Down Expand Up @@ -470,7 +470,7 @@ enum InternalInstantiationStrategy {
Builtin,
}

#[derive(Clone, codec::Encode)]
#[derive(Debug, Clone, codec::Encode)]
pub struct Semantics {
/// The instantiation strategy to use.
pub instantiation_strategy: InstantiationStrategy,
Expand Down

0 comments on commit b07b47e

Please sign in to comment.