diff --git a/polkadot/parachain/src/wasm.rs b/polkadot/parachain/src/wasm.rs index 494f176a3de56b2e51bb08390b6e57859bd4252c..73ccfdfdaff365e054d06eca92bf1bac1f083478 100644 --- a/polkadot/parachain/src/wasm.rs +++ b/polkadot/parachain/src/wasm.rs @@ -25,6 +25,7 @@ use codec::{Decode, Encode}; use wasmi::{self, Module, ModuleInstance, MemoryInstance, MemoryDescriptor, MemoryRef, ModuleImportResolver}; use wasmi::{memory_units, RuntimeValue}; use wasmi::Error as WasmError; +use wasmi::memory_units::{Bytes, Pages, RoundUpTo}; use super::{ValidationParams, ValidationResult}; @@ -101,7 +102,7 @@ pub fn validate_candidate(validation_code: &[u8], params: ValidationParams) -> R &wasmi::ImportsBuilder::new().with_resolver("env", &module_resolver), )?.run_start(&mut wasmi::NopExternals).map_err(WasmError::Trap)?; - let memory = module_resolver.memory.borrow_mut() + let memory = module_resolver.memory.borrow() .as_ref() .ok_or_else(|| WasmError::Instantiation("No imported memory instance".to_owned()))? .clone(); @@ -118,24 +119,22 @@ pub fn validate_candidate(validation_code: &[u8], params: ValidationParams) -> R bail!(ErrorKind::ParamsTooLarge(encoded_call_data.len())); } - let call_data_pages = (encoded_call_data.len() / LINEAR_MEMORY_PAGE_SIZE.0) + - (encoded_call_data.len() % LINEAR_MEMORY_PAGE_SIZE.0); + // allocate sufficient amount of wasm pages to fit encoded call data. + let call_data_pages: Pages = Bytes(encoded_call_data.len()).round_up_to(); + let allocated_mem_start: Bytes = memory.grow(call_data_pages)?.into(); - let call_data_pages = wasmi::memory_units::Pages(call_data_pages); + memory.set(allocated_mem_start.0 as u32, &encoded_call_data) + .expect( + "enough memory allocated just before this; \ + copying never fails if memory is large enough; qed" + ); - if memory.current_size() < call_data_pages { - memory.grow(call_data_pages - memory.current_size())?; - } - - memory.set(0, &encoded_call_data).expect("enough memory allocated just before this; \ - copying never fails if memory is large enough; qed"); - - (0, encoded_call_data.len() as i32) + (allocated_mem_start.0, encoded_call_data.len()) }; let output = module.invoke_export( "validate", - &[RuntimeValue::I32(offset), RuntimeValue::I32(len)], + &[RuntimeValue::I32(offset as i32), RuntimeValue::I32(len as i32)], &mut wasmi::NopExternals, )?; diff --git a/polkadot/parachain/tests/adder.rs b/polkadot/parachain/tests/adder.rs index d93b2d46a3243c9deb65de78e2277a31f107cce0..485eb41bcf8716aa3858503127b0db81c243a27f 100644 --- a/polkadot/parachain/tests/adder.rs +++ b/polkadot/parachain/tests/adder.rs @@ -148,7 +148,7 @@ fn execute_good_chain_on_parent() { #[test] fn execute_bad_on_parent() { - let parent_head = HeadData { + let parent_head = HeadData { number: 0, parent_hash: [0; 32], post_state: hash_state(0),