Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix allow_missing_func_imports #2

Merged
merged 3 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading