From 3e0c8b662186816d9b0ebf81c4efa3410ff44588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 1 Jun 2021 08:36:30 +0200 Subject: [PATCH 1/7] Remove pre-charging for code size --- frame/contracts/fixtures/dummy.wat | 5 + frame/contracts/fixtures/ok_trap_revert.wat | 2 +- frame/contracts/src/benchmarking/code.rs | 7 +- frame/contracts/src/benchmarking/mod.rs | 88 +- frame/contracts/src/exec.rs | 177 +-- frame/contracts/src/lib.rs | 23 +- frame/contracts/src/rent.rs | 22 +- frame/contracts/src/schedule.rs | 34 +- frame/contracts/src/tests.rs | 66 +- frame/contracts/src/wasm/code_cache.rs | 80 +- frame/contracts/src/wasm/mod.rs | 27 +- frame/contracts/src/wasm/runtime.rs | 87 +- frame/contracts/src/weights.rs | 1337 +++++++++---------- 13 files changed, 953 insertions(+), 1002 deletions(-) create mode 100644 frame/contracts/fixtures/dummy.wat diff --git a/frame/contracts/fixtures/dummy.wat b/frame/contracts/fixtures/dummy.wat new file mode 100644 index 0000000000000..0aeefbcb7ebfe --- /dev/null +++ b/frame/contracts/fixtures/dummy.wat @@ -0,0 +1,5 @@ +;; A valid contract which does nothing at all +(module + (func (export "deploy")) + (func (export "call")) +) diff --git a/frame/contracts/fixtures/ok_trap_revert.wat b/frame/contracts/fixtures/ok_trap_revert.wat index b71a6435db9c1..b7eaa9b700af5 100644 --- a/frame/contracts/fixtures/ok_trap_revert.wat +++ b/frame/contracts/fixtures/ok_trap_revert.wat @@ -32,4 +32,4 @@ ;; 2 = trap (unreachable) ) -) \ No newline at end of file +) diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index b9bd693f1c2c7..6faba8a2e064c 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -258,9 +258,14 @@ where /// Same as `dummy` but with maximum sized linear memory and a dummy section of specified size. pub fn dummy_with_bytes(dummy_bytes: u32) -> Self { + // We want the module to have the size `dummy_bytes`. + // This is not completely correct as the overhead grows when the contract grows + // because of variable length integer encoding. However, it is good enough to be that + // close for benchmarking purposes. + let module_overhead = 65; ModuleDefinition { memory: Some(ImportedMemory::max::()), - dummy_section: dummy_bytes, + dummy_section: dummy_bytes.saturating_sub(module_overhead), .. Default::default() } .into() diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index bb04e9b2cf32f..8948e7474e611 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -320,6 +320,25 @@ benchmarks! { Contracts::::reinstrument_module(&mut module, &schedule)?; } + // The weight of loading and decoding of a contract's code per kilobyte. + code_load { + let c in 0 .. T::Schedule::get().limits.code_len / 1024; + let WasmModule { code, hash, .. } = WasmModule::::dummy_with_bytes(c * 1024); + Contracts::::store_code_raw(code)?; + }: { + >::from_storage_noinstr(hash)?; + } + + // The weight of changing the refcount of a contract's code per kilobyte. + code_refcount { + let c in 0 .. T::Schedule::get().limits.code_len / 1024; + let WasmModule { code, hash, .. } = WasmModule::::dummy_with_bytes(c * 1024); + Contracts::::store_code_raw(code)?; + let mut gas_meter = GasMeter::new(Weight::max_value()); + }: { + >::add_user(hash, &mut gas_meter)?; + } + // This constructs a contract that is maximal expensive to instrument. // It creates a maximum number of metering blocks per byte. // The size of the salt influences the runtime because is is hashed in order to @@ -352,16 +371,14 @@ benchmarks! { } // Instantiate uses a dummy contract constructor to measure the overhead of the instantiate. - // `c`: Size of the code in kilobytes. // `s`: Size of the salt in kilobytes. instantiate { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; let s in 0 .. code::max_pages::() * 64; let salt = vec![42u8; (s * 1024) as usize]; let endowment = caller_funding::() / 3u32.into(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); - let WasmModule { code, hash, .. } = WasmModule::::dummy_with_bytes(c * 1024); + let WasmModule { code, hash, .. } = WasmModule::::dummy(); let origin = RawOrigin::Signed(caller.clone()); let addr = Contracts::::contract_address(&caller, &hash, &salt); Contracts::::store_code_raw(code)?; @@ -380,12 +397,10 @@ benchmarks! { // won't call `seal_input` in its constructor to copy the data to contract memory. // The dummy contract used here does not do this. The costs for the data copy is billed as // part of `seal_input`. - // `c`: Size of the code in kilobytes. call { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; let data = vec![42u8; 1024]; let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent + whitelisted_caller(), WasmModule::dummy(), vec![], Endow::CollectRent )?; let value = T::Currency::minimum_balance() * 100u32.into(); let origin = RawOrigin::Signed(instance.caller.clone()); @@ -720,43 +735,6 @@ benchmarks! { } } - seal_terminate_per_code_kb { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; - let beneficiary = account::("beneficiary", 0, 0); - let beneficiary_bytes = beneficiary.encode(); - let beneficiary_len = beneficiary_bytes.len(); - let code = WasmModule::::from(ModuleDefinition { - memory: Some(ImportedMemory::max::()), - imported_functions: vec![ImportedFunction { - module: "seal0", - name: "seal_terminate", - params: vec![ValueType::I32, ValueType::I32], - return_type: None, - }], - data_segments: vec![ - DataSegment { - offset: 0, - value: beneficiary_bytes, - }, - ], - call_body: Some(body::repeated(1, &[ - Instruction::I32Const(0), // beneficiary_ptr - Instruction::I32Const(beneficiary_len as i32), // beneficiary_len - Instruction::Call(0), - ])), - dummy_section: c * 1024, - .. Default::default() - }); - let instance = Contract::::new(code, vec![], Endow::Max)?; - let origin = RawOrigin::Signed(instance.caller.clone()); - assert_eq!(T::Currency::total_balance(&beneficiary), 0u32.into()); - assert_eq!(T::Currency::total_balance(&instance.account_id), Endow::max::()); - }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - verify { - assert_eq!(T::Currency::total_balance(&instance.account_id), 0u32.into()); - assert_eq!(T::Currency::total_balance(&beneficiary), Endow::max::()); - } - seal_restore_to { let r in 0 .. 1; @@ -836,18 +814,15 @@ benchmarks! { } } - // `c`: Code size of caller contract - // `t`: Code size of tombstone contract // `d`: Number of supplied delta keys - seal_restore_to_per_code_kb_delta { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; - let t in 0 .. T::Schedule::get().limits.code_len / 1024; + seal_restore_to_per_delta { let d in 0 .. API_BENCHMARK_BATCHES; - let mut tombstone = ContractWithStorage::::with_code( - WasmModule::::dummy_with_bytes(t * 1024), 0, 0 - )?; + let mut tombstone = ContractWithStorage::::new(0, 0)?; tombstone.evict()?; - let delta = create_storage::(d * API_BENCHMARK_BATCH_SIZE, T::Schedule::get().limits.payload_len)?; + let delta = create_storage::( + d * API_BENCHMARK_BATCH_SIZE, + T::Schedule::get().limits.payload_len, + )?; let dest = tombstone.contract.account_id.encode(); let dest_len = dest.len(); @@ -909,7 +884,6 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), - dummy_section: c * 1024, .. Default::default() }); @@ -1393,8 +1367,7 @@ benchmarks! { let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - seal_call_per_code_transfer_input_output_kb { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; + seal_call_per_transfer_input_output_kb { let t in 0 .. 1; let i in 0 .. code::max_pages::() * 64; let o in 0 .. (code::max_pages::() - 1) * 64; @@ -1417,7 +1390,6 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), - dummy_section: c * 1024, .. Default::default() }); let callees = (0..API_BENCHMARK_BATCH_SIZE) @@ -1593,8 +1565,7 @@ benchmarks! { } } - seal_instantiate_per_code_input_output_salt_kb { - let c in 0 .. T::Schedule::get().limits.code_len / 1024; + seal_instantiate_per_input_output_salt_kb { let i in 0 .. (code::max_pages::() - 1) * 64; let o in 0 .. (code::max_pages::() - 1) * 64; let s in 0 .. (code::max_pages::() - 1) * 64; @@ -1617,7 +1588,6 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), - dummy_section: c * 1024, .. Default::default() }); let hash = callee_code.hash.clone(); diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index f3a981347c981..3876bac868b45 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -168,7 +168,7 @@ pub trait Ext: sealing::Sealed { value: BalanceOf, input_data: Vec, allows_reentry: bool, - ) -> Result<(ExecReturnValue, u32), (ExecError, u32)>; + ) -> Result; /// Instantiate a contract from the given code. /// @@ -186,24 +186,16 @@ pub trait Ext: sealing::Sealed { value: BalanceOf, input_data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)>; + ) -> Result<(AccountIdOf, ExecReturnValue ), ExecError>; /// Transfer all funds to `beneficiary` and delete the contract. /// - /// Returns the original code size of the terminated contract. /// Since this function removes the self contract eagerly, if succeeded, no further actions should /// be performed on this `Ext` instance. /// /// This function will fail if the same contract is present on the contract /// call stack. - /// - /// # Return Value - /// - /// Result - fn terminate( - &mut self, - beneficiary: &AccountIdOf, - ) -> Result; + fn terminate(&mut self, beneficiary: &AccountIdOf) -> Result<(), DispatchError>; /// Restores the given destination contract sacrificing the current one. /// @@ -222,7 +214,7 @@ pub trait Ext: sealing::Sealed { code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(u32, u32), (DispatchError, u32, u32)>; + ) -> Result<(), DispatchError>; /// Transfer some amount of funds into the specified account. fn transfer( @@ -325,6 +317,9 @@ pub enum ExportedFunction { /// order to be able to mock the wasm logic for testing. pub trait Executable: Sized { /// Load the executable from storage. + /// + /// # Note + /// Charges size base load and instrumentation weight from the gas meter. fn from_storage( code_hash: CodeHash, schedule: &Schedule, @@ -336,6 +331,10 @@ pub trait Executable: Sized { /// A code module is re-instrumented on-load when it was originally instrumented with /// an older schedule. This skips this step for cases where the code storage is /// queried for purposes other than execution. + /// + /// # Note + /// + /// Does not charge from the gas meter. Do not in contexts where this is important. fn from_storage_noinstr(code_hash: CodeHash) -> Result; /// Decrements the refcount by one and deletes the code if it drops to zero. @@ -344,12 +343,22 @@ pub trait Executable: Sized { /// Increment the refcount by one. Fails if the code does not exist on-chain. /// /// Returns the size of the original code. - fn add_user(code_hash: CodeHash) -> Result; + /// + /// # Note + /// + /// Charges weight proportional to the code size from the gas meter. + fn add_user(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError>; /// Decrement the refcount by one and remove the code when it drops to zero. /// /// Returns the size of the original code. - fn remove_user(code_hash: CodeHash) -> u32; + /// + /// # Note + /// + /// Charges weight proportional to the code size from the gas meter + fn remove_user(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError>; /// Execute the specified exported function and return the result. /// @@ -595,7 +604,7 @@ where value: BalanceOf, input_data: Vec, debug_message: Option<&'a mut Vec>, - ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { + ) -> Result { let (mut stack, executable) = Self::new( FrameArgs::Call{dest, cached_info: None}, origin, @@ -639,11 +648,9 @@ where schedule, value, debug_message, - ).map_err(|(e, _code_len)| e)?; + )?; let account_id = stack.top_frame().account_id.clone(); - stack.run(executable, input_data) - .map(|(ret, _code_len)| (account_id, ret)) - .map_err(|(err, _code_len)| err) + stack.run(executable, input_data).map(|ret| (account_id, ret)) } /// Create a new call stack. @@ -654,7 +661,7 @@ where schedule: &'a Schedule, value: BalanceOf, debug_message: Option<&'a mut Vec>, - ) -> Result<(Self, E), (ExecError, u32)> { + ) -> Result<(Self, E), ExecError> { let (first_frame, executable) = Self::new_frame(args, value, gas_meter, 0, &schedule)?; let stack = Self { origin, @@ -682,22 +689,20 @@ where gas_meter: &mut GasMeter, gas_limit: Weight, schedule: &Schedule - ) -> Result<(Frame, E), (ExecError, u32)> { + ) -> Result<(Frame, E), ExecError> { let (account_id, contract_info, executable, entry_point) = match frame_args { FrameArgs::Call{dest, cached_info} => { let contract = if let Some(contract) = cached_info { contract } else { >::get(&dest) - .ok_or((>::ContractNotFound.into(), 0)) + .ok_or(>::ContractNotFound.into()) .and_then(|contract| - contract.get_alive() - .ok_or((>::ContractIsTombstone.into(), 0)) + contract.get_alive().ok_or(>::ContractIsTombstone) )? }; - let executable = E::from_storage(contract.code_hash, schedule, gas_meter) - .map_err(|e| (e.into(), 0))?; + let executable = E::from_storage(contract.code_hash, schedule, gas_meter)?; // This charges the rent and denies access to a contract that is in need of // eviction by returning `None`. We cannot evict eagerly here because those @@ -705,9 +710,8 @@ where // contract. // See: https://github.com/paritytech/substrate/issues/6439#issuecomment-648754324 let contract = Rent:: - ::charge(&dest, contract, executable.occupied_storage()) - .map_err(|e| (e.into(), executable.code_len()))? - .ok_or((Error::::RentNotPaid.into(), executable.code_len()))?; + ::charge(&dest, contract, executable.occupied_storage())? + .ok_or(Error::::RentNotPaid)?; (dest, contract, executable, ExportedFunction::Call) } FrameArgs::Instantiate{sender, trie_seed, executable, salt} => { @@ -719,7 +723,7 @@ where &account_id, trie_id, executable.code_hash().clone(), - ).map_err(|e| (e.into(), executable.code_len()))?; + )?; (account_id, contract, executable, ExportedFunction::Constructor) } }; @@ -732,8 +736,7 @@ where contract_info: CachedContract::Cached(contract_info), account_id, entry_point, - nested_meter: gas_meter.nested(gas_limit) - .map_err(|e| (e.into(), executable.code_len()))?, + nested_meter: gas_meter.nested(gas_limit)?, allows_reentry: true, }; @@ -746,9 +749,9 @@ where frame_args: FrameArgs, value_transferred: BalanceOf, gas_limit: Weight, - ) -> Result { + ) -> Result { if self.frames.len() == T::CallStack::size() { - return Err((Error::::MaxCallDepthReached.into(), 0)); + return Err(Error::::MaxCallDepthReached.into()); } // We need to make sure that changes made to the contract info are not discarded. @@ -787,7 +790,7 @@ where &mut self, executable: E, input_data: Vec - ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { + ) -> Result { let entry_point = self.top_frame().entry_point; let do_transaction = || { // Cache the value before calling into the constructor because that @@ -795,17 +798,16 @@ where // the same code hash we still charge the "1 block rent" as if they weren't // spawned. This is OK as overcharging is always safe. let occupied_storage = executable.occupied_storage(); - let code_len = executable.code_len(); // Every call or instantiate also optionally transferres balance. - self.initial_transfer().map_err(|e| (ExecError::from(e), code_len))?; + self.initial_transfer()?; // Call into the wasm blob. let output = executable.execute( self, &entry_point, input_data, - ).map_err(|e| (ExecError { error: e.error, origin: ErrorOrigin::Callee }, code_len))?; + ).map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; // Additional work needs to be performed in case of an instantiation. if output.is_success() && entry_point == ExportedFunction::Constructor { @@ -814,7 +816,7 @@ where // It is not allowed to terminate a contract inside its constructor. if let CachedContract::Terminated = frame.contract_info { - return Err((Error::::TerminatedInConstructor.into(), code_len)); + return Err(Error::::TerminatedInConstructor.into()); } // Collect the rent for the first block to prevent the creation of very large @@ -823,9 +825,8 @@ where // in order to keep up the guarantuee that we always leave a tombstone behind // with the exception of a contract that called `seal_terminate`. let contract = Rent:: - ::charge(&account_id, frame.invalidate(), occupied_storage) - .map_err(|e| (e.into(), code_len))? - .ok_or((Error::::NewContractNotFunded.into(), code_len))?; + ::charge(&account_id, frame.invalidate(), occupied_storage)? + .ok_or(Error::::NewContractNotFunded)?; frame.contract_info = CachedContract::Cached(contract); // Deposit an instantiation event. @@ -835,7 +836,7 @@ where )); } - Ok((output, code_len)) + Ok(output) }; // All changes performed by the contract are executed under a storage transaction. @@ -843,8 +844,8 @@ where // comitted or rolled back when popping the frame. let (success, output) = with_transaction(|| { let output = do_transaction(); - match output { - Ok((ref result, _)) if result.is_success() => { + match &output { + Ok(result) if result.is_success() => { TransactionOutcome::Commit((true, output)) }, _ => TransactionOutcome::Rollback((false, output)), @@ -1055,7 +1056,7 @@ where value: BalanceOf, input_data: Vec, allows_reentry: bool, - ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { + ) -> Result { // Before pushing the new frame: Protect the caller contract against reentrancy attacks. // It is important to do this before calling `allows_reentry` so that a direct recursion // is caught by it. @@ -1063,7 +1064,7 @@ where let try_call = || { if !self.allows_reentry(&to) { - return Err((>::ReentranceDenied.into(), 0)); + return Err(>::ReentranceDenied.into()); } // We ignore instantiate frames in our search for a cached contract. // Otherwise it would be possible to recursively call a contract from its own @@ -1101,9 +1102,8 @@ where endowment: BalanceOf, input_data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)> { - let executable = E::from_storage(code_hash, &self.schedule, self.gas_meter()) - .map_err(|e| (e.into(), 0))?; + ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { + let executable = E::from_storage(code_hash, &self.schedule, self.gas_meter())?; let trie_seed = self.next_trie_seed(); let executable = self.push_frame( FrameArgs::Instantiate { @@ -1116,33 +1116,29 @@ where gas_limit, )?; let account_id = self.top_frame().account_id.clone(); - self.run(executable, input_data) - .map(|(ret, code_len)| (account_id, ret, code_len)) + self.run(executable, input_data).map(|ret| (account_id, ret)) } - fn terminate( - &mut self, - beneficiary: &AccountIdOf, - ) -> Result { + fn terminate(&mut self, beneficiary: &AccountIdOf) -> Result<(), DispatchError> { if self.is_recursive() { - return Err((Error::::TerminatedWhileReentrant.into(), 0)); + return Err(Error::::TerminatedWhileReentrant.into()); } let frame = self.top_frame_mut(); let info = frame.terminate(); - Storage::::queue_trie_for_deletion(&info).map_err(|e| (e, 0))?; + Storage::::queue_trie_for_deletion(&info)?; >::transfer( true, true, &frame.account_id, beneficiary, T::Currency::free_balance(&frame.account_id), - ).map_err(|e| (e, 0))?; + )?; ContractInfoOf::::remove(&frame.account_id); - let code_len = E::remove_user(info.code_hash); + E::remove_user(info.code_hash, &mut frame.nested_meter)?; Contracts::::deposit_event( Event::Terminated(frame.account_id.clone(), beneficiary.clone()), ); - Ok(code_len) + Ok(()) } fn restore_to( @@ -1151,30 +1147,33 @@ where code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(u32, u32), (DispatchError, u32, u32)> { + ) -> Result<(), DispatchError> { if self.is_recursive() { - return Err((Error::::TerminatedWhileReentrant.into(), 0, 0)); + return Err(Error::::TerminatedWhileReentrant.into()); } - let origin_contract = self.top_frame_mut().contract_info().clone(); + let frame = self.top_frame_mut(); + let origin_contract = frame.contract_info().clone(); + let account_id = frame.account_id.clone(); let result = Rent::::restore_to( - &self.top_frame().account_id, + &account_id, origin_contract, dest.clone(), code_hash.clone(), rent_allowance, delta, + &mut frame.nested_meter, ); if let Ok(_) = result { deposit_event::( vec![], Event::Restored( - self.top_frame().account_id.clone(), + account_id, dest, code_hash, rent_allowance, ), ); - self.top_frame_mut().terminate(); + frame.terminate(); } result } @@ -1463,14 +1462,18 @@ mod tests { MockLoader::decrement_refcount(self.code_hash); } - fn add_user(code_hash: CodeHash) -> Result { + fn add_user(code_hash: CodeHash, _: &mut GasMeter) + -> Result<(), DispatchError> + { MockLoader::increment_refcount(code_hash); - Ok(0) + Ok(()) } - fn remove_user(code_hash: CodeHash) -> u32 { + fn remove_user(code_hash: CodeHash, _: &mut GasMeter) + -> Result<(), DispatchError> + { MockLoader::decrement_refcount(code_hash); - 0 + Ok(()) } fn execute>( @@ -1597,7 +1600,7 @@ mod tests { None, ).unwrap(); - assert!(!output.0.is_success()); + assert!(!output.is_success()); assert_eq!(get_balance(&origin), 100); // the rent is still charged @@ -1658,8 +1661,8 @@ mod tests { ); let output = result.unwrap(); - assert!(output.0.is_success()); - assert_eq!(output.0.data, Bytes(vec![1, 2, 3, 4])); + assert!(output.is_success()); + assert_eq!(output.data, Bytes(vec![1, 2, 3, 4])); }); } @@ -1689,8 +1692,8 @@ mod tests { ); let output = result.unwrap(); - assert!(!output.0.is_success()); - assert_eq!(output.0.data, Bytes(vec![1, 2, 3, 4])); + assert!(!output.is_success()); + assert_eq!(output.data, Bytes(vec![1, 2, 3, 4])); }); } @@ -1770,7 +1773,7 @@ mod tests { // Verify that we've got proper error and set `reached_bottom`. assert_eq!( r, - Err((Error::::MaxCallDepthReached.into(), 0)) + Err(Error::::MaxCallDepthReached.into()) ); *reached_bottom = true; } else { @@ -2000,7 +2003,7 @@ mod tests { let instantiated_contract_address = Rc::clone(&instantiated_contract_address); move |ctx, _| { // Instantiate a contract and save it's address in `instantiated_contract_address`. - let (address, output, _) = ctx.ext.instantiate( + let (address, output) = ctx.ext.instantiate( 0, dummy_ch, Contracts::::subsistence_threshold() * 3, @@ -2053,10 +2056,10 @@ mod tests { vec![], &[], ), - Err((ExecError { + Err(ExecError { error: DispatchError::Other("It's a trap!"), origin: ErrorOrigin::Callee, - }, 0)) + }) ); exec_success() @@ -2293,7 +2296,7 @@ mod tests { assert_ne!(original_allowance, changed_allowance); ctx.ext.set_rent_allowance(changed_allowance); assert_eq!( - ctx.ext.call(0, CHARLIE, 0, vec![], true).map(|v| v.0).map_err(|e| e.0), + ctx.ext.call(0, CHARLIE, 0, vec![], true), exec_trapped() ); assert_eq!(ctx.ext.rent_allowance(), changed_allowance); @@ -2330,7 +2333,7 @@ mod tests { let code = MockLoader::insert(Constructor, |ctx, _| { assert_matches!( ctx.ext.call(0, ctx.ext.address().clone(), 0, vec![], true), - Err((ExecError{error, ..}, _)) if error == >::ContractNotFound.into() + Err(ExecError{error, ..}) if error == >::ContractNotFound.into() ); exec_success() }); @@ -2426,7 +2429,7 @@ mod tests { // call the contract passed as input with disabled reentry let code_bob = MockLoader::insert(Call, |ctx, _| { let dest = Decode::decode(&mut ctx.input_data.as_ref()).unwrap(); - ctx.ext.call(0, dest, 0, vec![], false).map(|v| v.0).map_err(|e| e.0) + ctx.ext.call(0, dest, 0, vec![], false) }); let code_charlie = MockLoader::insert(Call, |_, _| { @@ -2459,7 +2462,7 @@ mod tests { 0, BOB.encode(), None, - ).map_err(|e| e.0.error), + ).map_err(|e| e.error), >::ReentranceDenied, ); }); @@ -2469,7 +2472,7 @@ mod tests { fn call_deny_reentry() { let code_bob = MockLoader::insert(Call, |ctx, _| { if ctx.input_data[0] == 0 { - ctx.ext.call(0, CHARLIE, 0, vec![], false).map(|v| v.0).map_err(|e| e.0) + ctx.ext.call(0, CHARLIE, 0, vec![], false) } else { exec_success() } @@ -2477,7 +2480,7 @@ mod tests { // call BOB with input set to '1' let code_charlie = MockLoader::insert(Call, |ctx, _| { - ctx.ext.call(0, BOB, 0, vec![1], true).map(|v| v.0).map_err(|e| e.0) + ctx.ext.call(0, BOB, 0, vec![1], true) }); ExtBuilder::default().build().execute_with(|| { @@ -2495,7 +2498,7 @@ mod tests { 0, vec![0], None, - ).map_err(|e| e.0.error), + ).map_err(|e| e.error), >::ReentranceDenied, ); }); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index f7dec843a7f7c..3ac56d8980cb2 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -275,9 +275,7 @@ pub mod pallet { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. - #[pallet::weight(T::WeightInfo::call(T::Schedule::get().limits.code_len / 1024) - .saturating_add(*gas_limit) - )] + #[pallet::weight(T::WeightInfo::call().saturating_add(*gas_limit))] pub fn call( origin: OriginFor, dest: ::Source, @@ -289,13 +287,10 @@ pub mod pallet { let dest = T::Lookup::lookup(dest)?; let mut gas_meter = GasMeter::new(gas_limit); let schedule = T::Schedule::get(); - let (result, code_len) = match ExecStack::>::run_call( + let result = ExecStack::>::run_call( origin, dest, &mut gas_meter, &schedule, value, data, None, - ) { - Ok((output, len)) => (Ok(output), len), - Err((err, len)) => (Err(err), len), - }; - gas_meter.into_dispatch_result(result, T::WeightInfo::call(code_len / 1024)) + ); + gas_meter.into_dispatch_result(result, T::WeightInfo::call()) } /// Instantiates a new contract from the supplied `code` optionally transferring @@ -357,10 +352,7 @@ pub mod pallet { /// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary /// must be supplied. #[pallet::weight( - T::WeightInfo::instantiate( - T::Schedule::get().limits.code_len / 1024, salt.len() as u32 / 1024 - ) - .saturating_add(*gas_limit) + T::WeightInfo::instantiate(salt.len() as u32 / 1024).saturating_add(*gas_limit) )] pub fn instantiate( origin: OriginFor, @@ -374,13 +366,12 @@ pub mod pallet { let mut gas_meter = GasMeter::new(gas_limit); let schedule = T::Schedule::get(); let executable = PrefabWasmModule::from_storage(code_hash, &schedule, &mut gas_meter)?; - let code_len = executable.code_len(); let result = ExecStack::>::run_instantiate( origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, None, ).map(|(_address, output)| output); gas_meter.into_dispatch_result( result, - T::WeightInfo::instantiate(code_len / 1024, salt.len() as u32 / 1024), + T::WeightInfo::instantiate(salt.len() as u32 / 1024), ) } @@ -666,7 +657,7 @@ where origin, dest, &mut gas_meter, &schedule, value, input_data, debug_message.as_mut(), ); ContractExecResult { - result: result.map(|r| r.0).map_err(|r| r.0.error), + result: result.map_err(|r| r.error), gas_consumed: gas_meter.gas_spent(), debug_message: debug_message.unwrap_or_default(), } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 68e8c57e9adeb..3135862e88c90 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -20,7 +20,7 @@ use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Pallet, Event, TombstoneContractInfo, Config, CodeHash, Error, - storage::Storage, wasm::PrefabWasmModule, exec::Executable, + storage::Storage, wasm::PrefabWasmModule, exec::Executable, gas::GasMeter, }; use sp_std::prelude::*; use sp_io::hashing::blake2_256; @@ -232,10 +232,6 @@ where /// Upon succesful restoration, `origin` will be destroyed, all its funds are transferred to /// the restored account. The restored account will inherit the last write block and its last /// deduct block will be set to the current block. - /// - /// # Return Value - /// - /// Result<(CallerCodeSize, DestCodeSize), (DispatchError, CallerCodeSize, DestCodesize)> pub fn restore_to( origin: &T::AccountId, mut origin_contract: AliveContractInfo, @@ -243,18 +239,19 @@ where code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(u32, u32), (DispatchError, u32, u32)> { + gas_meter: &mut GasMeter, + ) -> Result<(), DispatchError> { let child_trie_info = origin_contract.child_trie_info(); let current_block = >::block_number(); if origin_contract.last_write == Some(current_block) { - return Err((Error::::InvalidContractOrigin.into(), 0, 0)); + return Err(Error::::InvalidContractOrigin.into()); } let dest_tombstone = >::get(&dest) .and_then(|c| c.get_tombstone()) - .ok_or((Error::::InvalidDestinationContract.into(), 0, 0))?; + .ok_or(Error::::InvalidDestinationContract)?; let last_write = if !delta.is_empty() { Some(current_block) @@ -263,7 +260,7 @@ where }; // Fails if the code hash does not exist on chain - let caller_code_len = E::add_user(code_hash).map_err(|e| (e, 0, 0))?; + E::add_user(code_hash, gas_meter)?; // We are allowed to eagerly modify storage even though the function can // fail later due to tombstones not matching. This is because the restoration @@ -287,13 +284,13 @@ where ); if tombstone != dest_tombstone { - return Err((Error::::InvalidTombstone.into(), caller_code_len, 0)); + return Err(Error::::InvalidTombstone.into()); } origin_contract.storage_size -= bytes_taken; >::remove(&origin); - let tombstone_code_len = E::remove_user(origin_contract.code_hash); + E::remove_user(origin_contract.code_hash, gas_meter)?; >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { code_hash, rent_allowance, @@ -306,8 +303,7 @@ where let origin_free_balance = T::Currency::free_balance(&origin); T::Currency::make_free_balance_be(&origin, >::zero()); T::Currency::deposit_creating(&dest, origin_free_balance); - - Ok((caller_code_len, tombstone_code_len)) + Ok(()) } /// Create a new `RentStatus` struct for pass through to a requesting contract. diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index 0bf7c050e5dfa..0abe0c54d7481 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -300,18 +300,9 @@ pub struct HostFnWeights { /// Weight of calling `seal_terminate`. pub terminate: Weight, - /// Weight per byte of the terminated contract. - pub terminate_per_code_byte: Weight, - /// Weight of calling `seal_restore_to`. pub restore_to: Weight, - /// Weight per byte of the restoring contract. - pub restore_to_per_caller_code_byte: Weight, - - /// Weight per byte of the restored contract. - pub restore_to_per_tombstone_code_byte: Weight, - /// Weight per delta key supplied to `seal_restore_to`. pub restore_to_per_delta: Weight, @@ -354,9 +345,6 @@ pub struct HostFnWeights { /// Weight of calling `seal_call`. pub call: Weight, - /// Weight per byte of the called contract. - pub call_per_code_byte: Weight, - /// Weight surcharge that is claimed if `seal_call` does a balance transfer. pub call_transfer_surcharge: Weight, @@ -369,9 +357,6 @@ pub struct HostFnWeights { /// Weight of calling `seal_instantiate`. pub instantiate: Weight, - /// Weight per byte of the instantiated contract. - pub instantiate_per_code_byte: Weight, - /// Weight per input byte supplied to `seal_instantiate`. pub instantiate_per_input_byte: Weight, @@ -588,11 +573,8 @@ impl Default for HostFnWeights { r#return: cost!(seal_return), return_per_byte: cost_byte!(seal_return_per_kb), terminate: cost!(seal_terminate), - terminate_per_code_byte: cost_byte!(seal_terminate_per_code_kb), restore_to: cost!(seal_restore_to), - restore_to_per_caller_code_byte: cost_byte_args!(seal_restore_to_per_code_kb_delta, 1, 0, 0), - restore_to_per_tombstone_code_byte: cost_byte_args!(seal_restore_to_per_code_kb_delta, 0, 1, 0), - restore_to_per_delta: cost_batched_args!(seal_restore_to_per_code_kb_delta, 0, 0, 1), + restore_to_per_delta: cost_batched!(seal_restore_to_per_delta), random: cost_batched!(seal_random), deposit_event: cost_batched!(seal_deposit_event), deposit_event_per_topic: cost_batched_args!(seal_deposit_event_per_topic_and_kb, 1, 0), @@ -606,15 +588,13 @@ impl Default for HostFnWeights { get_storage_per_byte: cost_byte_batched!(seal_get_storage_per_kb), transfer: cost_batched!(seal_transfer), call: cost_batched!(seal_call), - call_per_code_byte: cost_byte_batched_args!(seal_call_per_code_transfer_input_output_kb, 1, 0, 0, 0), - call_transfer_surcharge: cost_batched_args!(seal_call_per_code_transfer_input_output_kb, 0, 1, 0, 0), - call_per_input_byte: cost_byte_batched_args!(seal_call_per_code_transfer_input_output_kb, 0, 0, 1, 0), - call_per_output_byte: cost_byte_batched_args!(seal_call_per_code_transfer_input_output_kb, 0, 0, 0, 1), + call_transfer_surcharge: cost_batched_args!(seal_call_per_transfer_input_output_kb, 1, 0, 0), + call_per_input_byte: cost_byte_batched_args!(seal_call_per_transfer_input_output_kb, 0, 1, 0), + call_per_output_byte: cost_byte_batched_args!(seal_call_per_transfer_input_output_kb, 0, 0, 1), instantiate: cost_batched!(seal_instantiate), - instantiate_per_code_byte: cost_byte_batched_args!(seal_instantiate_per_code_input_output_salt_kb, 1, 0, 0, 0), - instantiate_per_input_byte: cost_byte_batched_args!(seal_instantiate_per_code_input_output_salt_kb, 0, 1, 0, 0), - instantiate_per_output_byte: cost_byte_batched_args!(seal_instantiate_per_code_input_output_salt_kb, 0, 0, 1, 0), - instantiate_per_salt_byte: cost_byte_batched_args!(seal_instantiate_per_code_input_output_salt_kb, 0, 0, 0, 1), + instantiate_per_input_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 1, 0, 0), + instantiate_per_output_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 0, 1, 0), + instantiate_per_salt_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 0, 0, 1), hash_sha2_256: cost_batched!(seal_hash_sha2_256), hash_sha2_256_per_byte: cost_byte_batched!(seal_hash_sha2_256_per_kb), hash_keccak_256: cost_batched!(seal_hash_keccak_256), diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 75ea8d9bd89b6..a4997eb7b33c4 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -362,7 +362,7 @@ where fn calling_plain_account_fails() { ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&ALICE, 100_000_000); - let base_cost = <::WeightInfo as WeightInfo>::call(0); + let base_cost = <::WeightInfo as WeightInfo>::call(); assert_eq!( Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, Vec::new()), @@ -1726,6 +1726,10 @@ fn self_destruct_works() { Ok(_) ); + // The call triggers rent collection that reduces the amount of balance + // that remains for the beneficiary. + let balance_after_rent = 93_078; + pretty_assertions::assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, @@ -1737,7 +1741,7 @@ fn self_destruct_works() { EventRecord { phase: Phase::Initialization, event: Event::pallet_balances( - pallet_balances::Event::Transfer(addr.clone(), DJANGO, 93_086) + pallet_balances::Event::Transfer(addr.clone(), DJANGO, balance_after_rent) ), topics: vec![], }, @@ -1760,7 +1764,7 @@ fn self_destruct_works() { // check that the beneficiary (django) got remaining balance // some rent was deducted before termination - assert_eq!(Balances::free_balance(DJANGO), 1_093_086); + assert_eq!(Balances::free_balance(DJANGO), 1_000_000 + balance_after_rent); }); } @@ -2937,3 +2941,59 @@ fn debug_message_invalid_utf8() { assert_err!(result.result, >::DebugMessageInvalidUTF8); }); } + +#[test] +fn gas_estimation_correct() { + let (caller_code, caller_hash) = compile_module::("call_return_code").unwrap(); + let (callee_code, callee_hash) = compile_module::("dummy").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = Pallet::::subsistence_threshold(); + let _ = Balances::deposit_creating(&ALICE, 1000 * subsistence); + let _ = Balances::deposit_creating(&CHARLIE, 1000 * subsistence); + + assert_ok!( + Contracts::instantiate_with_code( + Origin::signed(ALICE), + subsistence * 100, + GAS_LIMIT, + caller_code, + vec![], + vec![0], + ), + ); + let addr_caller = Contracts::contract_address(&ALICE, &caller_hash, &[0]); + + assert_ok!( + Contracts::instantiate_with_code( + Origin::signed(ALICE), + subsistence * 100, + GAS_LIMIT, + callee_code, + vec![], + vec![1], + ), + ); + let addr_callee = Contracts::contract_address(&ALICE, &callee_hash, &[1]); + + // Call in order to determine the gas that is required for this call + let result = Contracts::bare_call( + ALICE, + addr_caller.clone(), + 0, + GAS_LIMIT, + AsRef::<[u8]>::as_ref(&addr_callee).to_vec(), + false, + ); + assert_ok!(result.result); + + // Make the same call using the estimated gas. Should succeed. + assert_ok!(Contracts::bare_call( + ALICE, + addr_caller, + 0, + result.gas_consumed, + AsRef::<[u8]>::as_ref(&addr_callee).to_vec(), + false, + ).result); + }); +} diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index 8df604cdb0e1c..e80df31a68969 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -81,14 +81,16 @@ where } /// Increment the refcount of a code in-storage by one. -pub fn increment_refcount(code_hash: CodeHash) -> Result +pub fn increment_refcount(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError> where T::AccountId: UncheckedFrom + AsRef<[u8]> { + gas_meter.charge(CodeToken::UpdateRefcount(estimate_code_size::(&code_hash)?))?; >::mutate(code_hash, |existing| { if let Some(module) = existing { increment_64(&mut module.refcount); - Ok(module.original_code_len) + Ok(()) } else { Err(Error::::CodeNotFound.into()) } @@ -96,23 +98,24 @@ where } /// Decrement the refcount of a code in-storage by one and remove the code when it drops to zero. -pub fn decrement_refcount(code_hash: CodeHash) -> u32 +pub fn decrement_refcount(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError> where T::AccountId: UncheckedFrom + AsRef<[u8]> { + if let Ok(len) = estimate_code_size::(&code_hash) { + gas_meter.charge(CodeToken::UpdateRefcount(len))?; + } >::mutate_exists(code_hash, |existing| { if let Some(module) = existing { - let code_len = module.original_code_len; module.refcount = module.refcount.saturating_sub(1); if module.refcount == 0 { *existing = None; finish_removal::(code_hash); } - code_len - } else { - 0 } - }) + }); + Ok(()) } /// Load code with the given code hash. @@ -120,13 +123,24 @@ where /// If the module was instrumented with a lower version of schedule than /// the current one given as an argument, then this function will perform /// re-instrumentation and update the cache in the storage. +/// +/// # Note +/// +/// If `reinstrument` is set it is assumed that the load is performed in the context of +/// a contract call: This means we charge the size based cased for loading the contract. pub fn load( code_hash: CodeHash, - reinstrument: Option<(&Schedule, &mut GasMeter)>, + mut reinstrument: Option<(&Schedule, &mut GasMeter)>, ) -> Result, DispatchError> where T::AccountId: UncheckedFrom + AsRef<[u8]> { + // The reinstrument case coincides with the cases where we need to charge extra + // based upon the code size: On-chain execution. + if let Some((_, gas_meter)) = &mut reinstrument { + gas_meter.charge(CodeToken::Load(estimate_code_size::(&code_hash)?))?; + } + let mut prefab_module = >::get(code_hash) .ok_or_else(|| Error::::CodeNotFound)?; prefab_module.code_hash = code_hash; @@ -135,7 +149,7 @@ where if prefab_module.instruction_weights_version < schedule.instruction_weights.version { // The instruction weights have changed. // We need to re-instrument the code with the new instruction weights. - gas_meter.charge(InstrumentToken(prefab_module.original_code_len))?; + gas_meter.charge(CodeToken::Instrument(prefab_module.original_code_len))?; private::reinstrument(&mut prefab_module, schedule)?; } } @@ -185,14 +199,50 @@ fn increment_64(refcount: &mut u64) { "); } -/// Token to be supplied to the gas meter which charges the weight needed for reinstrumenting -/// a contract of the specified size in bytes. +/// Get the size of the instrumented code stored at `code_hash` without loading it. +/// +/// The returned value is slightly too large because it also contains the fields apart from +/// `code` which are located inside [`PrefabWasmModule`]. However, those are negligible when +/// compared to the code size. Additionally, charging too much weight is completely safe. +fn estimate_code_size(code_hash: &CodeHash) -> Result +where + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ + let key = >::hashed_key_for(code_hash); + let mut data = [0u8; 0]; + let len = sp_io::storage::read(&key, &mut data, 0).ok_or_else(|| Error::::CodeNotFound)?; + Ok(len) +} + +/// Costs for operations that are related to code handling. #[cfg_attr(test, derive(Debug, PartialEq, Eq))] #[derive(Clone, Copy)] -struct InstrumentToken(u32); +enum CodeToken { + /// Weight for instrumenting a contract contract of the supplied size in bytes. + Instrument(u32), + /// Weight for loading a contract per kilobyte. + Load(u32), + /// Weight for changing the refcount of a contract per kilobyte. + UpdateRefcount(u32), +} -impl Token for InstrumentToken { +impl Token for CodeToken +where + T: Config, + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ fn weight(&self) -> Weight { - T::WeightInfo::instrument(self.0 / 1024) + use self::CodeToken::*; + // In case of `Load` and `UpdateRefcount` we already covered the general costs of + // accessing the storage but still need to account for the actual size of the + // contract code. This is why we substract `T::*::(0)`. We need to do this at this + // point because when charging the general weight we do not know the size of + // the contract. + match *self { + Instrument(len) => T::WeightInfo::instrument(len / 1024), + Load(len) => T::WeightInfo::code_load(len / 1024) - T::WeightInfo::code_load(0), + UpdateRefcount(len) => + T::WeightInfo::code_refcount(len / 1024) - T::WeightInfo::code_refcount(0), + } } } diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 5f9936c68dfbe..0741573a7dfb6 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -168,12 +168,16 @@ where code_cache::store_decremented(self); } - fn add_user(code_hash: CodeHash) -> Result { - code_cache::increment_refcount::(code_hash) + fn add_user(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError> + { + code_cache::increment_refcount::(code_hash, gas_meter) } - fn remove_user(code_hash: CodeHash) -> u32 { - code_cache::decrement_refcount::(code_hash) + fn remove_user(code_hash: CodeHash, gas_meter: &mut GasMeter) + -> Result<(), DispatchError> + { + code_cache::decrement_refcount::(code_hash, gas_meter) } fn execute>( @@ -349,14 +353,14 @@ mod tests { value: u64, data: Vec, allows_reentry: bool, - ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { + ) -> Result { self.calls.push(CallEntry { to, value, data, allows_reentry, }); - Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: call_return_data() }, 0)) + Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: call_return_data() }) } fn instantiate( &mut self, @@ -365,7 +369,7 @@ mod tests { endowment: u64, data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)> { + ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { self.instantiates.push(InstantiateEntry { code_hash: code_hash.clone(), endowment, @@ -379,7 +383,6 @@ mod tests { flags: ReturnFlags::empty(), data: Bytes(Vec::new()), }, - 0, )) } fn transfer( @@ -396,11 +399,11 @@ mod tests { fn terminate( &mut self, beneficiary: &AccountIdOf, - ) -> Result { + ) -> Result<(), DispatchError> { self.terminations.push(TerminationEntry { beneficiary: beneficiary.clone(), }); - Ok(0) + Ok(()) } fn restore_to( &mut self, @@ -408,14 +411,14 @@ mod tests { code_hash: H256, rent_allowance: u64, delta: Vec, - ) -> Result<(u32, u32), (DispatchError, u32, u32)> { + ) -> Result<(), DispatchError> { self.restores.push(RestoreEntry { dest, code_hash, rent_allowance, delta, }); - Ok((0, 0)) + Ok(()) } fn get_storage(&mut self, key: &StorageKey) -> Option> { self.storage.get(key).cloned() diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 7ca6dfed15819..362d396464704 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -26,7 +26,7 @@ use crate::{ }; use bitflags::bitflags; use pwasm_utils::parity_wasm::elements::ValueType; -use frame_support::{dispatch::DispatchError, ensure, traits::Get, weights::Weight}; +use frame_support::{dispatch::DispatchError, ensure, weights::Weight}; use sp_std::prelude::*; use codec::{Decode, DecodeAll, Encode}; use sp_core::{Bytes, crypto::UncheckedFrom}; @@ -170,12 +170,8 @@ pub enum RuntimeCosts { Return(u32), /// Weight of calling `seal_terminate`. Terminate, - /// Weight that is added to `seal_terminate` for every byte of the terminated contract. - TerminateSurchargeCodeSize(u32), /// Weight of calling `seal_restore_to` per number of supplied delta entries. RestoreTo(u32), - /// Weight that is added to `seal_restore_to` for the involved code sizes. - RestoreToSurchargeCodeSize{caller_code: u32, tombstone_code: u32}, /// Weight of calling `seal_random`. It includes the weight for copying the subject. Random, /// Weight of calling `seal_deposit_event` with the given number of topics and event size. @@ -197,8 +193,6 @@ pub enum RuntimeCosts { Transfer, /// Weight of calling `seal_call` for the given input size. CallBase(u32), - /// Weight that is added to `seal_call` for every byte of the called contract. - CallSurchargeCodeSize(u32), /// Weight of the transfer performed during a call. CallSurchargeTransfer, /// Weight of output received through `seal_call` for the given size. @@ -207,8 +201,6 @@ pub enum RuntimeCosts { /// This includes the transfer as an instantiate without a value will always be below /// the existential deposit and is disregarded as corner case. InstantiateBase{input_data_len: u32, salt_len: u32}, - /// Weight that is added to `seal_instantiate` for every byte of the instantiated contract. - InstantiateSurchargeCodeSize(u32), /// Weight of output received through `seal_instantiate` for the given size. InstantiateCopyOut(u32), /// Weight of calling `seal_hash_sha_256` for the given input size. @@ -250,13 +242,8 @@ impl RuntimeCosts { Return(len) => s.r#return .saturating_add(s.return_per_byte.saturating_mul(len.into())), Terminate => s.terminate, - TerminateSurchargeCodeSize(len) => s.terminate_per_code_byte.saturating_mul(len.into()), RestoreTo(delta) => s.restore_to .saturating_add(s.restore_to_per_delta.saturating_mul(delta.into())), - RestoreToSurchargeCodeSize{caller_code, tombstone_code} => - s.restore_to_per_caller_code_byte.saturating_mul(caller_code.into()).saturating_add( - s.restore_to_per_tombstone_code_byte.saturating_mul(tombstone_code.into()) - ), Random => s.random, DepositEvent{num_topic, len} => s.deposit_event .saturating_add(s.deposit_event_per_topic.saturating_mul(num_topic.into())) @@ -272,14 +259,11 @@ impl RuntimeCosts { Transfer => s.transfer, CallBase(len) => s.call .saturating_add(s.call_per_input_byte.saturating_mul(len.into())), - CallSurchargeCodeSize(len) => s.call_per_code_byte.saturating_mul(len.into()), CallSurchargeTransfer => s.call_transfer_surcharge, CallCopyOut(len) => s.call_per_output_byte.saturating_mul(len.into()), InstantiateBase{input_data_len, salt_len} => s.instantiate .saturating_add(s.instantiate_per_input_byte.saturating_mul(input_data_len.into())) .saturating_add(s.instantiate_per_salt_byte.saturating_mul(salt_len.into())), - InstantiateSurchargeCodeSize(len) => - s.instantiate_per_code_byte.saturating_mul(len.into()), InstantiateCopyOut(len) => s.instantiate_per_output_byte .saturating_mul(len.into()), HashSha256(len) => s.hash_sha2_256 @@ -476,15 +460,6 @@ where self.ext.gas_meter().charge(token) } - /// Correct previously charged gas amount. - pub fn adjust_gas(&mut self, charged_amount: ChargedAmount, adjusted_amount: RuntimeCosts) { - let adjusted_amount = adjusted_amount.token(&self.ext.schedule().host_fn_weights); - self.ext.gas_meter().adjust_gas( - charged_amount, - adjusted_amount, - ); - } - /// Read designated chunk from the sandbox memory. /// /// Returns `Err` if one of the following conditions occurs: @@ -698,23 +673,15 @@ where if value > 0u32.into() { self.charge_gas(RuntimeCosts::CallSurchargeTransfer)?; } - let charged = self.charge_gas( - RuntimeCosts::CallSurchargeCodeSize(::Schedule::get().limits.code_len) - )?; let ext = &mut self.ext; let call_outcome = ext.call( gas, callee, value, input_data, flags.contains(CallFlags::ALLOW_REENTRY), ); - let code_len = match &call_outcome { - Ok((_, len)) => len, - Err((_, len)) => len, - }; - self.adjust_gas(charged, RuntimeCosts::CallSurchargeCodeSize(*code_len)); // `TAIL_CALL` only matters on an `OK` result. Otherwise the call stack comes to // a halt anyways without anymore code being executed. if flags.contains(CallFlags::TAIL_CALL) { - if let Ok((return_value, _)) = call_outcome { + if let Ok(return_value) = call_outcome { return Err(TrapReason::Return(ReturnData { flags: return_value.flags.bits(), data: return_value.data.0, @@ -722,12 +689,12 @@ where } } - if let Ok((output, _)) = &call_outcome { + if let Ok(output) = &call_outcome { self.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { Some(RuntimeCosts::CallCopyOut(len)) })?; } - Ok(Runtime::::exec_into_return_code(call_outcome.map(|r| r.0).map_err(|r| r.0))?) + Ok(Runtime::::exec_into_return_code(call_outcome)?) } } @@ -1014,19 +981,9 @@ define_env!(Env, , let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?; - let charged = ctx.charge_gas( - RuntimeCosts::InstantiateSurchargeCodeSize( - ::Schedule::get().limits.code_len - ) - )?; let ext = &mut ctx.ext; let instantiate_outcome = ext.instantiate(gas, code_hash, value, input_data, &salt); - let code_len = match &instantiate_outcome { - Ok((_, _, code_len)) => code_len, - Err((_, code_len)) => code_len, - }; - ctx.adjust_gas(charged, RuntimeCosts::InstantiateSurchargeCodeSize(*code_len)); - if let Ok((address, output, _)) = &instantiate_outcome { + if let Ok((address, output)) = &instantiate_outcome { if !output.flags.contains(ReturnFlags::REVERT) { ctx.write_sandbox_output( address_ptr, address_len_ptr, &address.encode(), true, already_charged, @@ -1036,9 +993,7 @@ define_env!(Env, , Some(RuntimeCosts::InstantiateCopyOut(len)) })?; } - Ok(Runtime::::exec_into_return_code( - instantiate_outcome.map(|(_, retval, _)| retval).map_err(|(err, _)| err) - )?) + Ok(Runtime::::exec_into_return_code(instantiate_outcome.map(|(_, retval)| retval))?) }, // Remove the calling account and transfer remaining balance. @@ -1065,17 +1020,7 @@ define_env!(Env, , ctx.charge_gas(RuntimeCosts::Terminate)?; let beneficiary: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; - let charged = ctx.charge_gas( - RuntimeCosts::TerminateSurchargeCodeSize( - ::Schedule::get().limits.code_len - ) - )?; - let (result, code_len) = match ctx.ext.terminate(&beneficiary) { - Ok(len) => (Ok(()), len), - Err((err, len)) => (Err(err), len), - }; - ctx.adjust_gas(charged, RuntimeCosts::TerminateSurchargeCodeSize(code_len)); - result?; + ctx.ext.terminate(&beneficiary)?; Err(TrapReason::Termination) }, @@ -1397,23 +1342,7 @@ define_env!(Env, , delta }; - - let max_len = ::Schedule::get().limits.code_len; - let charged = ctx.charge_gas(RuntimeCosts::RestoreToSurchargeCodeSize { - caller_code: max_len, - tombstone_code: max_len, - })?; - let (result, caller_code, tombstone_code) = match ctx.ext.restore_to( - dest, code_hash, rent_allowance, delta - ) { - Ok((code, tomb)) => (Ok(()), code, tomb), - Err((err, code, tomb)) => (Err(err), code, tomb), - }; - ctx.adjust_gas(charged, RuntimeCosts::RestoreToSurchargeCodeSize { - caller_code, - tombstone_code, - }); - result?; + ctx.ext.restore_to(dest, code_hash, rent_allowance, delta)?; Err(TrapReason::Restoration) }, diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index b96a3cad5b735..503d952b110ed 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_contracts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-05-11, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-06-08, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -48,9 +48,11 @@ pub trait WeightInfo { fn on_initialize_per_trie_key(k: u32, ) -> Weight; fn on_initialize_per_queue_item(q: u32, ) -> Weight; fn instrument(c: u32, ) -> Weight; + fn code_load(c: u32, ) -> Weight; + fn code_refcount(c: u32, ) -> Weight; fn instantiate_with_code(c: u32, s: u32, ) -> Weight; - fn instantiate(c: u32, s: u32, ) -> Weight; - fn call(c: u32, ) -> Weight; + fn instantiate(s: u32, ) -> Weight; + fn call() -> Weight; fn claim_surcharge(c: u32, ) -> Weight; fn seal_caller(r: u32, ) -> Weight; fn seal_address(r: u32, ) -> Weight; @@ -62,8 +64,6 @@ pub trait WeightInfo { fn seal_rent_allowance(r: u32, ) -> Weight; fn seal_block_number(r: u32, ) -> Weight; fn seal_now(r: u32, ) -> Weight; - fn seal_rent_params(r: u32, ) -> Weight; - fn seal_rent_status(r: u32, ) -> Weight; fn seal_weight_to_fee(r: u32, ) -> Weight; fn seal_gas(r: u32, ) -> Weight; fn seal_input(r: u32, ) -> Weight; @@ -71,9 +71,8 @@ pub trait WeightInfo { fn seal_return(r: u32, ) -> Weight; fn seal_return_per_kb(n: u32, ) -> Weight; fn seal_terminate(r: u32, ) -> Weight; - fn seal_terminate_per_code_kb(c: u32, ) -> Weight; fn seal_restore_to(r: u32, ) -> Weight; - fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight; + fn seal_restore_to_per_delta(d: u32, ) -> Weight; fn seal_random(r: u32, ) -> Weight; fn seal_deposit_event(r: u32, ) -> Weight; fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight; @@ -86,9 +85,9 @@ pub trait WeightInfo { fn seal_get_storage_per_kb(n: u32, ) -> Weight; fn seal_transfer(r: u32, ) -> Weight; fn seal_call(r: u32, ) -> Weight; - fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight; + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight; fn seal_instantiate(r: u32, ) -> Weight; - fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight; + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight; fn seal_hash_sha2_256(r: u32, ) -> Weight; fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight; fn seal_hash_keccak_256(r: u32, ) -> Weight; @@ -154,286 +153,270 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn on_initialize() -> Weight { - (3_656_000 as Weight) + (4_636_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 3_000 - .saturating_add((2_241_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_851_000 as Weight).saturating_mul(k as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (36_820_000 as Weight) - // Standard Error: 4_000 - .saturating_add((34_550_000 as Weight).saturating_mul(q as Weight)) + (0 as Weight) + // Standard Error: 11_000 + .saturating_add((38_093_000 as Weight).saturating_mul(q as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instrument(c: u32, ) -> Weight { - (42_348_000 as Weight) - // Standard Error: 185_000 - .saturating_add((95_664_000 as Weight).saturating_mul(c as Weight)) + (60_027_000 as Weight) + // Standard Error: 109_000 + .saturating_add((169_008_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn code_load(c: u32, ) -> Weight { + (7_881_000 as Weight) + // Standard Error: 0 + .saturating_add((2_007_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + fn code_refcount(c: u32, ) -> Weight { + (12_861_000 as Weight) + // Standard Error: 0 + .saturating_add((3_028_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (210_852_000 as Weight) - // Standard Error: 138_000 - .saturating_add((135_241_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 9_000 - .saturating_add((1_846_000 as Weight).saturating_mul(s as Weight)) + (189_624_000 as Weight) + // Standard Error: 120_000 + .saturating_add((244_984_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 7_000 + .saturating_add((1_588_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn instantiate(c: u32, s: u32, ) -> Weight { - (217_380_000 as Weight) - // Standard Error: 6_000 - .saturating_add((8_483_000 as Weight).saturating_mul(c as Weight)) + fn instantiate(s: u32, ) -> Weight { + (224_867_000 as Weight) // Standard Error: 0 - .saturating_add((1_752_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((1_476_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - fn call(c: u32, ) -> Weight { - (181_443_000 as Weight) - // Standard Error: 3_000 - .saturating_add((3_955_000 as Weight).saturating_mul(c as Weight)) + fn call() -> Weight { + (197_338_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn claim_surcharge(c: u32, ) -> Weight { - (132_551_000 as Weight) - // Standard Error: 1_000 - .saturating_add((4_740_000 as Weight).saturating_mul(c as Weight)) + (147_775_000 as Weight) + // Standard Error: 5_000 + .saturating_add((3_094_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (137_742_000 as Weight) - // Standard Error: 74_000 - .saturating_add((242_261_000 as Weight).saturating_mul(r as Weight)) + (150_159_000 as Weight) + // Standard Error: 90_000 + .saturating_add((274_529_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (137_739_000 as Weight) - // Standard Error: 91_000 - .saturating_add((241_803_000 as Weight).saturating_mul(r as Weight)) + (140_207_000 as Weight) + // Standard Error: 116_000 + .saturating_add((276_569_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (139_631_000 as Weight) - // Standard Error: 83_000 - .saturating_add((236_790_000 as Weight).saturating_mul(r as Weight)) + (156_581_000 as Weight) + // Standard Error: 107_000 + .saturating_add((270_368_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (142_506_000 as Weight) - // Standard Error: 176_000 - .saturating_add((525_752_000 as Weight).saturating_mul(r as Weight)) + (141_778_000 as Weight) + // Standard Error: 305_000 + .saturating_add((615_927_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (138_569_000 as Weight) - // Standard Error: 76_000 - .saturating_add((237_016_000 as Weight).saturating_mul(r as Weight)) + (138_752_000 as Weight) + // Standard Error: 91_000 + .saturating_add((280_176_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (134_713_000 as Weight) - // Standard Error: 81_000 - .saturating_add((237_962_000 as Weight).saturating_mul(r as Weight)) + (141_089_000 as Weight) + // Standard Error: 82_000 + .saturating_add((274_199_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (131_523_000 as Weight) - // Standard Error: 90_000 - .saturating_add((237_435_000 as Weight).saturating_mul(r as Weight)) + (140_447_000 as Weight) + // Standard Error: 119_000 + .saturating_add((270_823_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (141_574_000 as Weight) - // Standard Error: 86_000 - .saturating_add((238_102_000 as Weight).saturating_mul(r as Weight)) + (138_394_000 as Weight) + // Standard Error: 105_000 + .saturating_add((275_261_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (140_240_000 as Weight) - // Standard Error: 101_000 - .saturating_add((236_568_000 as Weight).saturating_mul(r as Weight)) + (151_633_000 as Weight) + // Standard Error: 109_000 + .saturating_add((269_666_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (138_265_000 as Weight) - // Standard Error: 91_000 - .saturating_add((237_187_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn seal_rent_params(r: u32, ) -> Weight { - (149_701_000 as Weight) - // Standard Error: 297_000 - .saturating_add((357_149_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn seal_rent_status(r: u32, ) -> Weight { - (146_863_000 as Weight) - // Standard Error: 191_000 - .saturating_add((638_683_000 as Weight).saturating_mul(r as Weight)) + (129_087_000 as Weight) + // Standard Error: 252_000 + .saturating_add((277_368_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (144_278_000 as Weight) - // Standard Error: 149_000 - .saturating_add((470_264_000 as Weight).saturating_mul(r as Weight)) + (176_205_000 as Weight) + // Standard Error: 304_000 + .saturating_add((555_094_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (111_361_000 as Weight) - // Standard Error: 157_000 - .saturating_add((118_441_000 as Weight).saturating_mul(r as Weight)) + (129_942_000 as Weight) + // Standard Error: 92_000 + .saturating_add((144_914_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (129_970_000 as Weight) - // Standard Error: 316_000 - .saturating_add((7_160_000 as Weight).saturating_mul(r as Weight)) + (141_540_000 as Weight) + // Standard Error: 68_000 + .saturating_add((6_576_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (139_275_000 as Weight) + (150_832_000 as Weight) // Standard Error: 0 - .saturating_add((250_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((263_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (119_240_000 as Weight) - // Standard Error: 57_000 - .saturating_add((4_347_000 as Weight).saturating_mul(r as Weight)) + (135_920_000 as Weight) + // Standard Error: 61_000 + .saturating_add((3_733_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (128_896_000 as Weight) - // Standard Error: 1_000 - .saturating_add((757_000 as Weight).saturating_mul(n as Weight)) + (144_104_000 as Weight) + // Standard Error: 0 + .saturating_add((640_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (130_119_000 as Weight) - // Standard Error: 108_000 - .saturating_add((95_078_000 as Weight).saturating_mul(r as Weight)) + (141_631_000 as Weight) + // Standard Error: 70_000 + .saturating_add((112_747_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } - fn seal_terminate_per_code_kb(c: u32, ) -> Weight { - (230_167_000 as Weight) - // Standard Error: 2_000 - .saturating_add((8_495_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - } fn seal_restore_to(r: u32, ) -> Weight { - (159_200_000 as Weight) - // Standard Error: 261_000 - .saturating_add((103_048_000 as Weight).saturating_mul(r as Weight)) + (168_955_000 as Weight) + // Standard Error: 211_000 + .saturating_add((119_247_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } - fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { - (58_389_000 as Weight) - // Standard Error: 131_000 - .saturating_add((7_910_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 131_000 - .saturating_add((4_036_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 1_156_000 - .saturating_add((3_714_110_000 as Weight).saturating_mul(d as Weight)) + fn seal_restore_to_per_delta(d: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 3_299_000 + .saturating_add((3_257_862_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(7 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (138_794_000 as Weight) - // Standard Error: 216_000 - .saturating_add((599_742_000 as Weight).saturating_mul(r as Weight)) + (124_927_000 as Weight) + // Standard Error: 407_000 + .saturating_add((730_247_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (139_890_000 as Weight) - // Standard Error: 263_000 - .saturating_add((885_805_000 as Weight).saturating_mul(r as Weight)) + (135_014_000 as Weight) + // Standard Error: 892_000 + .saturating_add((1_131_992_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_117_962_000 as Weight) - // Standard Error: 4_029_000 - .saturating_add((566_825_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 794_000 - .saturating_add((251_096_000 as Weight).saturating_mul(n as Weight)) + (1_401_344_000 as Weight) + // Standard Error: 2_961_000 + .saturating_add((701_918_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 583_000 + .saturating_add((169_206_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (132_720_000 as Weight) - // Standard Error: 87_000 - .saturating_add((164_134_000 as Weight).saturating_mul(r as Weight)) + (146_753_000 as Weight) + // Standard Error: 117_000 + .saturating_add((194_150_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_debug_message(r: u32, ) -> Weight { - (125_834_000 as Weight) - // Standard Error: 142_000 - .saturating_add((127_200_000 as Weight).saturating_mul(r as Weight)) + (141_972_000 as Weight) + // Standard Error: 114_000 + .saturating_add((164_981_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (478_734_000 as Weight) - // Standard Error: 2_559_000 - .saturating_add((3_766_445_000 as Weight).saturating_mul(r as Weight)) + (549_424_000 as Weight) + // Standard Error: 7_901_000 + .saturating_add((4_159_879_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (600_306_000 as Weight) - // Standard Error: 234_000 - .saturating_add((70_989_000 as Weight).saturating_mul(n as Weight)) + (682_814_000 as Weight) + // Standard Error: 229_000 + .saturating_add((59_572_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 2_380_000 - .saturating_add((1_242_131_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_889_000 + .saturating_add((1_563_117_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -441,23 +424,23 @@ impl WeightInfo for SubstrateWeight { } fn seal_get_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_060_000 - .saturating_add((910_861_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_414_000 + .saturating_add((1_178_803_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (605_545_000 as Weight) - // Standard Error: 252_000 - .saturating_add((153_519_000 as Weight).saturating_mul(n as Weight)) + (696_056_000 as Weight) + // Standard Error: 266_000 + .saturating_add((108_870_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (36_854_000 as Weight) - // Standard Error: 2_076_000 - .saturating_add((5_183_774_000 as Weight).saturating_mul(r as Weight)) + (0 as Weight) + // Standard Error: 2_764_000 + .saturating_add((6_397_838_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) @@ -465,645 +448,625 @@ impl WeightInfo for SubstrateWeight { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 6_583_000 - .saturating_add((11_599_057_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 8_279_000 + .saturating_add((13_318_274_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } - fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { - (10_431_738_000 as Weight) - // Standard Error: 301_000 - .saturating_add((392_174_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 125_400_000 - .saturating_add((3_698_896_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 39_000 - .saturating_add((60_692_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 42_000 - .saturating_add((78_872_000 as Weight).saturating_mul(o as Weight)) + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { + (13_411_599_000 as Weight) + // Standard Error: 40_931_000 + .saturating_add((4_291_567_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 14_000 + .saturating_add((48_818_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 15_000 + .saturating_add((68_502_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(205 as Weight)) .saturating_add(T::DbWeight::get().writes(101 as Weight)) .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 32_118_000 - .saturating_add((21_117_947_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 31_671_000 + .saturating_add((24_164_540_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { - (8_542_521_000 as Weight) - // Standard Error: 644_000 - .saturating_add((878_020_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 91_000 - .saturating_add((63_004_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 91_000 - .saturating_add((83_203_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 91_000 - .saturating_add((240_170_000 as Weight).saturating_mul(s as Weight)) + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { + (17_228_488_000 as Weight) + // Standard Error: 26_000 + .saturating_add((50_822_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 26_000 + .saturating_add((71_276_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 26_000 + .saturating_add((198_669_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(206 as Weight)) .saturating_add(T::DbWeight::get().writes(204 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (130_991_000 as Weight) - // Standard Error: 106_000 - .saturating_add((230_186_000 as Weight).saturating_mul(r as Weight)) + (149_183_000 as Weight) + // Standard Error: 99_000 + .saturating_add((279_233_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (508_089_000 as Weight) - // Standard Error: 38_000 - .saturating_add((491_916_000 as Weight).saturating_mul(n as Weight)) + (457_629_000 as Weight) + // Standard Error: 14_000 + .saturating_add((480_686_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (135_384_000 as Weight) - // Standard Error: 111_000 - .saturating_add((233_638_000 as Weight).saturating_mul(r as Weight)) + (141_603_000 as Weight) + // Standard Error: 120_000 + .saturating_add((283_527_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (445_961_000 as Weight) - // Standard Error: 29_000 - .saturating_add((340_992_000 as Weight).saturating_mul(n as Weight)) + (463_644_000 as Weight) + // Standard Error: 18_000 + .saturating_add((332_183_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (133_593_000 as Weight) - // Standard Error: 112_000 - .saturating_add((208_000_000 as Weight).saturating_mul(r as Weight)) + (144_145_000 as Weight) + // Standard Error: 113_000 + .saturating_add((252_640_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (444_562_000 as Weight) - // Standard Error: 27_000 - .saturating_add((159_521_000 as Weight).saturating_mul(n as Weight)) + (455_101_000 as Weight) + // Standard Error: 23_000 + .saturating_add((149_174_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (131_381_000 as Weight) - // Standard Error: 82_000 - .saturating_add((207_479_000 as Weight).saturating_mul(r as Weight)) + (147_166_000 as Weight) + // Standard Error: 233_000 + .saturating_add((254_430_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (576_129_000 as Weight) - // Standard Error: 49_000 - .saturating_add((156_900_000 as Weight).saturating_mul(n as Weight)) + (445_667_000 as Weight) + // Standard Error: 24_000 + .saturating_add((149_178_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (20_276_000 as Weight) - // Standard Error: 16_000 - .saturating_add((3_355_000 as Weight).saturating_mul(r as Weight)) + (21_505_000 as Weight) + // Standard Error: 10_000 + .saturating_add((7_963_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (22_345_000 as Weight) - // Standard Error: 18_000 - .saturating_add((133_628_000 as Weight).saturating_mul(r as Weight)) + (24_775_000 as Weight) + // Standard Error: 37_000 + .saturating_add((157_130_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (22_294_000 as Weight) - // Standard Error: 95_000 - .saturating_add((204_007_000 as Weight).saturating_mul(r as Weight)) + (24_722_000 as Weight) + // Standard Error: 69_000 + .saturating_add((240_564_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (20_266_000 as Weight) - // Standard Error: 25_000 - .saturating_add((12_605_000 as Weight).saturating_mul(r as Weight)) + (21_506_000 as Weight) + // Standard Error: 21_000 + .saturating_add((45_277_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (20_208_000 as Weight) - // Standard Error: 13_000 - .saturating_add((12_589_000 as Weight).saturating_mul(r as Weight)) + (21_587_000 as Weight) + // Standard Error: 18_000 + .saturating_add((42_269_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (20_227_000 as Weight) - // Standard Error: 18_000 - .saturating_add((6_429_000 as Weight).saturating_mul(r as Weight)) + (21_538_000 as Weight) + // Standard Error: 807_000 + .saturating_add((22_392_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (20_279_000 as Weight) - // Standard Error: 15_000 - .saturating_add((14_560_000 as Weight).saturating_mul(r as Weight)) + (21_634_000 as Weight) + // Standard Error: 57_000 + .saturating_add((44_203_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (20_210_000 as Weight) - // Standard Error: 16_000 - .saturating_add((15_613_000 as Weight).saturating_mul(r as Weight)) + (21_531_000 as Weight) + // Standard Error: 19_000 + .saturating_add((33_198_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (34_276_000 as Weight) - // Standard Error: 0 - .saturating_add((130_000 as Weight).saturating_mul(e as Weight)) + (60_960_000 as Weight) + // Standard Error: 1_000 + .saturating_add((151_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (20_426_000 as Weight) - // Standard Error: 69_000 - .saturating_add((91_850_000 as Weight).saturating_mul(r as Weight)) + (21_777_000 as Weight) + // Standard Error: 141_000 + .saturating_add((245_105_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (27_099_000 as Weight) - // Standard Error: 111_000 - .saturating_add((169_212_000 as Weight).saturating_mul(r as Weight)) + (34_307_000 as Weight) + // Standard Error: 365_000 + .saturating_add((344_623_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (206_492_000 as Weight) - // Standard Error: 4_000 - .saturating_add((4_685_000 as Weight).saturating_mul(p as Weight)) + (398_310_000 as Weight) + // Standard Error: 6_000 + .saturating_add((4_163_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (37_892_000 as Weight) - // Standard Error: 24_000 - .saturating_add((3_510_000 as Weight).saturating_mul(r as Weight)) + (40_478_000 as Weight) + // Standard Error: 19_000 + .saturating_add((9_991_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (37_773_000 as Weight) - // Standard Error: 15_000 - .saturating_add((3_814_000 as Weight).saturating_mul(r as Weight)) + (40_427_000 as Weight) + // Standard Error: 26_000 + .saturating_add((8_526_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (37_785_000 as Weight) - // Standard Error: 20_000 - .saturating_add((4_949_000 as Weight).saturating_mul(r as Weight)) + (40_463_000 as Weight) + // Standard Error: 19_000 + .saturating_add((16_497_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (23_467_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_493_000 as Weight).saturating_mul(r as Weight)) + (25_998_000 as Weight) + // Standard Error: 21_000 + .saturating_add((18_214_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (23_492_000 as Weight) - // Standard Error: 28_000 - .saturating_add((8_499_000 as Weight).saturating_mul(r as Weight)) + (25_972_000 as Weight) + // Standard Error: 42_000 + .saturating_add((18_901_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (22_347_000 as Weight) - // Standard Error: 18_000 - .saturating_add((3_565_000 as Weight).saturating_mul(r as Weight)) + (24_949_000 as Weight) + // Standard Error: 17_000 + .saturating_add((8_541_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (20_849_000 as Weight) - // Standard Error: 2_751_000 - .saturating_add((2_072_517_000 as Weight).saturating_mul(r as Weight)) + (22_204_000 as Weight) + // Standard Error: 4_776_000 + .saturating_add((2_198_462_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (20_216_000 as Weight) + (21_506_000 as Weight) // Standard Error: 18_000 - .saturating_add((5_067_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((25_302_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (20_218_000 as Weight) - // Standard Error: 11_000 - .saturating_add((5_015_000 as Weight).saturating_mul(r as Weight)) + (21_523_000 as Weight) + // Standard Error: 29_000 + .saturating_add((25_206_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (20_215_000 as Weight) - // Standard Error: 16_000 - .saturating_add((5_888_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 466_000 + .saturating_add((19_925_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (20_232_000 as Weight) - // Standard Error: 12_000 - .saturating_add((5_366_000 as Weight).saturating_mul(r as Weight)) + (21_569_000 as Weight) + // Standard Error: 30_000 + .saturating_add((25_027_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (20_205_000 as Weight) - // Standard Error: 17_000 - .saturating_add((4_847_000 as Weight).saturating_mul(r as Weight)) + (21_536_000 as Weight) + // Standard Error: 193_000 + .saturating_add((17_690_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (20_181_000 as Weight) - // Standard Error: 12_000 - .saturating_add((4_849_000 as Weight).saturating_mul(r as Weight)) + (21_555_000 as Weight) + // Standard Error: 356_000 + .saturating_add((17_105_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (20_175_000 as Weight) - // Standard Error: 18_000 - .saturating_add((4_981_000 as Weight).saturating_mul(r as Weight)) + (21_561_000 as Weight) + // Standard Error: 1_038_000 + .saturating_add((22_198_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (20_273_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) + (21_513_000 as Weight) + // Standard Error: 21_000 + .saturating_add((33_620_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (20_260_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + (21_556_000 as Weight) + // Standard Error: 17_000 + .saturating_add((33_669_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (20_248_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_363_000 as Weight).saturating_mul(r as Weight)) + (21_571_000 as Weight) + // Standard Error: 19_000 + .saturating_add((33_649_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (20_229_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_412_000 as Weight).saturating_mul(r as Weight)) + (21_533_000 as Weight) + // Standard Error: 23_000 + .saturating_add((33_450_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (20_232_000 as Weight) - // Standard Error: 9_000 - .saturating_add((7_364_000 as Weight).saturating_mul(r as Weight)) + (21_525_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_727_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (20_252_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_383_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 16_000 + .saturating_add((33_420_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (20_258_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_359_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_720_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (20_245_000 as Weight) - // Standard Error: 21_000 - .saturating_add((7_400_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 20_000 + .saturating_add((33_383_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (20_245_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) + (21_577_000 as Weight) + // Standard Error: 27_000 + .saturating_add((33_454_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (20_230_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_439_000 as Weight).saturating_mul(r as Weight)) + (21_566_000 as Weight) + // Standard Error: 25_000 + .saturating_add((33_665_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (20_254_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_204_000 as Weight).saturating_mul(r as Weight)) + (21_524_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_351_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (20_182_000 as Weight) - // Standard Error: 22_000 - .saturating_add((7_327_000 as Weight).saturating_mul(r as Weight)) + (21_558_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_423_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (20_203_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_221_000 as Weight).saturating_mul(r as Weight)) + (21_554_000 as Weight) + // Standard Error: 17_000 + .saturating_add((33_588_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (20_187_000 as Weight) - // Standard Error: 16_000 - .saturating_add((13_738_000 as Weight).saturating_mul(r as Weight)) + (21_568_000 as Weight) + // Standard Error: 29_000 + .saturating_add((38_897_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (20_153_000 as Weight) - // Standard Error: 11_000 - .saturating_add((12_766_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 31_000 + .saturating_add((38_756_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (20_219_000 as Weight) - // Standard Error: 13_000 - .saturating_add((13_732_000 as Weight).saturating_mul(r as Weight)) + (21_540_000 as Weight) + // Standard Error: 20_000 + .saturating_add((39_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (20_246_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_686_000 as Weight).saturating_mul(r as Weight)) + (21_581_000 as Weight) + // Standard Error: 24_000 + .saturating_add((38_461_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (20_228_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_245_000 as Weight).saturating_mul(r as Weight)) + (21_555_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_367_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (20_238_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_250_000 as Weight).saturating_mul(r as Weight)) + (21_523_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_466_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (20_213_000 as Weight) - // Standard Error: 10_000 - .saturating_add((7_292_000 as Weight).saturating_mul(r as Weight)) + (21_536_000 as Weight) + // Standard Error: 34_000 + .saturating_add((33_452_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (20_224_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_554_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_809_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (20_261_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_551_000 as Weight).saturating_mul(r as Weight)) + (21_580_000 as Weight) + // Standard Error: 32_000 + .saturating_add((33_849_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (20_212_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_616_000 as Weight).saturating_mul(r as Weight)) + (21_571_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_799_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (20_176_000 as Weight) - // Standard Error: 9_000 - .saturating_add((7_877_000 as Weight).saturating_mul(r as Weight)) + (21_559_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_947_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (20_230_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) + (21_565_000 as Weight) + // Standard Error: 20_000 + .saturating_add((33_754_000 as Weight).saturating_mul(r as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { fn on_initialize() -> Weight { - (3_656_000 as Weight) + (4_636_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 3_000 - .saturating_add((2_241_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_851_000 as Weight).saturating_mul(k as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (36_820_000 as Weight) - // Standard Error: 4_000 - .saturating_add((34_550_000 as Weight).saturating_mul(q as Weight)) + (0 as Weight) + // Standard Error: 11_000 + .saturating_add((38_093_000 as Weight).saturating_mul(q as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instrument(c: u32, ) -> Weight { - (42_348_000 as Weight) - // Standard Error: 185_000 - .saturating_add((95_664_000 as Weight).saturating_mul(c as Weight)) + (60_027_000 as Weight) + // Standard Error: 109_000 + .saturating_add((169_008_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn code_load(c: u32, ) -> Weight { + (7_881_000 as Weight) + // Standard Error: 0 + .saturating_add((2_007_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } + fn code_refcount(c: u32, ) -> Weight { + (12_861_000 as Weight) + // Standard Error: 0 + .saturating_add((3_028_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (210_852_000 as Weight) - // Standard Error: 138_000 - .saturating_add((135_241_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 9_000 - .saturating_add((1_846_000 as Weight).saturating_mul(s as Weight)) + (189_624_000 as Weight) + // Standard Error: 120_000 + .saturating_add((244_984_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 7_000 + .saturating_add((1_588_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } - fn instantiate(c: u32, s: u32, ) -> Weight { - (217_380_000 as Weight) - // Standard Error: 6_000 - .saturating_add((8_483_000 as Weight).saturating_mul(c as Weight)) + fn instantiate(s: u32, ) -> Weight { + (224_867_000 as Weight) // Standard Error: 0 - .saturating_add((1_752_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((1_476_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } - fn call(c: u32, ) -> Weight { - (181_443_000 as Weight) - // Standard Error: 3_000 - .saturating_add((3_955_000 as Weight).saturating_mul(c as Weight)) + fn call() -> Weight { + (197_338_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn claim_surcharge(c: u32, ) -> Weight { - (132_551_000 as Weight) - // Standard Error: 1_000 - .saturating_add((4_740_000 as Weight).saturating_mul(c as Weight)) + (147_775_000 as Weight) + // Standard Error: 5_000 + .saturating_add((3_094_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (137_742_000 as Weight) - // Standard Error: 74_000 - .saturating_add((242_261_000 as Weight).saturating_mul(r as Weight)) + (150_159_000 as Weight) + // Standard Error: 90_000 + .saturating_add((274_529_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (137_739_000 as Weight) - // Standard Error: 91_000 - .saturating_add((241_803_000 as Weight).saturating_mul(r as Weight)) + (140_207_000 as Weight) + // Standard Error: 116_000 + .saturating_add((276_569_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (139_631_000 as Weight) - // Standard Error: 83_000 - .saturating_add((236_790_000 as Weight).saturating_mul(r as Weight)) + (156_581_000 as Weight) + // Standard Error: 107_000 + .saturating_add((270_368_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (142_506_000 as Weight) - // Standard Error: 176_000 - .saturating_add((525_752_000 as Weight).saturating_mul(r as Weight)) + (141_778_000 as Weight) + // Standard Error: 305_000 + .saturating_add((615_927_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (138_569_000 as Weight) - // Standard Error: 76_000 - .saturating_add((237_016_000 as Weight).saturating_mul(r as Weight)) + (138_752_000 as Weight) + // Standard Error: 91_000 + .saturating_add((280_176_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (134_713_000 as Weight) - // Standard Error: 81_000 - .saturating_add((237_962_000 as Weight).saturating_mul(r as Weight)) + (141_089_000 as Weight) + // Standard Error: 82_000 + .saturating_add((274_199_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (131_523_000 as Weight) - // Standard Error: 90_000 - .saturating_add((237_435_000 as Weight).saturating_mul(r as Weight)) + (140_447_000 as Weight) + // Standard Error: 119_000 + .saturating_add((270_823_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (141_574_000 as Weight) - // Standard Error: 86_000 - .saturating_add((238_102_000 as Weight).saturating_mul(r as Weight)) + (138_394_000 as Weight) + // Standard Error: 105_000 + .saturating_add((275_261_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (140_240_000 as Weight) - // Standard Error: 101_000 - .saturating_add((236_568_000 as Weight).saturating_mul(r as Weight)) + (151_633_000 as Weight) + // Standard Error: 109_000 + .saturating_add((269_666_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (138_265_000 as Weight) - // Standard Error: 91_000 - .saturating_add((237_187_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn seal_rent_params(r: u32, ) -> Weight { - (149_701_000 as Weight) - // Standard Error: 297_000 - .saturating_add((357_149_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn seal_rent_status(r: u32, ) -> Weight { - (146_863_000 as Weight) - // Standard Error: 191_000 - .saturating_add((638_683_000 as Weight).saturating_mul(r as Weight)) + (129_087_000 as Weight) + // Standard Error: 252_000 + .saturating_add((277_368_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (144_278_000 as Weight) - // Standard Error: 149_000 - .saturating_add((470_264_000 as Weight).saturating_mul(r as Weight)) + (176_205_000 as Weight) + // Standard Error: 304_000 + .saturating_add((555_094_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (111_361_000 as Weight) - // Standard Error: 157_000 - .saturating_add((118_441_000 as Weight).saturating_mul(r as Weight)) + (129_942_000 as Weight) + // Standard Error: 92_000 + .saturating_add((144_914_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (129_970_000 as Weight) - // Standard Error: 316_000 - .saturating_add((7_160_000 as Weight).saturating_mul(r as Weight)) + (141_540_000 as Weight) + // Standard Error: 68_000 + .saturating_add((6_576_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (139_275_000 as Weight) + (150_832_000 as Weight) // Standard Error: 0 - .saturating_add((250_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((263_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (119_240_000 as Weight) - // Standard Error: 57_000 - .saturating_add((4_347_000 as Weight).saturating_mul(r as Weight)) + (135_920_000 as Weight) + // Standard Error: 61_000 + .saturating_add((3_733_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (128_896_000 as Weight) - // Standard Error: 1_000 - .saturating_add((757_000 as Weight).saturating_mul(n as Weight)) + (144_104_000 as Weight) + // Standard Error: 0 + .saturating_add((640_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (130_119_000 as Weight) - // Standard Error: 108_000 - .saturating_add((95_078_000 as Weight).saturating_mul(r as Weight)) + (141_631_000 as Weight) + // Standard Error: 70_000 + .saturating_add((112_747_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } - fn seal_terminate_per_code_kb(c: u32, ) -> Weight { - (230_167_000 as Weight) - // Standard Error: 2_000 - .saturating_add((8_495_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) - .saturating_add(RocksDbWeight::get().writes(5 as Weight)) - } fn seal_restore_to(r: u32, ) -> Weight { - (159_200_000 as Weight) - // Standard Error: 261_000 - .saturating_add((103_048_000 as Weight).saturating_mul(r as Weight)) + (168_955_000 as Weight) + // Standard Error: 211_000 + .saturating_add((119_247_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } - fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { - (58_389_000 as Weight) - // Standard Error: 131_000 - .saturating_add((7_910_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 131_000 - .saturating_add((4_036_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 1_156_000 - .saturating_add((3_714_110_000 as Weight).saturating_mul(d as Weight)) + fn seal_restore_to_per_delta(d: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 3_299_000 + .saturating_add((3_257_862_000 as Weight).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (138_794_000 as Weight) - // Standard Error: 216_000 - .saturating_add((599_742_000 as Weight).saturating_mul(r as Weight)) + (124_927_000 as Weight) + // Standard Error: 407_000 + .saturating_add((730_247_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (139_890_000 as Weight) - // Standard Error: 263_000 - .saturating_add((885_805_000 as Weight).saturating_mul(r as Weight)) + (135_014_000 as Weight) + // Standard Error: 892_000 + .saturating_add((1_131_992_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_117_962_000 as Weight) - // Standard Error: 4_029_000 - .saturating_add((566_825_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 794_000 - .saturating_add((251_096_000 as Weight).saturating_mul(n as Weight)) + (1_401_344_000 as Weight) + // Standard Error: 2_961_000 + .saturating_add((701_918_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 583_000 + .saturating_add((169_206_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (132_720_000 as Weight) - // Standard Error: 87_000 - .saturating_add((164_134_000 as Weight).saturating_mul(r as Weight)) + (146_753_000 as Weight) + // Standard Error: 117_000 + .saturating_add((194_150_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_debug_message(r: u32, ) -> Weight { - (125_834_000 as Weight) - // Standard Error: 142_000 - .saturating_add((127_200_000 as Weight).saturating_mul(r as Weight)) + (141_972_000 as Weight) + // Standard Error: 114_000 + .saturating_add((164_981_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (478_734_000 as Weight) - // Standard Error: 2_559_000 - .saturating_add((3_766_445_000 as Weight).saturating_mul(r as Weight)) + (549_424_000 as Weight) + // Standard Error: 7_901_000 + .saturating_add((4_159_879_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (600_306_000 as Weight) - // Standard Error: 234_000 - .saturating_add((70_989_000 as Weight).saturating_mul(n as Weight)) + (682_814_000 as Weight) + // Standard Error: 229_000 + .saturating_add((59_572_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 2_380_000 - .saturating_add((1_242_131_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_889_000 + .saturating_add((1_563_117_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) @@ -1111,23 +1074,23 @@ impl WeightInfo for () { } fn seal_get_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_060_000 - .saturating_add((910_861_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_414_000 + .saturating_add((1_178_803_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (605_545_000 as Weight) - // Standard Error: 252_000 - .saturating_add((153_519_000 as Weight).saturating_mul(n as Weight)) + (696_056_000 as Weight) + // Standard Error: 266_000 + .saturating_add((108_870_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (36_854_000 as Weight) - // Standard Error: 2_076_000 - .saturating_add((5_183_774_000 as Weight).saturating_mul(r as Weight)) + (0 as Weight) + // Standard Error: 2_764_000 + .saturating_add((6_397_838_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) @@ -1135,358 +1098,354 @@ impl WeightInfo for () { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 6_583_000 - .saturating_add((11_599_057_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 8_279_000 + .saturating_add((13_318_274_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } - fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { - (10_431_738_000 as Weight) - // Standard Error: 301_000 - .saturating_add((392_174_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 125_400_000 - .saturating_add((3_698_896_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 39_000 - .saturating_add((60_692_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 42_000 - .saturating_add((78_872_000 as Weight).saturating_mul(o as Weight)) + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { + (13_411_599_000 as Weight) + // Standard Error: 40_931_000 + .saturating_add((4_291_567_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 14_000 + .saturating_add((48_818_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 15_000 + .saturating_add((68_502_000 as Weight).saturating_mul(o as Weight)) .saturating_add(RocksDbWeight::get().reads(205 as Weight)) .saturating_add(RocksDbWeight::get().writes(101 as Weight)) .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 32_118_000 - .saturating_add((21_117_947_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 31_671_000 + .saturating_add((24_164_540_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) .saturating_add(RocksDbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { - (8_542_521_000 as Weight) - // Standard Error: 644_000 - .saturating_add((878_020_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 91_000 - .saturating_add((63_004_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 91_000 - .saturating_add((83_203_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 91_000 - .saturating_add((240_170_000 as Weight).saturating_mul(s as Weight)) + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { + (17_228_488_000 as Weight) + // Standard Error: 26_000 + .saturating_add((50_822_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 26_000 + .saturating_add((71_276_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 26_000 + .saturating_add((198_669_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(206 as Weight)) .saturating_add(RocksDbWeight::get().writes(204 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (130_991_000 as Weight) - // Standard Error: 106_000 - .saturating_add((230_186_000 as Weight).saturating_mul(r as Weight)) + (149_183_000 as Weight) + // Standard Error: 99_000 + .saturating_add((279_233_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (508_089_000 as Weight) - // Standard Error: 38_000 - .saturating_add((491_916_000 as Weight).saturating_mul(n as Weight)) + (457_629_000 as Weight) + // Standard Error: 14_000 + .saturating_add((480_686_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (135_384_000 as Weight) - // Standard Error: 111_000 - .saturating_add((233_638_000 as Weight).saturating_mul(r as Weight)) + (141_603_000 as Weight) + // Standard Error: 120_000 + .saturating_add((283_527_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (445_961_000 as Weight) - // Standard Error: 29_000 - .saturating_add((340_992_000 as Weight).saturating_mul(n as Weight)) + (463_644_000 as Weight) + // Standard Error: 18_000 + .saturating_add((332_183_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (133_593_000 as Weight) - // Standard Error: 112_000 - .saturating_add((208_000_000 as Weight).saturating_mul(r as Weight)) + (144_145_000 as Weight) + // Standard Error: 113_000 + .saturating_add((252_640_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (444_562_000 as Weight) - // Standard Error: 27_000 - .saturating_add((159_521_000 as Weight).saturating_mul(n as Weight)) + (455_101_000 as Weight) + // Standard Error: 23_000 + .saturating_add((149_174_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (131_381_000 as Weight) - // Standard Error: 82_000 - .saturating_add((207_479_000 as Weight).saturating_mul(r as Weight)) + (147_166_000 as Weight) + // Standard Error: 233_000 + .saturating_add((254_430_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (576_129_000 as Weight) - // Standard Error: 49_000 - .saturating_add((156_900_000 as Weight).saturating_mul(n as Weight)) + (445_667_000 as Weight) + // Standard Error: 24_000 + .saturating_add((149_178_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (20_276_000 as Weight) - // Standard Error: 16_000 - .saturating_add((3_355_000 as Weight).saturating_mul(r as Weight)) + (21_505_000 as Weight) + // Standard Error: 10_000 + .saturating_add((7_963_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (22_345_000 as Weight) - // Standard Error: 18_000 - .saturating_add((133_628_000 as Weight).saturating_mul(r as Weight)) + (24_775_000 as Weight) + // Standard Error: 37_000 + .saturating_add((157_130_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (22_294_000 as Weight) - // Standard Error: 95_000 - .saturating_add((204_007_000 as Weight).saturating_mul(r as Weight)) + (24_722_000 as Weight) + // Standard Error: 69_000 + .saturating_add((240_564_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (20_266_000 as Weight) - // Standard Error: 25_000 - .saturating_add((12_605_000 as Weight).saturating_mul(r as Weight)) + (21_506_000 as Weight) + // Standard Error: 21_000 + .saturating_add((45_277_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (20_208_000 as Weight) - // Standard Error: 13_000 - .saturating_add((12_589_000 as Weight).saturating_mul(r as Weight)) + (21_587_000 as Weight) + // Standard Error: 18_000 + .saturating_add((42_269_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (20_227_000 as Weight) - // Standard Error: 18_000 - .saturating_add((6_429_000 as Weight).saturating_mul(r as Weight)) + (21_538_000 as Weight) + // Standard Error: 807_000 + .saturating_add((22_392_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (20_279_000 as Weight) - // Standard Error: 15_000 - .saturating_add((14_560_000 as Weight).saturating_mul(r as Weight)) + (21_634_000 as Weight) + // Standard Error: 57_000 + .saturating_add((44_203_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (20_210_000 as Weight) - // Standard Error: 16_000 - .saturating_add((15_613_000 as Weight).saturating_mul(r as Weight)) + (21_531_000 as Weight) + // Standard Error: 19_000 + .saturating_add((33_198_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (34_276_000 as Weight) - // Standard Error: 0 - .saturating_add((130_000 as Weight).saturating_mul(e as Weight)) + (60_960_000 as Weight) + // Standard Error: 1_000 + .saturating_add((151_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (20_426_000 as Weight) - // Standard Error: 69_000 - .saturating_add((91_850_000 as Weight).saturating_mul(r as Weight)) + (21_777_000 as Weight) + // Standard Error: 141_000 + .saturating_add((245_105_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (27_099_000 as Weight) - // Standard Error: 111_000 - .saturating_add((169_212_000 as Weight).saturating_mul(r as Weight)) + (34_307_000 as Weight) + // Standard Error: 365_000 + .saturating_add((344_623_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (206_492_000 as Weight) - // Standard Error: 4_000 - .saturating_add((4_685_000 as Weight).saturating_mul(p as Weight)) + (398_310_000 as Weight) + // Standard Error: 6_000 + .saturating_add((4_163_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (37_892_000 as Weight) - // Standard Error: 24_000 - .saturating_add((3_510_000 as Weight).saturating_mul(r as Weight)) + (40_478_000 as Weight) + // Standard Error: 19_000 + .saturating_add((9_991_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (37_773_000 as Weight) - // Standard Error: 15_000 - .saturating_add((3_814_000 as Weight).saturating_mul(r as Weight)) + (40_427_000 as Weight) + // Standard Error: 26_000 + .saturating_add((8_526_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (37_785_000 as Weight) - // Standard Error: 20_000 - .saturating_add((4_949_000 as Weight).saturating_mul(r as Weight)) + (40_463_000 as Weight) + // Standard Error: 19_000 + .saturating_add((16_497_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (23_467_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_493_000 as Weight).saturating_mul(r as Weight)) + (25_998_000 as Weight) + // Standard Error: 21_000 + .saturating_add((18_214_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (23_492_000 as Weight) - // Standard Error: 28_000 - .saturating_add((8_499_000 as Weight).saturating_mul(r as Weight)) + (25_972_000 as Weight) + // Standard Error: 42_000 + .saturating_add((18_901_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (22_347_000 as Weight) - // Standard Error: 18_000 - .saturating_add((3_565_000 as Weight).saturating_mul(r as Weight)) + (24_949_000 as Weight) + // Standard Error: 17_000 + .saturating_add((8_541_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (20_849_000 as Weight) - // Standard Error: 2_751_000 - .saturating_add((2_072_517_000 as Weight).saturating_mul(r as Weight)) + (22_204_000 as Weight) + // Standard Error: 4_776_000 + .saturating_add((2_198_462_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (20_216_000 as Weight) + (21_506_000 as Weight) // Standard Error: 18_000 - .saturating_add((5_067_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((25_302_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (20_218_000 as Weight) - // Standard Error: 11_000 - .saturating_add((5_015_000 as Weight).saturating_mul(r as Weight)) + (21_523_000 as Weight) + // Standard Error: 29_000 + .saturating_add((25_206_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (20_215_000 as Weight) - // Standard Error: 16_000 - .saturating_add((5_888_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 466_000 + .saturating_add((19_925_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (20_232_000 as Weight) - // Standard Error: 12_000 - .saturating_add((5_366_000 as Weight).saturating_mul(r as Weight)) + (21_569_000 as Weight) + // Standard Error: 30_000 + .saturating_add((25_027_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (20_205_000 as Weight) - // Standard Error: 17_000 - .saturating_add((4_847_000 as Weight).saturating_mul(r as Weight)) + (21_536_000 as Weight) + // Standard Error: 193_000 + .saturating_add((17_690_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (20_181_000 as Weight) - // Standard Error: 12_000 - .saturating_add((4_849_000 as Weight).saturating_mul(r as Weight)) + (21_555_000 as Weight) + // Standard Error: 356_000 + .saturating_add((17_105_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (20_175_000 as Weight) - // Standard Error: 18_000 - .saturating_add((4_981_000 as Weight).saturating_mul(r as Weight)) + (21_561_000 as Weight) + // Standard Error: 1_038_000 + .saturating_add((22_198_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (20_273_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) + (21_513_000 as Weight) + // Standard Error: 21_000 + .saturating_add((33_620_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (20_260_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + (21_556_000 as Weight) + // Standard Error: 17_000 + .saturating_add((33_669_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (20_248_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_363_000 as Weight).saturating_mul(r as Weight)) + (21_571_000 as Weight) + // Standard Error: 19_000 + .saturating_add((33_649_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (20_229_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_412_000 as Weight).saturating_mul(r as Weight)) + (21_533_000 as Weight) + // Standard Error: 23_000 + .saturating_add((33_450_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (20_232_000 as Weight) - // Standard Error: 9_000 - .saturating_add((7_364_000 as Weight).saturating_mul(r as Weight)) + (21_525_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_727_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (20_252_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_383_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 16_000 + .saturating_add((33_420_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (20_258_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_359_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_720_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (20_245_000 as Weight) - // Standard Error: 21_000 - .saturating_add((7_400_000 as Weight).saturating_mul(r as Weight)) + (21_546_000 as Weight) + // Standard Error: 20_000 + .saturating_add((33_383_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (20_245_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) + (21_577_000 as Weight) + // Standard Error: 27_000 + .saturating_add((33_454_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (20_230_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_439_000 as Weight).saturating_mul(r as Weight)) + (21_566_000 as Weight) + // Standard Error: 25_000 + .saturating_add((33_665_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (20_254_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_204_000 as Weight).saturating_mul(r as Weight)) + (21_524_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_351_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (20_182_000 as Weight) - // Standard Error: 22_000 - .saturating_add((7_327_000 as Weight).saturating_mul(r as Weight)) + (21_558_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_423_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (20_203_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_221_000 as Weight).saturating_mul(r as Weight)) + (21_554_000 as Weight) + // Standard Error: 17_000 + .saturating_add((33_588_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (20_187_000 as Weight) - // Standard Error: 16_000 - .saturating_add((13_738_000 as Weight).saturating_mul(r as Weight)) + (21_568_000 as Weight) + // Standard Error: 29_000 + .saturating_add((38_897_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (20_153_000 as Weight) - // Standard Error: 11_000 - .saturating_add((12_766_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 31_000 + .saturating_add((38_756_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (20_219_000 as Weight) - // Standard Error: 13_000 - .saturating_add((13_732_000 as Weight).saturating_mul(r as Weight)) + (21_540_000 as Weight) + // Standard Error: 20_000 + .saturating_add((39_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (20_246_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_686_000 as Weight).saturating_mul(r as Weight)) + (21_581_000 as Weight) + // Standard Error: 24_000 + .saturating_add((38_461_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (20_228_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_245_000 as Weight).saturating_mul(r as Weight)) + (21_555_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_367_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (20_238_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_250_000 as Weight).saturating_mul(r as Weight)) + (21_523_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_466_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (20_213_000 as Weight) - // Standard Error: 10_000 - .saturating_add((7_292_000 as Weight).saturating_mul(r as Weight)) + (21_536_000 as Weight) + // Standard Error: 34_000 + .saturating_add((33_452_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (20_224_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_554_000 as Weight).saturating_mul(r as Weight)) + (21_567_000 as Weight) + // Standard Error: 24_000 + .saturating_add((33_809_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (20_261_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_551_000 as Weight).saturating_mul(r as Weight)) + (21_580_000 as Weight) + // Standard Error: 32_000 + .saturating_add((33_849_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (20_212_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_616_000 as Weight).saturating_mul(r as Weight)) + (21_571_000 as Weight) + // Standard Error: 18_000 + .saturating_add((33_799_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (20_176_000 as Weight) - // Standard Error: 9_000 - .saturating_add((7_877_000 as Weight).saturating_mul(r as Weight)) + (21_559_000 as Weight) + // Standard Error: 22_000 + .saturating_add((33_947_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (20_230_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) + (21_565_000 as Weight) + // Standard Error: 20_000 + .saturating_add((33_754_000 as Weight).saturating_mul(r as Weight)) } } From 3dddd19155f659f98064df1bdd3eaa6c99640662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 1 Jun 2021 14:34:34 +0200 Subject: [PATCH 2/7] Remove pre charging when reading values of fixed size --- frame/contracts/src/chain_extension.rs | 21 +++--- frame/contracts/src/gas.rs | 9 --- frame/contracts/src/wasm/mod.rs | 27 ++----- frame/contracts/src/wasm/runtime.rs | 97 ++++++++++++-------------- 4 files changed, 62 insertions(+), 92 deletions(-) diff --git a/frame/contracts/src/chain_extension.rs b/frame/contracts/src/chain_extension.rs index d2839dfdbc2e1..87603592eaf06 100644 --- a/frame/contracts/src/chain_extension.rs +++ b/frame/contracts/src/chain_extension.rs @@ -59,7 +59,7 @@ use crate::{ wasm::{Runtime, RuntimeCosts}, }; use codec::Decode; -use frame_support::weights::Weight; +use frame_support::{weights::Weight, traits::MaxEncodedLen}; use sp_runtime::DispatchError; use sp_std::{ marker::PhantomData, @@ -300,18 +300,21 @@ where Ok(()) } - /// Reads `in_len` from contract memory and scale decodes it. + /// Reads and decodes a type with a size fixed at compile time from contract memory. /// /// This function is secure and recommended for all input types of fixed size /// as long as the cost of reading the memory is included in the overall already charged /// weight of the chain extension. This should usually be the case when fixed input types - /// are used. Non fixed size types (like everything using `Vec`) usually need to use - /// [`in_len()`](Self::in_len) in order to properly charge the necessary weight. - pub fn read_as(&mut self) -> Result { - self.inner.runtime.read_sandbox_memory_as( - self.inner.input_ptr, - self.inner.input_len, - ) + /// are used. + pub fn read_as(&mut self) -> Result { + self.inner.runtime.read_sandbox_memory_as(self.inner.input_ptr) + } + + /// Reads and decodes a type with a dynamic size from contract memory. + /// + /// Make sure to include `len` in your weight calculations. + pub fn read_as_unbounded(&mut self, len: u32) -> Result { + self.inner.runtime.read_sandbox_memory_as_unbounded(self.inner.input_ptr, len) } /// The length of the input as passed in as `input_len`. diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 2c19c999b56a3..34ddb3ceb0434 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -167,15 +167,6 @@ where self.gas_left = self.gas_left.saturating_add(adjustment).min(self.gas_limit); } - /// Refund previously charged gas back to the gas meter. - /// - /// This can be used if a gas worst case estimation must be charged before - /// performing a certain action. This way the difference can be refundend when - /// the worst case did not happen. - pub fn refund(&mut self, amount: ChargedAmount) { - self.gas_left = self.gas_left.saturating_add(amount.0).min(self.gas_limit) - } - /// Returns how much gas was used. pub fn gas_spent(&self) -> Weight { self.gas_limit - self.gas_left diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 0741573a7dfb6..03a409bb12fe2 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -619,7 +619,7 @@ mod tests { fn contract_call_forward_input() { const CODE: &str = r#" (module - (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") @@ -627,10 +627,8 @@ mod tests { (call $seal_call (i32.const 1) ;; Set FORWARD_INPUT bit (i32.const 4) ;; Pointer to "callee" address. - (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 36) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 44) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output @@ -681,7 +679,7 @@ mod tests { fn contract_call_clone_input() { const CODE: &str = r#" (module - (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) @@ -690,10 +688,8 @@ mod tests { (call $seal_call (i32.const 11) ;; Set FORWARD_INPUT | CLONE_INPUT | ALLOW_REENTRY bits (i32.const 4) ;; Pointer to "callee" address. - (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 36) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 44) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output @@ -744,17 +740,15 @@ mod tests { fn contract_call_tail_call() { const CODE: &str = r#" (module - (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "__unstable__" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop (call $seal_call (i32.const 5) ;; Set FORWARD_INPUT | TAIL_CALL bit (i32.const 4) ;; Pointer to "callee" address. - (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 36) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output @@ -2003,25 +1997,18 @@ mod tests { "#; #[test] - fn contract_decode_failure() { + fn contract_decode_length_ignored() { let mut mock_ext = MockExt::default(); let result = execute( CODE_DECODE_FAILURE, vec![], &mut mock_ext, ); - - assert_eq!( - result, - Err(ExecError { - error: Error::::DecodingFailed.into(), - origin: ErrorOrigin::Caller, - }) - ); + // AccountID implements `MaxEncodeLen` and therefore the supplied length is + // no longer needed nor used to determine how much is read from contract memory. + assert_ok!(result); } - - #[test] #[cfg(feature = "unstable-interface")] fn rent_params_work() { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 362d396464704..47bd3896a5b10 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -26,7 +26,7 @@ use crate::{ }; use bitflags::bitflags; use pwasm_utils::parity_wasm::elements::ValueType; -use frame_support::{dispatch::DispatchError, ensure, weights::Weight}; +use frame_support::{dispatch::DispatchError, ensure, weights::Weight, traits::MaxEncodedLen}; use sp_std::prelude::*; use codec::{Decode, DecodeAll, Encode}; use sp_core::{Bytes, crypto::UncheckedFrom}; @@ -213,8 +213,6 @@ pub enum RuntimeCosts { HashBlake128(u32), /// Weight charged by a chain extension through `seal_call_chain_extension`. ChainExtension(u64), - /// Weight charged for copying data from the sandbox. - CopyIn(u32), } impl RuntimeCosts { @@ -275,7 +273,6 @@ impl RuntimeCosts { HashBlake128(len) => s.hash_blake2_128 .saturating_add(s.hash_blake2_128_per_byte.saturating_mul(len.into())), ChainExtension(amount) => amount, - CopyIn(len) => s.return_per_byte.saturating_mul(len.into()), }; RuntimeToken { #[cfg(test)] @@ -486,6 +483,21 @@ where self.memory.get(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) } + /// Reads and decodes a type with a size fixed at compile time from contract memory. + /// + /// # Note + /// + /// The weight of reading a fixed value is included in the overall weight of any + /// contract callable function. + pub fn read_sandbox_memory_as(&self, ptr: u32) + -> Result + { + let buf = self.read_sandbox_memory(ptr, D::max_encoded_len() as u32)?; + let decoded = D::decode_all(&mut &buf[..]) + .map_err(|_| DispatchError::from(Error::::DecodingFailed))?; + Ok(decoded) + } + /// Read designated chunk from the sandbox memory and attempt to decode into the specified type. /// /// Returns `Err` if one of the following conditions occurs: @@ -495,25 +507,14 @@ where /// /// # Note /// - /// It is safe to forgo benchmarking and charging weight relative to `len` for fixed - /// size types (basically everything not containing a heap collection): - /// Despite the fact that we are usually about to read the encoding of a fixed size - /// type, we cannot know the encoded size of that type. We therefore are required to - /// use the length provided by the contract. This length is untrusted and therefore - /// we charge weight relative to the provided size upfront that covers the copy costs. - /// On success this cost is refunded as the copying was already covered in the - /// overall cost of the host function. This is different from `read_sandbox_memory` - /// where the size is dynamic and the costs resulting from that dynamic size must - /// be charged relative to this dynamic size anyways (before reading) by constructing - /// the benchmark for that. - pub fn read_sandbox_memory_as(&mut self, ptr: u32, len: u32) + /// There must be an extra benchmark for determining the influence of `len` with + /// regard to the overall weight. + pub fn read_sandbox_memory_as_unbounded(&self, ptr: u32, len: u32) -> Result { - let amount = self.charge_gas(RuntimeCosts::CopyIn(len))?; let buf = self.read_sandbox_memory(ptr, len)?; let decoded = D::decode_all(&mut &buf[..]) .map_err(|_| DispatchError::from(Error::::DecodingFailed))?; - self.ext.gas_meter().refund(amount); Ok(decoded) } @@ -550,7 +551,7 @@ where } let buf_len = buf.len() as u32; - let len: u32 = self.read_sandbox_memory_as(out_len_ptr, 4)?; + let len: u32 = self.read_sandbox_memory_as(out_len_ptr)?; if len < buf_len { Err(Error::::OutputBufferTooSmall)? @@ -650,10 +651,8 @@ where &mut self, flags: CallFlags, callee_ptr: u32, - callee_len: u32, gas: u64, value_ptr: u32, - value_len: u32, input_data_ptr: u32, input_data_len: u32, output_ptr: u32, @@ -661,8 +660,8 @@ where ) -> Result { self.charge_gas(RuntimeCosts::CallBase(input_data_len))?; let callee: <::T as frame_system::Config>::AccountId = - self.read_sandbox_memory_as(callee_ptr, callee_len)?; - let value: BalanceOf<::T> = self.read_sandbox_memory_as(value_ptr, value_len)?; + self.read_sandbox_memory_as(callee_ptr)?; + let value: BalanceOf<::T> = self.read_sandbox_memory_as(value_ptr)?; let input_data = if flags.contains(CallFlags::CLONE_INPUT) { self.input_data.as_ref().ok_or_else(|| Error::::InputForwarded)?.clone() } else if flags.contains(CallFlags::FORWARD_INPUT) { @@ -805,15 +804,15 @@ define_env!(Env, , [seal0] seal_transfer( ctx, account_ptr: u32, - account_len: u32, + _account_len: u32, value_ptr: u32, - value_len: u32 + _value_len: u32 ) -> ReturnCode => { ctx.charge_gas(RuntimeCosts::Transfer)?; let callee: <::T as frame_system::Config>::AccountId = - ctx.read_sandbox_memory_as(account_ptr, account_len)?; + ctx.read_sandbox_memory_as(account_ptr)?; let value: BalanceOf<::T> = - ctx.read_sandbox_memory_as(value_ptr, value_len)?; + ctx.read_sandbox_memory_as(value_ptr)?; let result = ctx.ext.transfer(&callee, value); match result { @@ -832,10 +831,10 @@ define_env!(Env, , [seal0] seal_call( ctx, callee_ptr: u32, - callee_len: u32, + _callee_len: u32, gas: u64, value_ptr: u32, - value_len: u32, + _value_len: u32, input_data_ptr: u32, input_data_len: u32, output_ptr: u32, @@ -844,10 +843,8 @@ define_env!(Env, , ctx.call( CallFlags::ALLOW_REENTRY, callee_ptr, - callee_len, gas, value_ptr, - value_len, input_data_ptr, input_data_len, output_ptr, @@ -866,11 +863,9 @@ define_env!(Env, , // - flags: See [`CallFlags`] for a documenation of the supported flags. // - callee_ptr: a pointer to the address of the callee contract. // Should be decodable as an `T::AccountId`. Traps otherwise. - // - callee_len: length of the address buffer. // - gas: how much gas to devote to the execution. // - value_ptr: a pointer to the buffer with value, how much value to send. // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the callee. // - input_data_len: length of the input data buffer. // - output_ptr: a pointer where the output buffer is copied to. @@ -891,10 +886,8 @@ define_env!(Env, , ctx, flags: u32, callee_ptr: u32, - callee_len: u32, gas: u64, value_ptr: u32, - value_len: u32, input_data_ptr: u32, input_data_len: u32, output_ptr: u32, @@ -903,10 +896,8 @@ define_env!(Env, , ctx.call( CallFlags::from_bits(flags).ok_or_else(|| "used rerved bit in CallFlags")?, callee_ptr, - callee_len, gas, value_ptr, - value_len, input_data_ptr, input_data_len, output_ptr, @@ -962,10 +953,10 @@ define_env!(Env, , [seal0] seal_instantiate( ctx, code_hash_ptr: u32, - code_hash_len: u32, + _code_hash_len: u32, gas: u64, value_ptr: u32, - value_len: u32, + _value_len: u32, input_data_ptr: u32, input_data_len: u32, address_ptr: u32, @@ -976,9 +967,8 @@ define_env!(Env, , salt_len: u32 ) -> ReturnCode => { ctx.charge_gas(RuntimeCosts::InstantiateBase {input_data_len, salt_len})?; - let code_hash: CodeHash<::T> = - ctx.read_sandbox_memory_as(code_hash_ptr, code_hash_len)?; - let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; + let code_hash: CodeHash<::T> = ctx.read_sandbox_memory_as(code_hash_ptr)?; + let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?; let ext = &mut ctx.ext; @@ -1015,11 +1005,11 @@ define_env!(Env, , [seal0] seal_terminate( ctx, beneficiary_ptr: u32, - beneficiary_len: u32 + _beneficiary_len: u32 ) => { ctx.charge_gas(RuntimeCosts::Terminate)?; let beneficiary: <::T as frame_system::Config>::AccountId = - ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; + ctx.read_sandbox_memory_as(beneficiary_ptr)?; ctx.ext.terminate(&beneficiary)?; Err(TrapReason::Termination) }, @@ -1302,21 +1292,21 @@ define_env!(Env, , [seal0] seal_restore_to( ctx, dest_ptr: u32, - dest_len: u32, + _dest_len: u32, code_hash_ptr: u32, - code_hash_len: u32, + _code_hash_len: u32, rent_allowance_ptr: u32, - rent_allowance_len: u32, + _rent_allowance_len: u32, delta_ptr: u32, delta_count: u32 ) => { ctx.charge_gas(RuntimeCosts::RestoreTo(delta_count))?; let dest: <::T as frame_system::Config>::AccountId = - ctx.read_sandbox_memory_as(dest_ptr, dest_len)?; + ctx.read_sandbox_memory_as(dest_ptr)?; let code_hash: CodeHash<::T> = - ctx.read_sandbox_memory_as(code_hash_ptr, code_hash_len)?; + ctx.read_sandbox_memory_as(code_hash_ptr)?; let rent_allowance: BalanceOf<::T> = - ctx.read_sandbox_memory_as(rent_allowance_ptr, rent_allowance_len)?; + ctx.read_sandbox_memory_as(rent_allowance_ptr)?; let delta = { const KEY_SIZE: usize = 32; @@ -1389,7 +1379,7 @@ define_env!(Env, , let mut topics: Vec::::T>> = match topics_len { 0 => Vec::new(), - _ => ctx.read_sandbox_memory_as(topics_ptr, topics_len)?, + _ => ctx.read_sandbox_memory_as_unbounded(topics_ptr, topics_len)?, }; // If there are more than `event_topics`, then trap. @@ -1416,10 +1406,9 @@ define_env!(Env, , // - value_ptr: a pointer to the buffer with value, how much to allow for rent // Should be decodable as a `T::Balance`. Traps otherwise. // - value_len: length of the value buffer. - [seal0] seal_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => { + [seal0] seal_set_rent_allowance(ctx, value_ptr: u32, _value_len: u32) => { ctx.charge_gas(RuntimeCosts::SetRentAllowance)?; - let value: BalanceOf<::T> = - ctx.read_sandbox_memory_as(value_ptr, value_len)?; + let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; ctx.ext.set_rent_allowance(value); Ok(()) From 4e3f371c7bae758459aa19cef33c6387c21f015b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 2 Jun 2021 11:51:41 +0200 Subject: [PATCH 3/7] Add new versions of API functions that leave out parameters --- .../fixtures/instantiate_return_code.wat | 6 +- frame/contracts/fixtures/restoration.wat | 13 +- frame/contracts/src/wasm/runtime.rs | 289 +++++++++++++----- 3 files changed, 221 insertions(+), 87 deletions(-) diff --git a/frame/contracts/fixtures/instantiate_return_code.wat b/frame/contracts/fixtures/instantiate_return_code.wat index 544489329cfad..6a8654520f106 100644 --- a/frame/contracts/fixtures/instantiate_return_code.wat +++ b/frame/contracts/fixtures/instantiate_return_code.wat @@ -4,8 +4,8 @@ ;; The rest of the input is forwarded to the constructor of the callee (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_instantiate" (func $seal_instantiate - (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + (import "seal1" "seal_instantiate" (func $seal_instantiate + (param i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) )) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) @@ -29,10 +29,8 @@ (i32.const 8) (call $seal_instantiate (i32.const 16) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 48) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy address diff --git a/frame/contracts/fixtures/restoration.wat b/frame/contracts/fixtures/restoration.wat index 3462af2870816..e24e5695a3568 100644 --- a/frame/contracts/fixtures/restoration.wat +++ b/frame/contracts/fixtures/restoration.wat @@ -1,9 +1,9 @@ (module (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_restore_to" + (import "seal1" "seal_restore_to" (func $seal_restore_to - (param i32 i32 i32 i32 i32 i32 i32 i32) + (param i32 i32 i32 i32 i32) ) ) (import "env" "memory" (memory 1 1)) @@ -27,15 +27,12 @@ ) ) (call $seal_restore_to - ;; Pointer and length of the encoded dest buffer. + ;; Pointer to the encoded dest buffer. (i32.const 340) - (i32.const 32) - ;; Pointer and length of the encoded code hash buffer + ;; Pointer to the encoded code hash buffer (i32.const 308) - (i32.const 32) - ;; Pointer and length of the encoded rent_allowance buffer + ;; Pointer to the encoded rent_allowance buffer (i32.const 296) - (i32.const 8) ;; Pointer and number of items in the delta buffer. ;; This buffer specifies multiple keys for removal before restoration. (i32.const 100) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 47bd3896a5b10..b92a0dab507bf 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -657,7 +657,8 @@ where input_data_len: u32, output_ptr: u32, output_len_ptr: u32 - ) -> Result { + ) -> Result + { self.charge_gas(RuntimeCosts::CallBase(input_data_len))?; let callee: <::T as frame_system::Config>::AccountId = self.read_sandbox_memory_as(callee_ptr)?; @@ -695,6 +696,92 @@ where } Ok(Runtime::::exec_into_return_code(call_outcome)?) } + + fn instantiate( + &mut self, + code_hash_ptr: u32, + gas: u64, + value_ptr: u32, + input_data_ptr: u32, + input_data_len: u32, + address_ptr: u32, + address_len_ptr: u32, + output_ptr: u32, + output_len_ptr: u32, + salt_ptr: u32, + salt_len: u32 + ) -> Result + { + self.charge_gas(RuntimeCosts::InstantiateBase {input_data_len, salt_len})?; + let code_hash: CodeHash<::T> = self.read_sandbox_memory_as(code_hash_ptr)?; + let value: BalanceOf<::T> = self.read_sandbox_memory_as(value_ptr)?; + let input_data = self.read_sandbox_memory(input_data_ptr, input_data_len)?; + let salt = self.read_sandbox_memory(salt_ptr, salt_len)?; + let instantiate_outcome = self.ext.instantiate(gas, code_hash, value, input_data, &salt); + if let Ok((address, output)) = &instantiate_outcome { + if !output.flags.contains(ReturnFlags::REVERT) { + self.write_sandbox_output( + address_ptr, address_len_ptr, &address.encode(), true, already_charged, + )?; + } + self.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { + Some(RuntimeCosts::InstantiateCopyOut(len)) + })?; + } + Ok(Runtime::::exec_into_return_code(instantiate_outcome.map(|(_, retval)| retval))?) + } + + fn terminate(&mut self, beneficiary_ptr: u32) -> Result<(), TrapReason> { + self.charge_gas(RuntimeCosts::Terminate)?; + let beneficiary: <::T as frame_system::Config>::AccountId = + self.read_sandbox_memory_as(beneficiary_ptr)?; + self.ext.terminate(&beneficiary)?; + Err(TrapReason::Termination) + } + + fn restore_to( + &mut self, + dest_ptr: u32, + code_hash_ptr: u32, + rent_allowance_ptr: u32, + delta_ptr: u32, + delta_count: u32 + ) -> Result<(), TrapReason> { + self.charge_gas(RuntimeCosts::RestoreTo(delta_count))?; + let dest: <::T as frame_system::Config>::AccountId = + self.read_sandbox_memory_as(dest_ptr)?; + let code_hash: CodeHash<::T> = + self.read_sandbox_memory_as(code_hash_ptr)?; + let rent_allowance: BalanceOf<::T> = + self.read_sandbox_memory_as(rent_allowance_ptr)?; + let delta = { + const KEY_SIZE: usize = 32; + + // We can eagerly allocate because we charged for the complete delta count already + // We still need to make sure that the allocation isn't larger than the memory + // allocator can handle. + let max_memory = self.ext.schedule().limits.max_memory_size(); + ensure!( + delta_count.saturating_mul(KEY_SIZE as u32) <= max_memory, + Error::::OutOfBounds, + ); + let mut delta = vec![[0; KEY_SIZE]; delta_count as usize]; + let mut key_ptr = delta_ptr; + + for i in 0..delta_count { + // Read the delta into the provided buffer + // This cannot panic because of the loop condition + self.read_sandbox_memory_into_buf(key_ptr, &mut delta[i as usize])?; + + // Offset key_ptr to the next element. + key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or(Error::::OutOfBounds)?; + } + + delta + }; + self.ext.restore_to(dest, code_hash, rent_allowance, delta)?; + Err(TrapReason::Restoration) + } } // *********************************************************** @@ -826,8 +913,16 @@ define_env!(Env, , // Make a call to another contract. // + // # Deprecation + // // This is equivalent to calling the newer version of this function with // `flags` set to `ALLOW_REENTRY`. See the newer version for documentation. + // + // # Note + // + // The values `_callee_len` and `_value_len` are ignored because the encoded sizes + // of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards + // compatibility. Consider switching to the newest version of this function. [seal0] seal_call( ctx, callee_ptr: u32, @@ -905,6 +1000,49 @@ define_env!(Env, , ) }, + // Instantiate a contract with the specified code hash. + // + // # Deprecation + // + // This is equivalent to calling the newer version of this function. The newer version + // drops the now unnecessary length fields. + // + // # Note + // + // The values `_code_hash_len` and `_value_len` are ignored because the encoded sizes + // of those types are fixed through `[`MaxEncodedLen`]. The fields exist for backwards + // compatibility. Consider switching to the newest version of this function. + [seal0] seal_instantiate( + ctx, + code_hash_ptr: u32, + _code_hash_len: u32, + gas: u64, + value_ptr: u32, + _value_len: u32, + input_data_ptr: u32, + input_data_len: u32, + address_ptr: u32, + address_len_ptr: u32, + output_ptr: u32, + output_len_ptr: u32, + salt_ptr: u32, + salt_len: u32 + ) -> ReturnCode => { + ctx.instantiate ( + code_hash_ptr, + gas, + value_ptr, + input_data_ptr, + input_data_len, + address_ptr, + address_len_ptr, + output_ptr, + output_len_ptr, + salt_ptr, + salt_len, + ) + }, + // Instantiate a contract with the specified code hash. // // This function creates an account and executes the constructor defined in the code specified @@ -920,11 +1058,9 @@ define_env!(Env, , // # Parameters // // - code_hash_ptr: a pointer to the buffer that contains the initializer code. - // - code_hash_len: length of the initializer code buffer. // - gas: how much gas to devote to the execution of the initializer code. // - value_ptr: a pointer to the buffer with value, how much value to send. // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code. // - input_data_len: length of the input data buffer. // - address_ptr: a pointer where the new account's address is copied to. @@ -950,13 +1086,11 @@ define_env!(Env, , // `ReturnCode::TransferFailed` // `ReturnCode::NewContractNotFunded` // `ReturnCode::CodeNotFound` - [seal0] seal_instantiate( + [seal1] seal_instantiate( ctx, code_hash_ptr: u32, - _code_hash_len: u32, gas: u64, value_ptr: u32, - _value_len: u32, input_data_ptr: u32, input_data_len: u32, address_ptr: u32, @@ -966,24 +1100,35 @@ define_env!(Env, , salt_ptr: u32, salt_len: u32 ) -> ReturnCode => { - ctx.charge_gas(RuntimeCosts::InstantiateBase {input_data_len, salt_len})?; - let code_hash: CodeHash<::T> = ctx.read_sandbox_memory_as(code_hash_ptr)?; - let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; - let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; - let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?; - let ext = &mut ctx.ext; - let instantiate_outcome = ext.instantiate(gas, code_hash, value, input_data, &salt); - if let Ok((address, output)) = &instantiate_outcome { - if !output.flags.contains(ReturnFlags::REVERT) { - ctx.write_sandbox_output( - address_ptr, address_len_ptr, &address.encode(), true, already_charged, - )?; - } - ctx.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { - Some(RuntimeCosts::InstantiateCopyOut(len)) - })?; - } - Ok(Runtime::::exec_into_return_code(instantiate_outcome.map(|(_, retval)| retval))?) + ctx.instantiate( + code_hash_ptr, + gas, + value_ptr, + input_data_ptr, + input_data_len, + address_ptr, + address_len_ptr, + output_ptr, + output_len_ptr, + salt_ptr, + salt_len, + ) + }, + + // Remove the calling account and transfer remaining balance. + // + // # Deprecation + // + // This is equivalent to calling the newer version of this function. The newer version + // drops the now unnecessary length fields. + // + // # Note + // + // The value `_beneficiary_len` is ignored because the encoded sizes + // this type is fixed through `[`MaxEncodedLen`]. The field exist for backwards + // compatibility. Consider switching to the newest version of this function. + [seal0] seal_terminate(ctx, beneficiary_ptr: u32, _beneficiary_len: u32) => { + ctx.terminate(beneficiary_ptr) }, // Remove the calling account and transfer remaining balance. @@ -1002,16 +1147,8 @@ define_env!(Env, , // - The contract is live i.e is already on the call stack. // - Failed to send the balance to the beneficiary. // - The deletion queue is full. - [seal0] seal_terminate( - ctx, - beneficiary_ptr: u32, - _beneficiary_len: u32 - ) => { - ctx.charge_gas(RuntimeCosts::Terminate)?; - let beneficiary: <::T as frame_system::Config>::AccountId = - ctx.read_sandbox_memory_as(beneficiary_ptr)?; - ctx.ext.terminate(&beneficiary)?; - Err(TrapReason::Termination) + [seal1] seal_terminate(ctx, beneficiary_ptr: u32) => { + ctx.terminate(beneficiary_ptr) }, // Stores the input passed by the caller into the supplied buffer. @@ -1258,6 +1395,38 @@ define_env!(Env, , )?) }, + // Try to restore the given destination contract sacrificing the caller. + // + // # Deprecation + // + // This is equivalent to calling the newer version of this function. The newer version + // drops the now unnecessary length fields. + // + // # Note + // + // The values `_dest_len`, `_code_hash_len` and `_rent_allowance_len` are ignored because + // the encoded sizes of those types are fixed through `[`MaxEncodedLen`]. The fields + // exist for backwards compatibility. Consider switching to the newest version of this function. + [seal0] seal_restore_to( + ctx, + dest_ptr: u32, + _dest_len: u32, + code_hash_ptr: u32, + _code_hash_len: u32, + rent_allowance_ptr: u32, + _rent_allowance_len: u32, + delta_ptr: u32, + delta_count: u32 + ) => { + ctx.restore_to( + dest_ptr, + code_hash_ptr, + rent_allowance_ptr, + delta_ptr, + delta_count, + ) + }, + // Try to restore the given destination contract sacrificing the caller. // // This function will compute a tombstone hash from the caller's storage and the given code hash @@ -1274,11 +1443,11 @@ define_env!(Env, , // On success, the destination contract is restored. This function is diverging and // stops execution even on success. // - // - `dest_ptr`, `dest_len` - the pointer and the length of a buffer that encodes `T::AccountId` + // - `dest_ptr` - the pointer to a buffer that encodes `T::AccountId` // with the address of the to be restored contract. - // - `code_hash_ptr`, `code_hash_len` - the pointer and the length of a buffer that encodes + // - `code_hash_ptr` - the pointer to a buffer that encodes // a code hash of the to be restored contract. - // - `rent_allowance_ptr`, `rent_allowance_len` - the pointer and the length of a buffer that + // - `rent_allowance_ptr` - the pointer to a buffer that // encodes the rent allowance that must be set in the case of successful restoration. // - `delta_ptr` is the pointer to the start of a buffer that has `delta_count` storage keys // laid out sequentially. @@ -1289,51 +1458,21 @@ define_env!(Env, , // - Tombstone hashes do not match. // - The calling contract is already present on the call stack. // - The supplied code_hash does not exist on-chain. - [seal0] seal_restore_to( + [seal1] seal_restore_to( ctx, dest_ptr: u32, - _dest_len: u32, code_hash_ptr: u32, - _code_hash_len: u32, rent_allowance_ptr: u32, - _rent_allowance_len: u32, delta_ptr: u32, delta_count: u32 ) => { - ctx.charge_gas(RuntimeCosts::RestoreTo(delta_count))?; - let dest: <::T as frame_system::Config>::AccountId = - ctx.read_sandbox_memory_as(dest_ptr)?; - let code_hash: CodeHash<::T> = - ctx.read_sandbox_memory_as(code_hash_ptr)?; - let rent_allowance: BalanceOf<::T> = - ctx.read_sandbox_memory_as(rent_allowance_ptr)?; - let delta = { - const KEY_SIZE: usize = 32; - - // We can eagerly allocate because we charged for the complete delta count already - // We still need to make sure that the allocation isn't larger than the memory - // allocator can handle. - ensure!( - delta_count - .saturating_mul(KEY_SIZE as u32) <= ctx.ext.schedule().limits.max_memory_size(), - Error::::OutOfBounds, - ); - let mut delta = vec![[0; KEY_SIZE]; delta_count as usize]; - let mut key_ptr = delta_ptr; - - for i in 0..delta_count { - // Read the delta into the provided buffer - // This cannot panic because of the loop condition - ctx.read_sandbox_memory_into_buf(key_ptr, &mut delta[i as usize])?; - - // Offset key_ptr to the next element. - key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or(Error::::OutOfBounds)?; - } - - delta - }; - ctx.ext.restore_to(dest, code_hash, rent_allowance, delta)?; - Err(TrapReason::Restoration) + ctx.restore_to( + dest_ptr, + code_hash_ptr, + rent_allowance_ptr, + delta_ptr, + delta_count, + ) }, // Deposit a contract event with the data buffer and optional list of topics. There is a limit From 57a9746b6a693e649156c7c582cf978eb0f6b26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 4 Jun 2021 10:33:20 +0200 Subject: [PATCH 4/7] Update CHANGELOG.md --- frame/contracts/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frame/contracts/CHANGELOG.md b/frame/contracts/CHANGELOG.md index dd679f432d314..03945d7b2e346 100644 --- a/frame/contracts/CHANGELOG.md +++ b/frame/contracts/CHANGELOG.md @@ -42,6 +42,11 @@ output to an RPC client. - Make storage and fields of `Schedule` private to the crate. [#8359](https://github.com/paritytech/substrate/pull/8359) +### Fixed + +- Remove pre-charging which caused wrongly estimated weights +[#8976](https://github.com/paritytech/substrate/pull/8976) + ## [v3.0.0] 2021-02-25 This version constitutes the first release that brings any stability guarantees (see above). From 7ddf9b60049bdf98c2ad7b7cd391ad8666d26b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 21 Jun 2021 11:46:20 +0200 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: Alexander Popiak --- frame/contracts/src/exec.rs | 2 +- frame/contracts/src/wasm/code_cache.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index abe0a07959e76..2b595ea6ce8d4 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -334,7 +334,7 @@ pub trait Executable: Sized { /// /// # Note /// - /// Does not charge from the gas meter. Do not in contexts where this is important. + /// Does not charge from the gas meter. Do not call in contexts where this is important. fn from_storage_noinstr(code_hash: CodeHash) -> Result; /// Decrements the refcount by one and deletes the code if it drops to zero. diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index e80df31a68969..a2aa2b55e1657 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -240,9 +240,9 @@ where // the contract. match *self { Instrument(len) => T::WeightInfo::instrument(len / 1024), - Load(len) => T::WeightInfo::code_load(len / 1024) - T::WeightInfo::code_load(0), + Load(len) => T::WeightInfo::code_load(len / 1024).saturating_sub(T::WeightInfo::code_load(0)), UpdateRefcount(len) => - T::WeightInfo::code_refcount(len / 1024) - T::WeightInfo::code_refcount(0), + T::WeightInfo::code_refcount(len / 1024).saturating_sub(T::WeightInfo::code_refcount(0)), } } } From 743667a7c1cc8407e91ec8bcf396a1aaa91f5a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 21 Jun 2021 11:56:23 +0200 Subject: [PATCH 6/7] Add v1 for seal_set_rent_allowance --- frame/contracts/src/wasm/runtime.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index b92a0dab507bf..09cc64c60c392 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -1140,7 +1140,6 @@ define_env!(Env, , // - beneficiary_ptr: a pointer to the address of the beneficiary account where all // where all remaining funds of the caller are transferred. // Should be decodable as an `T::AccountId`. Traps otherwise. - // - beneficiary_len: length of the address buffer. // // # Traps // @@ -1540,16 +1539,33 @@ define_env!(Env, , Ok(()) }, - // Set rent allowance of the contract + // Set rent allowance of the contract. // - // - value_ptr: a pointer to the buffer with value, how much to allow for rent - // Should be decodable as a `T::Balance`. Traps otherwise. - // - value_len: length of the value buffer. + // # Deprecation + // + // This is equivalent to calling the newer version of this function. The newer version + // drops the now unnecessary length fields. + // + // # Note + // + // The value `_VALUE_len` is ignored because the encoded sizes + // this type is fixed through `[`MaxEncodedLen`]. The field exist for backwards + // compatibility. Consider switching to the newest version of this function. [seal0] seal_set_rent_allowance(ctx, value_ptr: u32, _value_len: u32) => { ctx.charge_gas(RuntimeCosts::SetRentAllowance)?; let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; ctx.ext.set_rent_allowance(value); + Ok(()) + }, + // Set rent allowance of the contract. + // + // - value_ptr: a pointer to the buffer with value, how much to allow for rent + // Should be decodable as a `T::Balance`. Traps otherwise. + [seal1] seal_set_rent_allowance(ctx, value_ptr: u32) => { + ctx.charge_gas(RuntimeCosts::SetRentAllowance)?; + let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; + ctx.ext.set_rent_allowance(value); Ok(()) }, From 631ceb4d9bc68b08c7bb5cb9224492ddc4e524ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 25 Jun 2021 16:52:30 +0200 Subject: [PATCH 7/7] Remove unneeded trait bound Co-authored-by: Guillaume Thiolliere --- frame/contracts/src/chain_extension.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/contracts/src/chain_extension.rs b/frame/contracts/src/chain_extension.rs index 87603592eaf06..a6441f4aae15d 100644 --- a/frame/contracts/src/chain_extension.rs +++ b/frame/contracts/src/chain_extension.rs @@ -313,7 +313,7 @@ where /// Reads and decodes a type with a dynamic size from contract memory. /// /// Make sure to include `len` in your weight calculations. - pub fn read_as_unbounded(&mut self, len: u32) -> Result { + pub fn read_as_unbounded(&mut self, len: u32) -> Result { self.inner.runtime.read_sandbox_memory_as_unbounded(self.inner.input_ptr, len) }