Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

contracts: Upgrade to wasmi 0.28 #13312

Merged
merged 6 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
21 changes: 11 additions & 10 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions frame/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ serde = { version = "1", optional = true, features = ["derive"] }
smallvec = { version = "1", default-features = false, features = [
"const_generics",
] }
wasmi = { version = "0.20", default-features = false }
wasmparser = { package = "wasmparser-nostd", version = "0.91", default-features = false }
wasmi = { version = "0.28", default-features = false }
wasmparser = { package = "wasmparser-nostd", version = "0.100", default-features = false }
impl-trait-for-tuples = "0.2"

# Only used in benchmarking to generate random contract code
Expand Down
4 changes: 2 additions & 2 deletions frame/contracts/proc-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
let inner = if expand_blocks {
quote! { || #output {
let (memory, ctx) = __caller__
.host_data()
.data()
.memory()
.expect("Memory must be set when setting up host data; qed")
.data_and_store_mut(&mut __caller__);
Expand All @@ -630,7 +630,7 @@ fn expand_functions(def: &EnvDef, expand_blocks: bool, host_state: TokenStream2)
let map_err = if expand_blocks {
quote! {
|reason| {
::wasmi::core::Trap::host(reason)
::wasmi::core::Trap::from(reason)
}
}
} else {
Expand Down
6 changes: 3 additions & 3 deletions frame/contracts/src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl<T: Config> PrefabWasmModule<T> {
let engine = Engine::new(&config);
let module = Module::new(&engine, code)?;
let mut store = Store::new(&engine, host_state);
let mut linker = Linker::new();
let mut linker = Linker::new(&engine);
E::define(
&mut store,
&mut linker,
Expand Down Expand Up @@ -329,7 +329,7 @@ impl<T: Config> Executable<T> for PrefabWasmModule<T> {
log::debug!(target: "runtime::contracts", "failed to instantiate code: {}", msg);
Error::<T>::CodeRejected
})?;
store.state_mut().set_memory(memory);
store.data_mut().set_memory(memory);

let exported_func = instance
.get_export(&store, function.identifier())
Expand All @@ -346,7 +346,7 @@ impl<T: Config> Executable<T> for PrefabWasmModule<T> {

let result = exported_func.call(&mut store, &[], &mut []);

store.into_state().to_execution_result(result)
store.into_data().to_execution_result(result)
}

fn code_hash(&self) -> &CodeHash<T> {
Expand Down
63 changes: 7 additions & 56 deletions frame/contracts/src/wasm/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,52 +155,6 @@ impl<'a, T: Config> ContractModule<'a, T> {
Ok(())
}

/// Ensures that no floating point types are in use.
fn ensure_no_floating_types(&self) -> Result<(), &'static str> {
if let Some(global_section) = self.module.global_section() {
for global in global_section.entries() {
match global.global_type().content_type() {
ValueType::F32 | ValueType::F64 =>
return Err("use of floating point type in globals is forbidden"),
_ => {},
}
}
}

if let Some(code_section) = self.module.code_section() {
for func_body in code_section.bodies() {
for local in func_body.locals() {
match local.value_type() {
ValueType::F32 | ValueType::F64 =>
return Err("use of floating point type in locals is forbidden"),
_ => {},
}
}
}
}

if let Some(type_section) = self.module.type_section() {
for wasm_type in type_section.types() {
match wasm_type {
Type::Function(func_type) => {
let return_type = func_type.results().get(0);
for value_type in func_type.params().iter().chain(return_type) {
match value_type {
ValueType::F32 | ValueType::F64 =>
return Err(
"use of floating point type in function types is forbidden",
),
_ => {},
}
}
},
}
}
}

Ok(())
}

/// Ensure that no function exists that has more parameters than allowed.
fn ensure_parameter_limit(&self, limit: u32) -> Result<(), &'static str> {
let type_section = if let Some(type_section) = self.module.type_section() {
Expand Down Expand Up @@ -414,14 +368,15 @@ where
// This is not our only defense: We check for float types later in the preparation
// process. Additionally, all instructions explicitly need to have weights assigned
// or the deployment will fail. We have none assigned for float instructions.
deterministic_only: matches!(determinism, Determinism::Deterministic),
floats: matches!(determinism, Determinism::AllowIndeterminism),
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
mutable_global: false,
saturating_float_to_int: false,
sign_extension: false,
bulk_memory: false,
multi_value: false,
reference_types: false,
simd: false,
memory_control: false,
})
.validate_all(original_code)
.map_err(|err| {
Expand All @@ -439,10 +394,6 @@ where
contract_module.ensure_parameter_limit(schedule.limits.parameters)?;
contract_module.ensure_br_table_size_limit(schedule.limits.br_table_size)?;

if matches!(determinism, Determinism::Deterministic) {
contract_module.ensure_no_floating_types()?;
}
Comment on lines -442 to -444
Copy link
Member Author

@athei athei Mar 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer need this because the newest wasmparser rejects floating types for us if floats: false. Before it only rejected float instructions.

Copy link
Contributor

@pgherveou pgherveou Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wasmparser rejects floating types for us if floats: false

just curious, where do you define this setting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a bit above. Argument to Validator::new_with_features.


// We disallow importing `gas` function here since it is treated as implementation detail.
let disallowed_imports = [b"gas".as_ref()];
let memory_limits =
Expand Down Expand Up @@ -704,7 +655,7 @@ mod tests {
)
(func (export "deploy"))
)"#,
Err("gas instrumentation failed")
Err("validation of new code failed")
);

mod functions {
Expand Down Expand Up @@ -1214,7 +1165,7 @@ mod tests {
(func (export "deploy"))
)
"#,
Err("use of floating point type in globals is forbidden")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we want to keep the more specific error message?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't. The function returns a &'static str. We opted for logging the error message to the console instead of returning it. Not optimal. The error handling there is a mess. But the whole thing will become much simpler once we have #13639. Then we can have a hard look on the error handling there.

Err("validation of new code failed")
);

prepare_test!(
Expand All @@ -1226,7 +1177,7 @@ mod tests {
(func (export "deploy"))
)
"#,
Err("use of floating point type in locals is forbidden")
Err("validation of new code failed")
);

prepare_test!(
Expand All @@ -1238,7 +1189,7 @@ mod tests {
(func (export "deploy"))
)
"#,
Err("use of floating point type in function types is forbidden")
Err("validation of new code failed")
);

prepare_test!(
Expand All @@ -1250,7 +1201,7 @@ mod tests {
(func (export "deploy"))
)
"#,
Err("use of floating point type in function types is forbidden")
Err("validation of new code failed")
);
}
}
6 changes: 1 addition & 5 deletions frame/contracts/src/wasm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,7 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
Err(wasmi::Error::Trap(trap)) => {
// If we encoded a reason then it is some abort generated by a host function.
// Otherwise the trap came from the contract.
let reason: TrapReason = *trap
.into_host()
.ok_or(Error::<E::T>::ContractTrapped)?
.downcast()
.expect("`TrapReason` is the only type we use to encode host errors; qed");
let reason: TrapReason = trap.downcast().ok_or(Error::<E::T>::ContractTrapped)?;
match reason {
Return(ReturnData { flags, data }) => {
let flags =
Expand Down
Loading