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

feat: bump up cosmwasm from v1.1.9 to v1.5.1 #342

Merged
merged 7 commits into from
Feb 5, 2024
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
16 changes: 16 additions & 0 deletions packages/vm/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ pub struct CacheOptions {
pub instance_memory_limit: Size,
}

impl CacheOptions {
pub fn new(
base_dir: impl Into<PathBuf>,
available_capabilities: impl Into<HashSet<String>>,
memory_cache_size: Size,
instance_memory_limit: Size,
) -> Self {
Self {
base_dir: base_dir.into(),
available_capabilities: available_capabilities.into(),
memory_cache_size,
instance_memory_limit,
}
}
}

pub struct CacheInner {
/// The directory in which the Wasm blobs are stored in the file system.
wasm_path: PathBuf,
Expand Down
26 changes: 26 additions & 0 deletions packages/vm/src/compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ const TABLE_SIZE_LIMIT: u32 = 2500; // entries
/// when a user accidentally includes wasm-bindgen, they get a bunch of unsupported imports.
const MAX_IMPORTS: usize = 100;

const MAX_FUNCTIONS: usize = 10000;

const MAX_FUNCTION_PARAMS: usize = 50;

const MAX_FUNCTION_RESULTS: usize = 1;

/// Checks if the data is valid wasm and compatibility with the CosmWasm API (imports and exports)
pub fn check_wasm(wasm_code: &[u8], available_capabilities: &HashSet<String>) -> VmResult<()> {
let module = ParsedWasm::parse(wasm_code)?;
Expand All @@ -88,6 +94,7 @@ pub fn check_wasm(wasm_code: &[u8], available_capabilities: &HashSet<String>) ->
check_wasm_exports(&module)?;
check_wasm_imports(&module, SUPPORTED_IMPORTS)?;
check_wasm_capabilities(&module, available_capabilities)?;
check_wasm_functions(&module)?;

Ok(())
}
Expand Down Expand Up @@ -235,6 +242,25 @@ fn check_wasm_capabilities(
Ok(())
}

fn check_wasm_functions(module: &ParsedWasm) -> VmResult<()> {
if module.function_count > MAX_FUNCTIONS {
return Err(VmError::static_validation_err(format!(
"Wasm contract contains more than {MAX_FUNCTIONS} functions"
)));
}
if module.max_func_params > MAX_FUNCTION_PARAMS {
return Err(VmError::static_validation_err(format!(
"Wasm contract contains function with more than {MAX_FUNCTION_PARAMS} parameters"
)));
}
if module.max_func_results > MAX_FUNCTION_RESULTS {
return Err(VmError::static_validation_err(format!(
"Wasm contract contains function with more than {MAX_FUNCTION_RESULTS} results"
)));
}
Ok(())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 7 additions & 3 deletions packages/vm/src/modules/file_system_cache.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::fs;
use std::hash::Hash;
use std::io;
use std::panic::catch_unwind;
use std::path::{Path, PathBuf};
use thiserror::Error;

Expand Down Expand Up @@ -166,9 +167,12 @@ impl FileSystemCache {
.map_err(|_e| VmError::cache_err("Error creating modules directory"))?;

let path = self.module_file(checksum);
module
.serialize_to_file(&path)
.map_err(|e| VmError::cache_err(format!("Error writing module to disk: {e}")))?;
catch_unwind(|| {
module
.serialize_to_file(&path)
.map_err(|e| VmError::cache_err(format!("Error writing module to disk: {e}")))
})
.map_err(|_| VmError::cache_err("Could not write module to disk"))??;
let module_size = module_size(&path)?;
Ok(module_size)
}
Expand Down
37 changes: 31 additions & 6 deletions packages/vm/src/parsed_wasm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use wasmer::wasmparser::{
Export, Import, MemoryType, Parser, TableType, ValidPayload, Validator, WasmFeatures,
Export, Import, MemoryType, Parser, Payload, TableType, Type, ValidPayload, Validator,
WasmFeatures,
};

use crate::VmResult;
Expand All @@ -13,6 +14,10 @@ pub struct ParsedWasm<'a> {
pub imports: Vec<Import<'a>>,
pub tables: Vec<TableType>,
pub memories: Vec<MemoryType>,
pub function_count: usize,
pub type_count: u32,
pub max_func_params: usize,
pub max_func_results: usize,
}

impl<'a> ParsedWasm<'a> {
Expand All @@ -34,6 +39,10 @@ impl<'a> ParsedWasm<'a> {
imports: vec![],
tables: vec![],
memories: vec![],
function_count: 0,
type_count: 0,
max_func_params: 0,
max_func_results: 0,
};

let mut fun_allocations = Default::default();
Expand All @@ -45,20 +54,36 @@ impl<'a> ParsedWasm<'a> {
let mut fun_validator = fv.into_validator(fun_allocations);
fun_validator.validate(&body)?;
fun_allocations = fun_validator.into_allocations();

this.function_count += 1;
}

match p {
wasmer::wasmparser::Payload::Version { num, .. } => this.version = num,
wasmer::wasmparser::Payload::ImportSection(i) => {
Payload::TypeSection(t) => {
this.type_count = t.get_count();
for t_res in t {
let ty: Type = t_res?;
match ty {
Type::Func(ft) => {
this.max_func_params =
core::cmp::max(ft.params().len(), this.max_func_params);
this.max_func_results =
core::cmp::max(ft.results().len(), this.max_func_results);
}
}
}
}
Payload::Version { num, .. } => this.version = num,
Payload::ImportSection(i) => {
this.imports = i.into_iter().collect::<Result<Vec<_>, _>>()?;
}
wasmer::wasmparser::Payload::TableSection(t) => {
Payload::TableSection(t) => {
this.tables = t.into_iter().collect::<Result<Vec<_>, _>>()?;
}
wasmer::wasmparser::Payload::MemorySection(m) => {
Payload::MemorySection(m) => {
this.memories = m.into_iter().collect::<Result<Vec<_>, _>>()?;
}
wasmer::wasmparser::Payload::ExportSection(e) => {
Payload::ExportSection(e) => {
this.exports = e.into_iter().collect::<Result<Vec<_>, _>>()?;
}
_ => {} // ignore everything else
Expand Down
Loading