diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index fb2b189e2d379..b52b24ed01bc7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -112,8 +112,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 264, - impl_version: 1, + spec_version: 265, + impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, }; @@ -735,6 +735,7 @@ parameter_types! { ::WeightInfo::on_initialize_per_queue_item(1) - ::WeightInfo::on_initialize_per_queue_item(0) )) / 5) as u32; + pub MaxCodeSize: u32 = 128 * 1024; } impl pallet_contracts::Config for Runtime { @@ -757,6 +758,7 @@ impl pallet_contracts::Config for Runtime { type ChainExtension = (); type DeletionQueueDepth = DeletionQueueDepth; type DeletionWeightLimit = DeletionWeightLimit; + type MaxCodeSize = MaxCodeSize; } impl pallet_sudo::Config for Runtime { diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index 01ca7d3aac22d..64d2a0cf011d9 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -27,12 +27,14 @@ use crate::Config; use crate::Module as Contracts; -use parity_wasm::elements::{Instruction, Instructions, FuncBody, ValueType, BlockType}; +use parity_wasm::elements::{ + Instruction, Instructions, FuncBody, ValueType, BlockType, Section, CustomSection, +}; use pwasm_utils::stack_height::inject_limiter; use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::Hash; use sp_sandbox::{EnvironmentDefinitionBuilder, Memory}; -use sp_std::{prelude::*, convert::TryFrom}; +use sp_std::{prelude::*, convert::TryFrom, borrow::ToOwned}; /// Pass to `create_code` in order to create a compiled `WasmModule`. /// @@ -66,6 +68,10 @@ pub struct ModuleDefinition { pub inject_stack_metering: bool, /// Create a table containing function pointers. pub table: Option, + /// Create a section named "dummy" of the specified size. This is useful in order to + /// benchmark the overhead of loading and storing codes of specified sizes. The dummy + /// section only contributes to the size of the contract but does not affect execution. + pub dummy_section: u32, } pub struct TableSegment { @@ -204,6 +210,15 @@ where .build(); } + // Add the dummy section + if def.dummy_section > 0 { + contract = contract.with_section( + Section::Custom( + CustomSection::new("dummy".to_owned(), vec![42; def.dummy_section as usize]) + ) + ); + } + let mut code = contract.build(); // Inject stack height metering @@ -235,10 +250,11 @@ where ModuleDefinition::default().into() } - /// Same as `dummy` but with maximum sized linear memory. - pub fn dummy_with_mem() -> Self { + /// 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 { ModuleDefinition { memory: Some(ImportedMemory::max::()), + dummy_section: dummy_bytes, .. Default::default() } .into() diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index f982316e98b94..b6ff4c04ff7ec 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -304,6 +304,19 @@ benchmarks! { Storage::::process_deletion_queue_batch(Weight::max_value()) } + // This benchmarks the additional weight that is charged when a contract is executed the + // first time after a new schedule was deployed: For every new schedule a contract needs + // to re-run the instrumentation once. + instrument { + let c in 0 .. T::MaxCodeSize::get() / 1024; + let WasmModule { code, hash, .. } = WasmModule::::sized(c * 1024); + Contracts::::store_code_raw(code)?; + let mut module = PrefabWasmModule::from_storage_noinstr(hash)?; + let schedule = Contracts::::current_schedule(); + }: { + Contracts::::reinstrument_module(&mut module, &schedule)?; + } + // This extrinsic is pretty much constant as it is only a simple setter. update_schedule { let schedule = Schedule { @@ -318,8 +331,13 @@ benchmarks! { // determine the contract address. // `c`: Size of the code in kilobytes. // `s`: Size of the salt in kilobytes. + // + // # Note + // + // We cannot let `c` grow to the maximum code size because the code is not allowed + // to be larger than the maximum size **after instrumentation**. instantiate_with_code { - let c in 0 .. Contracts::::current_schedule().limits.code_size / 1024; + let c in 0 .. Perbill::from_percent(50).mul_ceil(T::MaxCodeSize::get() / 1024); let s in 0 .. code::max_pages::() * 64; let salt = vec![42u8; (s * 1024) as usize]; let endowment = caller_funding::() / 3u32.into(); @@ -339,14 +357,16 @@ 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::MaxCodeSize::get() / 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_mem(); + let WasmModule { code, hash, .. } = WasmModule::::dummy_with_bytes(c * 1024); let origin = RawOrigin::Signed(caller.clone()); let addr = Contracts::::contract_address(&caller, &hash, &salt); Contracts::::store_code_raw(code)?; @@ -365,10 +385,12 @@ 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::MaxCodeSize::get() / 1024; let data = vec![42u8; 1024]; let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::dummy_with_mem(), vec![], Endow::CollectRent + whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent )?; let value = T::Currency::minimum_balance() * 100u32.into(); let origin = RawOrigin::Signed(instance.caller.clone()); @@ -396,9 +418,11 @@ benchmarks! { // will be distributed over multiple blocks using a scheduler. Otherwise there is // no incentive to remove large contracts when the removal is more expensive than // the reward for removing them. + // `c`: Size of the code of the contract that should be evicted. claim_surcharge { + let c in 0 .. T::MaxCodeSize::get() / 1024; let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::dummy(), vec![], Endow::CollectRent + whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent )?; let origin = RawOrigin::Signed(instance.caller.clone()); let account_id = instance.account_id.clone(); @@ -694,6 +718,42 @@ benchmarks! { } } + seal_terminate_per_code_kb { + let c in 0 .. T::MaxCodeSize::get() / 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 { + 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; @@ -772,9 +832,16 @@ benchmarks! { } } - seal_restore_to_per_delta { + // `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::MaxCodeSize::get() / 1024; + let t in 0 .. T::MaxCodeSize::get() / 1024; let d in 0 .. API_BENCHMARK_BATCHES; - let mut tombstone = ContractWithStorage::::new(0, 0)?; + let mut tombstone = ContractWithStorage::::with_code( + WasmModule::::dummy_with_bytes(t * 1024), 0, 0 + )?; tombstone.evict()?; let delta = create_storage::(d * API_BENCHMARK_BATCH_SIZE, T::MaxValueSize::get())?; @@ -837,6 +904,7 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), + dummy_section: c * 1024, .. Default::default() }); @@ -1225,7 +1293,7 @@ benchmarks! { // We call unique accounts. seal_call { let r in 0 .. API_BENCHMARK_BATCHES; - let dummy_code = WasmModule::::dummy_with_mem(); + let dummy_code = WasmModule::::dummy_with_bytes(0); let callees = (0..r * API_BENCHMARK_BATCH_SIZE) .map(|i| Contract::with_index(i + 1, dummy_code.clone(), vec![], Endow::Max)) .collect::, _>>()?; @@ -1280,7 +1348,8 @@ benchmarks! { let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - seal_call_per_transfer_input_output_kb { + seal_call_per_code_transfer_input_output_kb { + let c in 0 .. T::MaxCodeSize::get() / 1024; let t in 0 .. 1; let i in 0 .. code::max_pages::() * 64; let o in 0 .. (code::max_pages::() - 1) * 64; @@ -1302,6 +1371,7 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), + dummy_section: c * 1024, .. Default::default() }); let callees = (0..API_BENCHMARK_BATCH_SIZE) @@ -1475,7 +1545,8 @@ benchmarks! { } } - seal_instantiate_per_input_output_salt_kb { + seal_instantiate_per_code_input_output_salt_kb { + let c in 0 .. T::MaxCodeSize::get() / 1024; 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; @@ -1497,6 +1568,7 @@ benchmarks! { Instruction::Call(0), Instruction::End, ])), + dummy_section: c * 1024, .. Default::default() }); let hash = callee_code.hash.clone(); @@ -2440,8 +2512,6 @@ benchmarks! { }: {} } - - impl_benchmark_test_suite!( Contracts, crate::tests::ExtBuilder::default().build(), diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index bbb972b2ed2e2..bf9efddc6166f 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -72,8 +72,13 @@ pub trait Ext { /// Instantiate a contract from the given code. /// + /// Returns the original code size of the called contract. /// The newly created account will be associated with `code`. `value` specifies the amount of value /// transferred from this to the newly created account (also known as endowment). + /// + /// # Return Value + /// + /// Result<(AccountId, ExecReturnValue, CodeSize), (ExecError, CodeSize)> fn instantiate( &mut self, code: CodeHash, @@ -81,7 +86,7 @@ pub trait Ext { gas_meter: &mut GasMeter, input_data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError>; + ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)>; /// Transfer some amount of funds into the specified account. fn transfer( @@ -92,24 +97,35 @@ pub trait Ext { /// 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, - ) -> DispatchResult; + ) -> Result; /// Call (possibly transferring some amount of funds) into the specified account. + /// + /// Returns the original code size of the called contract. + /// + /// # Return Value + /// + /// Result<(ExecReturnValue, CodeSize), (ExecError, CodeSize)> fn call( &mut self, to: &AccountIdOf, value: BalanceOf, gas_meter: &mut GasMeter, input_data: Vec, - ) -> ExecResult; + ) -> Result<(ExecReturnValue, u32), (ExecError, u32)>; /// Restores the given destination contract sacrificing the current one. /// @@ -118,13 +134,17 @@ pub trait Ext { /// /// This function will fail if the same contract is present /// on the contract call stack. + /// + /// # Return Value + /// + /// Result<(CallerCodeSize, DestCodeSize), (DispatchError, CallerCodeSize, DestCodesize)> fn restore_to( &mut self, dest: AccountIdOf, code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> DispatchResult; + ) -> Result<(u32, u32), (DispatchError, u32, u32)>; /// Returns a reference to the account id of the caller. fn caller(&self) -> &AccountIdOf; @@ -190,7 +210,11 @@ pub enum ExportedFunction { /// order to be able to mock the wasm logic for testing. pub trait Executable: Sized { /// Load the executable from storage. - fn from_storage(code_hash: CodeHash, schedule: &Schedule) -> Result; + fn from_storage( + code_hash: CodeHash, + schedule: &Schedule, + gas_meter: &mut GasMeter, + ) -> Result; /// Load the module from storage without re-instrumenting it. /// @@ -203,10 +227,14 @@ pub trait Executable: Sized { fn drop_from_storage(self); /// Increment the refcount by one. Fails if the code does not exist on-chain. - fn add_user(code_hash: CodeHash) -> DispatchResult; + /// + /// Returns the size of the original code. + fn add_user(code_hash: CodeHash) -> Result; /// Decrement the refcount by one and remove the code when it drops to zero. - fn remove_user(code_hash: CodeHash); + /// + /// Returns the size of the original code. + fn remove_user(code_hash: CodeHash) -> u32; /// Execute the specified exported function and return the result. /// @@ -238,6 +266,9 @@ pub trait Executable: Sized { /// without refetching this from storage the result can be inaccurate as it might be /// working with a stale value. Usually this inaccuracy is tolerable. fn occupied_storage(&self) -> u32; + + /// Size of the instrumented code in bytes. + fn code_len(&self) -> u32; } pub struct ExecutionContext<'a, T: Config + 'a, E> { @@ -290,35 +321,42 @@ where } /// Make a call to the specified address, optionally transferring some funds. + /// + /// # Return Value + /// + /// Result<(ExecReturnValue, CodeSize), (ExecError, CodeSize)> pub fn call( &mut self, dest: T::AccountId, value: BalanceOf, gas_meter: &mut GasMeter, input_data: Vec, - ) -> ExecResult { + ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { if self.depth == T::MaxDepth::get() as usize { - Err(Error::::MaxCallDepthReached)? + return Err((Error::::MaxCallDepthReached.into(), 0)); } let contract = >::get(&dest) .and_then(|contract| contract.get_alive()) - .ok_or(Error::::NotCallable)?; + .ok_or((Error::::NotCallable.into(), 0))?; - let executable = E::from_storage(contract.code_hash, &self.schedule)?; + let executable = E::from_storage(contract.code_hash, &self.schedule, gas_meter) + .map_err(|e| (e.into(), 0))?; + let code_len = executable.code_len(); // 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 // changes would be rolled back in case this contract is called by another // contract. // See: https://github.com/paritytech/substrate/issues/6439#issuecomment-648754324 - let contract = Rent::::charge(&dest, contract, executable.occupied_storage())? - .ok_or(Error::::NotCallable)?; + let contract = Rent::::charge(&dest, contract, executable.occupied_storage()) + .map_err(|e| (e.into(), code_len))? + .ok_or((Error::::NotCallable.into(), code_len))?; let transactor_kind = self.transactor_kind(); let caller = self.self_account.clone(); - self.with_nested_context(dest.clone(), contract.trie_id.clone(), |nested| { + let result = self.with_nested_context(dest.clone(), contract.trie_id.clone(), |nested| { if value > BalanceOf::::zero() { transfer::( TransferCause::Call, @@ -336,7 +374,8 @@ where gas_meter, ).map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; Ok(output) - }) + }).map_err(|e| (e, code_len))?; + Ok((result, code_len)) } pub fn instantiate( @@ -581,10 +620,13 @@ where gas_meter: &mut GasMeter, input_data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { - let executable = E::from_storage(code_hash, &self.ctx.schedule)?; - let result = self.ctx.instantiate(endowment, gas_meter, executable, input_data, salt)?; - Ok(result) + ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)> { + let executable = E::from_storage(code_hash, &self.ctx.schedule, gas_meter) + .map_err(|e| (e.into(), 0))?; + let code_len = executable.code_len(); + self.ctx.instantiate(endowment, gas_meter, executable, input_data, salt) + .map(|r| (r.0, r.1, code_len)) + .map_err(|e| (e, code_len)) } fn transfer( @@ -604,12 +646,12 @@ where fn terminate( &mut self, beneficiary: &AccountIdOf, - ) -> DispatchResult { + ) -> Result { let self_id = self.ctx.self_account.clone(); let value = T::Currency::free_balance(&self_id); if let Some(caller_ctx) = self.ctx.caller { if caller_ctx.is_live(&self_id) { - return Err(Error::::ReentranceDenied.into()); + return Err((Error::::ReentranceDenied.into(), 0)); } } transfer::( @@ -618,12 +660,12 @@ where &self_id, beneficiary, value, - )?; + ).map_err(|e| (e, 0))?; if let Some(ContractInfo::Alive(info)) = ContractInfoOf::::take(&self_id) { - Storage::::queue_trie_for_deletion(&info)?; - E::remove_user(info.code_hash); + Storage::::queue_trie_for_deletion(&info).map_err(|e| (e, 0))?; + let code_len = E::remove_user(info.code_hash); Contracts::::deposit_event(RawEvent::Terminated(self_id, beneficiary.clone())); - Ok(()) + Ok(code_len) } else { panic!( "this function is only invoked by in the context of a contract;\ @@ -639,7 +681,7 @@ where value: BalanceOf, gas_meter: &mut GasMeter, input_data: Vec, - ) -> ExecResult { + ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { self.ctx.call(to.clone(), value, gas_meter, input_data) } @@ -649,10 +691,10 @@ where code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> DispatchResult { + ) -> Result<(u32, u32), (DispatchError, u32, u32)> { if let Some(caller_ctx) = self.ctx.caller { if caller_ctx.is_live(&self.ctx.self_account) { - return Err(Error::::ReentranceDenied.into()); + return Err((Error::::ReentranceDenied.into(), 0, 0)); } } @@ -828,7 +870,8 @@ mod tests { impl Executable for MockExecutable { fn from_storage( code_hash: CodeHash, - _schedule: &Schedule + _schedule: &Schedule, + _gas_meter: &mut GasMeter, ) -> Result { Self::from_storage_noinstr(code_hash) } @@ -845,11 +888,11 @@ mod tests { fn drop_from_storage(self) {} - fn add_user(_code_hash: CodeHash) -> DispatchResult { - Ok(()) + fn add_user(_code_hash: CodeHash) -> Result { + Ok(0) } - fn remove_user(_code_hash: CodeHash) {} + fn remove_user(_code_hash: CodeHash) -> u32 { 0 } fn execute>( self, @@ -872,6 +915,10 @@ mod tests { fn occupied_storage(&self) -> u32 { 0 } + + fn code_len(&self) -> u32 { + 0 + } } fn exec_success() -> ExecResult { @@ -954,7 +1001,7 @@ mod tests { vec![], ).unwrap(); - assert!(!output.is_success()); + assert!(!output.0.is_success()); assert_eq!(get_balance(&origin), 100); // the rent is still charged @@ -1012,8 +1059,8 @@ mod tests { ); let output = result.unwrap(); - assert!(output.is_success()); - assert_eq!(output.data, vec![1, 2, 3, 4]); + assert!(output.0.is_success()); + assert_eq!(output.0.data, vec![1, 2, 3, 4]); }); } @@ -1040,8 +1087,8 @@ mod tests { ); let output = result.unwrap(); - assert!(!output.is_success()); - assert_eq!(output.data, vec![1, 2, 3, 4]); + assert!(!output.0.is_success()); + assert_eq!(output.0.data, vec![1, 2, 3, 4]); }); } @@ -1080,13 +1127,17 @@ mod tests { let schedule = Contracts::current_schedule(); let subsistence = Contracts::::subsistence_threshold(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + input_data_ch, &schedule, &mut gas_meter + ).unwrap(); set_balance(&ALICE, subsistence * 10); let result = ctx.instantiate( subsistence * 3, - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(input_data_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![1, 2, 3, 4], &[], ); @@ -1113,7 +1164,7 @@ mod tests { // Verify that we've got proper error and set `reached_bottom`. assert_eq!( r, - Err(Error::::MaxCallDepthReached.into()) + Err((Error::::MaxCallDepthReached.into(), 0)) ); *reached_bottom = true; } else { @@ -1235,12 +1286,16 @@ mod tests { ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let schedule = Contracts::current_schedule(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + dummy_ch, &schedule, &mut gas_meter + ).unwrap(); assert_matches!( ctx.instantiate( 0, // <- zero endowment - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(dummy_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![], &[], ), @@ -1258,13 +1313,17 @@ mod tests { ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let schedule = Contracts::current_schedule(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + dummy_ch, &schedule, &mut gas_meter + ).unwrap(); set_balance(&ALICE, 1000); let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(dummy_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![], &[], ), @@ -1289,13 +1348,17 @@ mod tests { ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let schedule = Contracts::current_schedule(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + dummy_ch, &schedule, &mut gas_meter + ).unwrap(); set_balance(&ALICE, 1000); let instantiated_contract_address = assert_matches!( ctx.instantiate( 100, - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(dummy_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![], &[], ), @@ -1317,7 +1380,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( dummy_ch, Contracts::::subsistence_threshold() * 3, ctx.gas_meter, @@ -1369,10 +1432,10 @@ mod tests { vec![], &[], ), - Err(ExecError { + Err((ExecError { error: DispatchError::Other("It's a trap!"), origin: ErrorOrigin::Callee, - }) + }, 0)) ); exec_success() @@ -1410,13 +1473,17 @@ mod tests { .execute_with(|| { let schedule = Contracts::current_schedule(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + terminate_ch, &schedule, &mut gas_meter + ).unwrap(); set_balance(&ALICE, 1000); assert_eq!( ctx.instantiate( 100, - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(terminate_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![], &[], ), @@ -1445,12 +1512,16 @@ mod tests { let subsistence = Contracts::::subsistence_threshold(); let schedule = Contracts::current_schedule(); let mut ctx = MockContext::top_level(ALICE, &schedule); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let executable = MockExecutable::from_storage( + rent_allowance_ch, &schedule, &mut gas_meter + ).unwrap(); set_balance(&ALICE, subsistence * 10); let result = ctx.instantiate( subsistence * 5, - &mut GasMeter::::new(GAS_LIMIT), - MockExecutable::from_storage(rent_allowance_ch, &schedule).unwrap(), + &mut gas_meter, + executable, vec![], &[], ); diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 4bdfcdd577119..2737f351a50de 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -15,14 +15,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::Config; +use crate::{Config, Error}; use sp_std::marker::PhantomData; use sp_runtime::traits::Zero; use frame_support::{ - dispatch::{DispatchResultWithPostInfo, PostDispatchInfo, DispatchErrorWithPostInfo}, + dispatch::{ + DispatchResultWithPostInfo, PostDispatchInfo, DispatchErrorWithPostInfo, DispatchError, + }, weights::Weight, }; use pallet_contracts_primitives::ExecError; +use sp_core::crypto::UncheckedFrom; #[cfg(test)] use std::{any::Any, fmt::Debug}; @@ -30,22 +33,6 @@ use std::{any::Any, fmt::Debug}; // Gas is essentially the same as weight. It is a 1 to 1 correspondence. pub type Gas = Weight; -#[must_use] -#[derive(Debug, PartialEq, Eq)] -pub enum GasMeterResult { - Proceed(ChargedAmount), - OutOfGas, -} - -impl GasMeterResult { - pub fn is_out_of_gas(&self) -> bool { - match *self { - GasMeterResult::OutOfGas => true, - GasMeterResult::Proceed(_) => false, - } - } -} - #[derive(Debug, PartialEq, Eq)] pub struct ChargedAmount(Gas); @@ -103,7 +90,11 @@ pub struct GasMeter { #[cfg(test)] tokens: Vec, } -impl GasMeter { + +impl GasMeter +where + T::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]> +{ pub fn new(gas_limit: Gas) -> Self { GasMeter { gas_limit, @@ -128,7 +119,7 @@ impl GasMeter { &mut self, metadata: &Tok::Metadata, token: Tok, - ) -> GasMeterResult { + ) -> Result { #[cfg(test)] { // Unconditionally add the token to the storage. @@ -149,11 +140,25 @@ impl GasMeter { self.gas_left = new_value.unwrap_or_else(Zero::zero); match new_value { - Some(_) => GasMeterResult::Proceed(ChargedAmount(amount)), - None => GasMeterResult::OutOfGas, + Some(_) => Ok(ChargedAmount(amount)), + None => Err(Error::::OutOfGas.into()), } } + /// Adjust a previously charged amount down to its actual amount. + /// + /// This is when a maximum a priori amount was charged and then should be partially + /// refunded to match the actual amount. + pub fn adjust_gas>( + &mut self, + charged_amount: ChargedAmount, + metadata: &Tok::Metadata, + token: Tok, + ) { + let adjustment = charged_amount.0.saturating_sub(token.calculate_amount(metadata)); + 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 @@ -304,7 +309,7 @@ mod tests { let result = gas_meter .charge(&MultiplierTokenMetadata { multiplier: 3 }, MultiplierToken(10)); - assert!(!result.is_out_of_gas()); + assert!(!result.is_err()); assert_eq!(gas_meter.gas_left(), 49_970); } @@ -312,10 +317,10 @@ mod tests { #[test] fn tracing() { let mut gas_meter = GasMeter::::new(50000); - assert!(!gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); + assert!(!gas_meter.charge(&(), SimpleToken(1)).is_err()); assert!(!gas_meter .charge(&MultiplierTokenMetadata { multiplier: 3 }, MultiplierToken(10)) - .is_out_of_gas()); + .is_err()); let mut tokens = gas_meter.tokens()[0..2].iter(); match_tokens!(tokens, SimpleToken(1), MultiplierToken(10),); @@ -325,7 +330,7 @@ mod tests { #[test] fn refuse_to_execute_anything_if_zero() { let mut gas_meter = GasMeter::::new(0); - assert!(gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); + assert!(gas_meter.charge(&(), SimpleToken(1)).is_err()); } // Make sure that if the gas meter is charged by exceeding amount then not only an error @@ -338,10 +343,10 @@ mod tests { let mut gas_meter = GasMeter::::new(200); // The first charge is should lead to OOG. - assert!(gas_meter.charge(&(), SimpleToken(300)).is_out_of_gas()); + assert!(gas_meter.charge(&(), SimpleToken(300)).is_err()); // The gas meter is emptied at this moment, so this should also fail. - assert!(gas_meter.charge(&(), SimpleToken(1)).is_out_of_gas()); + assert!(gas_meter.charge(&(), SimpleToken(1)).is_err()); } @@ -350,6 +355,6 @@ mod tests { #[test] fn charge_exact_amount() { let mut gas_meter = GasMeter::::new(25); - assert!(!gas_meter.charge(&(), SimpleToken(25)).is_out_of_gas()); + assert!(!gas_meter.charge(&(), SimpleToken(25)).is_err()); } } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index b20db8dd8cd84..4e56230e93f3a 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -80,7 +80,7 @@ //! * [Balances](../pallet_balances/index.html) #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "runtime-benchmarks", recursion_limit="256")] +#![cfg_attr(feature = "runtime-benchmarks", recursion_limit="512")] #[macro_use] mod gas; @@ -126,9 +126,9 @@ use frame_support::{ }; use frame_system::{ensure_signed, ensure_root, Module as System}; use pallet_contracts_primitives::{ - RentProjectionResult, GetStorageResult, ContractAccessError, ContractExecResult, ExecResult, + RentProjectionResult, GetStorageResult, ContractAccessError, ContractExecResult, }; -use frame_support::weights::Weight; +use frame_support::weights::{Weight, PostDispatchInfo, WithPostDispatchInfo}; pub type CodeHash = ::Hash; pub type TrieId = Vec; @@ -344,6 +344,11 @@ pub trait Config: frame_system::Config { /// The maximum amount of weight that can be consumed per block for lazy trie removal. type DeletionWeightLimit: Get; + + /// The maximum length of a contract code in bytes. This limit applies to the instrumented + /// version of the code. Therefore `instantiate_with_code` can fail even when supplying + /// a wasm binary below this maximum size. + type MaxCodeSize: Get; } decl_error! { @@ -538,7 +543,7 @@ decl_module! { /// * 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. - #[weight = T::WeightInfo::call().saturating_add(*gas_limit)] + #[weight = T::WeightInfo::call(T::MaxCodeSize::get() / 1024).saturating_add(*gas_limit)] pub fn call( origin, dest: ::Source, @@ -549,10 +554,13 @@ decl_module! { let origin = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; let mut gas_meter = GasMeter::new(gas_limit); - let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, data) - }); - gas_meter.into_dispatch_result(result, T::WeightInfo::call()) + let schedule = >::current_schedule(); + let mut ctx = ExecutionContext::>::top_level(origin, &schedule); + let (result, code_len) = match ctx.call(dest, value, &mut gas_meter, data) { + Ok((output, len)) => (Ok(output), len), + Err((err, len)) => (Err(err), len), + }; + gas_meter.into_dispatch_result(result, T::WeightInfo::call(code_len / 1024)) } /// Instantiates a new contract from the supplied `code` optionally transferring @@ -592,16 +600,16 @@ decl_module! { salt: Vec, ) -> DispatchResultWithPostInfo { let origin = ensure_signed(origin)?; - let schedule = >::current_schedule(); let code_len = code.len() as u32; - ensure!(code_len <= schedule.limits.code_size, Error::::CodeTooLarge); + ensure!(code_len <= T::MaxCodeSize::get(), Error::::CodeTooLarge); let mut gas_meter = GasMeter::new(gas_limit); - let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - let executable = PrefabWasmModule::from_code(code, &schedule)?; - let result = ctx.instantiate(endowment, gas_meter, executable, data, &salt) - .map(|(_address, output)| output)?; - Ok(result) - }); + let schedule = >::current_schedule(); + let executable = PrefabWasmModule::from_code(code, &schedule)?; + let code_len = executable.code_len(); + ensure!(code_len <= T::MaxCodeSize::get(), Error::::CodeTooLarge); + let mut ctx = ExecutionContext::>::top_level(origin, &schedule); + let result = ctx.instantiate(endowment, &mut gas_meter, executable, data, &salt) + .map(|(_address, output)| output); gas_meter.into_dispatch_result( result, T::WeightInfo::instantiate_with_code(code_len / 1024, salt.len() as u32 / 1024) @@ -614,8 +622,8 @@ decl_module! { /// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary /// must be supplied. #[weight = - T::WeightInfo::instantiate(salt.len() as u32 / 1024) - .saturating_add(*gas_limit) + T::WeightInfo::instantiate(T::MaxCodeSize::get() / 1024, salt.len() as u32 / 1024) + .saturating_add(*gas_limit) ] pub fn instantiate( origin, @@ -627,15 +635,15 @@ decl_module! { ) -> DispatchResultWithPostInfo { let origin = ensure_signed(origin)?; let mut gas_meter = GasMeter::new(gas_limit); - let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - let executable = PrefabWasmModule::from_storage(code_hash, &ctx.schedule)?; - let result = ctx.instantiate(endowment, gas_meter, executable, data, &salt) - .map(|(_address, output)| output)?; - Ok(result) - }); + let schedule = >::current_schedule(); + let executable = PrefabWasmModule::from_storage(code_hash, &schedule, &mut gas_meter)?; + let mut ctx = ExecutionContext::>::top_level(origin, &schedule); + let code_len = executable.code_len(); + let result = ctx.instantiate(endowment, &mut gas_meter, executable, data, &salt) + .map(|(_address, output)| output); gas_meter.into_dispatch_result( result, - T::WeightInfo::instantiate(salt.len() as u32 / 1024) + T::WeightInfo::instantiate(code_len / 1024, salt.len() as u32 / 1024), ) } @@ -648,7 +656,7 @@ decl_module! { /// /// If contract is not evicted as a result of this call, [`Error::ContractNotEvictable`] /// is returned and the sender is not eligible for the reward. - #[weight = T::WeightInfo::claim_surcharge()] + #[weight = T::WeightInfo::claim_surcharge(T::MaxCodeSize::get() / 1024)] pub fn claim_surcharge( origin, dest: T::AccountId, @@ -675,23 +683,26 @@ decl_module! { }; // If poking the contract has lead to eviction of the contract, give out the rewards. - if let Some(rent_payed) = - Rent::>::try_eviction(&dest, handicap)? - { - T::Currency::deposit_into_existing( - &rewarded, - T::SurchargeReward::get().min(rent_payed), - ) - .map(|_| Pays::No.into()) - .map_err(Into::into) - } else { - Err(Error::::ContractNotEvictable.into()) + match Rent::>::try_eviction(&dest, handicap)? { + (Some(rent_payed), code_len) => { + T::Currency::deposit_into_existing( + &rewarded, + T::SurchargeReward::get().min(rent_payed), + ) + .map(|_| PostDispatchInfo { + actual_weight: Some(T::WeightInfo::claim_surcharge(code_len / 1024)), + pays_fee: Pays::No, + }) + .map_err(Into::into) + } + (None, code_len) => Err(Error::::ContractNotEvictable.with_weight( + T::WeightInfo::claim_surcharge(code_len / 1024) + )), } } } } -/// Public APIs provided by the contracts module. impl Module where T::AccountId: UncheckedFrom + AsRef<[u8]>, @@ -710,12 +721,12 @@ where input_data: Vec, ) -> ContractExecResult { let mut gas_meter = GasMeter::new(gas_limit); - let exec_result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, input_data) - }); + let schedule = >::current_schedule(); + let mut ctx = ExecutionContext::>::top_level(origin, &schedule); + let result = ctx.call(dest, value, &mut gas_meter, input_data); let gas_consumed = gas_meter.gas_spent(); ContractExecResult { - exec_result, + exec_result: result.map(|r| r.0).map_err(|r| r.0), gas_consumed, } } @@ -731,18 +742,12 @@ where Ok(maybe_value) } + /// Query how many blocks the contract stays alive given that the amount endowment + /// and consumed storage does not change. pub fn rent_projection(address: T::AccountId) -> RentProjectionResult { Rent::>::compute_projection(&address) } - /// Store code for benchmarks which does not check nor instrument the code. - #[cfg(feature = "runtime-benchmarks")] - pub fn store_code_raw(code: Vec) -> DispatchResult { - let schedule = >::current_schedule(); - PrefabWasmModule::store_code_unchecked(code, &schedule)?; - Ok(()) - } - /// Determine the address of a contract, /// /// This is the address generation function used by contract instantiation. Its result @@ -775,23 +780,22 @@ where pub fn subsistence_threshold() -> BalanceOf { T::Currency::minimum_balance().saturating_add(T::TombstoneDeposit::get()) } -} -impl Module -where - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - fn execute_wasm( - origin: T::AccountId, - gas_meter: &mut GasMeter, - func: impl FnOnce( - &mut ExecutionContext>, - &mut GasMeter, - ) -> ExecResult, - ) -> ExecResult { + /// Store code for benchmarks which does not check nor instrument the code. + #[cfg(feature = "runtime-benchmarks")] + fn store_code_raw(code: Vec) -> DispatchResult { let schedule = >::current_schedule(); - let mut ctx = ExecutionContext::top_level(origin, &schedule); - func(&mut ctx, gas_meter) + PrefabWasmModule::store_code_unchecked(code, &schedule)?; + Ok(()) + } + + /// This exists so that benchmarks can determine the weight of running an instrumentation. + #[cfg(feature = "runtime-benchmarks")] + fn reinstrument_module( + module: &mut PrefabWasmModule, + schedule: &Schedule + ) -> DispatchResult { + self::wasm::reinstrument(module, schedule) } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 38b1e8bd11753..087c6c518300b 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -325,13 +325,14 @@ where pub fn try_eviction( account: &T::AccountId, handicap: T::BlockNumber, - ) -> Result>, DispatchError> { + ) -> Result<(Option>, u32), DispatchError> { let contract = >::get(account); let contract = match contract { - None | Some(ContractInfo::Tombstone(_)) => return Ok(None), + None | Some(ContractInfo::Tombstone(_)) => return Ok((None, 0)), Some(ContractInfo::Alive(contract)) => contract, }; let module = PrefabWasmModule::::from_storage_noinstr(contract.code_hash)?; + let code_len = module.code_len(); let current_block_number = >::block_number(); let verdict = Self::consider_case( account, @@ -353,9 +354,9 @@ where Self::enact_verdict( account, contract, current_block_number, verdict, Some(module), )?; - Ok(Some(rent_payed)) + Ok((Some(rent_payed), code_len)) } - _ => Ok(None), + _ => Ok((None, code_len)), } } @@ -447,28 +448,32 @@ 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, dest: T::AccountId, code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(), DispatchError> { + ) -> Result<(u32, u32), (DispatchError, u32, u32)> { let mut origin_contract = >::get(&origin) .and_then(|c| c.get_alive()) - .ok_or(Error::::InvalidSourceContract)?; + .ok_or((Error::::InvalidSourceContract.into(), 0, 0))?; 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()); + return Err((Error::::InvalidContractOrigin.into(), 0, 0)); } let dest_tombstone = >::get(&dest) .and_then(|c| c.get_tombstone()) - .ok_or(Error::::InvalidDestinationContract)?; + .ok_or((Error::::InvalidDestinationContract.into(), 0, 0))?; let last_write = if !delta.is_empty() { Some(current_block) @@ -477,7 +482,7 @@ where }; // Fails if the code hash does not exist on chain - E::add_user(code_hash)?; + let caller_code_len = E::add_user(code_hash).map_err(|e| (e, 0, 0))?; // We are allowed to eagerly modify storage even though the function can // fail later due to tombstones not matching. This is because the restoration @@ -501,13 +506,13 @@ where ); if tombstone != dest_tombstone { - return Err(Error::::InvalidTombstone.into()); + return Err((Error::::InvalidTombstone.into(), caller_code_len, 0)); } origin_contract.storage_size -= bytes_taken; >::remove(&origin); - E::remove_user(origin_contract.code_hash); + let tombstone_code_len = E::remove_user(origin_contract.code_hash); >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { trie_id: origin_contract.trie_id, storage_size: origin_contract.storage_size, @@ -523,6 +528,6 @@ where T::Currency::make_free_balance_be(&origin, >::zero()); T::Currency::deposit_creating(&dest, origin_free_balance); - Ok(()) + Ok((caller_code_len, tombstone_code_len)) } } diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index 3580fa2aae209..c86134bc415d1 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -104,10 +104,6 @@ pub struct Limits { /// The maximum length of a subject in bytes used for PRNG generation. pub subject_len: u32, - - /// The maximum length of a contract code in bytes. This limit applies to the uninstrumented - /// and pristine form of the code as supplied to `instantiate_with_code`. - pub code_size: u32, } impl Limits { @@ -250,9 +246,18 @@ 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, @@ -292,6 +297,9 @@ 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, @@ -304,6 +312,9 @@ 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, @@ -443,7 +454,6 @@ impl Default for Limits { table_size: 4096, br_table_size: 256, subject_len: 32, - code_size: 512 * 1024, } } } @@ -528,8 +538,11 @@ 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_delta: cost_batched!(seal_restore_to_per_delta), + 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), 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), @@ -542,13 +555,15 @@ 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_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), + 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), instantiate: cost_batched!(seal_instantiate), - 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), + 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), 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 62768641ac165..f10cd2882ace4 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -24,6 +24,7 @@ use crate::{ UncheckedFrom, InitState, ReturnFlags, }, exec::{AccountIdOf, Executable}, wasm::PrefabWasmModule, + weights::WeightInfo, }; use assert_matches::assert_matches; use codec::Encode; @@ -35,7 +36,7 @@ use sp_runtime::{ use sp_io::hashing::blake2_256; use frame_support::{ assert_ok, assert_err, assert_err_ignore_postinfo, - parameter_types, StorageMap, assert_storage_noop, + parameter_types, StorageMap, StorageValue, assert_storage_noop, traits::{Currency, ReservableCurrency, OnInitialize}, weights::{Weight, PostDispatchInfo, DispatchClass, constants::WEIGHT_PER_SECOND}, dispatch::DispatchErrorWithPostInfo, @@ -250,6 +251,7 @@ parameter_types! { pub const MaxValueSize: u32 = 16_384; pub const DeletionQueueDepth: u32 = 1024; pub const DeletionWeightLimit: Weight = 500_000_000_000; + pub const MaxCodeSize: u32 = 2 * 1024; } parameter_types! { @@ -282,6 +284,7 @@ impl Config for Test { type ChainExtension = TestExtension; type DeletionQueueDepth = DeletionQueueDepth; type DeletionWeightLimit = DeletionWeightLimit; + type MaxCodeSize = MaxCodeSize; } pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); @@ -350,7 +353,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 crate::WeightInfo>::call(); + let base_cost = <::WeightInfo as WeightInfo>::call(0); assert_eq!( Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, Vec::new()), @@ -2432,7 +2435,7 @@ fn lazy_removal_does_no_run_on_full_block() { // Run the lazy removal without any limit so that all keys would be removed if there // had been some weight left in the block. let weight_used = Contracts::on_initialize(Weight::max_value()); - let base = <::WeightInfo as crate::WeightInfo>::on_initialize(); + let base = <::WeightInfo as WeightInfo>::on_initialize(); assert_eq!(weight_used, base); // All the keys are still in place @@ -2717,3 +2720,69 @@ fn refcounter() { assert_matches!(crate::CodeStorage::::get(code_hash), None); }); } + + +#[test] +fn reinstrument_does_charge() { + let (wasm, code_hash) = compile_module::("return_with_data").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + let subsistence = Module::::subsistence_threshold(); + let zero = 0u32.to_le_bytes().encode(); + let code_len = wasm.len() as u32; + + assert_ok!(Contracts::instantiate_with_code( + Origin::signed(ALICE), + subsistence * 100, + GAS_LIMIT, + wasm, + zero.clone(), + vec![], + )); + + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + + // Call the contract two times without reinstrument + + let result0 = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + zero.clone(), + ); + assert!(result0.exec_result.unwrap().is_success()); + + let result1 = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + zero.clone(), + ); + assert!(result1.exec_result.unwrap().is_success()); + + // They should match because both where called with the same schedule. + assert_eq!(result0.gas_consumed, result1.gas_consumed); + + // Update the schedule version but keep the rest the same + crate::CurrentSchedule::mutate(|old: &mut Schedule| { + old.version += 1; + }); + + // This call should trigger reinstrumentation + let result2 = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + zero.clone(), + ); + assert!(result2.exec_result.unwrap().is_success()); + assert!(result2.gas_consumed > result1.gas_consumed); + assert_eq!( + result2.gas_consumed, + result1.gas_consumed + ::WeightInfo::instrument(code_len / 1024), + ); + }); +} diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index 6166918c80c94..1132d31776db6 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -30,9 +30,13 @@ use crate::{ CodeHash, CodeStorage, PristineCode, Schedule, Config, Error, wasm::{prepare, PrefabWasmModule}, Module as Contracts, RawEvent, + gas::{Gas, GasMeter, Token}, + weights::WeightInfo, }; use sp_core::crypto::UncheckedFrom; -use frame_support::{StorageMap, dispatch::{DispatchError, DispatchResult}}; +use frame_support::{StorageMap, dispatch::DispatchError}; +#[cfg(feature = "runtime-benchmarks")] +pub use self::private::reinstrument as reinstrument; /// Put the instrumented module in storage. /// @@ -77,14 +81,14 @@ where } /// Increment the refcount of a code in-storage by one. -pub fn increment_refcount(code_hash: CodeHash) -> DispatchResult +pub fn increment_refcount(code_hash: CodeHash) -> Result where T::AccountId: UncheckedFrom + AsRef<[u8]> { >::mutate(code_hash, |existing| { if let Some(module) = existing { increment_64(&mut module.refcount); - Ok(()) + Ok(module.original_code_len) } else { Err(Error::::CodeNotFound.into()) } @@ -92,19 +96,23 @@ 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) +pub fn decrement_refcount(code_hash: CodeHash) -> u32 where T::AccountId: UncheckedFrom + AsRef<[u8]> { >::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 } - }); + }) } /// Load code with the given code hash. @@ -114,31 +122,48 @@ where /// re-instrumentation and update the cache in the storage. pub fn load( code_hash: CodeHash, - schedule: Option<&Schedule>, + reinstrument: Option<(&Schedule, &mut GasMeter)>, ) -> Result, DispatchError> where T::AccountId: UncheckedFrom + AsRef<[u8]> { let mut prefab_module = >::get(code_hash) .ok_or_else(|| Error::::CodeNotFound)?; + prefab_module.code_hash = code_hash; - if let Some(schedule) = schedule { + if let Some((schedule, gas_meter)) = reinstrument { if prefab_module.schedule_version < schedule.version { // The current schedule version is greater than the version of the one cached // in the storage. // // We need to re-instrument the code with the latest schedule here. - let original_code = >::get(code_hash) - .ok_or_else(|| Error::::CodeNotFound)?; - prefab_module.code = prepare::reinstrument_contract::(original_code, schedule)?; - prefab_module.schedule_version = schedule.version; - >::insert(&code_hash, &prefab_module); + gas_meter.charge(&(), InstrumentToken(prefab_module.original_code_len))?; + private::reinstrument(&mut prefab_module, schedule)?; } } - prefab_module.code_hash = code_hash; Ok(prefab_module) } +mod private { + use super::*; + + /// Instruments the passed prefab wasm module with the supplied schedule. + pub fn reinstrument( + prefab_module: &mut PrefabWasmModule, + schedule: &Schedule, + ) -> Result<(), DispatchError> + where + T::AccountId: UncheckedFrom + AsRef<[u8]> + { + let original_code = >::get(&prefab_module.code_hash) + .ok_or_else(|| Error::::CodeNotFound)?; + prefab_module.code = prepare::reinstrument_contract::(original_code, schedule)?; + prefab_module.schedule_version = schedule.version; + >::insert(&prefab_module.code_hash, &*prefab_module); + Ok(()) + } +} + /// Finish removal of a code by deleting the pristine code and emitting an event. fn finish_removal(code_hash: CodeHash) where @@ -161,3 +186,17 @@ fn increment_64(refcount: &mut u64) { qed "); } + +/// Token to be supplied to the gas meter which charges the weight needed for reinstrumenting +/// a contract of the specified size in bytes. +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Clone, Copy)] +struct InstrumentToken(u32); + +impl Token for InstrumentToken { + type Metadata = (); + + fn calculate_amount(&self, _metadata: &Self::Metadata) -> Gas { + T::WeightInfo::instrument(self.0 / 1024) + } +} diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 56be9f35313a6..c6970b2b1eb06 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -33,9 +33,11 @@ use crate::{ use sp_std::prelude::*; use sp_core::crypto::UncheckedFrom; use codec::{Encode, Decode}; -use frame_support::dispatch::{DispatchError, DispatchResult}; +use frame_support::dispatch::DispatchError; use pallet_contracts_primitives::ExecResult; pub use self::runtime::{ReturnCode, Runtime, RuntimeToken}; +#[cfg(feature = "runtime-benchmarks")] +pub use self::code_cache::reinstrument; /// A prepared wasm module ready for execution. /// @@ -125,7 +127,7 @@ where pub fn store_code_unchecked( original_code: Vec, schedule: &Schedule - ) -> DispatchResult { + ) -> Result<(), DispatchError> { let executable = prepare::benchmarking::prepare_contract(original_code, schedule) .map_err::(Into::into)?; code_cache::store(executable); @@ -145,9 +147,10 @@ where { fn from_storage( code_hash: CodeHash, - schedule: &Schedule + schedule: &Schedule, + gas_meter: &mut GasMeter, ) -> Result { - code_cache::load(code_hash, Some(schedule)) + code_cache::load(code_hash, Some((schedule, gas_meter))) } fn from_storage_noinstr(code_hash: CodeHash) -> Result { @@ -158,11 +161,11 @@ where code_cache::store_decremented(self); } - fn add_user(code_hash: CodeHash) -> DispatchResult { + fn add_user(code_hash: CodeHash) -> Result { code_cache::increment_refcount::(code_hash) } - fn remove_user(code_hash: CodeHash) { + fn remove_user(code_hash: CodeHash) -> u32 { code_cache::decrement_refcount::(code_hash) } @@ -222,6 +225,10 @@ where let len = self.original_code_len.saturating_add(self.code.len() as u32); len.checked_div(self.refcount as u32).unwrap_or(len) } + + fn code_len(&self) -> u32 { + self.code.len() as u32 + } } #[cfg(test)] @@ -305,7 +312,7 @@ mod tests { gas_meter: &mut GasMeter, data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { + ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)> { self.instantiates.push(InstantiateEntry { code_hash: code_hash.clone(), endowment, @@ -319,6 +326,7 @@ mod tests { flags: ReturnFlags::empty(), data: Vec::new(), }, + 0, )) } fn transfer( @@ -339,7 +347,7 @@ mod tests { value: u64, _gas_meter: &mut GasMeter, data: Vec, - ) -> ExecResult { + ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { self.transfers.push(TransferEntry { to: to.clone(), value, @@ -347,16 +355,16 @@ mod tests { }); // Assume for now that it was just a plain transfer. // TODO: Add tests for different call outcomes. - Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) + Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }, 0)) } fn terminate( &mut self, beneficiary: &AccountIdOf, - ) -> Result<(), DispatchError> { + ) -> Result { self.terminations.push(TerminationEntry { beneficiary: beneficiary.clone(), }); - Ok(()) + Ok(0) } fn restore_to( &mut self, @@ -364,14 +372,14 @@ mod tests { code_hash: H256, rent_allowance: u64, delta: Vec, - ) -> Result<(), DispatchError> { + ) -> Result<(u32, u32), (DispatchError, u32, u32)> { self.restores.push(RestoreEntry { dest, code_hash, rent_allowance, delta, }); - Ok(()) + Ok((0, 0)) } fn caller(&self) -> &AccountIdOf { &ALICE @@ -443,7 +451,7 @@ mod tests { gas_meter: &mut GasMeter, input_data: Vec, salt: &[u8], - ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { + ) -> Result<(AccountIdOf, ExecReturnValue, u32), (ExecError, u32)> { (**self).instantiate(code, value, gas_meter, input_data, salt) } fn transfer( @@ -456,7 +464,7 @@ mod tests { fn terminate( &mut self, beneficiary: &AccountIdOf, - ) -> Result<(), DispatchError> { + ) -> Result { (**self).terminate(beneficiary) } fn call( @@ -465,7 +473,7 @@ mod tests { value: u64, gas_meter: &mut GasMeter, input_data: Vec, - ) -> ExecResult { + ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { (**self).call(to, value, gas_meter, input_data) } fn restore_to( @@ -474,7 +482,7 @@ mod tests { code_hash: H256, rent_allowance: u64, delta: Vec, - ) -> Result<(), DispatchError> { + ) -> Result<(u32, u32), (DispatchError, u32, u32)> { (**self).restore_to( dest, code_hash, diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 9dd098e852666..020be381851f8 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -20,11 +20,11 @@ use crate::{ HostFnWeights, Config, CodeHash, BalanceOf, Error, exec::{Ext, StorageKey, TopicOf}, - gas::{Gas, GasMeter, Token, GasMeterResult, ChargedAmount}, + gas::{Gas, GasMeter, Token, ChargedAmount}, wasm::env_def::ConvertibleToWasm, }; use parity_wasm::elements::ValueType; -use frame_support::{dispatch::DispatchError, ensure}; +use frame_support::{dispatch::DispatchError, ensure, traits::Get}; use sp_std::prelude::*; use codec::{Decode, DecodeAll, Encode}; use sp_runtime::traits::SaturatedConversion; @@ -165,8 +165,12 @@ pub enum RuntimeToken { 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_reposit_event` with the given number of topics and event size. @@ -185,6 +189,8 @@ pub enum RuntimeToken { 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. @@ -193,6 +199,8 @@ pub enum RuntimeToken { /// 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. @@ -235,8 +243,13 @@ where 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())) @@ -250,11 +263,14 @@ where 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 @@ -408,10 +424,19 @@ where where Tok: Token>, { - match self.gas_meter.charge(&self.ext.schedule().host_fn_weights, token) { - GasMeterResult::Proceed(amount) => Ok(amount), - GasMeterResult::OutOfGas => Err(Error::::OutOfGas.into()) - } + self.gas_meter.charge(&self.ext.schedule().host_fn_weights, token) + } + + /// Correct previously charged gas amount. + pub fn adjust_gas(&mut self, charged_amount: ChargedAmount, adjusted_amount: Tok) + where + Tok: Token>, + { + self.gas_meter.adjust_gas( + charged_amount, + &self.ext.schedule().host_fn_weights, + adjusted_amount, + ); } /// Read designated chunk from the sandbox memory. @@ -774,11 +799,12 @@ define_env!(Env, , ctx.read_sandbox_memory_as(callee_ptr, callee_len)?; 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)?; - if value > 0u32.into() { ctx.charge_gas(RuntimeToken::CallSurchargeTransfer)?; } - + let charged = ctx.charge_gas( + RuntimeToken::CallSurchargeCodeSize(::MaxCodeSize::get()) + )?; let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { @@ -796,16 +822,20 @@ define_env!(Env, , ) } // there is not enough gas to allocate for the nested call. - None => Err(Error::<::T>::OutOfGas.into()), + None => Err((Error::<::T>::OutOfGas.into(), 0)), } }); - - if let Ok(output) = &call_outcome { + let code_len = match &call_outcome { + Ok((_, len)) => len, + Err((_, len)) => len, + }; + ctx.adjust_gas(charged, RuntimeToken::CallSurchargeCodeSize(*code_len)); + if let Ok((output, _)) = &call_outcome { ctx.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { Some(RuntimeToken::CallCopyOut(len)) })?; } - Ok(Runtime::::exec_into_return_code(call_outcome)?) + Ok(Runtime::::exec_into_return_code(call_outcome.map(|r| r.0).map_err(|r| r.0))?) }, // Instantiate a contract with the specified code hash. @@ -875,7 +905,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( + RuntimeToken::InstantiateSurchargeCodeSize(::MaxCodeSize::get()) + )?; let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { @@ -894,10 +926,15 @@ define_env!(Env, , ) } // there is not enough gas to allocate for the nested call. - None => Err(Error::<::T>::OutOfGas.into()), + None => Err((Error::<::T>::OutOfGas.into(), 0)), } }); - if let Ok((address, output)) = &instantiate_outcome { + let code_len = match &instantiate_outcome { + Ok((_, _, code_len)) => code_len, + Err((_, code_len)) => code_len, + }; + ctx.adjust_gas(charged, RuntimeToken::InstantiateSurchargeCodeSize(*code_len)); + 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, @@ -907,7 +944,9 @@ define_env!(Env, , Some(RuntimeToken::InstantiateCopyOut(len)) })?; } - Ok(Runtime::::exec_into_return_code(instantiate_outcome.map(|(_id, retval)| retval))?) + Ok(Runtime::::exec_into_return_code( + instantiate_outcome.map(|(_, retval, _)| retval).map_err(|(err, _)| err) + )?) }, // Remove the calling account and transfer remaining balance. @@ -935,7 +974,15 @@ define_env!(Env, , let beneficiary: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; - ctx.ext.terminate(&beneficiary)?; + let charged = ctx.charge_gas( + RuntimeToken::TerminateSurchargeCodeSize(::MaxCodeSize::get()) + )?; + let (result, code_len) = match ctx.ext.terminate(&beneficiary) { + Ok(len) => (Ok(()), len), + Err((err, len)) => (Err(err), len), + }; + ctx.adjust_gas(charged, RuntimeToken::TerminateSurchargeCodeSize(code_len)); + result?; Err(TrapReason::Termination) }, @@ -1220,7 +1267,22 @@ define_env!(Env, , delta }; - ctx.ext.restore_to(dest, code_hash, rent_allowance, delta)?; + let max_len = ::MaxCodeSize::get(); + let charged = ctx.charge_gas(RuntimeToken::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, RuntimeToken::RestoreToSurchargeCodeSize { + caller_code, + tombstone_code, + }); + result?; Err(TrapReason::Restoration) }, diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index 9c53611038739..905ccf8cb5a2f 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -17,8 +17,8 @@ //! Autogenerated weights for pallet_contracts //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.1 -//! DATE: 2021-02-04, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-02-18, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -47,11 +47,12 @@ pub trait WeightInfo { fn on_initialize() -> Weight; fn on_initialize_per_trie_key(k: u32, ) -> Weight; fn on_initialize_per_queue_item(q: u32, ) -> Weight; + fn instrument(c: u32, ) -> Weight; fn update_schedule() -> Weight; fn instantiate_with_code(c: u32, s: u32, ) -> Weight; - fn instantiate(s: u32, ) -> Weight; - fn call() -> Weight; - fn claim_surcharge() -> Weight; + fn instantiate(c: u32, s: u32, ) -> Weight; + fn call(c: u32, ) -> Weight; + fn claim_surcharge(c: u32, ) -> Weight; fn seal_caller(r: u32, ) -> Weight; fn seal_address(r: u32, ) -> Weight; fn seal_gas_left(r: u32, ) -> Weight; @@ -69,8 +70,9 @@ 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_delta(d: u32, ) -> Weight; + fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, 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; @@ -82,9 +84,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_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight; + fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight; fn seal_instantiate(r: u32, ) -> Weight; - fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight; + fn seal_instantiate_per_code_input_output_salt_kb(c: u32, 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; @@ -150,11 +152,11 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn on_initialize() -> Weight { - (3_947_000 as Weight) + (3_733_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { - (46_644_000 as Weight) + (49_569_000 as Weight) // Standard Error: 5_000 .saturating_add((2_295_000 as Weight).saturating_mul(k as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) @@ -162,235 +164,259 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (0 as Weight) - // Standard Error: 164_000 - .saturating_add((165_220_000 as Weight).saturating_mul(q as Weight)) + (358_064_000 as Weight) + // Standard Error: 143_000 + .saturating_add((140_992_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 { + (44_198_000 as Weight) + // Standard Error: 188_000 + .saturating_add((125_833_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 update_schedule() -> Weight { - (28_195_000 as Weight) + (29_190_000 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 { - (0 as Weight) - // Standard Error: 126_000 - .saturating_add((154_196_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 63_000 - .saturating_add((2_764_000 as Weight).saturating_mul(s as Weight)) + (180_015_000 as Weight) + // Standard Error: 197_000 + .saturating_add((167_480_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 12_000 + .saturating_add((2_581_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } - fn instantiate(s: u32, ) -> Weight { - (201_407_000 as Weight) + fn instantiate(c: u32, s: u32, ) -> Weight { + (180_996_000 as Weight) + // Standard Error: 14_000 + .saturating_add((8_684_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 1_000 - .saturating_add((2_247_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_518_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } - fn call() -> Weight { - (180_337_000 as Weight) + fn call(c: u32, ) -> Weight { + (184_326_000 as Weight) + // Standard Error: 2_000 + .saturating_add((3_920_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - fn claim_surcharge() -> Weight { - (322_371_000 as Weight) + fn claim_surcharge(c: u32, ) -> Weight { + (303_270_000 as Weight) + // Standard Error: 5_000 + .saturating_add((5_108_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 { - (135_499_000 as Weight) - // Standard Error: 296_000 - .saturating_add((275_938_000 as Weight).saturating_mul(r as Weight)) + (128_965_000 as Weight) + // Standard Error: 130_000 + .saturating_add((270_123_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (132_674_000 as Weight) - // Standard Error: 158_000 - .saturating_add((273_808_000 as Weight).saturating_mul(r as Weight)) + (137_748_000 as Weight) + // Standard Error: 184_000 + .saturating_add((270_103_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (126_819_000 as Weight) - // Standard Error: 145_000 - .saturating_add((269_173_000 as Weight).saturating_mul(r as Weight)) + (118_784_000 as Weight) + // Standard Error: 234_000 + .saturating_add((264_467_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (140_223_000 as Weight) - // Standard Error: 259_000 - .saturating_add((581_353_000 as Weight).saturating_mul(r as Weight)) + (146_072_000 as Weight) + // Standard Error: 207_000 + .saturating_add((573_282_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (129_490_000 as Weight) - // Standard Error: 132_000 - .saturating_add((269_433_000 as Weight).saturating_mul(r as Weight)) + (133_857_000 as Weight) + // Standard Error: 151_000 + .saturating_add((263_110_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (127_251_000 as Weight) - // Standard Error: 161_000 - .saturating_add((268_720_000 as Weight).saturating_mul(r as Weight)) + (130_447_000 as Weight) + // Standard Error: 125_000 + .saturating_add((265_565_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (129_546_000 as Weight) - // Standard Error: 130_000 - .saturating_add((268_280_000 as Weight).saturating_mul(r as Weight)) + (116_232_000 as Weight) + // Standard Error: 327_000 + .saturating_add((265_728_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (133_306_000 as Weight) - // Standard Error: 208_000 - .saturating_add((604_235_000 as Weight).saturating_mul(r as Weight)) + (175_561_000 as Weight) + // Standard Error: 292_000 + .saturating_add((604_373_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (133_689_000 as Weight) - // Standard Error: 115_000 - .saturating_add((267_107_000 as Weight).saturating_mul(r as Weight)) + (133_961_000 as Weight) + // Standard Error: 150_000 + .saturating_add((262_329_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (133_773_000 as Weight) - // Standard Error: 130_000 - .saturating_add((268_897_000 as Weight).saturating_mul(r as Weight)) + (128_662_000 as Weight) + // Standard Error: 150_000 + .saturating_add((263_234_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (133_222_000 as Weight) - // Standard Error: 476_000 - .saturating_add((514_400_000 as Weight).saturating_mul(r as Weight)) + (142_580_000 as Weight) + // Standard Error: 205_000 + .saturating_add((505_378_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (118_769_000 as Weight) - // Standard Error: 102_000 - .saturating_add((134_134_000 as Weight).saturating_mul(r as Weight)) + (116_346_000 as Weight) + // Standard Error: 86_000 + .saturating_add((124_599_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (124_719_000 as Weight) - // Standard Error: 93_000 - .saturating_add((7_486_000 as Weight).saturating_mul(r as Weight)) + (124_679_000 as Weight) + // Standard Error: 81_000 + .saturating_add((7_310_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (136_348_000 as Weight) + (136_069_000 as Weight) // Standard Error: 0 .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (118_710_000 as Weight) - // Standard Error: 77_000 - .saturating_add((4_566_000 as Weight).saturating_mul(r as Weight)) + (118_807_000 as Weight) + // Standard Error: 66_000 + .saturating_add((4_740_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (127_609_000 as Weight) + (127_702_000 as Weight) // Standard Error: 0 - .saturating_add((786_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((784_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (125_463_000 as Weight) - // Standard Error: 154_000 - .saturating_add((106_188_000 as Weight).saturating_mul(r as Weight)) + (124_847_000 as Weight) + // Standard Error: 87_000 + .saturating_add((107_679_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } + fn seal_terminate_per_code_kb(c: u32, ) -> Weight { + (237_115_000 as Weight) + // Standard Error: 6_000 + .saturating_add((8_556_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } fn seal_restore_to(r: u32, ) -> Weight { - (219_195_000 as Weight) - // Standard Error: 361_000 - .saturating_add((131_326_000 as Weight).saturating_mul(r as Weight)) + (217_959_000 as Weight) + // Standard Error: 455_000 + .saturating_add((134_528_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((6 as Weight).saturating_mul(r as Weight))) } - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (6_742_000 as Weight) - // Standard Error: 2_484_000 - .saturating_add((3_747_735_000 as Weight).saturating_mul(d as Weight)) + fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 151_000 + .saturating_add((9_061_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 151_000 + .saturating_add((4_807_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 1_331_000 + .saturating_add((3_736_196_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(8 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 { - (137_248_000 as Weight) - // Standard Error: 662_000 - .saturating_add((661_121_000 as Weight).saturating_mul(r as Weight)) + (134_143_000 as Weight) + // Standard Error: 233_000 + .saturating_add((643_555_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (147_654_000 as Weight) - // Standard Error: 305_000 - .saturating_add((935_148_000 as Weight).saturating_mul(r as Weight)) + (142_838_000 as Weight) + // Standard Error: 367_000 + .saturating_add((937_126_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_246_123_000 as Weight) - // Standard Error: 2_807_000 - .saturating_add((585_535_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 553_000 - .saturating_add((249_976_000 as Weight).saturating_mul(n as Weight)) + (1_210_711_000 as Weight) + // Standard Error: 2_124_000 + .saturating_add((594_541_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 418_000 + .saturating_add((251_068_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (140_588_000 as Weight) - // Standard Error: 228_000 - .saturating_add((707_872_000 as Weight).saturating_mul(r as Weight)) + (144_533_000 as Weight) + // Standard Error: 220_000 + .saturating_add((714_590_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_set_storage(r: u32, ) -> Weight { - (2_767_124_000 as Weight) - // Standard Error: 18_504_000 - .saturating_add((17_507_873_000 as Weight).saturating_mul(r as Weight)) + (406_366_000 as Weight) + // Standard Error: 3_533_000 + .saturating_add((16_167_082_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 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 { - (1_748_586_000 as Weight) - // Standard Error: 359_000 - .saturating_add((75_231_000 as Weight).saturating_mul(n as Weight)) + (1_739_590_000 as Weight) + // Standard Error: 390_000 + .saturating_add((74_815_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 2_209_000 - .saturating_add((2_261_355_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_284_000 + .saturating_add((2_281_347_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 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_get_storage(r: u32, ) -> Weight { - (83_780_000 as Weight) - // Standard Error: 965_000 - .saturating_add((973_164_000 as Weight).saturating_mul(r as Weight)) + (81_889_000 as Weight) + // Standard Error: 1_171_000 + .saturating_add((930_704_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (728_625_000 as Weight) - // Standard Error: 294_000 - .saturating_add((154_625_000 as Weight).saturating_mul(n as Weight)) + (709_323_000 as Weight) + // Standard Error: 391_000 + .saturating_add((155_689_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_543_000 - .saturating_add((5_467_966_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 1_846_000 + .saturating_add((5_566_275_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 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)) @@ -398,355 +424,359 @@ impl WeightInfo for SubstrateWeight { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 9_216_000 - .saturating_add((10_265_093_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 4_823_000 + .saturating_add((10_461_861_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) } - fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (10_426_869_000 as Weight) - // Standard Error: 114_622_000 - .saturating_add((4_366_037_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 40_000 - .saturating_add((59_741_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 43_000 - .saturating_add((82_331_000 as Weight).saturating_mul(o as Weight)) + fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { + (9_686_594_000 as Weight) + // Standard Error: 473_000 + .saturating_add((393_132_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 197_094_000 + .saturating_add((4_957_181_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 62_000 + .saturating_add((59_974_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 66_000 + .saturating_add((83_027_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(206 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: 35_927_000 - .saturating_add((21_088_623_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 34_133_000 + .saturating_add((21_407_630_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (17_200_760_000 as Weight) - // Standard Error: 157_000 - .saturating_add((61_221_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 157_000 - .saturating_add((84_149_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 157_000 - .saturating_add((284_655_000 as Weight).saturating_mul(s as Weight)) + fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { + (9_705_322_000 as Weight) + // Standard Error: 674_000 + .saturating_add((879_118_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 95_000 + .saturating_add((63_025_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 95_000 + .saturating_add((87_633_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 95_000 + .saturating_add((311_987_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(207 as Weight)) .saturating_add(T::DbWeight::get().writes(203 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (126_005_000 as Weight) - // Standard Error: 133_000 - .saturating_add((252_338_000 as Weight).saturating_mul(r as Weight)) + (125_486_000 as Weight) + // Standard Error: 266_000 + .saturating_add((240_913_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (727_930_000 as Weight) - // Standard Error: 57_000 - .saturating_add((430_299_000 as Weight).saturating_mul(n as Weight)) + (636_153_000 as Weight) + // Standard Error: 47_000 + .saturating_add((429_541_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (129_778_000 as Weight) - // Standard Error: 146_000 - .saturating_add((266_097_000 as Weight).saturating_mul(r as Weight)) + (131_768_000 as Weight) + // Standard Error: 176_000 + .saturating_add((256_946_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (683_078_000 as Weight) - // Standard Error: 42_000 - .saturating_add((344_294_000 as Weight).saturating_mul(n as Weight)) + (647_777_000 as Weight) + // Standard Error: 29_000 + .saturating_add((344_145_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (141_731_000 as Weight) - // Standard Error: 251_000 - .saturating_add((239_931_000 as Weight).saturating_mul(r as Weight)) + (130_042_000 as Weight) + // Standard Error: 158_000 + .saturating_add((225_474_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (563_895_000 as Weight) - // Standard Error: 51_000 - .saturating_add((160_216_000 as Weight).saturating_mul(n as Weight)) + (638_275_000 as Weight) + // Standard Error: 30_000 + .saturating_add((159_832_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (132_587_000 as Weight) - // Standard Error: 159_000 - .saturating_add((239_287_000 as Weight).saturating_mul(r as Weight)) + (126_632_000 as Weight) + // Standard Error: 143_000 + .saturating_add((225_612_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (606_572_000 as Weight) - // Standard Error: 34_000 - .saturating_add((160_101_000 as Weight).saturating_mul(n as Weight)) + (656_936_000 as Weight) + // Standard Error: 35_000 + .saturating_add((159_763_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (24_366_000 as Weight) - // Standard Error: 21_000 - .saturating_add((3_114_000 as Weight).saturating_mul(r as Weight)) + (25_205_000 as Weight) + // Standard Error: 26_000 + .saturating_add((3_311_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (26_779_000 as Weight) + (27_394_000 as Weight) // Standard Error: 28_000 - .saturating_add((161_654_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((159_123_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (26_763_000 as Weight) - // Standard Error: 88_000 - .saturating_add((232_822_000 as Weight).saturating_mul(r as Weight)) + (27_398_000 as Weight) + // Standard Error: 57_000 + .saturating_add((229_775_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (24_342_000 as Weight) - // Standard Error: 36_000 - .saturating_add((12_530_000 as Weight).saturating_mul(r as Weight)) + (25_212_000 as Weight) + // Standard Error: 22_000 + .saturating_add((12_291_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (24_301_000 as Weight) - // Standard Error: 25_000 - .saturating_add((12_106_000 as Weight).saturating_mul(r as Weight)) + (25_116_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_146_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (24_253_000 as Weight) - // Standard Error: 21_000 - .saturating_add((6_464_000 as Weight).saturating_mul(r as Weight)) + (25_119_000 as Weight) + // Standard Error: 19_000 + .saturating_add((6_608_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (24_259_000 as Weight) - // Standard Error: 20_000 - .saturating_add((14_030_000 as Weight).saturating_mul(r as Weight)) + (25_146_000 as Weight) + // Standard Error: 23_000 + .saturating_add((14_017_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (24_313_000 as Weight) - // Standard Error: 37_000 - .saturating_add((15_788_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 21_000 + .saturating_add((15_460_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (37_991_000 as Weight) - // Standard Error: 0 - .saturating_add((138_000 as Weight).saturating_mul(e as Weight)) + (37_079_000 as Weight) + // Standard Error: 1_000 + .saturating_add((160_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (24_739_000 as Weight) - // Standard Error: 31_000 - .saturating_add((97_567_000 as Weight).saturating_mul(r as Weight)) + (25_599_000 as Weight) + // Standard Error: 201_000 + .saturating_add((99_705_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (32_395_000 as Weight) - // Standard Error: 432_000 - .saturating_add((198_972_000 as Weight).saturating_mul(r as Weight)) + (33_236_000 as Weight) + // Standard Error: 368_000 + .saturating_add((199_753_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (238_857_000 as Weight) + (247_488_000 as Weight) // Standard Error: 6_000 - .saturating_add((3_491_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((3_374_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (42_196_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_161_000 as Weight).saturating_mul(r as Weight)) + (44_133_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_235_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (42_133_000 as Weight) - // Standard Error: 29_000 - .saturating_add((3_459_000 as Weight).saturating_mul(r as Weight)) + (44_107_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_486_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (42_164_000 as Weight) - // Standard Error: 25_000 - .saturating_add((4_653_000 as Weight).saturating_mul(r as Weight)) + (44_116_000 as Weight) + // Standard Error: 23_000 + .saturating_add((4_757_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (27_802_000 as Weight) - // Standard Error: 28_000 - .saturating_add((7_780_000 as Weight).saturating_mul(r as Weight)) + (28_712_000 as Weight) + // Standard Error: 29_000 + .saturating_add((7_659_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (27_826_000 as Weight) - // Standard Error: 21_000 - .saturating_add((11_978_000 as Weight).saturating_mul(r as Weight)) + (28_624_000 as Weight) + // Standard Error: 25_000 + .saturating_add((11_841_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (26_753_000 as Weight) - // Standard Error: 20_000 - .saturating_add((3_494_000 as Weight).saturating_mul(r as Weight)) + (27_445_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_487_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_078_000 as Weight) - // Standard Error: 4_213_000 - .saturating_add((2_324_209_000 as Weight).saturating_mul(r as Weight)) + (26_016_000 as Weight) + // Standard Error: 4_230_000 + .saturating_add((2_300_044_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (24_301_000 as Weight) - // Standard Error: 28_000 - .saturating_add((5_201_000 as Weight).saturating_mul(r as Weight)) + (25_227_000 as Weight) + // Standard Error: 29_000 + .saturating_add((5_341_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (24_237_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_251_000 as Weight).saturating_mul(r as Weight)) + (25_163_000 as Weight) + // Standard Error: 26_000 + .saturating_add((5_355_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (24_290_000 as Weight) - // Standard Error: 20_000 - .saturating_add((5_780_000 as Weight).saturating_mul(r as Weight)) + (25_204_000 as Weight) + // Standard Error: 29_000 + .saturating_add((5_930_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (24_278_000 as Weight) - // Standard Error: 17_000 - .saturating_add((5_145_000 as Weight).saturating_mul(r as Weight)) + (25_177_000 as Weight) + // Standard Error: 21_000 + .saturating_add((5_457_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (24_249_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_248_000 as Weight).saturating_mul(r as Weight)) + (25_206_000 as Weight) + // Standard Error: 19_000 + .saturating_add((5_229_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (24_266_000 as Weight) - // Standard Error: 13_000 - .saturating_add((5_236_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 17_000 + .saturating_add((5_301_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (24_236_000 as Weight) - // Standard Error: 12_000 - .saturating_add((5_304_000 as Weight).saturating_mul(r as Weight)) + (25_184_000 as Weight) + // Standard Error: 28_000 + .saturating_add((5_356_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (24_262_000 as Weight) - // Standard Error: 22_000 - .saturating_add((7_220_000 as Weight).saturating_mul(r as Weight)) + (25_195_000 as Weight) + // Standard Error: 48_000 + .saturating_add((7_406_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (24_287_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_072_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_303_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (24_211_000 as Weight) - // Standard Error: 12_000 - .saturating_add((7_196_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 34_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (24_175_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + (25_152_000 as Weight) + // Standard Error: 46_000 + .saturating_add((7_464_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (24_209_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_131_000 as Weight).saturating_mul(r as Weight)) + (25_140_000 as Weight) + // Standard Error: 27_000 + .saturating_add((7_308_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (24_261_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_203_000 as Weight).saturating_mul(r as Weight)) + (25_723_000 as Weight) + // Standard Error: 29_000 + .saturating_add((6_846_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (24_258_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_120_000 as Weight).saturating_mul(r as Weight)) + (25_201_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (24_236_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_076_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_143_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (24_262_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_261_000 as Weight).saturating_mul(r as Weight)) + (25_146_000 as Weight) + // Standard Error: 37_000 + .saturating_add((7_451_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (24_242_000 as Weight) - // Standard Error: 23_000 - .saturating_add((7_249_000 as Weight).saturating_mul(r as Weight)) + (25_193_000 as Weight) + // Standard Error: 30_000 + .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (24_248_000 as Weight) - // Standard Error: 28_000 - .saturating_add((7_149_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 30_000 + .saturating_add((7_214_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (24_243_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_128_000 as Weight).saturating_mul(r as Weight)) + (25_221_000 as Weight) + // Standard Error: 34_000 + .saturating_add((7_168_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (24_217_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_237_000 as Weight).saturating_mul(r as Weight)) + (25_221_000 as Weight) + // Standard Error: 28_000 + .saturating_add((7_200_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (24_191_000 as Weight) - // Standard Error: 28_000 - .saturating_add((12_970_000 as Weight).saturating_mul(r as Weight)) + (25_229_000 as Weight) + // Standard Error: 32_000 + .saturating_add((13_066_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (24_213_000 as Weight) - // Standard Error: 19_000 - .saturating_add((12_106_000 as Weight).saturating_mul(r as Weight)) + (25_210_000 as Weight) + // Standard Error: 28_000 + .saturating_add((12_314_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (24_238_000 as Weight) - // Standard Error: 15_000 - .saturating_add((12_944_000 as Weight).saturating_mul(r as Weight)) + (25_186_000 as Weight) + // Standard Error: 24_000 + .saturating_add((13_055_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (24_317_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_129_000 as Weight).saturating_mul(r as Weight)) + (25_162_000 as Weight) + // Standard Error: 25_000 + .saturating_add((12_327_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (24_282_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_123_000 as Weight).saturating_mul(r as Weight)) + (25_191_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_153_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (24_243_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_148_000 as Weight).saturating_mul(r as Weight)) + (25_184_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_120_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (24_239_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_157_000 as Weight).saturating_mul(r as Weight)) + (25_129_000 as Weight) + // Standard Error: 31_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (24_279_000 as Weight) + (25_156_000 as Weight) // Standard Error: 16_000 - .saturating_add((7_253_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((7_333_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (24_285_000 as Weight) - // Standard Error: 29_000 - .saturating_add((7_333_000 as Weight).saturating_mul(r as Weight)) + (25_159_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_415_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (24_298_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_228_000 as Weight).saturating_mul(r as Weight)) + (25_181_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_265_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (24_226_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_269_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_443_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (24_235_000 as Weight) - // Standard Error: 27_000 - .saturating_add((7_299_000 as Weight).saturating_mul(r as Weight)) + (25_103_000 as Weight) + // Standard Error: 44_000 + .saturating_add((7_463_000 as Weight).saturating_mul(r as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { fn on_initialize() -> Weight { - (3_947_000 as Weight) + (3_733_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { - (46_644_000 as Weight) + (49_569_000 as Weight) // Standard Error: 5_000 .saturating_add((2_295_000 as Weight).saturating_mul(k as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) @@ -754,235 +784,259 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (0 as Weight) - // Standard Error: 164_000 - .saturating_add((165_220_000 as Weight).saturating_mul(q as Weight)) + (358_064_000 as Weight) + // Standard Error: 143_000 + .saturating_add((140_992_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 { + (44_198_000 as Weight) + // Standard Error: 188_000 + .saturating_add((125_833_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 update_schedule() -> Weight { - (28_195_000 as Weight) + (29_190_000 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 { - (0 as Weight) - // Standard Error: 126_000 - .saturating_add((154_196_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 63_000 - .saturating_add((2_764_000 as Weight).saturating_mul(s as Weight)) + (180_015_000 as Weight) + // Standard Error: 197_000 + .saturating_add((167_480_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 12_000 + .saturating_add((2_581_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } - fn instantiate(s: u32, ) -> Weight { - (201_407_000 as Weight) + fn instantiate(c: u32, s: u32, ) -> Weight { + (180_996_000 as Weight) + // Standard Error: 14_000 + .saturating_add((8_684_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 1_000 - .saturating_add((2_247_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_518_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } - fn call() -> Weight { - (180_337_000 as Weight) + fn call(c: u32, ) -> Weight { + (184_326_000 as Weight) + // Standard Error: 2_000 + .saturating_add((3_920_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } - fn claim_surcharge() -> Weight { - (322_371_000 as Weight) + fn claim_surcharge(c: u32, ) -> Weight { + (303_270_000 as Weight) + // Standard Error: 5_000 + .saturating_add((5_108_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 { - (135_499_000 as Weight) - // Standard Error: 296_000 - .saturating_add((275_938_000 as Weight).saturating_mul(r as Weight)) + (128_965_000 as Weight) + // Standard Error: 130_000 + .saturating_add((270_123_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (132_674_000 as Weight) - // Standard Error: 158_000 - .saturating_add((273_808_000 as Weight).saturating_mul(r as Weight)) + (137_748_000 as Weight) + // Standard Error: 184_000 + .saturating_add((270_103_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (126_819_000 as Weight) - // Standard Error: 145_000 - .saturating_add((269_173_000 as Weight).saturating_mul(r as Weight)) + (118_784_000 as Weight) + // Standard Error: 234_000 + .saturating_add((264_467_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (140_223_000 as Weight) - // Standard Error: 259_000 - .saturating_add((581_353_000 as Weight).saturating_mul(r as Weight)) + (146_072_000 as Weight) + // Standard Error: 207_000 + .saturating_add((573_282_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (129_490_000 as Weight) - // Standard Error: 132_000 - .saturating_add((269_433_000 as Weight).saturating_mul(r as Weight)) + (133_857_000 as Weight) + // Standard Error: 151_000 + .saturating_add((263_110_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (127_251_000 as Weight) - // Standard Error: 161_000 - .saturating_add((268_720_000 as Weight).saturating_mul(r as Weight)) + (130_447_000 as Weight) + // Standard Error: 125_000 + .saturating_add((265_565_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (129_546_000 as Weight) - // Standard Error: 130_000 - .saturating_add((268_280_000 as Weight).saturating_mul(r as Weight)) + (116_232_000 as Weight) + // Standard Error: 327_000 + .saturating_add((265_728_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (133_306_000 as Weight) - // Standard Error: 208_000 - .saturating_add((604_235_000 as Weight).saturating_mul(r as Weight)) + (175_561_000 as Weight) + // Standard Error: 292_000 + .saturating_add((604_373_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (133_689_000 as Weight) - // Standard Error: 115_000 - .saturating_add((267_107_000 as Weight).saturating_mul(r as Weight)) + (133_961_000 as Weight) + // Standard Error: 150_000 + .saturating_add((262_329_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (133_773_000 as Weight) - // Standard Error: 130_000 - .saturating_add((268_897_000 as Weight).saturating_mul(r as Weight)) + (128_662_000 as Weight) + // Standard Error: 150_000 + .saturating_add((263_234_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (133_222_000 as Weight) - // Standard Error: 476_000 - .saturating_add((514_400_000 as Weight).saturating_mul(r as Weight)) + (142_580_000 as Weight) + // Standard Error: 205_000 + .saturating_add((505_378_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (118_769_000 as Weight) - // Standard Error: 102_000 - .saturating_add((134_134_000 as Weight).saturating_mul(r as Weight)) + (116_346_000 as Weight) + // Standard Error: 86_000 + .saturating_add((124_599_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (124_719_000 as Weight) - // Standard Error: 93_000 - .saturating_add((7_486_000 as Weight).saturating_mul(r as Weight)) + (124_679_000 as Weight) + // Standard Error: 81_000 + .saturating_add((7_310_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (136_348_000 as Weight) + (136_069_000 as Weight) // Standard Error: 0 .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (118_710_000 as Weight) - // Standard Error: 77_000 - .saturating_add((4_566_000 as Weight).saturating_mul(r as Weight)) + (118_807_000 as Weight) + // Standard Error: 66_000 + .saturating_add((4_740_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (127_609_000 as Weight) + (127_702_000 as Weight) // Standard Error: 0 - .saturating_add((786_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((784_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (125_463_000 as Weight) - // Standard Error: 154_000 - .saturating_add((106_188_000 as Weight).saturating_mul(r as Weight)) + (124_847_000 as Weight) + // Standard Error: 87_000 + .saturating_add((107_679_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } + fn seal_terminate_per_code_kb(c: u32, ) -> Weight { + (237_115_000 as Weight) + // Standard Error: 6_000 + .saturating_add((8_556_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } fn seal_restore_to(r: u32, ) -> Weight { - (219_195_000 as Weight) - // Standard Error: 361_000 - .saturating_add((131_326_000 as Weight).saturating_mul(r as Weight)) + (217_959_000 as Weight) + // Standard Error: 455_000 + .saturating_add((134_528_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((6 as Weight).saturating_mul(r as Weight))) } - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (6_742_000 as Weight) - // Standard Error: 2_484_000 - .saturating_add((3_747_735_000 as Weight).saturating_mul(d as Weight)) + fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 151_000 + .saturating_add((9_061_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 151_000 + .saturating_add((4_807_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 1_331_000 + .saturating_add((3_736_196_000 as Weight).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(8 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 { - (137_248_000 as Weight) - // Standard Error: 662_000 - .saturating_add((661_121_000 as Weight).saturating_mul(r as Weight)) + (134_143_000 as Weight) + // Standard Error: 233_000 + .saturating_add((643_555_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (147_654_000 as Weight) - // Standard Error: 305_000 - .saturating_add((935_148_000 as Weight).saturating_mul(r as Weight)) + (142_838_000 as Weight) + // Standard Error: 367_000 + .saturating_add((937_126_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_246_123_000 as Weight) - // Standard Error: 2_807_000 - .saturating_add((585_535_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 553_000 - .saturating_add((249_976_000 as Weight).saturating_mul(n as Weight)) + (1_210_711_000 as Weight) + // Standard Error: 2_124_000 + .saturating_add((594_541_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 418_000 + .saturating_add((251_068_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (140_588_000 as Weight) - // Standard Error: 228_000 - .saturating_add((707_872_000 as Weight).saturating_mul(r as Weight)) + (144_533_000 as Weight) + // Standard Error: 220_000 + .saturating_add((714_590_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_set_storage(r: u32, ) -> Weight { - (2_767_124_000 as Weight) - // Standard Error: 18_504_000 - .saturating_add((17_507_873_000 as Weight).saturating_mul(r as Weight)) + (406_366_000 as Weight) + // Standard Error: 3_533_000 + .saturating_add((16_167_082_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 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 { - (1_748_586_000 as Weight) - // Standard Error: 359_000 - .saturating_add((75_231_000 as Weight).saturating_mul(n as Weight)) + (1_739_590_000 as Weight) + // Standard Error: 390_000 + .saturating_add((74_815_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 2_209_000 - .saturating_add((2_261_355_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_284_000 + .saturating_add((2_281_347_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 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_get_storage(r: u32, ) -> Weight { - (83_780_000 as Weight) - // Standard Error: 965_000 - .saturating_add((973_164_000 as Weight).saturating_mul(r as Weight)) + (81_889_000 as Weight) + // Standard Error: 1_171_000 + .saturating_add((930_704_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (728_625_000 as Weight) - // Standard Error: 294_000 - .saturating_add((154_625_000 as Weight).saturating_mul(n as Weight)) + (709_323_000 as Weight) + // Standard Error: 391_000 + .saturating_add((155_689_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_543_000 - .saturating_add((5_467_966_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 1_846_000 + .saturating_add((5_566_275_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) @@ -990,343 +1044,347 @@ impl WeightInfo for () { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 9_216_000 - .saturating_add((10_265_093_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 4_823_000 + .saturating_add((10_461_861_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) } - fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (10_426_869_000 as Weight) - // Standard Error: 114_622_000 - .saturating_add((4_366_037_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 40_000 - .saturating_add((59_741_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 43_000 - .saturating_add((82_331_000 as Weight).saturating_mul(o as Weight)) + fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { + (9_686_594_000 as Weight) + // Standard Error: 473_000 + .saturating_add((393_132_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 197_094_000 + .saturating_add((4_957_181_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 62_000 + .saturating_add((59_974_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 66_000 + .saturating_add((83_027_000 as Weight).saturating_mul(o as Weight)) .saturating_add(RocksDbWeight::get().reads(206 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: 35_927_000 - .saturating_add((21_088_623_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 34_133_000 + .saturating_add((21_407_630_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) .saturating_add(RocksDbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (17_200_760_000 as Weight) - // Standard Error: 157_000 - .saturating_add((61_221_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 157_000 - .saturating_add((84_149_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 157_000 - .saturating_add((284_655_000 as Weight).saturating_mul(s as Weight)) + fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { + (9_705_322_000 as Weight) + // Standard Error: 674_000 + .saturating_add((879_118_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 95_000 + .saturating_add((63_025_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 95_000 + .saturating_add((87_633_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 95_000 + .saturating_add((311_987_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(207 as Weight)) .saturating_add(RocksDbWeight::get().writes(203 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (126_005_000 as Weight) - // Standard Error: 133_000 - .saturating_add((252_338_000 as Weight).saturating_mul(r as Weight)) + (125_486_000 as Weight) + // Standard Error: 266_000 + .saturating_add((240_913_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (727_930_000 as Weight) - // Standard Error: 57_000 - .saturating_add((430_299_000 as Weight).saturating_mul(n as Weight)) + (636_153_000 as Weight) + // Standard Error: 47_000 + .saturating_add((429_541_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (129_778_000 as Weight) - // Standard Error: 146_000 - .saturating_add((266_097_000 as Weight).saturating_mul(r as Weight)) + (131_768_000 as Weight) + // Standard Error: 176_000 + .saturating_add((256_946_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (683_078_000 as Weight) - // Standard Error: 42_000 - .saturating_add((344_294_000 as Weight).saturating_mul(n as Weight)) + (647_777_000 as Weight) + // Standard Error: 29_000 + .saturating_add((344_145_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (141_731_000 as Weight) - // Standard Error: 251_000 - .saturating_add((239_931_000 as Weight).saturating_mul(r as Weight)) + (130_042_000 as Weight) + // Standard Error: 158_000 + .saturating_add((225_474_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (563_895_000 as Weight) - // Standard Error: 51_000 - .saturating_add((160_216_000 as Weight).saturating_mul(n as Weight)) + (638_275_000 as Weight) + // Standard Error: 30_000 + .saturating_add((159_832_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (132_587_000 as Weight) - // Standard Error: 159_000 - .saturating_add((239_287_000 as Weight).saturating_mul(r as Weight)) + (126_632_000 as Weight) + // Standard Error: 143_000 + .saturating_add((225_612_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (606_572_000 as Weight) - // Standard Error: 34_000 - .saturating_add((160_101_000 as Weight).saturating_mul(n as Weight)) + (656_936_000 as Weight) + // Standard Error: 35_000 + .saturating_add((159_763_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (24_366_000 as Weight) - // Standard Error: 21_000 - .saturating_add((3_114_000 as Weight).saturating_mul(r as Weight)) + (25_205_000 as Weight) + // Standard Error: 26_000 + .saturating_add((3_311_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (26_779_000 as Weight) + (27_394_000 as Weight) // Standard Error: 28_000 - .saturating_add((161_654_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((159_123_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (26_763_000 as Weight) - // Standard Error: 88_000 - .saturating_add((232_822_000 as Weight).saturating_mul(r as Weight)) + (27_398_000 as Weight) + // Standard Error: 57_000 + .saturating_add((229_775_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (24_342_000 as Weight) - // Standard Error: 36_000 - .saturating_add((12_530_000 as Weight).saturating_mul(r as Weight)) + (25_212_000 as Weight) + // Standard Error: 22_000 + .saturating_add((12_291_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (24_301_000 as Weight) - // Standard Error: 25_000 - .saturating_add((12_106_000 as Weight).saturating_mul(r as Weight)) + (25_116_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_146_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (24_253_000 as Weight) - // Standard Error: 21_000 - .saturating_add((6_464_000 as Weight).saturating_mul(r as Weight)) + (25_119_000 as Weight) + // Standard Error: 19_000 + .saturating_add((6_608_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (24_259_000 as Weight) - // Standard Error: 20_000 - .saturating_add((14_030_000 as Weight).saturating_mul(r as Weight)) + (25_146_000 as Weight) + // Standard Error: 23_000 + .saturating_add((14_017_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (24_313_000 as Weight) - // Standard Error: 37_000 - .saturating_add((15_788_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 21_000 + .saturating_add((15_460_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (37_991_000 as Weight) - // Standard Error: 0 - .saturating_add((138_000 as Weight).saturating_mul(e as Weight)) + (37_079_000 as Weight) + // Standard Error: 1_000 + .saturating_add((160_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (24_739_000 as Weight) - // Standard Error: 31_000 - .saturating_add((97_567_000 as Weight).saturating_mul(r as Weight)) + (25_599_000 as Weight) + // Standard Error: 201_000 + .saturating_add((99_705_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (32_395_000 as Weight) - // Standard Error: 432_000 - .saturating_add((198_972_000 as Weight).saturating_mul(r as Weight)) + (33_236_000 as Weight) + // Standard Error: 368_000 + .saturating_add((199_753_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (238_857_000 as Weight) + (247_488_000 as Weight) // Standard Error: 6_000 - .saturating_add((3_491_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((3_374_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (42_196_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_161_000 as Weight).saturating_mul(r as Weight)) + (44_133_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_235_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (42_133_000 as Weight) - // Standard Error: 29_000 - .saturating_add((3_459_000 as Weight).saturating_mul(r as Weight)) + (44_107_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_486_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (42_164_000 as Weight) - // Standard Error: 25_000 - .saturating_add((4_653_000 as Weight).saturating_mul(r as Weight)) + (44_116_000 as Weight) + // Standard Error: 23_000 + .saturating_add((4_757_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (27_802_000 as Weight) - // Standard Error: 28_000 - .saturating_add((7_780_000 as Weight).saturating_mul(r as Weight)) + (28_712_000 as Weight) + // Standard Error: 29_000 + .saturating_add((7_659_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (27_826_000 as Weight) - // Standard Error: 21_000 - .saturating_add((11_978_000 as Weight).saturating_mul(r as Weight)) + (28_624_000 as Weight) + // Standard Error: 25_000 + .saturating_add((11_841_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (26_753_000 as Weight) - // Standard Error: 20_000 - .saturating_add((3_494_000 as Weight).saturating_mul(r as Weight)) + (27_445_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_487_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_078_000 as Weight) - // Standard Error: 4_213_000 - .saturating_add((2_324_209_000 as Weight).saturating_mul(r as Weight)) + (26_016_000 as Weight) + // Standard Error: 4_230_000 + .saturating_add((2_300_044_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (24_301_000 as Weight) - // Standard Error: 28_000 - .saturating_add((5_201_000 as Weight).saturating_mul(r as Weight)) + (25_227_000 as Weight) + // Standard Error: 29_000 + .saturating_add((5_341_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (24_237_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_251_000 as Weight).saturating_mul(r as Weight)) + (25_163_000 as Weight) + // Standard Error: 26_000 + .saturating_add((5_355_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (24_290_000 as Weight) - // Standard Error: 20_000 - .saturating_add((5_780_000 as Weight).saturating_mul(r as Weight)) + (25_204_000 as Weight) + // Standard Error: 29_000 + .saturating_add((5_930_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (24_278_000 as Weight) - // Standard Error: 17_000 - .saturating_add((5_145_000 as Weight).saturating_mul(r as Weight)) + (25_177_000 as Weight) + // Standard Error: 21_000 + .saturating_add((5_457_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (24_249_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_248_000 as Weight).saturating_mul(r as Weight)) + (25_206_000 as Weight) + // Standard Error: 19_000 + .saturating_add((5_229_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (24_266_000 as Weight) - // Standard Error: 13_000 - .saturating_add((5_236_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 17_000 + .saturating_add((5_301_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (24_236_000 as Weight) - // Standard Error: 12_000 - .saturating_add((5_304_000 as Weight).saturating_mul(r as Weight)) + (25_184_000 as Weight) + // Standard Error: 28_000 + .saturating_add((5_356_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (24_262_000 as Weight) - // Standard Error: 22_000 - .saturating_add((7_220_000 as Weight).saturating_mul(r as Weight)) + (25_195_000 as Weight) + // Standard Error: 48_000 + .saturating_add((7_406_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (24_287_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_072_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_303_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (24_211_000 as Weight) - // Standard Error: 12_000 - .saturating_add((7_196_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 34_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (24_175_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + (25_152_000 as Weight) + // Standard Error: 46_000 + .saturating_add((7_464_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (24_209_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_131_000 as Weight).saturating_mul(r as Weight)) + (25_140_000 as Weight) + // Standard Error: 27_000 + .saturating_add((7_308_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (24_261_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_203_000 as Weight).saturating_mul(r as Weight)) + (25_723_000 as Weight) + // Standard Error: 29_000 + .saturating_add((6_846_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (24_258_000 as Weight) - // Standard Error: 25_000 - .saturating_add((7_120_000 as Weight).saturating_mul(r as Weight)) + (25_201_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (24_236_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_076_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_143_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (24_262_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_261_000 as Weight).saturating_mul(r as Weight)) + (25_146_000 as Weight) + // Standard Error: 37_000 + .saturating_add((7_451_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (24_242_000 as Weight) - // Standard Error: 23_000 - .saturating_add((7_249_000 as Weight).saturating_mul(r as Weight)) + (25_193_000 as Weight) + // Standard Error: 30_000 + .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (24_248_000 as Weight) - // Standard Error: 28_000 - .saturating_add((7_149_000 as Weight).saturating_mul(r as Weight)) + (25_192_000 as Weight) + // Standard Error: 30_000 + .saturating_add((7_214_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (24_243_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_128_000 as Weight).saturating_mul(r as Weight)) + (25_221_000 as Weight) + // Standard Error: 34_000 + .saturating_add((7_168_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (24_217_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_237_000 as Weight).saturating_mul(r as Weight)) + (25_221_000 as Weight) + // Standard Error: 28_000 + .saturating_add((7_200_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (24_191_000 as Weight) - // Standard Error: 28_000 - .saturating_add((12_970_000 as Weight).saturating_mul(r as Weight)) + (25_229_000 as Weight) + // Standard Error: 32_000 + .saturating_add((13_066_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (24_213_000 as Weight) - // Standard Error: 19_000 - .saturating_add((12_106_000 as Weight).saturating_mul(r as Weight)) + (25_210_000 as Weight) + // Standard Error: 28_000 + .saturating_add((12_314_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (24_238_000 as Weight) - // Standard Error: 15_000 - .saturating_add((12_944_000 as Weight).saturating_mul(r as Weight)) + (25_186_000 as Weight) + // Standard Error: 24_000 + .saturating_add((13_055_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (24_317_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_129_000 as Weight).saturating_mul(r as Weight)) + (25_162_000 as Weight) + // Standard Error: 25_000 + .saturating_add((12_327_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (24_282_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_123_000 as Weight).saturating_mul(r as Weight)) + (25_191_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_153_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (24_243_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_148_000 as Weight).saturating_mul(r as Weight)) + (25_184_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_120_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (24_239_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_157_000 as Weight).saturating_mul(r as Weight)) + (25_129_000 as Weight) + // Standard Error: 31_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (24_279_000 as Weight) + (25_156_000 as Weight) // Standard Error: 16_000 - .saturating_add((7_253_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((7_333_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (24_285_000 as Weight) - // Standard Error: 29_000 - .saturating_add((7_333_000 as Weight).saturating_mul(r as Weight)) + (25_159_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_415_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (24_298_000 as Weight) - // Standard Error: 17_000 - .saturating_add((7_228_000 as Weight).saturating_mul(r as Weight)) + (25_181_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_265_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (24_226_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_269_000 as Weight).saturating_mul(r as Weight)) + (25_165_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_443_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (24_235_000 as Weight) - // Standard Error: 27_000 - .saturating_add((7_299_000 as Weight).saturating_mul(r as Weight)) + (25_103_000 as Weight) + // Standard Error: 44_000 + .saturating_add((7_463_000 as Weight).saturating_mul(r as Weight)) } }