diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index b17bbed107..5acc429e95 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -822,16 +822,10 @@ impl pallet_tips::Config for Runtime { } parameter_types! { - pub TombstoneDeposit: Balance = deposit( + pub ContractDeposit: Balance = deposit( 1, >::contract_info_size(), ); - pub DepositPerContract: Balance = TombstoneDeposit::get(); - pub const DepositPerStorageByte: Balance = deposit(0, 1); - pub const DepositPerStorageItem: Balance = deposit(1, 0); - pub RentFraction: Perbill = Perbill::from_rational(1u32, 30 * DAYS); - pub const SurchargeReward: Balance = 150 * MILLICENTS; - pub const SignedClaimHandicap: u32 = 2; pub const MaxValueSize: u32 = 16 * 1024; // The lazy deletion runs inside on_initialize. pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * @@ -858,14 +852,7 @@ impl pallet_contracts::Config for Runtime { /// change because that would break already deployed contracts. The `Call` structure itself /// is not allowed to change the indices of existing pallets, too. type CallFilter = Nothing; - type RentPayment = (); - type SignedClaimHandicap = SignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type DepositPerContract = DepositPerContract; - type DepositPerStorageByte = DepositPerStorageByte; - type DepositPerStorageItem = DepositPerStorageItem; - type RentFraction = RentFraction; - type SurchargeReward = SurchargeReward; + type ContractDeposit = ContractDeposit; type CallStack = [pallet_contracts::Frame; 31]; type WeightPrice = pallet_transaction_payment::Pallet; type WeightInfo = pallet_contracts::weights::SubstrateWeight; @@ -1461,9 +1448,9 @@ impl_runtime_apis! { code: pallet_contracts_primitives::Code, data: Vec, salt: Vec, - ) -> pallet_contracts_primitives::ContractInstantiateResult + ) -> pallet_contracts_primitives::ContractInstantiateResult { - Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, true) + Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true) } fn get_storage( @@ -1472,12 +1459,6 @@ impl_runtime_apis! { ) -> pallet_contracts_primitives::GetStorageResult { Contracts::get_storage(address, key) } - - fn rent_projection( - address: AccountId, - ) -> pallet_contracts_primitives::RentProjectionResult { - Contracts::rent_projection(address) - } } impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< diff --git a/substrate/frame/contracts/common/src/lib.rs b/substrate/frame/contracts/common/src/lib.rs index 9260b3e05c..c57f728c26 100644 --- a/substrate/frame/contracts/common/src/lib.rs +++ b/substrate/frame/contracts/common/src/lib.rs @@ -70,35 +70,17 @@ pub struct ContractResult { pub type ContractExecResult = ContractResult>; /// Result type of a `bare_instantiate` call. -pub type ContractInstantiateResult = - ContractResult, DispatchError>>; +pub type ContractInstantiateResult = + ContractResult, DispatchError>>; /// Result type of a `get_storage` call. pub type GetStorageResult = Result>, ContractAccessError>; -/// Result type of a `rent_projection` call. -pub type RentProjectionResult = - Result, ContractAccessError>; - /// The possible errors that can happen querying the storage of a contract. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] pub enum ContractAccessError { /// The given address doesn't point to a contract. DoesntExist, - /// The specified contract is a tombstone and thus cannot have any storage. - IsTombstone, -} - -#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] -pub enum RentProjection { - /// Eviction is projected to happen at the specified block number. - EvictionAt(BlockNumber), - /// No eviction is scheduled. - /// - /// E.g. Contract accumulated enough funds to offset the rent storage costs. - NoEviction, } bitflags! { @@ -134,19 +116,11 @@ impl ExecReturnValue { #[derive(PartialEq, Eq, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] -pub struct InstantiateReturnValue { +pub struct InstantiateReturnValue { /// The output of the called constructor. pub result: ExecReturnValue, /// The account id of the new contract. pub account_id: AccountId, - /// Information about when and if the new project will be evicted. - /// - /// # Note - /// - /// `None` if `bare_instantiate` was called with - /// `compute_projection` set to false. From the perspective of an RPC this means that - /// the runtime API did not request this value and this feature is therefore unsupported. - pub rent_projection: Option>, } /// Reference to an existing code hash or a new wasm module. diff --git a/substrate/frame/contracts/fixtures/check_default_rent_allowance.wat b/substrate/frame/contracts/fixtures/check_default_rent_allowance.wat deleted file mode 100644 index 64cd67186b..0000000000 --- a/substrate/frame/contracts/fixtures/check_default_rent_allowance.wat +++ /dev/null @@ -1,43 +0,0 @@ -(module - (import "seal0" "seal_rent_allowance" (func $seal_rent_allowance (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) reserved for $seal_rent_allowance output - - ;; [8, 16) length of the buffer - (data (i32.const 8) "\08") - - ;; [16, inf) zero initialized - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call")) - - (func (export "deploy") - ;; fill the buffer with the rent allowance. - (call $seal_rent_allowance (i32.const 0) (i32.const 8)) - - ;; assert len == 8 - (call $assert - (i32.eq - (i32.load (i32.const 8)) - (i32.const 8) - ) - ) - - ;; assert that contents of the buffer is equal to >::max_value(). - (call $assert - (i64.eq - (i64.load (i32.const 0)) - (i64.const 0xFFFFFFFFFFFFFFFF) - ) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/destroy_and_transfer.wat b/substrate/frame/contracts/fixtures/destroy_and_transfer.wat index 7e1d84f3cf..aa13cd8b81 100644 --- a/substrate/frame/contracts/fixtures/destroy_and_transfer.wat +++ b/substrate/frame/contracts/fixtures/destroy_and_transfer.wat @@ -145,7 +145,7 @@ ;; Calling the destination address with non-empty input data should now work since the ;; contract has been removed. Also transfer a balance to the address so we can ensure this - ;; does not keep the contract alive. + ;; does not hinder the contract from being removed. (call $assert (i32.eq (call $seal_transfer diff --git a/substrate/frame/contracts/fixtures/restoration.wat b/substrate/frame/contracts/fixtures/restoration.wat deleted file mode 100644 index e24e5695a3..0000000000 --- a/substrate/frame/contracts/fixtures/restoration.wat +++ /dev/null @@ -1,72 +0,0 @@ -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal1" "seal_restore_to" - (func $seal_restore_to - (param i32 i32 i32 i32 i32) - ) - ) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; copy code hash to contract memory - (call $seal_input (i32.const 308) (i32.const 304)) - (call $assert - (i32.eq - (i32.load (i32.const 304)) - (i32.const 64) - ) - ) - (call $seal_restore_to - ;; Pointer to the encoded dest buffer. - (i32.const 340) - ;; Pointer to the encoded code hash buffer - (i32.const 308) - ;; Pointer to the encoded rent_allowance buffer - (i32.const 296) - ;; Pointer and number of items in the delta buffer. - ;; This buffer specifies multiple keys for removal before restoration. - (i32.const 100) - (i32.const 1) - ) - ) - (func (export "deploy") - ;; Data to restore - (call $seal_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - - ;; ACL - (call $seal_set_storage - (i32.const 100) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; Data to restore - (data (i32.const 0) "\28") - - ;; Buffer that has ACL storage keys. - (data (i32.const 100) "\01") - - ;; [296, 304) Rent allowance - (data (i32.const 296) "\32\00\00\00\00\00\00\00") - - ;; [304, 308) Size of the buffer that holds code_hash + addr - (data (i32.const 304) "\40") - - ;; [308, 340) code hash of bob (copied by seal_input) - ;; [340, 372) addr of bob (copied by seal_input) -) diff --git a/substrate/frame/contracts/fixtures/set_rent.wat b/substrate/frame/contracts/fixtures/set_rent.wat deleted file mode 100644 index 4abb7ffe9d..0000000000 --- a/substrate/frame/contracts/fixtures/set_rent.wat +++ /dev/null @@ -1,105 +0,0 @@ -(module - (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_clear_storage" (func $seal_clear_storage (param i32))) - (import "seal0" "seal_set_rent_allowance" (func $seal_set_rent_allowance (param i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; insert a value of 4 bytes into storage - (func $call_0 - (call $seal_set_storage - (i32.const 1) - (i32.const 0) - (i32.const 4) - ) - ) - - ;; remove the value inserted by call_1 - (func $call_1 - (call $seal_clear_storage - (i32.const 1) - ) - ) - - ;; transfer 50 to CHARLIE - (func $call_2 - (call $assert - (i32.eq - (call $seal_transfer (i32.const 136) (i32.const 32) (i32.const 100) (i32.const 8)) - (i32.const 0) - ) - ) - ) - - ;; do nothing - (func $call_else) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - ;; Dispatch the call according to input size - (func (export "call") - (local $input_size i32) - ;; 4 byte i32 for br_table followed by 32 byte destination for transfer - (i32.store (i32.const 128) (i32.const 36)) - (call $seal_input (i32.const 132) (i32.const 128)) - (set_local $input_size - (i32.load (i32.const 132)) - ) - (block $IF_ELSE - (block $IF_2 - (block $IF_1 - (block $IF_0 - (br_table $IF_0 $IF_1 $IF_2 $IF_ELSE - (get_local $input_size) - ) - (unreachable) - ) - (call $call_0) - return - ) - (call $call_1) - return - ) - (call $call_2) - return - ) - (call $call_else) - ) - - ;; Set into storage a 4 bytes value - ;; Set call set_rent_allowance with input - (func (export "deploy") - (call $seal_set_storage - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - (i32.store (i32.const 128) (i32.const 64)) - (call $seal_input - (i32.const 132) - (i32.const 128) - ) - (call $seal_set_rent_allowance - (i32.const 132) - (i32.load (i32.const 128)) - ) - ) - - ;; Encoding of 10 in balance - (data (i32.const 0) "\28") - - ;; encoding of 50 balance - (data (i32.const 100) "\32") - - ;; [128, 132) size of seal input buffer - - ;; [132, inf) output buffer for seal input -) diff --git a/substrate/frame/contracts/rpc/runtime-api/src/lib.rs b/substrate/frame/contracts/rpc/runtime-api/src/lib.rs index 742c299728..20dfbe210e 100644 --- a/substrate/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/substrate/frame/contracts/rpc/runtime-api/src/lib.rs @@ -25,7 +25,7 @@ use codec::Codec; use pallet_contracts_primitives::{ - Code, ContractExecResult, ContractInstantiateResult, GetStorageResult, RentProjectionResult, + Code, ContractExecResult, ContractInstantiateResult, GetStorageResult, }; use sp_std::vec::Vec; @@ -58,25 +58,16 @@ sp_api::decl_runtime_apis! { code: Code, data: Vec, salt: Vec, - ) -> ContractInstantiateResult; + ) -> ContractInstantiateResult; /// Query a given storage key in a given contract. /// /// Returns `Ok(Some(Vec))` if the storage value exists under the given key in the /// specified account and `Ok(None)` if it doesn't. If the account specified by the address - /// doesn't exist, or doesn't have a contract or if the contract is a tombstone, then `Err` - /// is returned. + /// doesn't exist, or doesn't have a contract then `Err` is returned. fn get_storage( address: AccountId, key: [u8; 32], ) -> GetStorageResult; - - /// Returns the projected time a given contract will be able to sustain paying its rent. - /// - /// The returned projection is relevant for the current block, i.e. it is as if the contract - /// was accessed at the current block. - /// - /// Returns `Err` if the contract is in a tombstone state or doesn't exist. - fn rent_projection(address: AccountId) -> RentProjectionResult; } } diff --git a/substrate/frame/contracts/rpc/src/lib.rs b/substrate/frame/contracts/rpc/src/lib.rs index 2586ec7903..e0796af056 100644 --- a/substrate/frame/contracts/rpc/src/lib.rs +++ b/substrate/frame/contracts/rpc/src/lib.rs @@ -22,9 +22,7 @@ use std::sync::Arc; use codec::Codec; use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_derive::rpc; -use pallet_contracts_primitives::{ - Code, ContractExecResult, ContractInstantiateResult, RentProjection, -}; +use pallet_contracts_primitives::{Code, ContractExecResult, ContractInstantiateResult}; use serde::{Deserialize, Serialize}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; @@ -40,7 +38,6 @@ pub use pallet_contracts_rpc_runtime_api::ContractsApi as ContractsRuntimeApi; const RUNTIME_ERROR: i64 = 1; const CONTRACT_DOESNT_EXIST: i64 = 2; -const CONTRACT_IS_A_TOMBSTONE: i64 = 3; pub type Weight = u64; @@ -69,11 +66,6 @@ impl From for Error { message: "The specified contract doesn't exist.".into(), data: None, }, - IsTombstone => Error { - code: ErrorCode::ServerError(CONTRACT_IS_A_TOMBSTONE), - message: "The contract is a tombstone and doesn't have any storage.".into(), - data: None, - }, } } } @@ -130,7 +122,7 @@ pub trait ContractsApi { &self, instantiate_request: InstantiateRequest, at: Option, - ) -> Result>; + ) -> Result>; /// Returns the value under a specified storage `key` in a contract given by `address` param, /// or `None` if it is not set. @@ -141,19 +133,6 @@ pub trait ContractsApi { key: H256, at: Option, ) -> Result>; - - /// Returns the projected time a given contract will be able to sustain paying its rent. - /// - /// The returned projection is relevant for the given block, i.e. it is as if the contract was - /// accessed at the beginning of that block. - /// - /// Returns `None` if the contract is exempted from rent. - #[rpc(name = "contracts_rentProjection")] - fn rent_projection( - &self, - address: AccountId, - at: Option, - ) -> Result>; } /// An implementation of contract specific RPC methods. @@ -217,8 +196,7 @@ where &self, instantiate_request: InstantiateRequest, at: Option<::Hash>, - ) -> Result::Header as HeaderT>::Number>> - { + ) -> Result> { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| // If the block hash is not supplied assume the best block. @@ -257,27 +235,6 @@ where Ok(result) } - - fn rent_projection( - &self, - address: AccountId, - at: Option<::Hash>, - ) -> Result::Header as HeaderT>::Number>> { - let api = self.client.runtime_api(); - let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); - - let result = api - .rent_projection(&at, address) - .map_err(runtime_error_into_rpc_err)? - .map_err(ContractAccessError)?; - - Ok(match result { - RentProjection::NoEviction => None, - RentProjection::EvictionAt(block_num) => Some(block_num), - }) - } } /// Converts a runtime trap into an RPC error. @@ -404,8 +361,7 @@ mod tests { #[test] fn instantiate_result_should_serialize_deserialize_properly() { fn test(expected: &str) { - let res: ContractInstantiateResult = - serde_json::from_str(expected).unwrap(); + let res: ContractInstantiateResult = serde_json::from_str(expected).unwrap(); let actual = serde_json::to_string(&res).unwrap(); assert_eq!(actual, trim(expected).as_str()); } @@ -420,8 +376,7 @@ mod tests { "flags": 5, "data": "0x1234" }, - "accountId": "5CiPP", - "rentProjection": null + "accountId": "5CiPP" } } }"#, diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index c3757cf705..509f96bf03 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -31,7 +31,6 @@ use self::{ }; use crate::{ exec::{AccountIdOf, StorageKey}, - rent::Rent, schedule::{API_BENCHMARK_BATCH_SIZE, INSTR_BENCHMARK_BATCH_SIZE}, storage::Storage, Pallet as Contracts, *, @@ -39,10 +38,12 @@ use crate::{ use codec::Encode; use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; use frame_support::weights::Weight; -use frame_system::{Pallet as System, RawOrigin}; -use pallet_contracts_primitives::RentProjection; +use frame_system::RawOrigin; use pwasm_utils::parity_wasm::elements::{BlockType, BrTableData, Instruction, ValueType}; -use sp_runtime::traits::{Bounded, Hash, Zero}; +use sp_runtime::{ + traits::{Bounded, Hash}, + Perbill, +}; use sp_std::{convert::TryInto, default::Default, vec, vec::Vec}; /// How many batches we do per API benchmark. @@ -57,26 +58,6 @@ struct Contract { account_id: T::AccountId, addr: ::Source, endowment: BalanceOf, - code_hash: ::Output, -} - -/// Describes how much balance should be transferred on instantiate from the caller. -enum Endow { - /// Endow the contract with a maximum amount of balance. This value is described by - /// `Contract::max_endowment`. - Max, - /// Endow so that the amount of balance that is transferred is big but not so big - /// to offset the rent payment. This is needed in order to test rent collection. - CollectRent, -} - -impl Endow { - /// The maximum amount of balance a caller can transfer without being brought below - /// the existential deposit. This assumes that every caller is funded with the amount - /// returned by `caller_funding`. - fn max() -> BalanceOf { - caller_funding::().saturating_sub(T::Currency::minimum_balance()) - } } impl Contract @@ -85,12 +66,8 @@ where T::AccountId: UncheckedFrom + AsRef<[u8]>, { /// Create new contract and use a default account id as instantiator. - fn new( - module: WasmModule, - data: Vec, - endowment: Endow, - ) -> Result, &'static str> { - Self::with_index(0, module, data, endowment) + fn new(module: WasmModule, data: Vec) -> Result, &'static str> { + Self::with_index(0, module, data) } /// Create new contract and use an account id derived from the supplied index as instantiator. @@ -98,9 +75,8 @@ where index: u32, module: WasmModule, data: Vec, - endowment: Endow, ) -> Result, &'static str> { - Self::with_caller(account("instantiator", index, 0), module, data, endowment) + Self::with_caller(account("instantiator", index, 0), module, data) } /// Create new contract and use the supplied `caller` as instantiator. @@ -108,37 +84,12 @@ where caller: T::AccountId, module: WasmModule, data: Vec, - endowment: Endow, ) -> Result, &'static str> { - let (storage_size, endowment) = match endowment { - Endow::CollectRent => { - // storage_size cannot be zero because otherwise a contract that is just above - // the subsistence threshold does not pay rent given a large enough subsistence - // threshold. But we need rent payments to occur in order to benchmark for worst - // cases. - let storage_size = u32::MAX / 10; - - // Endowment should be large but not as large to inhibit rent payments. - // Balance will only cover half the storage - let endowment = T::DepositPerStorageByte::get() - .saturating_mul(>::from(storage_size) / 2u32.into()) - .saturating_add(T::DepositPerContract::get()); - - (Some(storage_size), endowment) - }, - Endow::Max => (None, Endow::max::()), - }; + let endowment = contract_funding::(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let salt = vec![0xff]; let addr = Contracts::::contract_address(&caller, &module.hash, &salt); - // The default block number is zero. The benchmarking system bumps the block number - // to one for the benchmarking closure when it is set to zero. In order to prevent this - // undesired implicit bump (which messes with rent collection), we do the bump ourselves - // in the setup closure so that both the instantiate and subsequent call are run with the - // same block number. - System::::set_block_number(1u32.into()); - Contracts::::store_code_raw(module.code)?; Contracts::::instantiate( RawOrigin::Signed(caller.clone()).into(), @@ -154,125 +105,53 @@ where account_id: addr.clone(), addr: T::Lookup::unlookup(addr), endowment, - code_hash: module.hash.clone(), }; - let mut contract = result.alive_info()?; - if let Some(size) = storage_size { - contract.storage_size = size; - } - ContractInfoOf::::insert(&result.account_id, ContractInfo::Alive(contract)); + ContractInfoOf::::insert(&result.account_id, result.info()?); Ok(result) } + /// Create a new contract with the supplied storage item count and size each. + fn with_storage( + code: WasmModule, + stor_num: u32, + stor_size: u32, + ) -> Result { + let contract = Contract::::new(code, vec![])?; + let storage_items = (0..stor_num) + .map(|i| { + let hash = T::Hashing::hash_of(&i) + .as_ref() + .try_into() + .map_err(|_| "Hash too big for storage key")?; + Ok((hash, vec![42u8; stor_size as usize])) + }) + .collect::, &'static str>>()?; + contract.store(&storage_items)?; + Ok(contract) + } + /// Store the supplied storage items into this contracts storage. fn store(&self, items: &Vec<(StorageKey, Vec)>) -> Result<(), &'static str> { - let mut info = self.alive_info()?; + let mut info = self.info()?; for item in items { - Storage::::write( - >::block_number(), - &mut info, - &item.0, - Some(item.1.clone()), - ) - .map_err(|_| "Failed to write storage to restoration dest")?; + Storage::::write(&mut info, &item.0, Some(item.1.clone())) + .map_err(|_| "Failed to write storage to restoration dest")?; } - >::insert(&self.account_id, ContractInfo::Alive(info.clone())); + >::insert(&self.account_id, info.clone()); Ok(()) } - /// Get the `AliveContractInfo` of the `addr` or an error if it is no longer alive. - fn address_alive_info(addr: &T::AccountId) -> Result, &'static str> { - ContractInfoOf::::get(addr) - .and_then(|c| c.get_alive()) - .ok_or("Expected contract to be alive at this point.") + /// Get the `ContractInfo` of the `addr` or an error if it no longer exists. + fn address_info(addr: &T::AccountId) -> Result, &'static str> { + ContractInfoOf::::get(addr).ok_or("Expected contract to exist at this point.") } - /// Get the `AliveContractInfo` of this contract or an error if it is no longer alive. - fn alive_info(&self) -> Result, &'static str> { - Self::address_alive_info(&self.account_id) + /// Get the `ContractInfo` of this contract or an error if it no longer exists. + fn info(&self) -> Result, &'static str> { + Self::address_info(&self.account_id) } - - /// Return an error if this contract is no tombstone. - fn ensure_tombstone(&self) -> Result<(), &'static str> { - ContractInfoOf::::get(&self.account_id) - .and_then(|c| c.get_tombstone()) - .ok_or("Expected contract to be a tombstone at this point.") - .map(|_| ()) - } - - /// Get the block number when this contract will be evicted. Returns an error when - /// the rent collection won't happen because the contract has to much endowment. - fn eviction_at(&self) -> Result { - let projection = Rent::>::compute_projection(&self.account_id) - .map_err(|_| "Invalid acc for rent")?; - match projection { - RentProjection::EvictionAt(at) => Ok(at), - _ => Err("Account does not pay rent.")?, - } - } -} - -/// A `Contract` that contains some storage items. -/// -/// This is used to benchmark contract destruction and resurection. Those operations' -/// weight depend on the amount of storage accumulated. -struct ContractWithStorage { - /// The contract that was evicted. - contract: Contract, - /// The storage the contract held when it was avicted. - storage: Vec<(StorageKey, Vec)>, -} - -impl ContractWithStorage -where - T: Config, - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - /// Same as [`Self::with_code`] but with dummy contract code. - fn new(stor_num: u32, stor_size: u32) -> Result { - Self::with_code(WasmModule::dummy(), stor_num, stor_size) - } - - /// Create and evict a new contract with the supplied storage item count and size each. - fn with_code(code: WasmModule, stor_num: u32, stor_size: u32) -> Result { - let contract = Contract::::new(code, vec![], Endow::CollectRent)?; - let storage_items = create_storage::(stor_num, stor_size)?; - contract.store(&storage_items)?; - Ok(Self { contract, storage: storage_items }) - } - - /// Increase the system block number so that this contract is eligible for eviction. - fn set_block_num_for_eviction(&self) -> Result<(), &'static str> { - System::::set_block_number( - self.contract.eviction_at()? + T::SignedClaimHandicap::get() + 5u32.into(), - ); - Ok(()) - } - - /// Evict this contract. - fn evict(&mut self) -> Result<(), &'static str> { - self.set_block_num_for_eviction()?; - Rent::>::try_eviction(&self.contract.account_id, Zero::zero())?; - self.contract.ensure_tombstone() - } -} - -/// Generate `stor_num` storage items. Each has the size `stor_size`. -fn create_storage( - stor_num: u32, - stor_size: u32, -) -> Result)>, &'static str> { - (0..stor_num) - .map(|i| { - let hash = T::Hashing::hash_of(&i) - .as_ref() - .try_into() - .map_err(|_| "Hash too big for storage key")?; - Ok((hash, vec![42u8; stor_size as usize])) - }) - .collect::, &'static str>>() } /// The funding that each account that either calls or instantiates contracts is funded with. @@ -280,6 +159,11 @@ fn caller_funding() -> BalanceOf { BalanceOf::::max_value() / 2u32.into() } +/// The funding used for contracts. It is less than `caller_funding` in purpose. +fn contract_funding() -> BalanceOf { + caller_funding::().saturating_sub(T::Currency::minimum_balance() * 100u32.into()) +} + /// Load the specified contract file from disk by including it into the runtime. /// /// We need to load a different version of ink! contracts when the benchmark is run as @@ -312,8 +196,8 @@ benchmarks! { #[skip_meta] on_initialize_per_trie_key { let k in 0..1024; - let instance = ContractWithStorage::::new(k, T::Schedule::get().limits.payload_len)?; - Storage::::queue_trie_for_deletion(&instance.contract.alive_info()?)?; + let instance = Contract::::with_storage(WasmModule::dummy(), k, T::Schedule::get().limits.payload_len)?; + Storage::::queue_trie_for_deletion(&instance.info()?)?; }: { Storage::::process_deletion_queue_batch(Weight::max_value()) } @@ -321,8 +205,8 @@ benchmarks! { on_initialize_per_queue_item { let q in 0..1024.min(T::DeletionQueueDepth::get()); for i in 0 .. q { - let instance = Contract::::with_index(i, WasmModule::dummy(), vec![], Endow::Max)?; - Storage::::queue_trie_for_deletion(&instance.alive_info()?)?; + let instance = Contract::::with_index(i, WasmModule::dummy(), vec![])?; + Storage::::queue_trie_for_deletion(&instance.info()?)?; ContractInfoOf::::remove(instance.account_id); } }: { @@ -376,7 +260,7 @@ benchmarks! { let c in 0 .. Perbill::from_percent(50).mul_ceil(T::Schedule::get().limits.code_len / 1024); let s in 0 .. code::max_pages::() * 64; let salt = vec![42u8; (s * 1024) as usize]; - let endowment = caller_funding::() / 3u32.into(); + let endowment = contract_funding::() / 3u32.into(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let WasmModule { code, hash, .. } = WasmModule::::sized(c * 1024); @@ -386,10 +270,10 @@ benchmarks! { verify { // endowment was removed from the caller assert_eq!(T::Currency::free_balance(&caller), caller_funding::() - endowment); - // contract has the full endowment because no rent collection happended + // contract has the full endowment assert_eq!(T::Currency::free_balance(&addr), endowment); - // instantiate should leave a alive contract - Contract::::address_alive_info(&addr)?; + // instantiate should leave a contract + Contract::::address_info(&addr)?; } // Instantiate uses a dummy contract constructor to measure the overhead of the instantiate. @@ -397,7 +281,7 @@ benchmarks! { instantiate { let s in 0 .. code::max_pages::() * 64; let salt = vec![42u8; (s * 1024) as usize]; - let endowment = caller_funding::() / 3u32.into(); + let endowment = contract_funding::() / 3u32.into(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let WasmModule { code, hash, .. } = WasmModule::::dummy(); @@ -408,13 +292,13 @@ benchmarks! { verify { // endowment was removed from the caller assert_eq!(T::Currency::free_balance(&caller), caller_funding::() - endowment); - // contract has the full endowment because no rent collection happended + // contract has the full endowment assert_eq!(T::Currency::free_balance(&addr), endowment); - // instantiate should leave a alive contract - Contract::::address_alive_info(&addr)?; + // instantiate should leave a contract + Contract::::address_info(&addr)?; } - // We just call a dummy contract to measure to overhead of the call extrinsic. + // We just call a dummy contract to measure the overhead of the call extrinsic. // The size of the data has no influence on the costs of this extrinsic as long as the contract // 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 @@ -422,14 +306,11 @@ benchmarks! { call { let data = vec![42u8; 1024]; let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::dummy(), vec![], Endow::CollectRent + whitelisted_caller(), WasmModule::dummy(), vec![], )?; - let value = T::Currency::minimum_balance() * 100u32.into(); + let value = T::Currency::minimum_balance(); let origin = RawOrigin::Signed(instance.caller.clone()); let callee = instance.addr.clone(); - - // trigger rent collection for worst case performance of call - System::::set_block_number(instance.eviction_at()? - 5u32.into()); let before = T::Currency::free_balance(&instance.account_id); }: _(origin, callee, value, Weight::max_value(), data) verify { @@ -438,57 +319,17 @@ benchmarks! { T::Currency::free_balance(&instance.caller), caller_funding::() - instance.endowment - value, ); - // rent should have lowered the amount of balance of the contract - assert!(T::Currency::free_balance(&instance.account_id) < before + value); - // but it should not have been evicted by the rent collection - instance.alive_info()?; - } - - // We benchmark the costs for sucessfully evicting an empty contract. - // The actual costs are depending on how many storage items the evicted contract - // does have. However, those costs are not to be paid by the sender but - // 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::Schedule::get().limits.code_len / 1024; - let instance = Contract::::with_caller( - 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(); - - // instantiate should leave us with an alive contract - instance.alive_info()?; - - // generate enough rent so that the contract is evicted - System::::set_block_number( - instance.eviction_at()? + T::SignedClaimHandicap::get() + 5u32.into() - ); - }: _(origin, account_id, None) - verify { - // the claim surcharge should have evicted the contract - instance.ensure_tombstone()?; - - // the caller should get the reward for being a good snitch - // this is capped by the maximum amount of rent paid. So we only now that it should - // have increased by at most the surcharge reward. - assert!( - T::Currency::free_balance(&instance.caller) > - caller_funding::() - instance.endowment - ); - assert!( - T::Currency::free_balance(&instance.caller) <= - caller_funding::() - instance.endowment + ::SurchargeReward::get(), - ); + // contract should have received the value + assert_eq!(T::Currency::free_balance(&instance.account_id), before + value); + // contract should still exist + instance.info()?; } seal_caller { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_caller", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -496,7 +337,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_address", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -504,7 +345,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_gas_left", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -512,7 +353,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_balance", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -520,7 +361,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_value_transferred", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -528,7 +369,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_minimum_balance", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -536,15 +377,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_tombstone_deposit", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; - let origin = RawOrigin::Signed(instance.caller.clone()); - }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - - seal_rent_allowance { - let r in 0 .. API_BENCHMARK_BATCHES; - let instance = Contract::::new(WasmModule::getter( - "seal_rent_allowance", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -552,7 +385,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_block_number", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -560,7 +393,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::getter( "seal_now", r * API_BENCHMARK_BATCH_SIZE - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -587,7 +420,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -606,7 +439,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -637,7 +470,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -667,7 +500,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let data = vec![42u8; (n * 1024).min(buffer_size) as usize]; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), data) @@ -691,7 +524,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -714,7 +547,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -745,184 +578,18 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; 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::()); + assert_eq!(T::Currency::total_balance(&instance.account_id), contract_funding::()); }: call(origin, instance.addr.clone(), 0u32.into(), Weight::max_value(), vec![]) verify { if r > 0 { assert_eq!(T::Currency::total_balance(&instance.account_id), 0u32.into()); - assert_eq!(T::Currency::total_balance(&beneficiary), Endow::max::()); + assert_eq!(T::Currency::total_balance(&beneficiary), contract_funding::()); } } - seal_restore_to { - let r in 0 .. 1; - - // Restore just moves the trie id from origin to destination and therefore - // does not depend on the size of the destination contract. However, to not - // trigger any edge case we won't use an empty contract as destination. - let mut tombstone = ContractWithStorage::::new(10, T::Schedule::get().limits.payload_len)?; - tombstone.evict()?; - - let dest = tombstone.contract.account_id.encode(); - let dest_len = dest.len(); - let code_hash = tombstone.contract.code_hash.encode(); - let code_hash_len = code_hash.len(); - let rent_allowance = BalanceOf::::max_value().encode(); - let rent_allowance_len = rent_allowance.len(); - - let dest_offset = 0; - let code_hash_offset = dest_offset + dest_len; - let rent_allowance_offset = code_hash_offset + code_hash_len; - - let code = WasmModule::::from(ModuleDefinition { - memory: Some(ImportedMemory::max::()), - imported_functions: vec![ImportedFunction { - module: "seal0", - name: "seal_restore_to", - params: vec![ - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ], - return_type: None, - }], - data_segments: vec![ - DataSegment { - offset: dest_offset as u32, - value: dest, - }, - DataSegment { - offset: code_hash_offset as u32, - value: code_hash, - }, - DataSegment { - offset: rent_allowance_offset as u32, - value: rent_allowance, - }, - ], - call_body: Some(body::repeated(r, &[ - Instruction::I32Const(dest_offset as i32), - Instruction::I32Const(dest_len as i32), - Instruction::I32Const(code_hash_offset as i32), - Instruction::I32Const(code_hash_len as i32), - Instruction::I32Const(rent_allowance_offset as i32), - Instruction::I32Const(rent_allowance_len as i32), - Instruction::I32Const(0), // delta_ptr - Instruction::I32Const(0), // delta_count - Instruction::Call(0), - ])), - .. Default::default() - }); - - let instance = Contract::::with_caller( - account("origin", 0, 0), code, vec![], Endow::Max - )?; - instance.store(&tombstone.storage)?; - System::::set_block_number(System::::block_number() + 1u32.into()); - - let origin = RawOrigin::Signed(instance.caller.clone()); - }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - verify { - if r > 0 { - tombstone.contract.alive_info()?; - } - } - - // `d`: Number of supplied delta keys - #[skip_meta] - seal_restore_to_per_delta { - let d in 0 .. API_BENCHMARK_BATCHES; - let mut tombstone = ContractWithStorage::::new(0, 0)?; - tombstone.evict()?; - let delta = create_storage::( - d * API_BENCHMARK_BATCH_SIZE, - T::Schedule::get().limits.payload_len, - )?; - - let dest = tombstone.contract.account_id.encode(); - let dest_len = dest.len(); - let code_hash = tombstone.contract.code_hash.encode(); - let code_hash_len = code_hash.len(); - let rent_allowance = BalanceOf::::max_value().encode(); - let rent_allowance_len = rent_allowance.len(); - let delta_keys = delta.iter().flat_map(|(key, _)| key).cloned().collect::>(); - - let dest_offset = 0; - let code_hash_offset = dest_offset + dest_len; - let rent_allowance_offset = code_hash_offset + code_hash_len; - let delta_keys_offset = rent_allowance_offset + rent_allowance_len; - - let code = WasmModule::::from(ModuleDefinition { - memory: Some(ImportedMemory::max::()), - imported_functions: vec![ImportedFunction { - module: "seal0", - name: "seal_restore_to", - params: vec![ - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ValueType::I32, - ], - return_type: None, - }], - data_segments: vec![ - DataSegment { - offset: dest_offset as u32, - value: dest, - }, - DataSegment { - offset: code_hash_offset as u32, - value: code_hash, - }, - DataSegment { - offset: rent_allowance_offset as u32, - value: rent_allowance, - }, - DataSegment { - offset: delta_keys_offset as u32, - value: delta_keys, - }, - ], - call_body: Some(body::plain(vec![ - Instruction::I32Const(dest_offset as i32), - Instruction::I32Const(dest_len as i32), - Instruction::I32Const(code_hash_offset as i32), - Instruction::I32Const(code_hash_len as i32), - Instruction::I32Const(rent_allowance_offset as i32), - Instruction::I32Const(rent_allowance_len as i32), - Instruction::I32Const(delta_keys_offset as i32), // delta_ptr - Instruction::I32Const(delta.len() as i32), // delta_count - Instruction::Call(0), - Instruction::End, - ])), - .. Default::default() - }); - - let instance = Contract::::with_caller( - account("origin", 0, 0), code, vec![], Endow::Max - )?; - instance.store(&tombstone.storage)?; - instance.store(&delta)?; - System::::set_block_number(System::::block_number() + 1u32.into()); - - let origin = RawOrigin::Signed(instance.caller.clone()); - }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - verify { - tombstone.contract.alive_info()?; - } - // We benchmark only for the maximum subject length. We assume that this is some lowish // number (< 1 KB). Therefore we are not overcharging too much in case a smaller subject is // used. @@ -954,7 +621,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -979,7 +646,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1017,36 +684,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; - let origin = RawOrigin::Signed(instance.caller.clone()); - }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) - - seal_set_rent_allowance { - let r in 0 .. API_BENCHMARK_BATCHES; - let allowance = caller_funding::().encode(); - let allowance_len = allowance.len(); - let code = WasmModule::::from(ModuleDefinition { - memory: Some(ImportedMemory { min_pages: 1, max_pages: 1 }), - imported_functions: vec![ImportedFunction { - module: "seal0", - name: "seal_set_rent_allowance", - params: vec![ValueType::I32, ValueType::I32], - return_type: None, - }], - data_segments: vec![ - DataSegment { - offset: 0, - value: allowance, - }, - ], - call_body: Some(body::repeated(r * API_BENCHMARK_BATCH_SIZE, &[ - Instruction::I32Const(0), // value_ptr - Instruction::I32Const(allowance_len as i32), // value_len - Instruction::Call(0), - ])), - .. Default::default() - }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1072,7 +710,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1109,7 +747,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1139,7 +777,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1174,18 +812,17 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; - let mut info = instance.alive_info()?; + let instance = Contract::::new(code, vec![])?; + let mut info = instance.info()?; for key in keys { Storage::::write( - >::block_number(), &mut info, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, Some(vec![42; T::Schedule::get().limits.payload_len as usize]) ) .map_err(|_| "Failed to write to storage during setup.")?; } - >::insert(&instance.account_id, ContractInfo::Alive(info.clone())); + >::insert(&instance.account_id, info.clone()); let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1222,18 +859,17 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; - let mut info = instance.alive_info()?; + let instance = Contract::::new(code, vec![])?; + let mut info = instance.info()?; for key in keys { Storage::::write( - >::block_number(), &mut info, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, Some(vec![]) ) .map_err(|_| "Failed to write to storage during setup.")?; } - >::insert(&instance.account_id, ContractInfo::Alive(info.clone())); + >::insert(&instance.account_id, info.clone()); let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1269,16 +905,15 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; - let mut info = instance.alive_info()?; + let instance = Contract::::new(code, vec![])?; + let mut info = instance.info()?; Storage::::write( - >::block_number(), &mut info, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, Some(vec![42u8; (n * 1024) as usize]) ) .map_err(|_| "Failed to write to storage during setup.")?; - >::insert(&instance.account_id, ContractInfo::Alive(info.clone())); + >::insert(&instance.account_id, info.clone()); let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1322,7 +957,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); for account in &accounts { assert_eq!(T::Currency::total_balance(account), 0u32.into()); @@ -1339,7 +974,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; 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)) + .map(|i| Contract::with_index(i + 1, dummy_code.clone(), vec![])) .collect::, _>>()?; let callee_len = callees.get(0).map(|i| i.account_id.encode().len()).unwrap_or(0); let callee_bytes = callees.iter().flat_map(|x| x.account_id.encode()).collect(); @@ -1389,7 +1024,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1419,7 +1054,7 @@ benchmarks! { .. Default::default() }); let callees = (0..API_BENCHMARK_BATCH_SIZE) - .map(|i| Contract::with_index(i + 1, callee_code.clone(), vec![], Endow::Max)) + .map(|i| Contract::with_index(i + 1, callee_code.clone(), vec![])) .collect::, _>>()?; let callee_len = callees.get(0).map(|i| i.account_id.encode().len()).unwrap_or(0); let callee_bytes = callees.iter().flat_map(|x| x.account_id.encode()).collect::>(); @@ -1474,7 +1109,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1501,7 +1136,7 @@ benchmarks! { let hash_len = hashes.get(0).map(|x| x.encode().len()).unwrap_or(0); let hashes_bytes = hashes.iter().flat_map(|x| x.encode()).collect::>(); let hashes_len = hashes_bytes.len(); - let value = Endow::max::() / (r * API_BENCHMARK_BATCH_SIZE + 2).into(); + let value = contract_funding::() / (r * API_BENCHMARK_BATCH_SIZE + 2).into(); assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); @@ -1568,7 +1203,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); let callee = instance.addr.clone(); let addresses = hashes @@ -1586,7 +1221,7 @@ benchmarks! { }: call(origin, callee, 0u32.into(), Weight::max_value(), vec![]) verify { for addr in &addresses { - ContractInfoOf::::get(&addr).and_then(|c| c.get_alive()) + ContractInfoOf::::get(&addr) .ok_or_else(|| "Contract should have been instantiated")?; } } @@ -1624,7 +1259,7 @@ benchmarks! { let input_len = inputs.get(0).map(|x| x.len()).unwrap_or(0); let input_bytes = inputs.iter().cloned().flatten().collect::>(); let inputs_len = input_bytes.len(); - let value = Endow::max::() / (API_BENCHMARK_BATCH_SIZE + 2).into(); + let value = contract_funding::() / (API_BENCHMARK_BATCH_SIZE + 2).into(); assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); @@ -1706,7 +1341,7 @@ benchmarks! { ])), .. Default::default() }); - let instance = Contract::::new(code, vec![], Endow::Max)?; + let instance = Contract::::new(code, vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1715,7 +1350,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::hasher( "seal_hash_sha2_256", r * API_BENCHMARK_BATCH_SIZE, 0, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1724,7 +1359,7 @@ benchmarks! { let n in 0 .. code::max_pages::() * 64; let instance = Contract::::new(WasmModule::hasher( "seal_hash_sha2_256", API_BENCHMARK_BATCH_SIZE, n * 1024, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1733,7 +1368,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::hasher( "seal_hash_keccak_256", r * API_BENCHMARK_BATCH_SIZE, 0, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1742,7 +1377,7 @@ benchmarks! { let n in 0 .. code::max_pages::() * 64; let instance = Contract::::new(WasmModule::hasher( "seal_hash_keccak_256", API_BENCHMARK_BATCH_SIZE, n * 1024, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1751,7 +1386,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::hasher( "seal_hash_blake2_256", r * API_BENCHMARK_BATCH_SIZE, 0, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1760,7 +1395,7 @@ benchmarks! { let n in 0 .. code::max_pages::() * 64; let instance = Contract::::new(WasmModule::hasher( "seal_hash_blake2_256", API_BENCHMARK_BATCH_SIZE, n * 1024, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1769,7 +1404,7 @@ benchmarks! { let r in 0 .. API_BENCHMARK_BATCHES; let instance = Contract::::new(WasmModule::hasher( "seal_hash_blake2_128", r * API_BENCHMARK_BATCH_SIZE, 0, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -1778,7 +1413,7 @@ benchmarks! { let n in 0 .. code::max_pages::() * 64; let instance = Contract::::new(WasmModule::hasher( "seal_hash_blake2_128", API_BENCHMARK_BATCH_SIZE, n * 1024, - ), vec![], Endow::Max)?; + ), vec![])?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) @@ -2571,7 +2206,7 @@ benchmarks! { new.encode() }; let instance = Contract::::new( - WasmModule::instrumented(code, gas_metering, true), data, Endow::Max, + WasmModule::instrumented(code, gas_metering, true), data, )?; let data = { let transfer: ([u8; 4], AccountIdOf, BalanceOf) = ( @@ -2616,7 +2251,7 @@ benchmarks! { new.encode() }; let instance = Contract::::with_caller( - caller, WasmModule::instrumented(code, gas_metering, true), data, Endow::Max, + caller, WasmModule::instrumented(code, gas_metering, true), data, )?; balance[0] = 1; let data = { diff --git a/substrate/frame/contracts/src/exec.rs b/substrate/frame/contracts/src/exec.rs index ef19c443c7..4039b1d134 100644 --- a/substrate/frame/contracts/src/exec.rs +++ b/substrate/frame/contracts/src/exec.rs @@ -16,11 +16,8 @@ // limitations under the License. use crate::{ - gas::GasMeter, - rent::{Rent, RentStatus}, - storage::Storage, - AccountCounter, AliveContractInfo, BalanceOf, CodeHash, Config, ContractInfo, ContractInfoOf, - Error, Event, Pallet as Contracts, Schedule, + gas::GasMeter, storage::Storage, AccountCounter, BalanceOf, CodeHash, Config, ContractInfo, + ContractInfoOf, Error, Event, Pallet as Contracts, Schedule, }; use frame_support::{ dispatch::{DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable}, @@ -28,18 +25,19 @@ use frame_support::{ storage::{with_transaction, TransactionOutcome}, traits::{Contains, Currency, ExistenceRequirement, Get, OriginTrait, Randomness, Time}, weights::Weight, - DefaultNoBound, }; use frame_system::RawOrigin; use pallet_contracts_primitives::ExecReturnValue; use smallvec::{Array, SmallVec}; use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{Convert, Saturating}, - Perbill, -}; +use sp_runtime::traits::{Convert, Saturating}; use sp_std::{marker::PhantomData, mem, prelude::*}; +/// When fields are added to the [`ContractInfo`] that can change during execution this +/// variable needs to be set to true. This will also force changes to the +/// `in_memory_changes_not_discarded` test. +const CONTRACT_INFO_CAN_CHANGE: bool = false; + pub type AccountIdOf = ::AccountId; pub type MomentOf = <::Time as Time>::Moment; pub type SeedOf = ::Hash; @@ -81,67 +79,6 @@ impl> From for ExecError { } } -/// Information needed for rent calculations that can be requested by a contract. -#[derive(codec::Encode, DefaultNoBound)] -#[cfg_attr(test, derive(Debug, PartialEq))] -pub struct RentParams { - /// The total balance of the contract. Includes the balance transferred from the caller. - total_balance: BalanceOf, - /// The free balance of the contract. Includes the balance transferred from the caller. - free_balance: BalanceOf, - /// See crate [`Contracts::subsistence_threshold()`]. - subsistence_threshold: BalanceOf, - /// See crate [`Config::DepositPerContract`]. - deposit_per_contract: BalanceOf, - /// See crate [`Config::DepositPerStorageByte`]. - deposit_per_storage_byte: BalanceOf, - /// See crate [`Config::DepositPerStorageItem`]. - deposit_per_storage_item: BalanceOf, - /// See crate [`Ext::rent_allowance()`]. - rent_allowance: BalanceOf, - /// See crate [`Config::RentFraction`]. - rent_fraction: Perbill, - /// See crate [`AliveContractInfo::storage_size`]. - storage_size: u32, - /// See crate [`Executable::aggregate_code_len()`]. - code_size: u32, - /// See crate [`Executable::refcount()`]. - code_refcount: u32, - /// Reserved for backwards compatible changes to this data structure. - _reserved: Option<()>, -} - -impl RentParams -where - T: Config, - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - /// Derive new `RentParams` from the passed in data. - /// - /// `value` is added to the current free and total balance of the contracts' account. - fn new>( - account_id: &T::AccountId, - value: &BalanceOf, - contract: &AliveContractInfo, - executable: &E, - ) -> Self { - Self { - total_balance: T::Currency::total_balance(account_id).saturating_add(*value), - free_balance: T::Currency::free_balance(account_id).saturating_add(*value), - subsistence_threshold: >::subsistence_threshold(), - deposit_per_contract: T::DepositPerContract::get(), - deposit_per_storage_byte: T::DepositPerStorageByte::get(), - deposit_per_storage_item: T::DepositPerStorageItem::get(), - rent_allowance: contract.rent_allowance, - rent_fraction: T::RentFraction::get(), - storage_size: contract.storage_size, - code_size: executable.aggregate_code_len(), - code_refcount: executable.refcount(), - _reserved: None, - } - } -} - /// An interface that provides access to the external environment in which the /// smart-contract is executed. /// @@ -197,25 +134,6 @@ pub trait Ext: sealing::Sealed { /// call stack. fn terminate(&mut self, beneficiary: &AccountIdOf) -> Result<(), DispatchError>; - /// Restores the given destination contract sacrificing the current one. - /// - /// 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<(CallerCodeSize, DestCodeSize), (DispatchError, CallerCodeSize, DestCodesize)> - fn restore_to( - &mut self, - dest: AccountIdOf, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, - ) -> Result<(), DispatchError>; - /// Transfer some amount of funds into the specified account. fn transfer(&mut self, to: &AccountIdOf, value: BalanceOf) -> DispatchResult; @@ -249,8 +167,8 @@ pub trait Ext: sealing::Sealed { /// Returns the minimum balance that is required for creating an account. fn minimum_balance(&self) -> BalanceOf; - /// Returns the deposit required to create a tombstone upon contract eviction. - fn tombstone_deposit(&self) -> BalanceOf; + /// Returns the deposit required to instantiate a contract. + fn contract_deposit(&self) -> BalanceOf; /// Returns a random number for the current block with the given subject. fn random(&self, subject: &[u8]) -> (SeedOf, BlockNumberOf); @@ -260,12 +178,6 @@ pub trait Ext: sealing::Sealed { /// There should not be any duplicates in `topics`. fn deposit_event(&mut self, topics: Vec>, data: Vec); - /// Set rent allowance of the contract - fn set_rent_allowance(&mut self, rent_allowance: BalanceOf); - - /// Rent allowance of the contract - fn rent_allowance(&mut self) -> BalanceOf; - /// Returns the current block number. fn block_number(&self) -> BlockNumberOf; @@ -278,12 +190,6 @@ pub trait Ext: sealing::Sealed { /// Get a reference to the schedule used by the current call. fn schedule(&self) -> &Schedule; - /// Information needed for rent calculations. - fn rent_params(&self) -> &RentParams; - - /// Information about the required deposit and resulting rent. - fn rent_status(&mut self, at_refcount: u32) -> RentStatus; - /// Get a mutable reference to the nested gas meter. fn gas_meter(&mut self) -> &mut GasMeter; @@ -336,9 +242,6 @@ pub trait Executable: Sized { /// Does not charge from the gas meter. Do not call in contexts where this is important. fn from_storage_noinstr(code_hash: CodeHash) -> Result; - /// Decrements the refcount by one and deletes the code if it drops to zero. - fn drop_from_storage(self); - /// Increment the refcount by one. Fails if the code does not exist on-chain. /// /// Returns the size of the original code. @@ -387,23 +290,6 @@ pub trait Executable: Sized { // The number of contracts using this executable. fn refcount(&self) -> u32; - - /// The storage that is occupied by the instrumented executable and its pristine source. - /// - /// The returned size is already divided by the number of users who share the code. - /// This is essentially `aggregate_code_len() / refcount()`. - /// - /// # Note - /// - /// This works with the current in-memory value of refcount. When calling any contract - /// 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 { - // We disregard the size of the struct itself as the size is completely - // dominated by the code size. - let len = self.aggregate_code_len(); - len.checked_div(self.refcount()).unwrap_or(len) - } } /// The complete call stack of a contract execution. @@ -461,8 +347,6 @@ pub struct Frame { contract_info: CachedContract, /// The amount of balance transferred by the caller as part of the call. value_transferred: BalanceOf, - /// Snapshotted rent information that can be copied to the contract if requested. - rent_params: RentParams, /// Determines whether this is a call or instantiate frame. entry_point: ExportedFunction, /// The gas meter capped to the supplied gas limit. @@ -479,7 +363,7 @@ enum FrameArgs<'a, T: Config, E> { /// The account id of the contract that is to be called. dest: T::AccountId, /// If `None` the contract info needs to be reloaded from storage. - cached_info: Option>, + cached_info: Option>, }, Instantiate { /// The contract or signed origin which instantiates the new contract. @@ -496,12 +380,12 @@ enum FrameArgs<'a, T: Config, E> { /// Describes the different states of a contract as contained in a `Frame`. enum CachedContract { /// The cached contract is up to date with the in-storage value. - Cached(AliveContractInfo), + Cached(ContractInfo), /// A recursive call into the same contract did write to the contract info. /// /// In this case the cached contract is stale and needs to be reloaded from storage. Invalidated, - /// The current contract executed `terminate` or `restore_to` and removed the contract. + /// The current contract executed `terminate` and removed the contract. /// /// In this case a reload is neither allowed nor possible. Please note that recursive /// calls cannot remove a contract as this is checked and denied. @@ -510,13 +394,8 @@ enum CachedContract { impl Frame { /// Return the `contract_info` of the current contract. - fn contract_info(&mut self) -> &mut AliveContractInfo { - self.contract_info.as_alive(&self.account_id) - } - - /// Invalidate and return the `contract_info` of the current contract. - fn invalidate(&mut self) -> AliveContractInfo { - self.contract_info.invalidate(&self.account_id) + fn contract_info(&mut self) -> &mut ContractInfo { + self.contract_info.get(&self.account_id) } /// Terminate and return the `contract_info` of the current contract. @@ -525,7 +404,7 @@ impl Frame { /// /// Under no circumstances the contract is allowed to access the `contract_info` after /// a call to this function. This would constitute a programming error in the exec module. - fn terminate(&mut self) -> AliveContractInfo { + fn terminate(&mut self) -> ContractInfo { self.contract_info.terminate(&self.account_id) } } @@ -540,7 +419,7 @@ macro_rules! get_cached_or_panic_after_load { } else { panic!( "It is impossible to remove a contract that is on the call stack;\ - See implementations of terminate and restore_to;\ + See implementations of terminate;\ Therefore fetching a contract will never fail while using an account id that is currently active on the call stack;\ qed" @@ -553,28 +432,21 @@ impl CachedContract { /// Load the `contract_info` from storage if necessary. fn load(&mut self, account_id: &T::AccountId) { if let CachedContract::Invalidated = self { - let contract = - >::get(&account_id).and_then(|contract| contract.get_alive()); + let contract = >::get(&account_id); if let Some(contract) = contract { *self = CachedContract::Cached(contract); } } } - /// Return the cached contract_info as alive contract info. - fn as_alive(&mut self, account_id: &T::AccountId) -> &mut AliveContractInfo { + /// Return the cached contract_info. + fn get(&mut self, account_id: &T::AccountId) -> &mut ContractInfo { self.load(account_id); get_cached_or_panic_after_load!(self) } - /// Invalidate and return the contract info. - fn invalidate(&mut self, account_id: &T::AccountId) -> AliveContractInfo { - self.load(account_id); - get_cached_or_panic_after_load!(mem::replace(self, Self::Invalidated)) - } - /// Terminate and return the contract info. - fn terminate(&mut self, account_id: &T::AccountId) -> AliveContractInfo { + fn terminate(&mut self, account_id: &T::AccountId) -> ContractInfo { self.load(account_id); get_cached_or_panic_after_load!(mem::replace(self, Self::Terminated)) } @@ -695,23 +567,11 @@ where let contract = if let Some(contract) = cached_info { contract } else { - >::get(&dest) - .ok_or(>::ContractNotFound.into()) - .and_then(|contract| { - contract.get_alive().ok_or(>::ContractIsTombstone) - })? + >::get(&dest).ok_or(>::ContractNotFound)? }; let executable = E::from_storage(contract.code_hash, schedule, gas_meter)?; - // This charges the rent and denies access to a contract that is in need of - // eviction by returning `None`. We cannot evict eagerly here because those - // 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::::RentNotPaid)?; (dest, contract, executable, ExportedFunction::Call) }, FrameArgs::Instantiate { sender, trie_seed, executable, salt } => { @@ -728,12 +588,6 @@ where }; let frame = Frame { - rent_params: RentParams::new( - &account_id, - &value_transferred, - &contract_info, - &executable, - ), value_transferred, contract_info: CachedContract::Cached(contract_info), account_id, @@ -756,18 +610,17 @@ where return Err(Error::::MaxCallDepthReached.into()) } - // We need to make sure that changes made to the contract info are not discarded. - // See the `in_memory_changes_not_discarded` test for more information. - // We do not store on instantiate because we do not allow to call into a contract - // from its own constructor. - let frame = self.top_frame(); - if let (CachedContract::Cached(contract), ExportedFunction::Call) = - (&frame.contract_info, frame.entry_point) - { - >::insert( - frame.account_id.clone(), - ContractInfo::Alive(contract.clone()), - ); + if CONTRACT_INFO_CAN_CHANGE { + // We need to make sure that changes made to the contract info are not discarded. + // See the `in_memory_changes_not_discarded` test for more information. + // We do not store on instantiate because we do not allow to call into a contract + // from its own constructor. + let frame = self.top_frame(); + if let (CachedContract::Cached(contract), ExportedFunction::Call) = + (&frame.contract_info, frame.entry_point) + { + >::insert(frame.account_id.clone(), contract.clone()); + } } let nested_meter = @@ -784,12 +637,6 @@ where fn run(&mut self, executable: E, input_data: Vec) -> Result { let entry_point = self.top_frame().entry_point; let do_transaction = || { - // Cache the value before calling into the constructor because that - // consumes the value. If the constructor creates additional contracts using - // the same code hash we still charge the "1 block rent" as if they weren't - // spawned. This is OK as overcharging is always safe. - let occupied_storage = executable.occupied_storage(); - // Every call or instantiate also optionally transferres balance. self.initial_transfer()?; @@ -808,16 +655,6 @@ where return Err(Error::::TerminatedInConstructor.into()) } - // Collect the rent for the first block to prevent the creation of very large - // contracts that never intended to pay for even one block. - // This also makes sure that it is above the subsistence threshold - // in order to keep up the guarantuee that we always leave a tombstone behind - // with the exception of a contract that called `seal_terminate`. - let contract = - Rent::::charge(&account_id, frame.invalidate(), occupied_storage)? - .ok_or(Error::::NewContractNotFunded)?; - frame.contract_info = CachedContract::Cached(contract); - // Deposit an instantiation event. deposit_event::(vec![], Event::Instantiated(self.caller().clone(), account_id)); } @@ -877,7 +714,7 @@ where // because that case is already handled by the optimization above. Only the first // cache needs to be invalidated because that one will invalidate the next cache // when it is popped from the stack. - >::insert(account_id, ContractInfo::Alive(contract)); + >::insert(account_id, contract); if let Some(c) = self.frames_mut().skip(1).find(|f| f.account_id == *account_id) { c.contract_info = CachedContract::Invalidated; } @@ -897,10 +734,7 @@ where return } if let CachedContract::Cached(contract) = &self.first_frame.contract_info { - >::insert( - &self.first_frame.account_id, - ContractInfo::Alive(contract.clone()), - ); + >::insert(&self.first_frame.account_id, contract.clone()); } if let Some(counter) = self.account_counter { >::set(counter); @@ -1111,38 +945,6 @@ where Ok(()) } - fn restore_to( - &mut self, - dest: AccountIdOf, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, - ) -> Result<(), DispatchError> { - if self.is_recursive() { - return Err(Error::::TerminatedWhileReentrant.into()) - } - let frame = self.top_frame_mut(); - let origin_contract = frame.contract_info().clone(); - let account_id = frame.account_id.clone(); - let result = Rent::::restore_to( - &account_id, - origin_contract, - dest.clone(), - code_hash.clone(), - rent_allowance, - delta, - &mut frame.nested_meter, - ); - if let Ok(_) = result { - deposit_event::( - vec![], - Event::Restored(account_id, dest, code_hash, rent_allowance), - ); - frame.terminate(); - } - result - } - fn transfer(&mut self, to: &T::AccountId, value: BalanceOf) -> DispatchResult { Self::transfer(true, false, &self.top_frame().account_id, to, value) } @@ -1152,9 +954,8 @@ where } fn set_storage(&mut self, key: StorageKey, value: Option>) -> DispatchResult { - let block_number = self.block_number; let frame = self.top_frame_mut(); - Storage::::write(block_number, frame.contract_info(), &key, value) + Storage::::write(frame.contract_info(), &key, value) } fn address(&self) -> &T::AccountId { @@ -1185,8 +986,8 @@ where T::Currency::minimum_balance() } - fn tombstone_deposit(&self) -> BalanceOf { - T::TombstoneDeposit::get() + fn contract_deposit(&self) -> BalanceOf { + T::ContractDeposit::get() } fn deposit_event(&mut self, topics: Vec, data: Vec) { @@ -1196,14 +997,6 @@ where ); } - fn set_rent_allowance(&mut self, rent_allowance: BalanceOf) { - self.top_frame_mut().contract_info().rent_allowance = rent_allowance; - } - - fn rent_allowance(&mut self) -> BalanceOf { - self.top_frame_mut().contract_info().rent_allowance - } - fn block_number(&self) -> T::BlockNumber { self.block_number } @@ -1220,24 +1013,6 @@ where &self.schedule } - fn rent_params(&self) -> &RentParams { - &self.top_frame().rent_params - } - - fn rent_status(&mut self, at_refcount: u32) -> RentStatus { - let frame = self.top_frame_mut(); - let balance = T::Currency::free_balance(&frame.account_id); - let code_size = frame.rent_params.code_size; - let refcount = frame.rent_params.code_refcount; - >::rent_status( - &balance, - &frame.contract_info(), - code_size, - refcount, - at_refcount, - ) - } - fn gas_meter(&mut self) -> &mut GasMeter { &mut self.top_frame_mut().nested_meter } @@ -1304,7 +1079,7 @@ mod tests { use frame_support::{assert_err, assert_ok}; use frame_system::{EventRecord, Phase}; use pallet_contracts_primitives::ReturnFlags; - use pretty_assertions::{assert_eq, assert_ne}; + use pretty_assertions::assert_eq; use sp_core::Bytes; use sp_runtime::{ traits::{BadOrigin, Hash}, @@ -1400,12 +1175,6 @@ mod tests { } }); } - - fn refcount(code_hash: &CodeHash) -> u32 { - LOADER.with(|loader| { - loader.borrow().map.get(code_hash).expect("code_hash does not exist").refcount() - }) - } } impl Executable for MockExecutable { @@ -1428,10 +1197,6 @@ mod tests { }) } - fn drop_from_storage(self) { - MockLoader::decrement_refcount(self.code_hash); - } - fn add_user( code_hash: CodeHash, _: &mut GasMeter, @@ -1546,7 +1311,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let schedule = ::Schedule::get(); - place_contract(&BOB, return_ch); + place_contract(&dest, return_ch); set_balance(&origin, 100); let balance = get_balance(&dest); @@ -1563,9 +1328,7 @@ mod tests { assert!(!output.is_success()); assert_eq!(get_balance(&origin), 100); - - // the rent is still charged - assert!(get_balance(&dest) < balance); + assert_eq!(get_balance(&dest), balance); }); } @@ -2066,147 +1829,12 @@ mod tests { }); } - #[test] - fn rent_allowance() { - let rent_allowance_ch = MockLoader::insert(Constructor, |ctx, _| { - let subsistence = Contracts::::subsistence_threshold(); - let allowance = subsistence * 3; - assert_eq!(ctx.ext.rent_allowance(), >::max_value()); - ctx.ext.set_rent_allowance(allowance); - assert_eq!(ctx.ext.rent_allowance(), allowance); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let subsistence = Contracts::::subsistence_threshold(); - let schedule = ::Schedule::get(); - 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 = MockStack::run_instantiate( - ALICE, - executable, - &mut gas_meter, - &schedule, - subsistence * 5, - vec![], - &[], - None, - ); - assert_matches!(result, Ok(_)); - }); - } - - #[test] - fn rent_params_works() { - let code_hash = MockLoader::insert(Call, |ctx, executable| { - let address = ctx.ext.address(); - let contract = - >::get(address).and_then(|c| c.get_alive()).unwrap(); - assert_eq!(ctx.ext.rent_params(), &RentParams::new(address, &0, &contract, executable)); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let subsistence = Contracts::::subsistence_threshold(); - let schedule = ::Schedule::get(); - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - set_balance(&ALICE, subsistence * 10); - place_contract(&BOB, code_hash); - MockStack::run_call(ALICE, BOB, &mut gas_meter, &schedule, 0, vec![], None).unwrap(); - }); - } - - #[test] - fn rent_params_snapshotted() { - let code_hash = MockLoader::insert(Call, |ctx, executable| { - let subsistence = Contracts::::subsistence_threshold(); - let address = ctx.ext.address(); - let contract = - >::get(address).and_then(|c| c.get_alive()).unwrap(); - let rent_params = RentParams::new(address, &0, &contract, executable); - - // Changing the allowance during the call: rent params stay unchanged. - let allowance = 42; - assert_ne!(allowance, rent_params.rent_allowance); - ctx.ext.set_rent_allowance(allowance); - assert_eq!(ctx.ext.rent_params(), &rent_params); - - // Creating another instance from the same code_hash increases the refcount. - // This is also not reflected in the rent params. - assert_eq!(MockLoader::refcount(&executable.code_hash), 1); - ctx.ext - .instantiate(0, executable.code_hash, subsistence * 25, vec![], &[]) - .unwrap(); - assert_eq!(MockLoader::refcount(&executable.code_hash), 2); - assert_eq!(ctx.ext.rent_params(), &rent_params); - - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let subsistence = Contracts::::subsistence_threshold(); - let schedule = ::Schedule::get(); - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - set_balance(&ALICE, subsistence * 100); - place_contract(&BOB, code_hash); - MockStack::run_call( - ALICE, - BOB, - &mut gas_meter, - &schedule, - subsistence * 50, - vec![], - None, - ) - .unwrap(); - }); - } - - #[test] - fn rent_status_works() { - let code_hash = MockLoader::insert(Call, |ctx, _| { - assert_eq!( - ctx.ext.rent_status(0), - RentStatus { - max_deposit: 80000, - current_deposit: 80000, - custom_refcount_deposit: None, - max_rent: 32, - current_rent: 32, - custom_refcount_rent: None, - _reserved: None, - } - ); - assert_eq!( - ctx.ext.rent_status(1), - RentStatus { - max_deposit: 80000, - current_deposit: 80000, - custom_refcount_deposit: Some(80000), - max_rent: 32, - current_rent: 32, - custom_refcount_rent: Some(32), - _reserved: None, - } - ); - exec_success() - }); - - ExtBuilder::default().build().execute_with(|| { - let subsistence = Contracts::::subsistence_threshold(); - let schedule = ::Schedule::get(); - let mut gas_meter = GasMeter::::new(GAS_LIMIT); - set_balance(&ALICE, subsistence * 10); - place_contract(&BOB, code_hash); - MockStack::run_call(ALICE, BOB, &mut gas_meter, &schedule, 0, vec![], None).unwrap(); - }); - } - #[test] fn in_memory_changes_not_discarded() { + // Remove this assert and fill out the "DO" stubs once fields are added to the + // contract info that can be modified during exection. + assert!(!CONTRACT_INFO_CAN_CHANGE); + // Call stack: BOB -> CHARLIE (trap) -> BOB' (success) // This tests verfies some edge case of the contract info cache: // We change some value in our contract info before calling into a contract @@ -2217,13 +1845,9 @@ mod tests { // are made before calling into CHARLIE are not discarded. let code_bob = MockLoader::insert(Call, |ctx, _| { if ctx.input_data[0] == 0 { - let original_allowance = ctx.ext.rent_allowance(); - let changed_allowance = >::max_value() / 2; - assert_ne!(original_allowance, changed_allowance); - ctx.ext.set_rent_allowance(changed_allowance); + // DO: modify medata (ContractInfo) of own contract through ctx.ext functions assert_eq!(ctx.ext.call(0, CHARLIE, 0, vec![], true), exec_trapped()); - assert_eq!(ctx.ext.rent_allowance(), changed_allowance); - assert_ne!(ctx.ext.rent_allowance(), original_allowance); + // DO: check that the value is not discarded (query via ctx.ext) } exec_success() }); diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index 87db8048b3..7b165e51dc 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -70,7 +70,6 @@ //! * [`Pallet::instantiate`] - The same as `instantiate_with_code` but instead of uploading new //! code an existing `code_hash` is supplied. //! * [`Pallet::call`] - Makes a call to an account, optionally transferring some balance. -//! * [`Pallet::claim_surcharge`] - Evict a contract that cannot pay rent anymore. //! //! ## Usage //! @@ -89,7 +88,6 @@ mod gas; mod benchmarking; mod exec; mod migration; -mod rent; mod schedule; mod storage; mod wasm; @@ -108,38 +106,31 @@ pub use crate::{ use crate::{ exec::{Executable, Stack as ExecStack}, gas::GasMeter, - rent::Rent, - storage::{AliveContractInfo, ContractInfo, DeletedContract, Storage, TombstoneContractInfo}, + storage::{ContractInfo, DeletedContract, Storage}, wasm::PrefabWasmModule, weights::WeightInfo, }; use frame_support::{ dispatch::Dispatchable, - traits::{Contains, Currency, Get, OnUnbalanced, Randomness, StorageVersion, Time}, - weights::{GetDispatchInfo, PostDispatchInfo, Weight, WithPostDispatchInfo}, + traits::{Contains, Currency, Get, Randomness, StorageVersion, Time}, + weights::{GetDispatchInfo, PostDispatchInfo, Weight}, }; use frame_system::Pallet as System; use pallet_contracts_primitives::{ Code, ContractAccessError, ContractExecResult, ContractInstantiateResult, GetStorageResult, - InstantiateReturnValue, RentProjectionResult, + InstantiateReturnValue, }; use sp_core::{crypto::UncheckedFrom, Bytes}; -use sp_runtime::{ - traits::{Convert, Hash, Saturating, StaticLookup, Zero}, - Perbill, -}; +use sp_runtime::traits::{Convert, Hash, Saturating, StaticLookup}; use sp_std::prelude::*; type CodeHash = ::Hash; type TrieId = Vec; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency< - ::AccountId, ->>::NegativeImbalance; /// The current storage version. -const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); +const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); #[frame_support::pallet] pub mod pallet { @@ -177,8 +168,7 @@ pub mod pallet { /// /// The runtime **must** make sure that any allowed dispatchable makes sure that the /// `total_balance` of the contract stays above [`Pallet::subsistence_threshold()`]. - /// Otherwise contracts can clutter the storage with their tombstones without - /// deposting the correct amount of balance. + /// Otherwise users could clutter the storage with contracts. /// /// # Stability /// @@ -195,9 +185,6 @@ pub mod pallet { /// be exploited to drive the runtime into a panic. type CallFilter: Contains<::Call>; - /// Handler for rent payments. - type RentPayment: OnUnbalanced>; - /// Used to answer contracts' queries regarding the current weight price. This is **not** /// used to calculate the actual fee and is only for informational purposes. type WeightPrice: Convert>; @@ -213,56 +200,12 @@ pub mod pallet { #[pallet::constant] type Schedule: Get>; - /// Number of block delay an extrinsic claim surcharge has. - /// - /// When claim surcharge is called by an extrinsic the rent is checked - /// for current_block - delay + /// The deposit that must be placed into the contract's account to instantiate it. + /// This is in **addition** to the [`pallet_balances::Pallet::ExistenialDeposit`]. + /// The minimum balance for a contract's account can be queried using + /// [`Pallet::subsistence_threshold`]. #[pallet::constant] - type SignedClaimHandicap: Get; - - /// The minimum amount required to generate a tombstone. - #[pallet::constant] - type TombstoneDeposit: Get>; - - /// The balance every contract needs to deposit to stay alive indefinitely. - /// - /// This is different from the [`Self::TombstoneDeposit`] because this only needs to be - /// deposited while the contract is alive. Costs for additional storage are added to - /// this base cost. - /// - /// This is a simple way to ensure that contracts with empty storage eventually get deleted - /// by making them pay rent. This creates an incentive to remove them early in order to save - /// rent. - #[pallet::constant] - type DepositPerContract: Get>; - - /// The balance a contract needs to deposit per storage byte to stay alive indefinitely. - /// - /// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 - /// BU/byte/day, then a contract with 1,000,000 BU that uses 1,000 bytes of storage would - /// pay no rent. But if the balance reduced to 500,000 BU and the storage stayed the same at - /// 1,000, then it would pay 500 BU/day. - #[pallet::constant] - type DepositPerStorageByte: Get>; - - /// The balance a contract needs to deposit per storage item to stay alive indefinitely. - /// - /// It works the same as [`Self::DepositPerStorageByte`] but for storage items. - #[pallet::constant] - type DepositPerStorageItem: Get>; - - /// The fraction of the deposit that should be used as rent per block. - /// - /// When a contract hasn't enough balance deposited to stay alive indefinitely it needs - /// to pay per block for the storage it consumes that is not covered by the deposit. - /// This determines how high this rent payment is per block as a fraction of the deposit. - #[pallet::constant] - type RentFraction: Get; - - /// Reward that is received by the party whose touch has led - /// to removal of a contract. - #[pallet::constant] - type SurchargeReward: Get>; + type ContractDeposit: Get>; /// The type of the call stack determines the maximum nesting depth of contract calls. /// @@ -439,50 +382,6 @@ pub mod pallet { gas_meter .into_dispatch_result(result, T::WeightInfo::instantiate(salt.len() as u32 / 1024)) } - - /// Allows block producers to claim a small reward for evicting a contract. If a block - /// producer fails to do so, a regular users will be allowed to claim the reward. - /// - /// In case of a successful eviction no fees are charged from the sender. However, the - /// reward is capped by the total amount of rent that was paid by the contract while - /// it was alive. - /// - /// If contract is not evicted as a result of this call, [`Error::ContractNotEvictable`] - /// is returned and the sender is not eligible for the reward. - #[pallet::weight(T::WeightInfo::claim_surcharge(T::Schedule::get().limits.code_len / 1024))] - pub fn claim_surcharge( - origin: OriginFor, - dest: T::AccountId, - aux_sender: Option, - ) -> DispatchResultWithPostInfo { - let origin = origin.into(); - let (signed, rewarded) = match (origin, aux_sender) { - (Ok(frame_system::RawOrigin::Signed(account)), None) => (true, account), - (Ok(frame_system::RawOrigin::None), Some(aux_sender)) => (false, aux_sender), - _ => Err(Error::::InvalidSurchargeClaim)?, - }; - - // Add some advantage for block producers (who send unsigned extrinsics) by - // adding a handicap: for signed extrinsics we use a slightly older block number - // for the eviction check. This can be viewed as if we pushed regular users back in - // past. - let handicap = if signed { T::SignedClaimHandicap::get() } else { Zero::zero() }; - - // If poking the contract has lead to eviction of the contract, give out the rewards. - match Rent::>::try_eviction(&dest, handicap)? { - (Some(rent_paid), code_len) => T::Currency::deposit_into_existing( - &rewarded, - T::SurchargeReward::get().min(rent_paid), - ) - .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))), - } - } } #[pallet::event] @@ -492,10 +391,7 @@ pub mod pallet { /// Contract deployed by address at the specified address. \[deployer, contract\] Instantiated(T::AccountId, T::AccountId), - /// Contract has been evicted and is now in tombstone state. \[contract\] - Evicted(T::AccountId), - - /// Contract has been terminated without leaving a tombstone. + /// Contract has been removed. /// \[contract, beneficiary\] /// /// # Params @@ -505,21 +401,10 @@ pub mod pallet { /// /// # Note /// - /// The only way for a contract to be removed without a tombstone and emitting - /// this event is by calling `seal_terminate`. + /// The only way for a contract to be removed and emitting this event is by calling + /// `seal_terminate`. Terminated(T::AccountId, T::AccountId), - /// Restoration of a contract has been successful. - /// \[restorer, dest, code_hash, rent_allowance\] - /// - /// # Params - /// - /// - `restorer`: Account ID of the restoring contract. - /// - `dest`: Account ID of the restored contract. - /// - `code_hash`: Code hash of the restored contract. - /// - `rent_allowance`: Rent allowance of the restored contract. - Restored(T::AccountId, T::AccountId, T::Hash, BalanceOf), - /// Code with the specified hash has been stored. \[code_hash\] CodeStored(T::Hash), @@ -544,7 +429,7 @@ pub mod pallet { /// A code with the specified hash was removed. /// \[code_hash\] /// - /// This happens when the last contract that uses this code hash was removed or evicted. + /// This happens when the last contract that uses this code hash was removed. CodeRemoved(T::Hash), } @@ -552,24 +437,13 @@ pub mod pallet { pub enum Error { /// A new schedule must have a greater version than the current one. InvalidScheduleVersion, - /// An origin must be signed or inherent and auxiliary sender only provided on inherent. - InvalidSurchargeClaim, - /// Cannot restore from nonexisting or tombstone contract. - InvalidSourceContract, - /// Cannot restore to nonexisting or alive contract. - InvalidDestinationContract, - /// Tombstones don't match. - InvalidTombstone, - /// An origin TrieId written in the current block. - InvalidContractOrigin, /// The executed contract exhausted its gas limit. OutOfGas, /// The output buffer supplied to a contract API call was too small. OutputBufferTooSmall, /// Performing the requested transfer would have brought the contract below - /// the subsistence threshold. No transfer is allowed to do this in order to allow - /// for a tombstone to be created. Use `seal_terminate` to remove a contract without - /// leaving a tombstone behind. + /// the subsistence threshold. No transfer is allowed to do this. Use `seal_terminate` + /// to recover a deposit. BelowSubsistenceThreshold, /// The newly created contract is below the subsistence threshold after executing /// its contructor. No contracts are allowed to exist below that threshold. @@ -583,18 +457,6 @@ pub mod pallet { MaxCallDepthReached, /// No contract was found at the specified address. ContractNotFound, - /// A tombstone exist at the specified address. - /// - /// Tombstone cannot be called. Anyone can use `seal_restore_to` in order to revive - /// the contract, though. - ContractIsTombstone, - /// The called contract does not have enough balance to pay for its storage. - /// - /// The contract ran out of balance and is therefore eligible for eviction into a - /// tombstone. Anyone can evict the contract by submitting a `claim_surcharge` - /// extrinsic. Alternatively, a plain balance transfer can be used in order to - /// increase the contracts funds so that it can be called again. - RentNotPaid, /// The code supplied to `instantiate_with_code` exceeds the limit specified in the /// current schedule. CodeTooLarge, @@ -609,7 +471,7 @@ pub mod pallet { /// The size defined in `T::MaxValueSize` was exceeded. ValueTooLarge, /// Termination of a contract is not allowed while the contract is already - /// on the call stack. Can be triggered by `seal_terminate` or `seal_restore_to. + /// on the call stack. Can be triggered by `seal_terminate`. TerminatedWhileReentrant, /// `seal_call` forwarded this contracts input. It therefore is no longer available. InputForwarded, @@ -625,15 +487,10 @@ pub mod pallet { NoChainExtension, /// Removal of a contract failed because the deletion queue is full. /// - /// This can happen when either calling [`Pallet::claim_surcharge`] or `seal_terminate`. + /// This can happen when calling `seal_terminate`. /// The queue is filled by deleting contracts and emptied by a fixed amount each block. /// Trying again during another block is the only way to resolve this issue. DeletionQueueFull, - /// A contract could not be evicted because it has enough balance to pay rent. - /// - /// This can be returned from [`Pallet::claim_surcharge`] because the target - /// contract has enough balance to pay for its rent. - ContractNotEvictable, /// A storage modification exhausted the 32bit type that holds the storage size. /// /// This can either happen when the accumulated storage in bytes is too large or @@ -643,7 +500,7 @@ pub mod pallet { DuplicateContract, /// A contract self destructed in its constructor. /// - /// This can be triggered by a call to `seal_terminate` or `seal_restore_to`. + /// This can be triggered by a call to `seal_terminate`. TerminatedInConstructor, /// The debug message specified to `seal_debug_message` does contain invalid UTF-8. DebugMessageInvalidUTF8, @@ -730,9 +587,6 @@ where /// /// It returns the execution result, account id and the amount of used weight. /// - /// If `compute_projection` is set to `true` the result also contains the rent projection. - /// This is optional because some non trivial and stateful work is performed to compute - /// the projection. See [`Self::rent_projection`]. /// /// # Note /// @@ -746,9 +600,8 @@ where code: Code>, data: Vec, salt: Vec, - compute_projection: bool, debug: bool, - ) -> ContractInstantiateResult { + ) -> ContractInstantiateResult { let mut gas_meter = GasMeter::new(gas_limit); let schedule = T::Schedule::get(); let executable = match code { @@ -776,18 +629,7 @@ where &salt, debug_message.as_mut(), ) - .and_then(|(account_id, result)| { - let rent_projection = if compute_projection { - Some( - Rent::>::compute_projection(&account_id) - .map_err(|_| >::NewContractNotFunded)?, - ) - } else { - None - }; - - Ok(InstantiateReturnValue { result, account_id, rent_projection }) - }); + .and_then(|(account_id, result)| Ok(InstantiateReturnValue { result, account_id })); ContractInstantiateResult { result: result.map_err(|e| e.error), gas_consumed: gas_meter.gas_consumed(), @@ -798,21 +640,13 @@ where /// Query storage of a specified contract under a specified key. pub fn get_storage(address: T::AccountId, key: [u8; 32]) -> GetStorageResult { - let contract_info = ContractInfoOf::::get(&address) - .ok_or(ContractAccessError::DoesntExist)? - .get_alive() - .ok_or(ContractAccessError::IsTombstone)?; + let contract_info = + ContractInfoOf::::get(&address).ok_or(ContractAccessError::DoesntExist)?; let maybe_value = Storage::::read(&contract_info.trie_id, &key); 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) - } - /// Determine the address of a contract, /// /// This is the address generation function used by contract instantiation. Its result @@ -837,14 +671,13 @@ where } /// Subsistence threshold is the extension of the minimum balance (aka existential deposit) - /// by the tombstone deposit, required for leaving a tombstone. + /// by the contract deposit. It is the minimum balance any contract must hold. /// - /// Rent or any contract initiated balance transfer mechanism cannot make the balance lower - /// than the subsistence threshold in order to guarantee that a tombstone is created. - /// - /// The only way to completely kill a contract without a tombstone is calling `seal_terminate`. + /// Any contract initiated balance transfer mechanism cannot make the balance lower + /// than the subsistence threshold. The only way to recover the balance is to remove + /// contract using `seal_terminate`. pub fn subsistence_threshold() -> BalanceOf { - T::Currency::minimum_balance().saturating_add(T::TombstoneDeposit::get()) + T::Currency::minimum_balance().saturating_add(T::ContractDeposit::get()) } /// The in-memory size in bytes of the data structure associated with each contract. diff --git a/substrate/frame/contracts/src/migration.rs b/substrate/frame/contracts/src/migration.rs index fbf5b59e9e..b7fa9575e2 100644 --- a/substrate/frame/contracts/src/migration.rs +++ b/substrate/frame/contracts/src/migration.rs @@ -18,18 +18,104 @@ use crate::{Config, Pallet, Weight}; use frame_support::{ storage::migration, - traits::{Get, PalletInfoAccess, StorageVersion}, + traits::{Get, PalletInfoAccess}, }; +use sp_std::prelude::*; pub fn migrate() -> Weight { + use frame_support::traits::StorageVersion; + + let version = StorageVersion::get::>(); let mut weight: Weight = 0; - if StorageVersion::get::>() == 3 { - weight = weight.saturating_add(T::DbWeight::get().writes(1)); - migration::remove_storage_prefix(>::name().as_bytes(), b"CurrentSchedule", b""); - + if version < 4 { + weight = weight.saturating_add(v4::migrate::()); StorageVersion::new(4).put::>(); } + if version < 5 { + weight = weight.saturating_add(v5::migrate::()); + StorageVersion::new(5).put::>(); + } + weight } + +/// V4: `Schedule` is changed to be a config item rather than an in-storage value. +mod v4 { + use super::*; + + pub fn migrate() -> Weight { + migration::remove_storage_prefix(>::name().as_bytes(), b"CurrentSchedule", b""); + T::DbWeight::get().writes(1) + } +} + +/// V5: State rent is removed which obsoletes some fields in `ContractInfo`. +mod v5 { + use super::*; + use crate::{ + BalanceOf, CodeHash, ContractInfo, ContractInfoOf, DeletedContract, DeletionQueue, TrieId, + }; + use codec::Decode; + use sp_std::marker::PhantomData; + + type AliveContractInfo = + RawAliveContractInfo, BalanceOf, ::BlockNumber>; + type TombstoneContractInfo = RawTombstoneContractInfo< + ::Hash, + ::Hashing, + >; + + #[derive(Decode)] + enum OldContractInfo { + Alive(AliveContractInfo), + Tombstone(TombstoneContractInfo), + } + + #[derive(Decode)] + struct RawAliveContractInfo { + trie_id: TrieId, + _storage_size: u32, + _pair_count: u32, + code_hash: CodeHash, + _rent_allowance: Balance, + _rent_paid: Balance, + _deduct_block: BlockNumber, + _last_write: Option, + _reserved: Option<()>, + } + + #[derive(Decode)] + struct RawTombstoneContractInfo(H, PhantomData); + + #[derive(Decode)] + struct OldDeletedContract { + _pair_count: u32, + trie_id: TrieId, + } + + pub fn migrate() -> Weight { + let mut weight: Weight = 0; + + >::translate(|_key, old: OldContractInfo| { + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + match old { + OldContractInfo::Alive(old) => Some(ContractInfo:: { + trie_id: old.trie_id, + code_hash: old.code_hash, + _reserved: old._reserved, + }), + OldContractInfo::Tombstone(_) => None, + } + }); + + >::translate(|old: Option>| { + weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); + old.map(|old| old.into_iter().map(|o| DeletedContract { trie_id: o.trie_id }).collect()) + }) + .ok(); + + weight + } +} diff --git a/substrate/frame/contracts/src/rent.rs b/substrate/frame/contracts/src/rent.rs deleted file mode 100644 index 336f03153c..0000000000 --- a/substrate/frame/contracts/src/rent.rs +++ /dev/null @@ -1,577 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! A module responsible for computing the right amount of weight and charging it. - -use crate::{ - exec::Executable, gas::GasMeter, storage::Storage, wasm::PrefabWasmModule, AliveContractInfo, - BalanceOf, CodeHash, Config, ContractInfo, ContractInfoOf, Error, Event, Pallet, - TombstoneContractInfo, -}; -use frame_support::{ - storage::child, - traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReasons}, - DefaultNoBound, -}; -use pallet_contracts_primitives::{ContractAccessError, RentProjection, RentProjectionResult}; -use sp_core::crypto::UncheckedFrom; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}, - DispatchError, -}; -use sp_std::prelude::*; - -/// Information about the required deposit and resulting rent. -/// -/// The easiest way to guarantee that a contract stays alive is to assert that -/// `max_rent == 0` at the **end** of a contract's execution. -/// -/// # Note -/// -/// The `current_*` fields do **not** consider changes to the code's refcount made during -/// the currently running call. -#[derive(codec::Encode, DefaultNoBound)] -#[cfg_attr(test, derive(Debug, PartialEq))] -pub struct RentStatus { - /// Required deposit assuming that this contract is the only user of its code. - pub max_deposit: BalanceOf, - /// Required deposit assuming the code's current refcount. - pub current_deposit: BalanceOf, - /// Required deposit assuming the specified refcount (None if 0 is supplied). - pub custom_refcount_deposit: Option>, - /// Rent that is paid assuming that the contract is the only user of its code. - pub max_rent: BalanceOf, - /// Rent that is paid given the code's current refcount. - pub current_rent: BalanceOf, - /// Rent that is paid assuming the specified refcount (None is 0 is supplied). - pub custom_refcount_rent: Option>, - /// Reserved for backwards compatible changes to this data structure. - pub _reserved: Option<()>, -} - -pub struct Rent(sp_std::marker::PhantomData<(T, E)>); - -impl Rent -where - T: Config, - T::AccountId: UncheckedFrom + AsRef<[u8]>, - E: Executable, -{ - /// Make account paying the rent for the current block number - /// - /// This functions does **not** evict the contract. It returns `None` in case the - /// contract is in need of eviction. [`try_eviction`] must - /// be called to perform the eviction. - pub fn charge( - account: &T::AccountId, - contract: AliveContractInfo, - code_size: u32, - ) -> Result>, DispatchError> { - let current_block_number = >::block_number(); - let verdict = - Self::consider_case(account, current_block_number, Zero::zero(), &contract, code_size); - Self::enact_verdict(account, contract, current_block_number, verdict, None) - } - - /// Process a report that a contract under the given address should be evicted. - /// - /// Enact the eviction right away if the contract should be evicted and return the amount - /// of rent that the contract paid over its lifetime. - /// Otherwise, **do nothing** and return None. - /// - /// The `handicap` parameter gives a way to check the rent to a moment in the past instead - /// of current block. E.g. if the contract is going to be evicted at the current block, - /// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain - /// snitchers relative to others. - /// - /// NOTE this function performs eviction eagerly. All changes are read and written directly to - /// storage. - pub fn try_eviction( - account: &T::AccountId, - handicap: T::BlockNumber, - ) -> Result<(Option>, u32), DispatchError> { - let contract = >::get(account); - let contract = match contract { - 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, - current_block_number, - handicap, - &contract, - module.occupied_storage(), - ); - - // Enact the verdict only if the contract gets removed. - match verdict { - Verdict::Evict { ref amount } => { - // The outstanding `amount` is withdrawn inside `enact_verdict`. - let rent_paid = amount - .as_ref() - .map(|a| a.peek()) - .unwrap_or_else(|| >::zero()) - .saturating_add(contract.rent_paid); - Self::enact_verdict( - account, - contract, - current_block_number, - verdict, - Some(module), - )?; - Ok((Some(rent_paid), code_len)) - }, - _ => Ok((None, code_len)), - } - } - - /// Returns the projected time a given contract will be able to sustain paying its rent. The - /// returned projection is relevant for the current block, i.e. it is as if the contract was - /// accessed at the beginning of the current block. Returns `None` in case if the contract was - /// evicted before or as a result of the rent collection. - /// - /// The returned value is only an estimation. It doesn't take into account any top ups, changing - /// the rent allowance, or any problems coming from withdrawing the dues. - /// - /// NOTE that this is not a side-effect free function! It will actually collect rent and then - /// compute the projection. This function is only used for implementation of an RPC method - /// through `RuntimeApi` meaning that the changes will be discarded anyway. - pub fn compute_projection(account: &T::AccountId) -> RentProjectionResult { - use ContractAccessError::IsTombstone; - - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(IsTombstone), - Some(ContractInfo::Alive(contract)) => contract, - }; - let module = >::from_storage_noinstr(alive_contract_info.code_hash) - .map_err(|_| IsTombstone)?; - let code_size = module.occupied_storage(); - let current_block_number = >::block_number(); - let verdict = Self::consider_case( - account, - current_block_number, - Zero::zero(), - &alive_contract_info, - code_size, - ); - - // We skip the eviction in case one is in order. - // Evictions should only be performed by [`try_eviction`]. - let new_contract_info = - Self::enact_verdict(account, alive_contract_info, current_block_number, verdict, None); - - // Check what happened after enaction of the verdict. - let alive_contract_info = - new_contract_info.map_err(|_| IsTombstone)?.ok_or_else(|| IsTombstone)?; - - // Compute how much would the fee per block be with the *updated* balance. - let total_balance = T::Currency::total_balance(account); - let free_balance = T::Currency::free_balance(account); - let fee_per_block = Self::fee_per_block(&free_balance, &alive_contract_info, code_size); - if fee_per_block.is_zero() { - return Ok(RentProjection::NoEviction) - } - - // Then compute how much the contract will sustain under these circumstances. - let rent_budget = Self::rent_budget(&total_balance, &free_balance, &alive_contract_info) - .expect( - "the contract exists and in the alive state; - the updated balance must be greater than subsistence deposit; - this function doesn't return `None`; - qed - ", - ); - let blocks_left = match rent_budget.checked_div(&fee_per_block) { - Some(blocks_left) => blocks_left, - None => { - // `fee_per_block` is not zero here, so `checked_div` can return `None` if - // there is an overflow. This cannot happen with integers though. Return - // `NoEviction` here just in case. - return Ok(RentProjection::NoEviction) - }, - }; - - let blocks_left = blocks_left.saturated_into::().into(); - Ok(RentProjection::EvictionAt(current_block_number + blocks_left)) - } - - /// Restores the destination account using the origin as prototype. - /// - /// The restoration will be performed iff: - /// - the supplied code_hash does still exist on-chain - /// - origin exists and is alive, - /// - the origin's storage is not written in the current block - /// - the restored account has tombstone - /// - the tombstone matches the hash of the origin storage root, and code hash. - /// - /// 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. - pub fn restore_to( - origin: &T::AccountId, - mut origin_contract: AliveContractInfo, - dest: T::AccountId, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - let child_trie_info = origin_contract.child_trie_info(); - - let current_block = >::block_number(); - - if origin_contract.last_write == Some(current_block) { - return Err(Error::::InvalidContractOrigin.into()) - } - - let dest_tombstone = >::get(&dest) - .and_then(|c| c.get_tombstone()) - .ok_or(Error::::InvalidDestinationContract)?; - - let last_write = - if !delta.is_empty() { Some(current_block) } else { origin_contract.last_write }; - - // Fails if the code hash does not exist on chain - E::add_user(code_hash, gas_meter)?; - - // We are allowed to eagerly modify storage even though the function can - // fail later due to tombstones not matching. This is because the restoration - // is always called from a contract and therefore in a storage transaction. - // The failure of this function will lead to this transaction's rollback. - let bytes_taken: u32 = delta - .iter() - .filter_map(|key| { - let key = blake2_256(key); - child::get_raw(&child_trie_info, &key).map(|value| { - child::kill(&child_trie_info, &key); - value.len() as u32 - }) - }) - .sum(); - - let tombstone = >::new( - // This operation is cheap enough because last_write (delta not included) - // is not this block as it has been checked earlier. - &child::root(&child_trie_info)[..], - code_hash, - ); - - if tombstone != dest_tombstone { - return Err(Error::::InvalidTombstone.into()) - } - - origin_contract.storage_size -= bytes_taken; - - >::remove(&origin); - E::remove_user(origin_contract.code_hash, gas_meter)?; - >::insert( - &dest, - ContractInfo::Alive(AliveContractInfo:: { - code_hash, - rent_allowance, - rent_paid: >::zero(), - deduct_block: current_block, - last_write, - ..origin_contract - }), - ); - - let origin_free_balance = T::Currency::free_balance(&origin); - T::Currency::make_free_balance_be(&origin, >::zero()); - T::Currency::deposit_creating(&dest, origin_free_balance); - Ok(()) - } - - /// Create a new `RentStatus` struct for pass through to a requesting contract. - pub fn rent_status( - free_balance: &BalanceOf, - contract: &AliveContractInfo, - aggregated_code_size: u32, - current_refcount: u32, - at_refcount: u32, - ) -> RentStatus { - let calc_share = |refcount: u32| aggregated_code_size.checked_div(refcount).unwrap_or(0); - let current_share = calc_share(current_refcount); - let custom_share = calc_share(at_refcount); - RentStatus { - max_deposit: Self::required_deposit(contract, aggregated_code_size), - current_deposit: Self::required_deposit(contract, current_share), - custom_refcount_deposit: if at_refcount > 0 { - Some(Self::required_deposit(contract, custom_share)) - } else { - None - }, - max_rent: Self::fee_per_block(free_balance, contract, aggregated_code_size), - current_rent: Self::fee_per_block(free_balance, contract, current_share), - custom_refcount_rent: if at_refcount > 0 { - Some(Self::fee_per_block(free_balance, contract, custom_share)) - } else { - None - }, - _reserved: None, - } - } - - /// Returns how much deposit is required to not pay rent. - fn required_deposit(contract: &AliveContractInfo, code_size_share: u32) -> BalanceOf { - T::DepositPerStorageByte::get() - .saturating_mul(contract.storage_size.saturating_add(code_size_share).into()) - .saturating_add( - T::DepositPerStorageItem::get().saturating_mul(contract.pair_count.into()), - ) - .saturating_add(T::DepositPerContract::get()) - } - - /// Returns a fee charged per block from the contract. - /// - /// This function accounts for the storage rent deposit. I.e. if the contract - /// possesses enough funds then the fee can drop to zero. - fn fee_per_block( - free_balance: &BalanceOf, - contract: &AliveContractInfo, - code_size_share: u32, - ) -> BalanceOf { - let missing_deposit = - Self::required_deposit(contract, code_size_share).saturating_sub(*free_balance); - T::RentFraction::get().mul_ceil(missing_deposit) - } - - /// Returns amount of funds available to consume by rent mechanism. - /// - /// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot - /// make the balance lower than [`subsistence_threshold`]. - /// - /// In case the toal_balance is below the subsistence threshold, this function returns `None`. - fn rent_budget( - total_balance: &BalanceOf, - free_balance: &BalanceOf, - contract: &AliveContractInfo, - ) -> Option> { - let subsistence_threshold = Pallet::::subsistence_threshold(); - // Reserved balance contributes towards the subsistence threshold to stay consistent - // with the existential deposit where the reserved balance is also counted. - if *total_balance < subsistence_threshold { - return None - } - - // However, reserved balance cannot be charged so we need to use the free balance - // to calculate the actual budget (which can be 0). - let rent_allowed_to_charge = free_balance.saturating_sub(subsistence_threshold); - Some(>::min(contract.rent_allowance, rent_allowed_to_charge)) - } - - /// Consider the case for rent payment of the given account and returns a `Verdict`. - /// - /// Use `handicap` in case you want to change the reference block number. (To get more details - /// see `try_eviction` ). - fn consider_case( - account: &T::AccountId, - current_block_number: T::BlockNumber, - handicap: T::BlockNumber, - contract: &AliveContractInfo, - code_size: u32, - ) -> Verdict { - // How much block has passed since the last deduction for the contract. - let blocks_passed = { - // Calculate an effective block number, i.e. after adjusting for handicap. - let effective_block_number = current_block_number.saturating_sub(handicap); - effective_block_number.saturating_sub(contract.deduct_block) - }; - if blocks_passed.is_zero() { - // Rent has already been paid - return Verdict::Exempt - } - - let total_balance = T::Currency::total_balance(account); - let free_balance = T::Currency::free_balance(account); - - // An amount of funds to charge per block for storage taken up by the contract. - let fee_per_block = Self::fee_per_block(&free_balance, contract, code_size); - if fee_per_block.is_zero() { - // The rent deposit offset reduced the fee to 0. This means that the contract - // gets the rent for free. - return Verdict::Exempt - } - - let rent_budget = match Self::rent_budget(&total_balance, &free_balance, contract) { - Some(rent_budget) => rent_budget, - None => { - // All functions that allow a contract to transfer balance enforce - // that the contract always stays above the subsistence threshold. - // We want the rent system to always leave a tombstone to prevent the - // accidental loss of a contract. Ony `seal_terminate` can remove a - // contract without a tombstone. Therefore this case should be never - // hit. - log::error!( - target: "runtime::contracts", - "Tombstoned a contract that is below the subsistence threshold: {:?}", - account, - ); - 0u32.into() - }, - }; - - let dues = fee_per_block - .checked_mul(&blocks_passed.saturated_into::().into()) - .unwrap_or_else(|| >::max_value()); - let insufficient_rent = rent_budget < dues; - - // If the rent payment cannot be withdrawn due to locks on the account balance, then evict - // the account. - // - // NOTE: This seems problematic because it provides a way to tombstone an account while - // avoiding the last rent payment. In effect, someone could retroactively set rent_allowance - // for their contract to 0. - let dues_limited = dues.min(rent_budget); - let can_withdraw_rent = T::Currency::ensure_can_withdraw( - account, - dues_limited, - WithdrawReasons::FEE, - free_balance.saturating_sub(dues_limited), - ) - .is_ok(); - - if insufficient_rent || !can_withdraw_rent { - // The contract cannot afford the rent payment and has a balance above the subsistence - // threshold, so it leaves a tombstone. - let amount = - if can_withdraw_rent { Some(OutstandingAmount::new(dues_limited)) } else { None }; - return Verdict::Evict { amount } - } - - return Verdict::Charge { - // We choose to use `dues_limited` here instead of `dues` just to err on the safer side. - amount: OutstandingAmount::new(dues_limited), - } - } - - /// Enacts the given verdict and returns the updated `ContractInfo`. - /// - /// `alive_contract_info` should be from the same address as `account`. - /// - /// # Note - /// - /// if `evictable_code` is `None` an `Evict` verdict will not be enacted. This is for - /// when calling this function during a `call` where access to the soon to be evicted - /// contract should be denied but storage should be left unmodified. - fn enact_verdict( - account: &T::AccountId, - alive_contract_info: AliveContractInfo, - current_block_number: T::BlockNumber, - verdict: Verdict, - evictable_code: Option>, - ) -> Result>, DispatchError> { - match (verdict, evictable_code) { - (Verdict::Evict { amount }, Some(code)) => { - // We need to remove the trie first because it is the only operation - // that can fail and this function is called without a storage - // transaction when called through `claim_surcharge`. - Storage::::queue_trie_for_deletion(&alive_contract_info)?; - - if let Some(amount) = amount { - amount.withdraw(account); - } - - // Note: this operation is heavy. - let child_storage_root = child::root(&alive_contract_info.child_trie_info()); - - let tombstone = >::new( - &child_storage_root[..], - alive_contract_info.code_hash, - ); - let tombstone_info = ContractInfo::Tombstone(tombstone); - >::insert(account, &tombstone_info); - code.drop_from_storage(); - >::deposit_event(Event::Evicted(account.clone())); - Ok(None) - }, - (Verdict::Evict { amount: _ }, None) => Ok(None), - (Verdict::Exempt, _) => { - let contract = ContractInfo::Alive(AliveContractInfo:: { - deduct_block: current_block_number, - ..alive_contract_info - }); - >::insert(account, &contract); - Ok(Some(contract.get_alive().expect("We just constructed it as alive. qed"))) - }, - (Verdict::Charge { amount }, _) => { - let contract = ContractInfo::Alive(AliveContractInfo:: { - rent_allowance: alive_contract_info.rent_allowance - amount.peek(), - deduct_block: current_block_number, - rent_paid: alive_contract_info.rent_paid.saturating_add(amount.peek()), - ..alive_contract_info - }); - >::insert(account, &contract); - amount.withdraw(account); - Ok(Some(contract.get_alive().expect("We just constructed it as alive. qed"))) - }, - } - } -} - -/// The amount to charge. -/// -/// This amount respects the contract's rent allowance and the subsistence deposit. -/// Because of that, charging the amount cannot remove the contract. -struct OutstandingAmount { - amount: BalanceOf, -} - -impl OutstandingAmount { - /// Create the new outstanding amount. - /// - /// The amount should be always withdrawable and it should not kill the account. - fn new(amount: BalanceOf) -> Self { - Self { amount } - } - - /// Returns the amount this instance wraps. - fn peek(&self) -> BalanceOf { - self.amount - } - - /// Withdraws the outstanding amount from the given account. - fn withdraw(self, account: &T::AccountId) { - if let Ok(imbalance) = T::Currency::withdraw( - account, - self.amount, - WithdrawReasons::FEE, - ExistenceRequirement::KeepAlive, - ) { - // This should never fail. However, let's err on the safe side. - T::RentPayment::on_unbalanced(imbalance); - } - } -} - -enum Verdict { - /// The contract is exempted from paying rent. - /// - /// For example, it already paid its rent in the current block, or it has enough deposit for - /// not paying rent at all. - Exempt, - /// The contract cannot afford payment within its rent budget so it gets evicted. However, - /// because its balance is greater than the subsistence threshold it leaves a tombstone. - Evict { amount: Option> }, - /// Everything is OK, we just only take some charge. - Charge { amount: OutstandingAmount }, -} diff --git a/substrate/frame/contracts/src/schedule.rs b/substrate/frame/contracts/src/schedule.rs index a1118633bf..2768ddf43a 100644 --- a/substrate/frame/contracts/src/schedule.rs +++ b/substrate/frame/contracts/src/schedule.rs @@ -267,11 +267,8 @@ pub struct HostFnWeights { /// Weight of calling `seal_minimum_balance`. pub minimum_balance: Weight, - /// Weight of calling `seal_tombstone_deposit`. - pub tombstone_deposit: Weight, - - /// Weight of calling `seal_rent_allowance`. - pub rent_allowance: Weight, + /// Weight of calling `seal_contract_deposit`. + pub contract_deposit: Weight, /// Weight of calling `seal_block_number`. pub block_number: Weight, @@ -300,12 +297,6 @@ pub struct HostFnWeights { /// Weight of calling `seal_terminate`. pub terminate: Weight, - /// Weight of calling `seal_restore_to`. - pub restore_to: Weight, - - /// Weight per delta key supplied to `seal_restore_to`. - pub restore_to_per_delta: Weight, - /// Weight of calling `seal_random`. pub random: Weight, @@ -321,9 +312,6 @@ pub struct HostFnWeights { /// Weight of calling `seal_debug_message`. pub debug_message: Weight, - /// Weight of calling `seal_set_rent_allowance`. - pub set_rent_allowance: Weight, - /// Weight of calling `seal_set_storage`. pub set_storage: Weight, @@ -566,8 +554,7 @@ impl Default for HostFnWeights { balance: cost_batched!(seal_balance), value_transferred: cost_batched!(seal_value_transferred), minimum_balance: cost_batched!(seal_minimum_balance), - tombstone_deposit: cost_batched!(seal_tombstone_deposit), - rent_allowance: cost_batched!(seal_rent_allowance), + contract_deposit: cost_batched!(seal_tombstone_deposit), block_number: cost_batched!(seal_block_number), now: cost_batched!(seal_now), weight_to_fee: cost_batched!(seal_weight_to_fee), @@ -577,8 +564,6 @@ impl Default for HostFnWeights { r#return: cost!(seal_return), return_per_byte: cost_byte!(seal_return_per_kb), terminate: cost!(seal_terminate), - restore_to: cost!(seal_restore_to), - restore_to_per_delta: cost_batched!(seal_restore_to_per_delta), random: cost_batched!(seal_random), deposit_event: cost_batched!(seal_deposit_event), deposit_event_per_topic: cost_batched_args!(seal_deposit_event_per_topic_and_kb, 1, 0), @@ -588,7 +573,6 @@ impl Default for HostFnWeights { 1 ), debug_message: cost_batched!(seal_debug_message), - set_rent_allowance: cost_batched!(seal_set_rent_allowance), set_storage: cost_batched!(seal_set_storage), set_storage_per_byte: cost_byte_batched!(seal_set_storage_per_kb), clear_storage: cost_batched!(seal_clear_storage), diff --git a/substrate/frame/contracts/src/storage.rs b/substrate/frame/contracts/src/storage.rs index 0781983483..510a1c95f9 100644 --- a/substrate/frame/contracts/src/storage.rs +++ b/substrate/frame/contracts/src/storage.rs @@ -20,9 +20,9 @@ use crate::{ exec::{AccountIdOf, StorageKey}, weights::WeightInfo, - BalanceOf, CodeHash, Config, ContractInfoOf, DeletionQueue, Error, TrieId, + CodeHash, Config, ContractInfoOf, DeletionQueue, Error, TrieId, }; -use codec::{Codec, Decode, Encode}; +use codec::{Decode, Encode}; use frame_support::{ dispatch::{DispatchError, DispatchResult}, storage::child::{self, ChildInfo, KillStorageResult}, @@ -31,87 +31,26 @@ use frame_support::{ }; use sp_core::crypto::UncheckedFrom; use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Bounded, Hash, MaybeSerializeDeserialize, Member, Saturating, Zero}, - RuntimeDebug, -}; -use sp_std::{fmt::Debug, marker::PhantomData, prelude::*}; +use sp_runtime::{traits::Hash, RuntimeDebug}; +use sp_std::{marker::PhantomData, prelude::*}; -pub type AliveContractInfo = - RawAliveContractInfo, BalanceOf, ::BlockNumber>; -pub type TombstoneContractInfo = RawTombstoneContractInfo< - ::Hash, - ::Hashing, ->; - -/// Information for managing an account and its sub trie abstraction. -/// This is the required info to cache for an account -#[derive(Encode, Decode, RuntimeDebug)] -pub enum ContractInfo { - Alive(AliveContractInfo), - Tombstone(TombstoneContractInfo), -} - -impl ContractInfo { - /// If contract is alive then return some alive info - pub fn get_alive(self) -> Option> { - if let ContractInfo::Alive(alive) = self { - Some(alive) - } else { - None - } - } - - /// If contract is alive then return some reference to alive info - #[cfg(test)] - pub fn as_alive(&self) -> Option<&AliveContractInfo> { - if let ContractInfo::Alive(ref alive) = self { - Some(alive) - } else { - None - } - } - - /// If contract is tombstone then return some tombstone info - pub fn get_tombstone(self) -> Option> { - if let ContractInfo::Tombstone(tombstone) = self { - Some(tombstone) - } else { - None - } - } -} +pub type ContractInfo = RawContractInfo>; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct RawAliveContractInfo { +pub struct RawContractInfo { /// Unique ID for the subtree encoded as a bytes vector. pub trie_id: TrieId, - /// The total number of bytes used by this contract. - /// - /// It is a sum of each key-value pair stored by this contract. - pub storage_size: u32, - /// The total number of key-value pairs in storage of this contract. - pub pair_count: u32, /// The code associated with a given account. pub code_hash: CodeHash, - /// Pay rent at most up to this value. - pub rent_allowance: Balance, - /// The amount of rent that was paid by the contract over its whole lifetime. - /// - /// A restored contract starts with a value of zero just like a new contract. - pub rent_paid: Balance, - /// Last block rent has been paid. - pub deduct_block: BlockNumber, - /// Last block child storage has been written. - pub last_write: Option, /// This field is reserved for future evolution of format. pub _reserved: Option<()>, } -impl RawAliveContractInfo { +impl RawContractInfo { /// Associated child trie unique id is built from the hash part of the trie id. + #[cfg(test)] pub fn child_trie_info(&self) -> ChildInfo { child_trie_info(&self.trie_id[..]) } @@ -122,40 +61,9 @@ fn child_trie_info(trie_id: &[u8]) -> ChildInfo { ChildInfo::new_default(trie_id) } -#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] -pub struct RawTombstoneContractInfo(H, PhantomData); - -impl RawTombstoneContractInfo -where - H: Member - + MaybeSerializeDeserialize - + Debug - + AsRef<[u8]> - + AsMut<[u8]> - + Copy - + Default - + sp_std::hash::Hash - + Codec, - Hasher: Hash, -{ - pub fn new(storage_root: &[u8], code_hash: H) -> Self { - let mut buf = Vec::new(); - storage_root.using_encoded(|encoded| buf.extend_from_slice(encoded)); - buf.extend_from_slice(code_hash.as_ref()); - RawTombstoneContractInfo(::hash(&buf[..]), PhantomData) - } -} - -impl From> for ContractInfo { - fn from(alive_info: AliveContractInfo) -> Self { - Self::Alive(alive_info) - } -} - #[derive(Encode, Decode)] pub struct DeletedContract { - pair_count: u32, - trie_id: TrieId, + pub(crate) trie_id: TrieId, } pub struct Storage(PhantomData); @@ -181,47 +89,13 @@ where /// contract owns, the last block the storage was written to, etc. That's why, in contrast to /// `read`, this function also requires the `account` ID. pub fn write( - block_number: T::BlockNumber, - new_info: &mut AliveContractInfo, + new_info: &mut ContractInfo, key: &StorageKey, opt_new_value: Option>, ) -> DispatchResult { let hashed_key = blake2_256(key); let child_trie_info = &child_trie_info(&new_info.trie_id); - let opt_prev_len = child::len(&child_trie_info, &hashed_key); - - // Update the total number of KV pairs and the number of empty pairs. - match (&opt_prev_len, &opt_new_value) { - (Some(_), None) => { - new_info.pair_count = new_info - .pair_count - .checked_sub(1) - .ok_or_else(|| Error::::StorageExhausted)?; - }, - (None, Some(_)) => { - new_info.pair_count = new_info - .pair_count - .checked_add(1) - .ok_or_else(|| Error::::StorageExhausted)?; - }, - (Some(_), Some(_)) => {}, - (None, None) => {}, - } - - // Update the total storage size. - let prev_value_len = opt_prev_len.unwrap_or(0); - let new_value_len = - opt_new_value.as_ref().map(|new_value| new_value.len() as u32).unwrap_or(0); - new_info.storage_size = new_info - .storage_size - .checked_sub(prev_value_len) - .and_then(|val| val.checked_add(new_value_len)) - .ok_or_else(|| Error::::StorageExhausted)?; - - new_info.last_write = Some(block_number); - - // Finally, perform the change on the storage. match opt_new_value { Some(new_value) => child::put_raw(&child_trie_info, &hashed_key, &new_value[..]), None => child::kill(&child_trie_info, &hashed_key), @@ -233,47 +107,29 @@ where /// Creates a new contract descriptor in the storage with the given code hash at the given /// address. /// - /// Returns `Err` if there is already a contract (or a tombstone) exists at the given address. + /// Returns `Err` if there is already a contract at the given address. pub fn new_contract( account: &AccountIdOf, trie_id: TrieId, ch: CodeHash, - ) -> Result, DispatchError> { + ) -> Result, DispatchError> { if >::contains_key(account) { return Err(Error::::DuplicateContract.into()) } - let contract = AliveContractInfo:: { - code_hash: ch, - storage_size: 0, - trie_id, - deduct_block: - // We want to charge rent for the first block in advance. Therefore we - // treat the contract as if it was created in the last block and then - // charge rent for it during instantiation. - >::block_number().saturating_sub(1u32.into()), - rent_allowance: >::max_value(), - rent_paid: >::zero(), - pair_count: 0, - last_write: None, - _reserved: None, - }; + let contract = ContractInfo:: { code_hash: ch, trie_id, _reserved: None }; Ok(contract) } /// Push a contract's trie to the deletion queue for lazy removal. /// - /// You must make sure that the contract is also removed or converted into a tombstone - /// when queuing the trie for deletion. - pub fn queue_trie_for_deletion(contract: &AliveContractInfo) -> DispatchResult { + /// You must make sure that the contract is also removed when queuing the trie for deletion. + pub fn queue_trie_for_deletion(contract: &ContractInfo) -> DispatchResult { if >::decode_len().unwrap_or(0) >= T::DeletionQueueDepth::get() as usize { Err(Error::::DeletionQueueFull.into()) } else { - >::append(DeletedContract { - pair_count: contract.pair_count, - trie_id: contract.trie_id.clone(), - }); + >::append(DeletedContract { trie_id: contract.trie_id.clone() }); Ok(()) } } @@ -302,12 +158,11 @@ where /// Delete as many items from the deletion queue possible within the supplied weight limit. /// - /// It returns the amount of weight used for that task or `None` when no weight was used - /// apart from the base weight. + /// It returns the amount of weight used for that task. pub fn process_deletion_queue_batch(weight_limit: Weight) -> Weight { let queue_len = >::decode_len().unwrap_or(0); if queue_len == 0 { - return weight_limit + return 0 } let (weight_per_key, mut remaining_key_budget) = @@ -322,33 +177,20 @@ where let mut queue = >::get(); - while !queue.is_empty() && remaining_key_budget > 0 { - // Cannot panic due to loop condition - let trie = &mut queue[0]; - let pair_count = trie.pair_count; + if let (Some(trie), true) = (queue.get(0), remaining_key_budget > 0) { let outcome = child::kill_storage(&child_trie_info(&trie.trie_id), Some(remaining_key_budget)); - if pair_count > remaining_key_budget { - // Cannot underflow because of the if condition - trie.pair_count -= remaining_key_budget; - } else { - // We do not care to preserve order. The contract is deleted already and - // noone waits for the trie to be deleted. - let removed = queue.swap_remove(0); - match outcome { - // This should not happen as our budget was large enough to remove all keys. - KillStorageResult::SomeRemaining(_) => { - log::error!( - target: "runtime::contracts", - "After deletion keys are remaining in this child trie: {:?}", - removed.trie_id, - ); - }, - KillStorageResult::AllRemoved(_) => (), - } - } - remaining_key_budget = - remaining_key_budget.saturating_sub(remaining_key_budget.min(pair_count)); + let keys_removed = match outcome { + // This should not happen as our budget was large enough to remove all keys. + KillStorageResult::SomeRemaining(count) => count, + KillStorageResult::AllRemoved(count) => { + // We do not care to preserve order. The contract is deleted already and + // noone waits for the trie to be deleted. + queue.swap_remove(0); + count + }, + }; + remaining_key_budget = remaining_key_budget.saturating_sub(keys_removed); } >::put(queue); @@ -365,14 +207,14 @@ where /// Returns the code hash of the contract specified by `account` ID. #[cfg(test)] pub fn code_hash(account: &AccountIdOf) -> Option> { - >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) + >::get(account).map(|i| i.code_hash) } /// Fill up the queue in order to exercise the limits during testing. #[cfg(test)] pub fn fill_queue_with_dummies() { let queue: Vec<_> = (0..T::DeletionQueueDepth::get()) - .map(|_| DeletedContract { pair_count: 0, trie_id: vec![] }) + .map(|_| DeletedContract { trie_id: vec![] }) .collect(); >::put(queue); } diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index fc5a2cf522..5d2057a0b7 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -20,16 +20,16 @@ use crate::{ ChainExtension, Environment, Ext, InitState, Result as ExtensionResult, RetVal, ReturnFlags, SysConfig, UncheckedFrom, }, - exec::{AccountIdOf, Executable, Frame}, - storage::{RawAliveContractInfo, Storage}, + exec::Frame, + storage::{RawContractInfo, Storage}, wasm::{PrefabWasmModule, ReturnCode as RuntimeReturnCode}, weights::WeightInfo, - BalanceOf, Config, ContractInfo, ContractInfoOf, Error, Pallet, Schedule, + BalanceOf, Config, ContractInfoOf, Error, Pallet, Schedule, }; use assert_matches::assert_matches; use codec::Encode; use frame_support::{ - assert_err, assert_err_ignore_postinfo, assert_ok, assert_storage_noop, + assert_err, assert_err_ignore_postinfo, assert_ok, dispatch::DispatchErrorWithPostInfo, parameter_types, storage::child, @@ -43,7 +43,7 @@ use sp_io::hashing::blake2_256; use sp_runtime::{ testing::{Header, H256}, traits::{BlakeTwo256, Convert, Hash, IdentityLookup}, - AccountId32, Perbill, + AccountId32, }; use std::cell::RefCell; @@ -69,21 +69,20 @@ frame_support::construct_runtime!( #[macro_use] pub mod test_utils { - use super::{Balances, System, Test}; + use super::{Balances, Test}; use crate::{ exec::{AccountIdOf, StorageKey}, - storage::{ContractInfo, Storage}, + storage::Storage, AccountCounter, CodeHash, ContractInfoOf, Pallet as Contracts, TrieId, }; use frame_support::traits::Currency; pub fn set_storage(addr: &AccountIdOf, key: &StorageKey, value: Option>) { - let mut contract_info = >::get(&addr).unwrap().get_alive().unwrap(); - let block_number = System::block_number(); - Storage::::write(block_number, &mut contract_info, key, value).unwrap(); + let mut contract_info = >::get(&addr).unwrap(); + Storage::::write(&mut contract_info, key, value).unwrap(); } pub fn get_storage(addr: &AccountIdOf, key: &StorageKey) -> Option> { - let contract_info = >::get(&addr).unwrap().get_alive().unwrap(); + let contract_info = >::get(&addr).unwrap(); Storage::::read(&contract_info.trie_id, key) } pub fn generate_trie_id(address: &AccountIdOf) -> TrieId { @@ -97,7 +96,7 @@ pub mod test_utils { let trie_id = generate_trie_id(address); set_balance(address, Contracts::::subsistence_threshold() * 10); let contract = Storage::::new_contract(&address, trie_id, code_hash).unwrap(); - >::insert(address, ContractInfo::Alive(contract)); + >::insert(address, contract); } pub fn set_balance(who: &AccountIdOf, amount: u64) { let imbalance = Balances::deposit_creating(who, amount); @@ -248,13 +247,7 @@ impl pallet_utility::Config for Test { type WeightInfo = (); } parameter_types! { - pub const SignedClaimHandicap: u64 = 2; - pub const TombstoneDeposit: u64 = 16; - pub const DepositPerContract: u64 = 8 * DepositPerStorageByte::get(); - pub const DepositPerStorageByte: u64 = 10_000; - pub const DepositPerStorageItem: u64 = 10_000; - pub RentFraction: Perbill = Perbill::from_rational(4u32, 10_000u32); - pub const SurchargeReward: u64 = 500_000; + pub const ContractDeposit: u64 = 16; pub const MaxValueSize: u32 = 16_384; pub const DeletionQueueDepth: u32 = 1024; pub const DeletionWeightLimit: Weight = 500_000_000_000; @@ -295,14 +288,7 @@ impl Config for Test { type Event = Event; type Call = Call; type CallFilter = TestFilter; - type RentPayment = (); - type SignedClaimHandicap = SignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type DepositPerContract = DepositPerContract; - type DepositPerStorageByte = DepositPerStorageByte; - type DepositPerStorageItem = DepositPerStorageItem; - type RentFraction = RentFraction; - type SurchargeReward = SurchargeReward; + type ContractDeposit = ContractDeposit; type CallStack = [Frame; 31]; type WeightPrice = Self; type WeightInfo = (); @@ -395,33 +381,21 @@ fn account_removal_does_not_remove_storage() { // Set up two accounts with free balance above the existential threshold. { - let alice_contract_info = ContractInfo::Alive(RawAliveContractInfo { + let alice_contract_info = RawContractInfo { trie_id: trie_id1.clone(), - storage_size: 0, - pair_count: 0, - deduct_block: System::block_number(), code_hash: H256::repeat_byte(1), - rent_allowance: 40, - rent_paid: 0, - last_write: None, _reserved: None, - }); + }; let _ = Balances::deposit_creating(&ALICE, 110); ContractInfoOf::::insert(ALICE, &alice_contract_info); set_storage(&ALICE, &key1, Some(b"1".to_vec())); set_storage(&ALICE, &key2, Some(b"2".to_vec())); - let bob_contract_info = ContractInfo::Alive(RawAliveContractInfo { + let bob_contract_info = RawContractInfo { trie_id: trie_id2.clone(), - storage_size: 0, - pair_count: 0, - deduct_block: System::block_number(), code_hash: H256::repeat_byte(2), - rent_allowance: 40, - rent_paid: 0, - last_write: None, _reserved: None, - }); + }; let _ = Balances::deposit_creating(&BOB, 110); ContractInfoOf::::insert(BOB, &bob_contract_info); set_storage(&BOB, &key1, Some(b"3".to_vec())); @@ -593,7 +567,7 @@ fn run_out_of_gas() { Origin::signed(ALICE), addr, // newly created account 0, - 67_500_000, + 1_000_000_000_000, vec![], ), Error::::OutOfGas, @@ -601,881 +575,10 @@ fn run_out_of_gas() { }); } -/// Input data for each call in set_rent code -mod call { - use super::{AccountIdOf, Test}; - pub fn set_storage_4_byte() -> Vec { - 0u32.to_le_bytes().to_vec() - } - pub fn remove_storage_4_byte() -> Vec { - 1u32.to_le_bytes().to_vec() - } - #[allow(dead_code)] - pub fn transfer(to: &AccountIdOf) -> Vec { - 2u32.to_le_bytes().iter().chain(AsRef::<[u8]>::as_ref(to)).cloned().collect() - } - pub fn null() -> Vec { - 3u32.to_le_bytes().to_vec() - } -} - -#[test] -fn storage_size() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Storage size - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - // rent_allowance - ::Balance::from(10_000u32).encode(), - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.pair_count, 1); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::set_storage_4_byte() - )); - let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, 4 + 4); - assert_eq!(bob_contract.pair_count, 2); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::remove_storage_4_byte() - )); - let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.pair_count, 1); - }); -} - -#[test] -fn empty_kv_pairs() { - let (wasm, code_hash) = compile_module::("set_empty_storage").unwrap(); - - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - vec![], - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - - assert_eq!(bob_contract.storage_size, 0); - assert_eq!(bob_contract.pair_count, 1); - }); -} - fn initialize_block(number: u64) { System::initialize(&number, &[0u8; 32].into(), &Default::default(), Default::default()); } -#[test] -fn deduct_blocks() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - let endowment: BalanceOf = 100_000; - let allowance: BalanceOf = 70_000; - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - endowment, - GAS_LIMIT, - wasm, - allowance.encode(), - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - let code_len: BalanceOf = - PrefabWasmModule::::from_storage_noinstr(contract.code_hash) - .unwrap() - .occupied_storage() - .into(); - - // The instantiation deducted the rent for one block immediately - let rent0 = ::RentFraction::get() - // (base_deposit(8) + bytes in storage(4) + size of code) * byte_price - // + 1 storage item (10_000) - free_balance - .mul_ceil((8 + 4 + code_len) * 10_000 + 10_000 - endowment) - // blocks to rent - * 1; - assert!(rent0 > 0); - assert_eq!(contract.rent_allowance, allowance - rent0); - assert_eq!(contract.deduct_block, 1); - assert_eq!(Balances::free_balance(&addr), endowment - rent0); - - // Advance 4 blocks - initialize_block(5); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::null() - )); - - // Check result - let rent = ::RentFraction::get() - .mul_ceil((8 + 4 + code_len) * 10_000 + 10_000 - (endowment - rent0)) * - 4; - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(contract.rent_allowance, allowance - rent0 - rent); - assert_eq!(contract.deduct_block, 5); - assert_eq!(Balances::free_balance(&addr), endowment - rent0 - rent); - - // Advance 2 blocks more - initialize_block(7); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::null() - )); - - // Check result - let rent_2 = ::RentFraction::get() - .mul_ceil((8 + 4 + code_len) * 10_000 + 10_000 - (endowment - rent0 - rent)) * - 2; - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(contract.rent_allowance, allowance - rent0 - rent - rent_2); - assert_eq!(contract.deduct_block, 7); - assert_eq!(Balances::free_balance(&addr), endowment - rent0 - rent - rent_2); - - // Second call on same block should have no effect on rent - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::null() - )); - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - assert_eq!(contract.rent_allowance, allowance - rent0 - rent - rent_2); - assert_eq!(contract.deduct_block, 7); - assert_eq!(Balances::free_balance(&addr), endowment - rent0 - rent - rent_2) - }); -} - -#[test] -fn inherent_claim_surcharge_contract_removals() { - removals(|addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok()); -} - -#[test] -fn signed_claim_surcharge_contract_removals() { - removals(|addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok()); -} - -#[test] -fn claim_surcharge_malus() { - // Test surcharge malus for inherent - claim_surcharge( - 8, - |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 7, - |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 6, - |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), - true, - ); - claim_surcharge( - 5, - |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), - false, - ); - - // Test surcharge malus for signed - claim_surcharge( - 8, - |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), - true, - ); - claim_surcharge( - 7, - |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), - false, - ); - claim_surcharge( - 6, - |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), - false, - ); - claim_surcharge( - 5, - |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), - false, - ); -} - -/// Claim surcharge with the given trigger_call at the given blocks. -/// If `removes` is true then assert that the contract is a tombstone. -fn claim_surcharge(blocks: u64, trigger_call: impl Fn(AccountIdOf) -> bool, removes: bool) { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - wasm, - ::Balance::from(30_000u32).encode(), // rent allowance - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - - // Advance blocks - initialize_block(blocks); - - // Trigger rent through call - assert_eq!(trigger_call(addr.clone()), removes); - - if removes { - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - } else { - assert!(ContractInfoOf::::get(&addr).unwrap().get_alive().is_some()); - } - }); -} - -/// Test for all kind of removals for the given trigger: -/// * if balance is reached and balance > subsistence threshold -/// * if allowance is exceeded -/// * if balance is reached and balance < subsistence threshold -/// * this case cannot be triggered by a contract: we check whether a tombstone is left -fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Balance reached and superior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 70_000, - GAS_LIMIT, - wasm.clone(), - ::Balance::from(100_000u32).encode(), /* rent allowance */ - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let allowance = - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance; - let balance = Balances::free_balance(&addr); - - let subsistence_threshold = Pallet::::subsistence_threshold(); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert_eq!( - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance, - allowance, - ); - assert_eq!(Balances::free_balance(&addr), balance); - - // Advance blocks - initialize_block(27); - - // Trigger rent through call (should remove the contract) - assert!(trigger_call(addr.clone())); - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&addr), subsistence_threshold); - - // Advance blocks - initialize_block(30); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&addr), subsistence_threshold); - }); - - // Allowance exceeded - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - wasm.clone(), - ::Balance::from(70_000u32).encode(), // rent allowance - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let allowance = - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance; - let balance = Balances::free_balance(&addr); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert_eq!( - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance, - allowance, - ); - assert_eq!(Balances::free_balance(&addr), balance); - - // Advance blocks - initialize_block(27); - - // Trigger rent through call - assert!(trigger_call(addr.clone())); - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(&addr), 30_000); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&addr), 30_000); - }); - - // Balance reached and inferior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let subsistence_threshold = Pallet::::subsistence_threshold(); - let _ = Balances::deposit_creating(&ALICE, subsistence_threshold * 1000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - subsistence_threshold * 100, - GAS_LIMIT, - wasm, - (subsistence_threshold * 100).encode(), // rent allowance - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let allowance = - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance; - let balance = Balances::free_balance(&addr); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert_eq!( - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance, - allowance, - ); - assert_eq!(Balances::free_balance(&addr), balance); - - // Make contract have exactly the subsistence threshold - Balances::make_free_balance_be(&addr, subsistence_threshold); - assert_eq!(Balances::free_balance(&addr), subsistence_threshold); - - // Advance blocks (should remove as balance is exactly subsistence) - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call(addr.clone())); - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Tombstone(_))); - assert_eq!(Balances::free_balance(&addr), subsistence_threshold); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(!trigger_call(addr.clone())); - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Tombstone(_))); - assert_eq!(Balances::free_balance(&addr), subsistence_threshold); - }); -} - -#[test] -fn call_removed_contract() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // Balance reached and superior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - // rent allowance - ::Balance::from(10_000u32).encode(), - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - - // Calling contract should succeed. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::null() - )); - - // Advance blocks - initialize_block(27); - - // Calling contract should deny access because rent cannot be paid. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()), - Error::::RentNotPaid, - ); - // No event is generated because the contract is not actually removed. - assert_eq!(System::events(), vec![]); - - // Subsequent contract calls should also fail. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()), - Error::::RentNotPaid, - ); - - // A snitch can now remove the contract - assert_ok!(Contracts::claim_surcharge(Origin::none(), addr.clone(), Some(ALICE))); - assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); - }) -} - -#[test] -fn default_rent_allowance_on_instantiate() { - let (wasm, code_hash) = compile_module::("check_default_rent_allowance").unwrap(); - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - vec![], - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); - let code_len: BalanceOf = - PrefabWasmModule::::from_storage_noinstr(contract.code_hash) - .unwrap() - .occupied_storage() - .into(); - - // The instantiation deducted the rent for one block immediately - let first_rent = ::RentFraction::get() - // (base_deposit(8) + code_len) * byte_price - free_balance - .mul_ceil((8 + code_len) * 10_000 - 30_000) - // blocks to rent - * 1; - assert_eq!(contract.rent_allowance, >::max_value() - first_rent); - - // Advance blocks - initialize_block(5); - - // Trigger rent through call - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr.clone(), - 0, - GAS_LIMIT, - call::null() - )); - - // Check contract is still alive - let contract = ContractInfoOf::::get(&addr).unwrap().get_alive(); - assert!(contract.is_some()) - }); -} - -#[test] -fn restorations_dirty_storage_and_different_storage() { - restoration(true, true, false); -} - -#[test] -fn restorations_dirty_storage() { - restoration(false, true, false); -} - -#[test] -fn restoration_different_storage() { - restoration(true, false, false); -} - -#[test] -fn restoration_code_evicted() { - restoration(false, false, true); -} - -#[test] -fn restoration_success() { - restoration(false, false, false); -} - -fn restoration( - test_different_storage: bool, - test_restore_to_with_dirty_storage: bool, - test_code_evicted: bool, -) { - let (set_rent_wasm, set_rent_code_hash) = compile_module::("set_rent").unwrap(); - let (restoration_wasm, restoration_code_hash) = compile_module::("restoration").unwrap(); - let allowance: ::Balance = 10_000; - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - - // Create an account with address `BOB` with code `CODE_SET_RENT`. - // The input parameter sets the rent allowance to 0. - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - set_rent_wasm.clone(), - allowance.encode(), - vec![], - )); - let addr_bob = Contracts::contract_address(&ALICE, &set_rent_code_hash, &[]); - - let mut events = vec![ - EventRecord { - phase: Phase::Initialization, - event: Event::System(frame_system::Event::NewAccount(ALICE)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Endowed(ALICE, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::System(frame_system::Event::NewAccount(addr_bob.clone())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Endowed(addr_bob.clone(), 30_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Transfer( - ALICE, - addr_bob.clone(), - 30_000, - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::CodeStored(set_rent_code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::Instantiated(ALICE, addr_bob.clone())), - topics: vec![], - }, - ]; - - // Create another contract from the same code in order to increment the codes - // refcounter so that it stays on chain. - if !test_code_evicted { - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 20_000, - GAS_LIMIT, - set_rent_wasm, - allowance.encode(), - vec![1], - )); - assert_refcount!(set_rent_code_hash, 2); - let addr_dummy = Contracts::contract_address(&ALICE, &set_rent_code_hash, &[1]); - events.extend( - [ - EventRecord { - phase: Phase::Initialization, - event: Event::System(frame_system::Event::NewAccount(addr_dummy.clone())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Endowed( - addr_dummy.clone(), - 20_000, - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Transfer( - ALICE, - addr_dummy.clone(), - 20_000, - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::Instantiated( - ALICE, - addr_dummy.clone(), - )), - topics: vec![], - }, - ] - .iter() - .cloned(), - ); - } - - assert_eq!(System::events(), events); - - // Check if `BOB` was created successfully and that the rent allowance is below what - // we specified as the first rent was already collected. - let bob_contract = ContractInfoOf::::get(&addr_bob).unwrap().get_alive().unwrap(); - assert!(bob_contract.rent_allowance < allowance); - - if test_different_storage { - assert_ok!(Contracts::call( - Origin::signed(ALICE), - addr_bob.clone(), - 0, - GAS_LIMIT, - call::set_storage_4_byte() - )); - } - - // Advance blocks in order to make the contract run out of money for rent. - initialize_block(27); - - // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 20_000 - // we expect that it is no longer callable but keeps existing until someone - // calls `claim_surcharge`. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), addr_bob.clone(), 0, GAS_LIMIT, call::null()), - Error::::RentNotPaid, - ); - assert!(System::events().is_empty()); - assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_alive().is_some()); - assert_ok!(Contracts::claim_surcharge(Origin::none(), addr_bob.clone(), Some(ALICE))); - assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_tombstone().is_some()); - if test_code_evicted { - assert_refcount!(set_rent_code_hash, 0); - } else { - assert_refcount!(set_rent_code_hash, 1); - } - - // Create another account with the address `DJANGO` with `CODE_RESTORATION`. - // - // Note that we can't use `ALICE` for creating `DJANGO` so we create yet another - // account `CHARLIE` and create `DJANGO` with it. - let _ = Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(CHARLIE), - 30_000, - GAS_LIMIT, - restoration_wasm, - vec![], - vec![], - )); - let addr_django = Contracts::contract_address(&CHARLIE, &restoration_code_hash, &[]); - - // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = - ContractInfoOf::::get(&addr_django).unwrap().get_alive().unwrap().trie_id; - - // The trie is regarded as 'dirty' when it was written to in the current block. - if !test_restore_to_with_dirty_storage { - // Advance 1 block. - initialize_block(28); - } - - // Perform a call to `DJANGO`. This should either perform restoration successfully or - // fail depending on the test parameters. - let perform_the_restoration = || { - Contracts::call( - Origin::signed(ALICE), - addr_django.clone(), - 0, - GAS_LIMIT, - set_rent_code_hash - .as_ref() - .iter() - .chain(AsRef::<[u8]>::as_ref(&addr_bob)) - .cloned() - .collect(), - ) - }; - - // The key that is used in the restorer contract but is not in the target contract. - // Is supplied as delta to the restoration. We need it to check whether the key - // is properly removed on success but still there on failure. - let delta_key = { - let mut key = [0u8; 32]; - key[0] = 1; - key - }; - - if test_different_storage || test_restore_to_with_dirty_storage || test_code_evicted { - // Parametrization of the test imply restoration failure. Check that `DJANGO` aka - // restoration contract is still in place and also that `BOB` doesn't exist. - let result = perform_the_restoration(); - assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_tombstone().is_some()); - let django_contract = - ContractInfoOf::::get(&addr_django).unwrap().get_alive().unwrap(); - assert_eq!(django_contract.storage_size, 8); - assert_eq!(django_contract.trie_id, django_trie_id); - assert_eq!(django_contract.deduct_block, System::block_number()); - assert_eq!(Storage::::read(&django_trie_id, &delta_key), Some(vec![40, 0, 0, 0])); - match (test_different_storage, test_restore_to_with_dirty_storage, test_code_evicted) { - (true, false, false) => { - assert_err_ignore_postinfo!(result, Error::::InvalidTombstone); - assert_eq!(System::events(), vec![]); - }, - (_, true, false) => { - assert_err_ignore_postinfo!(result, Error::::InvalidContractOrigin); - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::Evicted(addr_bob)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::System(frame_system::Event::NewAccount(CHARLIE)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Endowed( - CHARLIE, 1_000_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::System(frame_system::Event::NewAccount( - addr_django.clone() - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Endowed( - addr_django.clone(), - 30_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Balances(pallet_balances::Event::Transfer( - CHARLIE, - addr_django.clone(), - 30_000 - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::CodeStored( - restoration_code_hash - )), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::Instantiated( - CHARLIE, - addr_django.clone() - )), - topics: vec![], - }, - ] - ); - }, - (false, false, true) => { - assert_err_ignore_postinfo!(result, Error::::CodeNotFound); - assert_refcount!(set_rent_code_hash, 0); - assert_eq!(System::events(), vec![]); - }, - _ => unreachable!(), - } - } else { - assert_ok!(perform_the_restoration()); - assert_refcount!(set_rent_code_hash, 2); - - // Here we expect that the restoration is succeeded. Check that the restoration - // contract `DJANGO` ceased to exist and that `BOB` returned back. - let bob_contract = ContractInfoOf::::get(&addr_bob).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 50); - assert_eq!(bob_contract.storage_size, 4); - assert_eq!(bob_contract.trie_id, django_trie_id); - assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(&addr_django).is_none()); - assert_matches!(Storage::::read(&django_trie_id, &delta_key), None); - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::CodeRemoved(restoration_code_hash)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::System(system::Event::KilledAccount(addr_django.clone())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: Event::Contracts(crate::Event::Restored( - addr_django, - addr_bob, - bob_contract.code_hash, - 50 - )), - topics: vec![], - }, - ] - ); - } - }); -} - #[test] fn storage_max_value_limit() { let (wasm, code_hash) = compile_module::("storage_size").unwrap(); @@ -1492,7 +595,7 @@ fn storage_max_value_limit() { vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); + ContractInfoOf::::get(&addr).unwrap(); // Call contract with allowed storage value. assert_ok!(Contracts::call( @@ -1572,7 +675,7 @@ fn cannot_self_destruct_through_draning() { let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_))); + assert_matches!(ContractInfoOf::::get(&addr), Some(_)); // Call BOB which makes it send all funds to the zero address // The contract code asserts that the correct error value is returned. @@ -1598,7 +701,7 @@ fn cannot_self_destruct_while_live() { let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_))); + assert_matches!(ContractInfoOf::::get(&addr), Some(_)); // Call BOB with input data, forcing it make a recursive call to itself to // self-destruct, resulting in a trap. @@ -1607,8 +710,8 @@ fn cannot_self_destruct_while_live() { Error::::ContractTrapped, ); - // Check that BOB is still alive. - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_))); + // Check that BOB is still there. + assert_matches!(ContractInfoOf::::get(&addr), Some(_)); }); } @@ -1631,7 +734,7 @@ fn self_destruct_works() { let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. - assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_))); + assert_matches!(ContractInfoOf::::get(&addr), Some(_)); // Drop all previous events initialize_block(2); @@ -1642,30 +745,8 @@ fn self_destruct_works() { Ok(_) ); - // The call triggers rent collection that reduces the amount of balance - // that remains for the beneficiary. - let mut events = System::events(); - let balance_after_rent = 99_000; - - // The actual figure will bounce about with wasm compiler updates as the rent depends on - // the compiled wasm size, so we replace it with a fixed value - // as rent isn't what we're testing for in this test. - let mut actual_balance_after_rent = 99_000; - if let Event::Balances(pallet_balances::Event::Transfer(_, _, ref mut actual_bal)) = - &mut events[1].event - { - std::mem::swap(&mut actual_balance_after_rent, actual_bal); - assert!( - (90_000..99_000).contains(&actual_balance_after_rent), - "expected less than 100_000: {}", - actual_balance_after_rent - ); - } else { - assert!(false); - } - pretty_assertions::assert_eq!( - events, + System::events(), vec![ EventRecord { phase: Phase::Initialization, @@ -1677,7 +758,7 @@ fn self_destruct_works() { event: Event::Balances(pallet_balances::Event::Transfer( addr.clone(), DJANGO, - balance_after_rent + 100_000, )), topics: vec![], }, @@ -1699,7 +780,7 @@ fn self_destruct_works() { // check that the beneficiary (django) got remaining balance // some rent was deducted before termination - assert_eq!(Balances::free_balance(DJANGO), 1_000_000 + actual_balance_after_rent); + assert_eq!(Balances::free_balance(DJANGO), 1_000_000 + 100_000); }); } @@ -1736,7 +817,7 @@ fn destroy_contract_and_transfer_funds() { let addr_charlie = Contracts::contract_address(&addr_bob, &callee_code_hash, &[0x47, 0x11]); // Check that the CHARLIE contract has been instantiated. - assert_matches!(ContractInfoOf::::get(&addr_charlie), Some(ContractInfo::Alive(_))); + assert_matches!(ContractInfoOf::::get(&addr_charlie), Some(_)); // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. assert_ok!(Contracts::call( @@ -2166,7 +1247,7 @@ fn lazy_removal_works() { ),); let addr = Contracts::contract_address(&ALICE, &hash, &[]); - let info = >::get(&addr).unwrap().get_alive().unwrap(); + let info = >::get(&addr).unwrap(); let trie = &info.child_trie_info(); // Put value into the contracts child trie @@ -2217,14 +1298,13 @@ fn lazy_removal_partial_remove_works() { ),); let addr = Contracts::contract_address(&ALICE, &hash, &[]); - let mut info = >::get(&addr).unwrap().get_alive().unwrap(); + let mut info = >::get(&addr).unwrap(); // Put value into the contracts child trie for val in &vals { - Storage::::write(System::block_number(), &mut info, &val.0, Some(val.2.clone())) - .unwrap(); + Storage::::write(&mut info, &val.0, Some(val.2.clone())).unwrap(); } - >::insert(&addr, ContractInfo::Alive(info.clone())); + >::insert(&addr, info.clone()); // Terminate the contract assert_ok!(Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, vec![])); @@ -2288,7 +1368,7 @@ fn lazy_removal_does_no_run_on_full_block() { ),); let addr = Contracts::contract_address(&ALICE, &hash, &[]); - let mut info = >::get(&addr).unwrap().get_alive().unwrap(); + let mut info = >::get(&addr).unwrap(); let max_keys = 30; // Create some storage items for the contract. @@ -2298,10 +1378,9 @@ fn lazy_removal_does_no_run_on_full_block() { // Put value into the contracts child trie for val in &vals { - Storage::::write(System::block_number(), &mut info, &val.0, Some(val.2.clone())) - .unwrap(); + Storage::::write(&mut info, &val.0, Some(val.2.clone())).unwrap(); } - >::insert(&addr, ContractInfo::Alive(info.clone())); + >::insert(&addr, info.clone()); // Terminate the contract assert_ok!(Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, vec![])); @@ -2346,7 +1425,11 @@ fn lazy_removal_does_no_run_on_full_block() { #[test] fn lazy_removal_does_not_use_all_weight() { let (code, hash) = compile_module::("self_destruct").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + + let weight_limit = 5_000_000_000; + let mut ext = ExtBuilder::default().existential_deposit(50).build(); + + let (trie, vals, weight_per_key) = ext.execute_with(|| { let subsistence = Pallet::::subsistence_threshold(); let _ = Balances::deposit_creating(&ALICE, 1000 * subsistence); @@ -2360,8 +1443,7 @@ fn lazy_removal_does_not_use_all_weight() { ),); let addr = Contracts::contract_address(&ALICE, &hash, &[]); - let mut info = >::get(&addr).unwrap().get_alive().unwrap(); - let weight_limit = 5_000_000_000; + let mut info = >::get(&addr).unwrap(); let (weight_per_key, max_keys) = Storage::::deletion_budget(1, weight_limit); // We create a contract with one less storage item than we can remove within the limit @@ -2371,10 +1453,9 @@ fn lazy_removal_does_not_use_all_weight() { // Put value into the contracts child trie for val in &vals { - Storage::::write(System::block_number(), &mut info, &val.0, Some(val.2.clone())) - .unwrap(); + Storage::::write(&mut info, &val.0, Some(val.2.clone())).unwrap(); } - >::insert(&addr, ContractInfo::Alive(info.clone())); + >::insert(&addr, info.clone()); // Terminate the contract assert_ok!(Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, vec![])); @@ -2389,6 +1470,14 @@ fn lazy_removal_does_not_use_all_weight() { assert_eq!(child::get::(&trie, &blake2_256(&val.0)), Some(val.1)); } + (trie, vals, weight_per_key) + }); + + // The lazy removal limit only applies to the backend but not to the overlay. + // This commits all keys from the overlay to the backend. + ext.commit_all().unwrap(); + + ext.execute_with(|| { // Run the lazy removal let weight_used = Storage::::process_deletion_queue_batch(weight_limit); @@ -2429,92 +1518,8 @@ fn deletion_queue_full() { Error::::DeletionQueueFull, ); - // Contract should be alive because removal failed - >::get(&addr).unwrap().get_alive().unwrap(); - - // make the contract ripe for eviction - initialize_block(5); - - // eviction should fail for the same reason as termination - assert_err!( - Contracts::claim_surcharge(Origin::none(), addr.clone(), Some(ALICE)), - Error::::DeletionQueueFull, - ); - - // Contract should be alive because removal failed - >::get(&addr).unwrap().get_alive().unwrap(); - }); -} - -#[test] -fn not_deployed_if_endowment_too_low_for_first_rent() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - - // The instantiation deducted the rent for one block immediately - let first_rent = ::RentFraction::get() - // base_deposit + deploy_set_storage (4 bytes in 1 item) - free_balance - .mul_ceil(80_000u32 + 40_000 + 10_000 - 30_000) - // blocks to rent - * 1; - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_storage_noop!(assert_err_ignore_postinfo!( - Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - (BalanceOf::::from(first_rent) - BalanceOf::::from(1u32)).encode(), /* rent allowance */ - vec![], - ), - Error::::NewContractNotFunded, - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - assert_matches!(ContractInfoOf::::get(&addr), None); - }); -} - -#[test] -fn surcharge_reward_is_capped() { - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let _ = Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::instantiate_with_code( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - wasm, - >::from(10_000u32).encode(), // rent allowance - vec![], - )); - let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); - let contract = >::get(&addr).unwrap().get_alive().unwrap(); - let balance = Balances::free_balance(&ALICE); - let reward = ::SurchargeReward::get(); - - // some rent should have paid due to instantiation - assert_ne!(contract.rent_paid, 0); - - // the reward should be parameterized sufficiently high to make this test useful - assert!(reward > contract.rent_paid); - - // make contract eligible for eviction - initialize_block(40); - - // this should have removed the contract - assert_ok!(Contracts::claim_surcharge(Origin::none(), addr.clone(), Some(ALICE))); - - // this reward does not take into account the last rent payment collected during eviction - let capped_reward = reward.min(contract.rent_paid); - - // this is smaller than the actual reward because it does not take into account the - // rent collected during eviction - assert!(Balances::free_balance(&ALICE) > balance + capped_reward); - - // the full reward is not paid out because of the cap introduced by rent_paid - assert!(Balances::free_balance(&ALICE) < balance + reward); + // Contract should exist because removal failed + >::get(&addr).unwrap(); }); } @@ -2564,18 +1569,15 @@ fn refcounter() { assert_ok!(Contracts::call(Origin::signed(ALICE), addr0, 0, GAS_LIMIT, vec![])); assert_refcount!(code_hash, 2); - // make remaining contracts eligible for eviction - initialize_block(40); - - // remove one of them - assert_ok!(Contracts::claim_surcharge(Origin::none(), addr1, Some(ALICE))); + // remove another one + assert_ok!(Contracts::call(Origin::signed(ALICE), addr1, 0, GAS_LIMIT, vec![])); assert_refcount!(code_hash, 1); // Pristine code should still be there crate::PristineCode::::get(code_hash).unwrap(); // remove the last contract - assert_ok!(Contracts::claim_surcharge(Origin::none(), addr2, Some(ALICE))); + assert_ok!(Contracts::call(Origin::signed(ALICE), addr2, 0, GAS_LIMIT, vec![])); assert_refcount!(code_hash, 0); // all code should be gone diff --git a/substrate/frame/contracts/src/wasm/code_cache.rs b/substrate/frame/contracts/src/wasm/code_cache.rs index 0a20485cab..08a7449683 100644 --- a/substrate/frame/contracts/src/wasm/code_cache.rs +++ b/substrate/frame/contracts/src/wasm/code_cache.rs @@ -64,22 +64,6 @@ where }); } -/// Decrement the refcount and store. -/// -/// Removes the code instead of storing it when the refcount drops to zero. -pub fn store_decremented(mut prefab_module: PrefabWasmModule) -where - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - prefab_module.refcount = prefab_module.refcount.saturating_sub(1); - if prefab_module.refcount > 0 { - >::insert(prefab_module.code_hash, prefab_module); - } else { - >::remove(prefab_module.code_hash); - finish_removal::(prefab_module.code_hash); - } -} - /// Increment the refcount of a code in-storage by one. pub fn increment_refcount( code_hash: CodeHash, diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index f9854bbbdc..843c78b73c 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -61,7 +61,7 @@ pub struct PrefabWasmModule { /// The maximum memory size of a contract's sandbox. #[codec(compact)] maximum: u32, - /// The number of alive contracts that use this as their contract code. + /// The number of contracts that use this as their contract code. /// /// If this number drops to zero this module is removed from storage. #[codec(compact)] @@ -164,10 +164,6 @@ where code_cache::load(code_hash, None) } - fn drop_from_storage(self) { - code_cache::store_decremented(self); - } - fn add_user(code_hash: CodeHash, gas_meter: &mut GasMeter) -> Result<(), DispatchError> { code_cache::increment_refcount::(code_hash, gas_meter) } @@ -240,11 +236,9 @@ mod tests { use super::*; use crate::{ exec::{ - AccountIdOf, BlockNumberOf, ErrorOrigin, ExecError, Executable, Ext, RentParams, - SeedOf, StorageKey, + AccountIdOf, BlockNumberOf, ErrorOrigin, ExecError, Executable, Ext, SeedOf, StorageKey, }, gas::GasMeter, - rent::RentStatus, tests::{Call, Test, ALICE, BOB}, BalanceOf, CodeHash, Error, Pallet as Contracts, }; @@ -261,14 +255,6 @@ mod tests { use sp_runtime::DispatchError; use std::{borrow::BorrowMut, cell::RefCell, collections::HashMap}; - #[derive(Debug, PartialEq, Eq)] - struct RestoreEntry { - dest: AccountIdOf, - code_hash: H256, - rent_allowance: u64, - delta: Vec, - } - #[derive(Debug, PartialEq, Eq)] struct InstantiateEntry { code_hash: H256, @@ -299,17 +285,14 @@ mod tests { pub struct MockExt { storage: HashMap>, - rent_allowance: u64, instantiates: Vec, terminations: Vec, calls: Vec, transfers: Vec, - restores: Vec, // (topics, data) events: Vec<(Vec, Vec)>, runtime_calls: RefCell>, schedule: Schedule, - rent_params: RentParams, gas_meter: GasMeter, debug_buffer: Vec, } @@ -323,16 +306,13 @@ mod tests { fn default() -> Self { Self { storage: Default::default(), - rent_allowance: Default::default(), instantiates: Default::default(), terminations: Default::default(), calls: Default::default(), transfers: Default::default(), - restores: Default::default(), events: Default::default(), runtime_calls: Default::default(), schedule: Default::default(), - rent_params: Default::default(), gas_meter: GasMeter::new(10_000_000_000), debug_buffer: Default::default(), } @@ -381,16 +361,6 @@ mod tests { self.terminations.push(TerminationEntry { beneficiary: beneficiary.clone() }); Ok(()) } - fn restore_to( - &mut self, - dest: AccountIdOf, - code_hash: H256, - rent_allowance: u64, - delta: Vec, - ) -> Result<(), DispatchError> { - self.restores.push(RestoreEntry { dest, code_hash, rent_allowance, delta }); - Ok(()) - } fn get_storage(&mut self, key: &StorageKey) -> Option> { self.storage.get(key).cloned() } @@ -416,7 +386,7 @@ mod tests { fn minimum_balance(&self) -> u64 { 666 } - fn tombstone_deposit(&self) -> u64 { + fn contract_deposit(&self) -> u64 { 16 } fn random(&self, subject: &[u8]) -> (SeedOf, BlockNumberOf) { @@ -425,12 +395,6 @@ mod tests { fn deposit_event(&mut self, topics: Vec, data: Vec) { self.events.push((topics, data)) } - fn set_rent_allowance(&mut self, rent_allowance: u64) { - self.rent_allowance = rent_allowance; - } - fn rent_allowance(&mut self) -> u64 { - self.rent_allowance - } fn block_number(&self) -> u64 { 121 } @@ -443,12 +407,6 @@ mod tests { fn schedule(&self) -> &Schedule { &self.schedule } - fn rent_params(&self) -> &RentParams { - &self.rent_params - } - fn rent_status(&mut self, _at_refcount: u32) -> RentStatus { - Default::default() - } fn gas_meter(&mut self) -> &mut GasMeter { &mut self.gas_meter } @@ -1380,9 +1338,9 @@ mod tests { assert_ok!(execute(CODE_MINIMUM_BALANCE, vec![], MockExt::default())); } - const CODE_TOMBSTONE_DEPOSIT: &str = r#" + const CODE_CONTRACT_DEPOSIT: &str = r#" (module - (import "seal0" "seal_tombstone_deposit" (func $seal_tombstone_deposit (param i32 i32))) + (import "seal0" "seal_contract_deposit" (func $seal_contract_deposit (param i32 i32))) (import "env" "memory" (memory 1 1)) ;; size of our buffer is 32 bytes @@ -1398,7 +1356,7 @@ mod tests { ) (func (export "call") - (call $seal_tombstone_deposit (i32.const 0) (i32.const 32)) + (call $seal_contract_deposit (i32.const 0) (i32.const 32)) ;; assert len == 8 (call $assert @@ -1421,8 +1379,8 @@ mod tests { "#; #[test] - fn tombstone_deposit() { - assert_ok!(execute(CODE_TOMBSTONE_DEPOSIT, vec![], MockExt::default())); + fn contract_deposit() { + assert_ok!(execute(CODE_CONTRACT_DEPOSIT, vec![], MockExt::default())); } const CODE_RANDOM: &str = r#" @@ -1856,81 +1814,6 @@ mod tests { assert_ok!(result); } - #[test] - #[cfg(feature = "unstable-interface")] - fn rent_params_work() { - const CODE_RENT_PARAMS: &str = r#" -(module - (import "__unstable__" "seal_rent_params" (func $seal_rent_params (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 4) buffer size = 128 bytes - (data (i32.const 0) "\80") - - ;; [4; inf) buffer where the result is copied - - (func (export "call") - ;; Load the rent params into memory - (call $seal_rent_params - (i32.const 4) ;; Pointer to the output buffer - (i32.const 0) ;; Pointer to the size of the buffer - ) - - ;; Return the contents of the buffer - (call $seal_return - (i32.const 0) ;; return flags - (i32.const 4) ;; buffer pointer - (i32.load (i32.const 0)) ;; buffer size - ) - ) - - (func (export "deploy")) -) -"#; - let output = execute(CODE_RENT_PARAMS, vec![], MockExt::default()).unwrap(); - let rent_params = Bytes(>::default().encode()); - assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_params }); - } - - #[test] - #[cfg(feature = "unstable-interface")] - fn rent_status_works() { - const CODE_RENT_STATUS: &str = r#" -(module - (import "__unstable__" "seal_rent_status" (func $seal_rent_status (param i32 i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 4) buffer size = 128 bytes - (data (i32.const 0) "\80") - - ;; [4; inf) buffer where the result is copied - - (func (export "call") - ;; Load the rent params into memory - (call $seal_rent_status - (i32.const 1) ;; at_refcount - (i32.const 4) ;; Pointer to the output buffer - (i32.const 0) ;; Pointer to the size of the buffer - ) - - ;; Return the contents of the buffer - (call $seal_return - (i32.const 0) ;; return flags - (i32.const 4) ;; buffer pointer - (i32.load (i32.const 0)) ;; buffer size - ) - ) - - (func (export "deploy")) -) -"#; - let output = execute(CODE_RENT_STATUS, vec![], MockExt::default()).unwrap(); - let rent_status = Bytes(>::default().encode()); - assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_status }); - } - #[test] fn debug_message_works() { const CODE_DEBUG_MESSAGE: &str = r#" diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index d238d3afcb..4612cc131f 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -31,6 +31,7 @@ use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags}; use pwasm_utils::parity_wasm::elements::ValueType; use sp_core::{crypto::UncheckedFrom, Bytes}; use sp_io::hashing::{blake2_128, blake2_256, keccak_256, sha2_256}; +use sp_runtime::traits::Bounded; use sp_std::prelude::*; /// Every error that can be returned to a contract when it calls any of the host functions. @@ -64,8 +65,7 @@ pub enum ReturnCode { NewContractNotFunded = 6, /// No code could be found at the supplied code hash. CodeNotFound = 7, - /// The contract that was called is either no contract at all (a plain account) - /// or is a tombstone. + /// The contract that was called is no contract (a plain account). NotCallable = 8, /// The call to `seal_debug_message` had no effect because debug message /// recording was disabled. @@ -121,8 +121,6 @@ pub enum TrapReason { /// Signals that a trap was generated in response to a successful call to the /// `seal_terminate` host function. Termination, - /// Signals that a trap was generated because of a successful restoration. - Restoration, } impl> From for TrapReason { @@ -149,10 +147,8 @@ pub enum RuntimeCosts { ValueTransferred, /// Weight of calling `seal_minimum_balance`. MinimumBalance, - /// Weight of calling `seal_tombstone_deposit`. - TombstoneDeposit, - /// Weight of calling `seal_rent_allowance`. - RentAllowance, + /// Weight of calling `seal_contract_deposit`. + ContractDeposit, /// Weight of calling `seal_block_number`. BlockNumber, /// Weight of calling `seal_now`. @@ -167,16 +163,12 @@ pub enum RuntimeCosts { Return(u32), /// Weight of calling `seal_terminate`. Terminate, - /// Weight of calling `seal_restore_to` per number of supplied delta entries. - RestoreTo(u32), /// Weight of calling `seal_random`. It includes the weight for copying the subject. Random, /// Weight of calling `seal_deposit_event` with the given number of topics and event size. DepositEvent { num_topic: u32, len: u32 }, /// Weight of calling `seal_debug_message`. DebugMessage, - /// Weight of calling `seal_set_rent_allowance`. - SetRentAllowance, /// Weight of calling `seal_set_storage` for the given storage item size. SetStorage(u32), /// Weight of calling `seal_clear_storage`. @@ -232,8 +224,7 @@ impl RuntimeCosts { Balance => s.balance, ValueTransferred => s.value_transferred, MinimumBalance => s.minimum_balance, - TombstoneDeposit => s.tombstone_deposit, - RentAllowance => s.rent_allowance, + ContractDeposit => s.contract_deposit, BlockNumber => s.block_number, Now => s.now, WeightToFee => s.weight_to_fee, @@ -241,15 +232,12 @@ impl RuntimeCosts { InputCopyOut(len) => s.input_per_byte.saturating_mul(len.into()), Return(len) => s.r#return.saturating_add(s.return_per_byte.saturating_mul(len.into())), Terminate => s.terminate, - RestoreTo(delta) => - s.restore_to.saturating_add(s.restore_to_per_delta.saturating_mul(delta.into())), Random => s.random, DepositEvent { num_topic, len } => s .deposit_event .saturating_add(s.deposit_event_per_topic.saturating_mul(num_topic.into())) .saturating_add(s.deposit_event_per_byte.saturating_mul(len.into())), DebugMessage => s.debug_message, - SetRentAllowance => s.set_rent_allowance, SetStorage(len) => s.set_storage.saturating_add(s.set_storage_per_byte.saturating_mul(len.into())), ClearStorage => s.clear_storage, @@ -395,8 +383,6 @@ where }, TrapReason::Termination => Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) }), - TrapReason::Restoration => - Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) }), TrapReason::SupervisorError(error) => Err(error)?, } } @@ -617,15 +603,13 @@ where let not_funded = Error::::NewContractNotFunded.into(); let no_code = Error::::CodeNotFound.into(); let not_found = Error::::ContractNotFound.into(); - let is_tombstone = Error::::ContractIsTombstone.into(); - let rent_not_paid = Error::::RentNotPaid.into(); match from { x if x == below_sub => Ok(BelowSubsistenceThreshold), x if x == transfer_failed => Ok(TransferFailed), x if x == not_funded => Ok(NewContractNotFunded), x if x == no_code => Ok(CodeNotFound), - x if (x == not_found || x == is_tombstone || x == rent_not_paid) => Ok(NotCallable), + x if x == not_found => Ok(NotCallable), err => Err(err), } } @@ -737,49 +721,6 @@ where self.ext.terminate(&beneficiary)?; Err(TrapReason::Termination) } - - fn restore_to( - &mut self, - dest_ptr: u32, - code_hash_ptr: u32, - rent_allowance_ptr: u32, - delta_ptr: u32, - delta_count: u32, - ) -> Result<(), TrapReason> { - self.charge_gas(RuntimeCosts::RestoreTo(delta_count))?; - let dest: <::T as frame_system::Config>::AccountId = - self.read_sandbox_memory_as(dest_ptr)?; - let code_hash: CodeHash<::T> = self.read_sandbox_memory_as(code_hash_ptr)?; - let rent_allowance: BalanceOf<::T> = - self.read_sandbox_memory_as(rent_allowance_ptr)?; - let delta = { - const KEY_SIZE: usize = 32; - - // We can eagerly allocate because we charged for the complete delta count already - // We still need to make sure that the allocation isn't larger than the memory - // allocator can handle. - let max_memory = self.ext.schedule().limits.max_memory_size(); - ensure!( - delta_count.saturating_mul(KEY_SIZE as u32) <= max_memory, - Error::::OutOfBounds, - ); - let mut delta = vec![[0; KEY_SIZE]; delta_count as usize]; - let mut key_ptr = delta_ptr; - - for i in 0..delta_count { - // Read the delta into the provided buffer - // This cannot panic because of the loop condition - self.read_sandbox_memory_into_buf(key_ptr, &mut delta[i as usize])?; - - // Offset key_ptr to the next element. - key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or(Error::::OutOfBounds)?; - } - - delta - }; - self.ext.restore_to(dest, code_hash, rent_allowance, delta)?; - Err(TrapReason::Restoration) - } } // *********************************************************** @@ -1369,7 +1310,20 @@ define_env!(Env, , )?) }, - // Stores the tombstone deposit into the supplied buffer. + // Stores the contract deposit into the supplied buffer. + // + // # Deprecation + // + // This is equivalent to calling `seal_contract_deposit` and only exists for backwards + // compatibility. See that function for documentation. + [seal0] seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { + ctx.charge_gas(RuntimeCosts::ContractDeposit)?; + Ok(ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.contract_deposit().encode(), false, already_charged + )?) + }, + + // Stores the contract deposit into the supplied buffer. // // The value is stored to linear memory at the address pointed to by `out_ptr`. // `out_len_ptr` must point to a u32 value that describes the available space at @@ -1380,95 +1334,53 @@ define_env!(Env, , // // # Note // - // The tombstone deposit is on top of the existential deposit. So in order for - // a contract to leave a tombstone the balance of the contract must not go - // below the sum of existential deposit and the tombstone deposit. The sum - // is commonly referred as subsistence threshold in code. - [seal0] seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { - ctx.charge_gas(RuntimeCosts::TombstoneDeposit)?; + // The contract deposit is on top of the existential deposit. The sum + // is commonly referred as subsistence threshold in code. No contract initiated + // balance transfer can go below this threshold. + [seal0] seal_contract_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { + ctx.charge_gas(RuntimeCosts::ContractDeposit)?; Ok(ctx.write_sandbox_output( - out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false, already_charged + out_ptr, out_len_ptr, &ctx.ext.contract_deposit().encode(), false, already_charged )?) }, - // Try to restore the given destination contract sacrificing the caller. - // - // # Deprecation - // - // This is equivalent to calling the newer version of this function. The newer version - // drops the now unnecessary length fields. + // Was used to restore the given destination contract sacrificing the caller. // // # Note // - // The values `_dest_len`, `_code_hash_len` and `_rent_allowance_len` are ignored because - // the encoded sizes of those types are fixed through `[`MaxEncodedLen`]. The fields - // exist for backwards compatibility. Consider switching to the newest version of this function. + // The state rent functionality was removed. This is stub only exists for + // backwards compatiblity [seal0] seal_restore_to( ctx, - dest_ptr: u32, + _dest_ptr: u32, _dest_len: u32, - code_hash_ptr: u32, + _code_hash_ptr: u32, _code_hash_len: u32, - rent_allowance_ptr: u32, + _rent_allowance_ptr: u32, _rent_allowance_len: u32, - delta_ptr: u32, - delta_count: u32 + _delta_ptr: u32, + _delta_count: u32 ) => { - ctx.restore_to( - dest_ptr, - code_hash_ptr, - rent_allowance_ptr, - delta_ptr, - delta_count, - ) + ctx.charge_gas(RuntimeCosts::DebugMessage)?; + Ok(()) }, - // Try to restore the given destination contract sacrificing the caller. + // Was used to restore the given destination contract sacrificing the caller. // - // This function will compute a tombstone hash from the caller's storage and the given code hash - // and if the hash matches the hash found in the tombstone at the specified address - kill - // the caller contract and restore the destination contract and set the specified `rent_allowance`. - // All caller's funds are transferred to the destination. + // # Note // - // The tombstone hash is derived as `hash(code_hash, storage_root_hash)`. In order to match - // this hash to its own hash the restorer must make its storage equal to the one of the - // evicted destination contract. In order to allow for additional storage items in the - // restoring contract a delta can be specified to this function. All keys specified as - // delta are disregarded when calculating the storage root hash. - // - // On success, the destination contract is restored. This function is diverging and - // stops execution even on success. - // - // - `dest_ptr` - the pointer to a buffer that encodes `T::AccountId` - // with the address of the to be restored contract. - // - `code_hash_ptr` - the pointer to a buffer that encodes - // a code hash of the to be restored contract. - // - `rent_allowance_ptr` - the pointer to a buffer that - // encodes the rent allowance that must be set in the case of successful restoration. - // - `delta_ptr` is the pointer to the start of a buffer that has `delta_count` storage keys - // laid out sequentially. - // - // # Traps - // - // - There is no tombstone at the destination address. - // - Tombstone hashes do not match. - // - The calling contract is already present on the call stack. - // - The supplied code_hash does not exist on-chain. + // The state rent functionality was removed. This is stub only exists for + // backwards compatiblity [seal1] seal_restore_to( ctx, - dest_ptr: u32, - code_hash_ptr: u32, - rent_allowance_ptr: u32, - delta_ptr: u32, - delta_count: u32 + _dest_ptr: u32, + _code_hash_ptr: u32, + _rent_allowance_ptr: u32, + _delta_ptr: u32, + _delta_count: u32 ) => { - ctx.restore_to( - dest_ptr, - code_hash_ptr, - rent_allowance_ptr, - delta_ptr, - delta_count, - ) + ctx.charge_gas(RuntimeCosts::DebugMessage)?; + Ok(()) }, // Deposit a contract event with the data buffer and optional list of topics. There is a limit @@ -1536,47 +1448,37 @@ define_env!(Env, , Ok(()) }, - // Set rent allowance of the contract. - // - // # Deprecation - // - // This is equivalent to calling the newer version of this function. The newer version - // drops the now unnecessary length fields. + // Was used to set rent allowance of the contract. // // # Note // - // The value `_VALUE_len` is ignored because the encoded sizes - // this type is fixed through `[`MaxEncodedLen`]. The field exist for backwards - // compatibility. Consider switching to the newest version of this function. - [seal0] seal_set_rent_allowance(ctx, value_ptr: u32, _value_len: u32) => { - ctx.charge_gas(RuntimeCosts::SetRentAllowance)?; - let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; - ctx.ext.set_rent_allowance(value); + // The state rent functionality was removed. This is stub only exists for + // backwards compatiblity. + [seal0] seal_set_rent_allowance(ctx, _value_ptr: u32, _value_len: u32) => { + ctx.charge_gas(RuntimeCosts::DebugMessage)?; Ok(()) }, - // Set rent allowance of the contract. + // Was used to set rent allowance of the contract. // - // - value_ptr: a pointer to the buffer with value, how much to allow for rent - // Should be decodable as a `T::Balance`. Traps otherwise. - [seal1] seal_set_rent_allowance(ctx, value_ptr: u32) => { - ctx.charge_gas(RuntimeCosts::SetRentAllowance)?; - let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr)?; - ctx.ext.set_rent_allowance(value); + // # Note + // + // The state rent functionality was removed. This is stub only exists for + // backwards compatiblity. + [seal1] seal_set_rent_allowance(ctx, _value_ptr: u32) => { + ctx.charge_gas(RuntimeCosts::DebugMessage)?; Ok(()) }, - // Stores the rent allowance into the supplied buffer. + // Was used to store the rent allowance into the supplied buffer. // - // The value is stored to linear memory at the address pointed to by `out_ptr`. - // `out_len_ptr` must point to a u32 value that describes the available space at - // `out_ptr`. This call overwrites it with the size of the value. If the available - // space at `out_ptr` is less than the size of the value a trap is triggered. + // # Note // - // The data is encoded as T::Balance. + // The state rent functionality was removed. This is stub only exists for + // backwards compatiblity. [seal0] seal_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => { - ctx.charge_gas(RuntimeCosts::RentAllowance)?; - let rent_allowance = ctx.ext.rent_allowance().encode(); + ctx.charge_gas(RuntimeCosts::Balance)?; + let rent_allowance = >::max_value().encode(); Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &rent_allowance, false, already_charged )?) @@ -1757,55 +1659,6 @@ define_env!(Env, , Ok(ReturnCode::LoggingDisabled) }, - // Stores the rent params into the supplied buffer. - // - // The value is stored to linear memory at the address pointed to by `out_ptr`. - // `out_len_ptr` must point to a u32 value that describes the available space at - // `out_ptr`. This call overwrites it with the size of the value. If the available - // space at `out_ptr` is less than the size of the value a trap is triggered. - // - // The data is encoded as [`crate::exec::RentParams`]. - // - // # Note - // - // The returned information was collected and cached when the current contract call - // started execution. Any change to those values that happens due to actions of the - // current call or contracts that are called by this contract are not considered. - // - // # Unstable - // - // This function is unstable and subject to change (or removal) in the future. Do not - // deploy a contract using it to a production chain. - [__unstable__] seal_rent_params(ctx, out_ptr: u32, out_len_ptr: u32) => { - Ok(ctx.write_sandbox_output( - out_ptr, out_len_ptr, &ctx.ext.rent_params().encode(), false, already_charged - )?) - }, - - // Stores the rent status into the supplied buffer. - // - // The value is stored to linear memory at the address pointed to by `out_ptr`. - // `out_len_ptr` must point to a u32 value that describes the available space at - // `out_ptr`. This call overwrites it with the size of the value. If the available - // space at `out_ptr` is less than the size of the value a trap is triggered. - // - // The data is encoded as [`crate::rent::RentStatus`]. - // - // # Parameters - // - // - `at_refcount`: The refcount assumed for the returned `custom_refcount_*` fields - // - // # Unstable - // - // This function is unstable and subject to change (or removal) in the future. Do not - // deploy a contract using it to a production chain. - [__unstable__] seal_rent_status(ctx, at_refcount: u32, out_ptr: u32, out_len_ptr: u32) => { - let rent_status = ctx.ext.rent_status(at_refcount).encode(); - Ok(ctx.write_sandbox_output( - out_ptr, out_len_ptr, &rent_status, false, already_charged - )?) - }, - // Call some dispatchable of the runtime. // // This function decodes the passed in data as the overarching `Call` type of the diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index b7e711a37a..75e5a84606 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_contracts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-08-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-09-06, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -54,7 +54,6 @@ pub trait WeightInfo { fn instantiate_with_code(c: u32, s: u32, ) -> Weight; fn instantiate(s: u32, ) -> Weight; fn call() -> Weight; - fn claim_surcharge(c: u32, ) -> Weight; fn seal_caller(r: u32, ) -> Weight; fn seal_address(r: u32, ) -> Weight; fn seal_gas_left(r: u32, ) -> Weight; @@ -62,7 +61,6 @@ pub trait WeightInfo { fn seal_value_transferred(r: u32, ) -> Weight; fn seal_minimum_balance(r: u32, ) -> Weight; fn seal_tombstone_deposit(r: u32, ) -> Weight; - fn seal_rent_allowance(r: u32, ) -> Weight; fn seal_block_number(r: u32, ) -> Weight; fn seal_now(r: u32, ) -> Weight; fn seal_weight_to_fee(r: u32, ) -> Weight; @@ -72,12 +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_restore_to(r: u32, ) -> Weight; - fn seal_restore_to_per_delta(d: u32, ) -> Weight; fn seal_random(r: u32, ) -> Weight; fn seal_deposit_event(r: u32, ) -> Weight; fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight; - fn seal_set_rent_allowance(r: u32, ) -> Weight; fn seal_debug_message(r: u32, ) -> Weight; fn seal_set_storage(r: u32, ) -> Weight; fn seal_set_storage_per_kb(n: u32, ) -> Weight; @@ -155,499 +150,353 @@ pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { // Storage: Contracts DeletionQueue (r:1 w:0) fn on_initialize() -> Weight { - (3_227_000 as Weight) + (3_259_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 3_000 - .saturating_add((2_273_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_197_000 as Weight).saturating_mul(k as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } // Storage: Contracts DeletionQueue (r:1 w:0) fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (50_365_000 as Weight) - // Standard Error: 7_000 - .saturating_add((39_799_000 as Weight).saturating_mul(q as Weight)) + (81_940_000 as Weight) + // Standard Error: 2_000 + .saturating_add((354_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)) } // Storage: Contracts PristineCode (r:1 w:0) // Storage: Contracts CodeStorage (r:0 w:1) fn instrument(c: u32, ) -> Weight { - (40_033_000 as Weight) - // Standard Error: 109_000 - .saturating_add((76_424_000 as Weight).saturating_mul(c as Weight)) + (32_129_000 as Weight) + // Standard Error: 95_000 + .saturating_add((65_706_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)) } // Storage: Contracts CodeStorage (r:1 w:0) fn code_load(c: u32, ) -> Weight { - (6_675_000 as Weight) - // Standard Error: 1_000 - .saturating_add((1_668_000 as Weight).saturating_mul(c as Weight)) + (6_215_000 as Weight) + // Standard Error: 0 + .saturating_add((1_430_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } // Storage: Contracts CodeStorage (r:1 w:1) fn code_refcount(c: u32, ) -> Weight { - (10_560_000 as Weight) - // Standard Error: 2_000 - .saturating_add((2_704_000 as Weight).saturating_mul(c as Weight)) + (10_499_000 as Weight) + // Standard Error: 0 + .saturating_add((2_278_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)) } // Storage: Contracts AccountCounter (r:1 w:0) // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:1) // Storage: Contracts PristineCode (r:0 w:1) fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (479_578_000 as Weight) - // Standard Error: 166_000 - .saturating_add((187_167_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 10_000 - .saturating_add((2_450_000 as Weight).saturating_mul(s as Weight)) + (473_826_000 as Weight) + // Standard Error: 133_000 + .saturating_add((171_504_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 8_000 + .saturating_add((2_161_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: Contracts CodeStorage (r:1 w:1) // Storage: Contracts AccountCounter (r:1 w:0) // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) fn instantiate(s: u32, ) -> Weight { - (237_664_000 as Weight) + (215_899_000 as Weight) // Standard Error: 2_000 - .saturating_add((2_249_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((1_991_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) fn call() -> Weight { - (223_426_000 as Weight) + (176_744_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Contracts DeletionQueue (r:1 w:1) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acafbc76efb655f52a2] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a45e3386f1a83f00b28] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a96e4ef3ab80b5c3a5f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3d24875569a319056f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a64ad561e495f01c762] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3b624bb134596373c1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aadbe519bace97698b4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7e33b1a343f33065bd] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a626f271ae6979bbffe] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7ce585fd4ae98b830b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ac889c022f51a43b527] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4f6353225ab0496d48] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ab578892d355575c3e4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a02b4c8040b81dc785d] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a8d13a70c1e380292ea] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a2e4d2fc709d989c778] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a6df81b28bd3ec99a3a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743af54f74589657eac0fd] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a1849a3092175db4a2f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4f05ecdc6c2c42c9fb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a24c3c0036dfb085bb9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a44d725ac77836eb10b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ad04db6c692ab73d90d] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a873009d6cdb99c5a4c] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aa958795fbfc2b5fa41] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a205b6f659d219c8cbc] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ade54b3bc3d3cdb1aeb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a538b748c1c5f92be98] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ad50de2ad89aaa1e067] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a0576917f19ecaf2a3f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a5b44bd2793555a71e7] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acc874645f7bbf62e62] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7ae1b958a847e98bc8] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a396ae49d5311ee6bd1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aa5d56999a2ebd1c4c9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a72f370c054587f81a5] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3a32934e459acb2ceb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ac10fd56a5e084aae1c] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a2ba8e27fcdbc3ab4f2] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4a75b804eec44f3f2a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a64ebb181fc616bfdb4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a9aaf019a62fd907a8a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a19730285453eb7702a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acced4c24d0ebee7c29] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ae458a57da6a2a6280a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a83b9f09b407c57d07e] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acc9fc095b3aaaef755] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a587ccf84053d9950ff] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a13d53bcf137f3784e9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abb79d34fb381ebd7c1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a935ea70a3e699d23b6] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a109fcd63aefdae75a1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abca8d937a761f2eb46] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a314c97ff9e866a835b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a691e4b5f67da0dea8e] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a127c680b864ee61620] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a148df8dfd47b4493f3] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a57c606ebe91374fcee] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acec20322704f7bec44] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abf6a27e09c6d0a9f0f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ae2e8bdcf5850e20836] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ab8399645bc39338a47] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a658619de90cae5dbe1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aeb9db1dfeed3a7b47b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abdc9db5edf43ffcb0d] (r:1 w:0) - fn claim_surcharge(c: u32, ) -> Weight { - (130_759_000 as Weight) - // Standard Error: 3_000 - .saturating_add((2_850_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)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_caller(r: u32, ) -> Weight { - (492_555_000 as Weight) - // Standard Error: 174_000 - .saturating_add((136_915_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (426_422_000 as Weight) + // Standard Error: 183_000 + .saturating_add((134_155_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_address(r: u32, ) -> Weight { - (487_655_000 as Weight) - // Standard Error: 165_000 - .saturating_add((137_827_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (424_450_000 as Weight) + // Standard Error: 157_000 + .saturating_add((134_814_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_gas_left(r: u32, ) -> Weight { - (488_993_000 as Weight) - // Standard Error: 195_000 - .saturating_add((137_040_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (423_245_000 as Weight) + // Standard Error: 158_000 + .saturating_add((133_566_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:0) fn seal_balance(r: u32, ) -> Weight { - (500_062_000 as Weight) - // Standard Error: 208_000 - .saturating_add((392_337_000 as Weight).saturating_mul(r as Weight)) + (438_039_000 as Weight) + // Standard Error: 216_000 + .saturating_add((383_624_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_value_transferred(r: u32, ) -> Weight { - (492_064_000 as Weight) - // Standard Error: 156_000 - .saturating_add((137_082_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (421_656_000 as Weight) + // Standard Error: 163_000 + .saturating_add((135_160_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_minimum_balance(r: u32, ) -> Weight { - (496_566_000 as Weight) - // Standard Error: 159_000 - .saturating_add((137_377_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (425_416_000 as Weight) + // Standard Error: 177_000 + .saturating_add((134_306_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_tombstone_deposit(r: u32, ) -> Weight { - (491_566_000 as Weight) - // Standard Error: 163_000 - .saturating_add((137_586_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (422_733_000 as Weight) + // Standard Error: 171_000 + .saturating_add((134_775_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_rent_allowance(r: u32, ) -> Weight { - (491_459_000 as Weight) - // Standard Error: 150_000 - .saturating_add((137_402_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_block_number(r: u32, ) -> Weight { - (488_379_000 as Weight) - // Standard Error: 170_000 - .saturating_add((136_564_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (425_223_000 as Weight) + // Standard Error: 193_000 + .saturating_add((133_823_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_now(r: u32, ) -> Weight { - (494_827_000 as Weight) - // Standard Error: 175_000 - .saturating_add((137_178_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (433_528_000 as Weight) + // Standard Error: 166_000 + .saturating_add((133_358_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) fn seal_weight_to_fee(r: u32, ) -> Weight { - (497_508_000 as Weight) - // Standard Error: 191_000 - .saturating_add((323_559_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (432_032_000 as Weight) + // Standard Error: 214_000 + .saturating_add((305_418_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_gas(r: u32, ) -> Weight { - (179_076_000 as Weight) - // Standard Error: 124_000 - .saturating_add((62_013_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (148_160_000 as Weight) + // Standard Error: 120_000 + .saturating_add((59_833_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) - fn seal_input(r: u32, ) -> Weight { - (480_920_000 as Weight) - // Standard Error: 182_000 - .saturating_add((3_254_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + fn seal_input(_r: u32, ) -> Weight { + (420_503_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_input_per_kb(n: u32, ) -> Weight { - (487_910_000 as Weight) + (424_727_000 as Weight) // Standard Error: 1_000 - .saturating_add((1_218_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add((1_017_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_return(r: u32, ) -> Weight { - (470_960_000 as Weight) - // Standard Error: 678_000 - .saturating_add((2_506_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (397_994_000 as Weight) + // Standard Error: 1_720_000 + .saturating_add((17_298_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_return_per_kb(n: u32, ) -> Weight { - (478_623_000 as Weight) + (414_811_000 as Weight) // Standard Error: 1_000 - .saturating_add((749_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add((637_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts DeletionQueue (r:1 w:1) + // Storage: System Account (r:2 w:2) fn seal_terminate(r: u32, ) -> Weight { - (481_930_000 as Weight) - // Standard Error: 511_000 - .saturating_add((84_726_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + (407_583_000 as Weight) + // Standard Error: 4_720_000 + .saturating_add((110_145_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743af3fd4cc2fc8d170b6d] (r:1 w:0) - fn seal_restore_to(r: u32, ) -> Weight { - (514_296_000 as Weight) - // Standard Error: 458_000 - .saturating_add((93_769_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) - } - // Storage: Skipped Metadata (r:0 w:0) - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (313_520_000 as Weight) - // Standard Error: 1_783_000 - .saturating_add((2_435_407_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) fn seal_random(r: u32, ) -> Weight { - (484_059_000 as Weight) - // Standard Error: 285_000 - .saturating_add((443_946_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)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_deposit_event(r: u32, ) -> Weight { - (491_593_000 as Weight) - // Standard Error: 386_000 - .saturating_add((733_958_000 as Weight).saturating_mul(r as Weight)) + (421_151_000 as Weight) + // Standard Error: 239_000 + .saturating_add((432_224_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + fn seal_deposit_event(r: u32, ) -> Weight { + (417_192_000 as Weight) + // Standard Error: 312_000 + .saturating_add((752_443_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Contracts ContractInfoOf (r:1 w:1) + // Storage: Contracts CodeStorage (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: System EventTopics (r:100 w:100) fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_342_357_000 as Weight) - // Standard Error: 2_458_000 - .saturating_add((521_445_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 484_000 - .saturating_add((195_792_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (1_265_810_000 as Weight) + // Standard Error: 2_068_000 + .saturating_add((507_093_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 407_000 + .saturating_add((165_100_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_set_rent_allowance(r: u32, ) -> Weight { - (209_818_000 as Weight) - // Standard Error: 157_000 - .saturating_add((93_289_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_debug_message(r: u32, ) -> Weight { - (200_027_000 as Weight) - // Standard Error: 145_000 - .saturating_add((79_038_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (161_459_000 as Weight) + // Standard Error: 151_000 + .saturating_add((76_693_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn seal_set_storage(r: u32, ) -> Weight { - (477_211_000 as Weight) - // Standard Error: 709_000 - .saturating_add((407_264_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + (402_875_000 as Weight) + // Standard Error: 282_000 + .saturating_add((258_574_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 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))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) - // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:1 w:1) + // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:0 w:1) fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (832_538_000 as Weight) - // Standard Error: 262_000 - .saturating_add((87_211_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (666_594_000 as Weight) + // Standard Error: 264_000 + .saturating_add((70_365_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn seal_clear_storage(r: u32, ) -> Weight { - (199_686_000 as Weight) - // Standard Error: 1_610_000 - .saturating_add((905_125_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + (452_019_000 as Weight) + // Standard Error: 236_000 + .saturating_add((233_300_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 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))) } // Storage: Skipped Metadata (r:0 w:0) fn seal_get_storage(r: u32, ) -> Weight { - (335_052_000 as Weight) - // Standard Error: 885_000 - .saturating_add((545_754_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (303_530_000 as Weight) + // Standard Error: 801_000 + .saturating_add((532_265_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 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)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:1 w:0) fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (800_556_000 as Weight) - // Standard Error: 337_000 - .saturating_add((133_492_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (734_714_000 as Weight) + // Standard Error: 246_000 + .saturating_add((112_631_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:101 w:101) fn seal_transfer(r: u32, ) -> Weight { - (317_531_000 as Weight) - // Standard Error: 1_627_000 - .saturating_add((4_748_591_000 as Weight).saturating_mul(r as Weight)) + (319_298_000 as Weight) + // Standard Error: 2_180_000 + .saturating_add((4_710_724_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) @@ -655,42 +504,42 @@ impl WeightInfo for SubstrateWeight { } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 8_848_000 - .saturating_add((46_947_679_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) + // Standard Error: 10_059_000 + .saturating_add((40_188_894_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } // Storage: Contracts ContractInfoOf (r:101 w:101) // Storage: Contracts CodeStorage (r:2 w:0) - // Storage: System Account (r:101 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:101 w:101) fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (47_469_660_000 as Weight) - // Standard Error: 45_192_000 - .saturating_add((3_691_145_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 16_000 - .saturating_add((75_339_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 17_000 - .saturating_add((121_494_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(T::DbWeight::get().reads(205 as Weight)) + (39_972_999_000 as Weight) + // Standard Error: 56_397_000 + .saturating_add((3_858_600_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 20_000 + .saturating_add((62_963_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 21_000 + .saturating_add((101_497_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(T::DbWeight::get().reads(104 as Weight)) + .saturating_add(T::DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes(101 as Weight)) .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts AccountCounter (r:1 w:1) + // Storage: System Account (r:101 w:101) fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 32_740_000 - .saturating_add((55_623_588_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 103_701_000 + .saturating_add((48_209_042_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(3 as Weight)) @@ -698,362 +547,354 @@ impl WeightInfo for SubstrateWeight { } // Storage: Contracts ContractInfoOf (r:101 w:101) // Storage: Contracts CodeStorage (r:2 w:1) - // Storage: System Account (r:101 w:101) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts AccountCounter (r:1 w:1) + // Storage: System Account (r:101 w:101) fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (54_718_944_000 as Weight) - // Standard Error: 29_000 - .saturating_add((75_276_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 29_000 - .saturating_add((121_341_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 29_000 - .saturating_add((223_964_000 as Weight).saturating_mul(s as Weight)) + (45_662_002_000 as Weight) + // Standard Error: 30_000 + .saturating_add((63_978_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 30_000 + .saturating_add((101_724_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 30_000 + .saturating_add((201_820_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(206 as Weight)) .saturating_add(T::DbWeight::get().writes(204 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_sha2_256(r: u32, ) -> Weight { - (485_310_000 as Weight) - // Standard Error: 169_000 - .saturating_add((143_364_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (422_425_000 as Weight) + // Standard Error: 164_000 + .saturating_add((139_580_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (632_820_000 as Weight) - // Standard Error: 29_000 - .saturating_add((511_722_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (691_929_000 as Weight) + // Standard Error: 26_000 + .saturating_add((499_602_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_keccak_256(r: u32, ) -> Weight { - (484_331_000 as Weight) - // Standard Error: 195_000 - .saturating_add((151_617_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (420_255_000 as Weight) + // Standard Error: 167_000 + .saturating_add((148_167_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (565_213_000 as Weight) - // Standard Error: 28_000 - .saturating_add((359_762_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (541_872_000 as Weight) + // Standard Error: 17_000 + .saturating_add((347_194_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_256(r: u32, ) -> Weight { - (481_843_000 as Weight) - // Standard Error: 186_000 - .saturating_add((122_838_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (419_267_000 as Weight) + // Standard Error: 139_000 + .saturating_add((119_855_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (582_445_000 as Weight) - // Standard Error: 28_000 - .saturating_add((176_329_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (547_517_000 as Weight) + // Standard Error: 16_000 + .saturating_add((164_328_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_128(r: u32, ) -> Weight { - (486_320_000 as Weight) - // Standard Error: 147_000 - .saturating_add((123_460_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (424_870_000 as Weight) + // Standard Error: 163_000 + .saturating_add((118_215_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (515_967_000 as Weight) - // Standard Error: 33_000 - .saturating_add((176_423_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) + (514_057_000 as Weight) + // Standard Error: 14_000 + .saturating_add((164_390_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (54_127_000 as Weight) - // Standard Error: 25_000 - .saturating_add((10_198_000 as Weight).saturating_mul(r as Weight)) + (51_570_000 as Weight) + // Standard Error: 74_000 + .saturating_add((9_529_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (55_411_000 as Weight) - // Standard Error: 148_000 - .saturating_add((22_916_000 as Weight).saturating_mul(r as Weight)) + (38_616_000 as Weight) + // Standard Error: 24_000 + .saturating_add((37_349_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (55_462_000 as Weight) - // Standard Error: 134_000 - .saturating_add((24_449_000 as Weight).saturating_mul(r as Weight)) + (38_576_000 as Weight) + // Standard Error: 17_000 + .saturating_add((38_351_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (54_114_000 as Weight) - // Standard Error: 18_000 - .saturating_add((26_214_000 as Weight).saturating_mul(r as Weight)) + (51_383_000 as Weight) + // Standard Error: 60_000 + .saturating_add((27_099_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (54_118_000 as Weight) - // Standard Error: 18_000 - .saturating_add((26_492_000 as Weight).saturating_mul(r as Weight)) + (38_218_000 as Weight) + // Standard Error: 28_000 + .saturating_add((41_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (54_119_000 as Weight) - // Standard Error: 304_000 - .saturating_add((18_424_000 as Weight).saturating_mul(r as Weight)) + (38_216_000 as Weight) + // Standard Error: 33_000 + .saturating_add((28_483_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (55_352_000 as Weight) - // Standard Error: 13_000 - .saturating_add((32_291_000 as Weight).saturating_mul(r as Weight)) + (51_637_000 as Weight) + // Standard Error: 56_000 + .saturating_add((34_688_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (54_115_000 as Weight) - // Standard Error: 16_000 - .saturating_add((27_785_000 as Weight).saturating_mul(r as Weight)) + (51_490_000 as Weight) + // Standard Error: 71_000 + .saturating_add((27_683_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (86_048_000 as Weight) - // Standard Error: 1_000 - .saturating_add((82_000 as Weight).saturating_mul(e as Weight)) + (77_260_000 as Weight) + // Standard Error: 2_000 + .saturating_add((130_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (54_654_000 as Weight) - // Standard Error: 82_000 - .saturating_add((199_159_000 as Weight).saturating_mul(r as Weight)) + (52_012_000 as Weight) + // Standard Error: 564_000 + .saturating_add((188_018_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (67_478_000 as Weight) - // Standard Error: 113_000 - .saturating_add((302_597_000 as Weight).saturating_mul(r as Weight)) + (65_670_000 as Weight) + // Standard Error: 5_489_000 + .saturating_add((294_560_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (384_281_000 as Weight) - // Standard Error: 13_000 - .saturating_add((9_984_000 as Weight).saturating_mul(p as Weight)) + (368_428_000 as Weight) + // Standard Error: 26_000 + .saturating_add((10_469_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (55_473_000 as Weight) - // Standard Error: 16_000 - .saturating_add((9_287_000 as Weight).saturating_mul(r as Weight)) + (52_091_000 as Weight) + // Standard Error: 32_000 + .saturating_add((11_160_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (55_426_000 as Weight) - // Standard Error: 38_000 - .saturating_add((10_559_000 as Weight).saturating_mul(r as Weight)) + (52_145_000 as Weight) + // Standard Error: 18_000 + .saturating_add((12_086_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (55_332_000 as Weight) - // Standard Error: 8_000 - .saturating_add((15_640_000 as Weight).saturating_mul(r as Weight)) + (52_057_000 as Weight) + // Standard Error: 26_000 + .saturating_add((2_555_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (74_497_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_067_000 as Weight).saturating_mul(r as Weight)) + (73_126_000 as Weight) + // Standard Error: 35_000 + .saturating_add((16_004_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (74_445_000 as Weight) - // Standard Error: 49_000 - .saturating_add((17_650_000 as Weight).saturating_mul(r as Weight)) + (73_104_000 as Weight) + // Standard Error: 63_000 + .saturating_add((2_267_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (54_500_000 as Weight) - // Standard Error: 17_000 - .saturating_add((9_307_000 as Weight).saturating_mul(r as Weight)) + (38_596_000 as Weight) + // Standard Error: 27_000 + .saturating_add((22_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (54_382_000 as Weight) - // Standard Error: 5_644_000 - .saturating_add((748_424_000 as Weight).saturating_mul(r as Weight)) + (39_320_000 as Weight) + // Standard Error: 4_805_000 + .saturating_add((642_459_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (54_133_000 as Weight) - // Standard Error: 20_000 - .saturating_add((15_830_000 as Weight).saturating_mul(r as Weight)) + (51_634_000 as Weight) + // Standard Error: 65_000 + .saturating_add((14_706_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (54_129_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_894_000 as Weight).saturating_mul(r as Weight)) + (51_490_000 as Weight) + // Standard Error: 63_000 + .saturating_add((14_759_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (54_181_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_847_000 as Weight).saturating_mul(r as Weight)) + (51_278_000 as Weight) + // Standard Error: 37_000 + .saturating_add((15_084_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (54_130_000 as Weight) - // Standard Error: 17_000 - .saturating_add((15_825_000 as Weight).saturating_mul(r as Weight)) + (51_524_000 as Weight) + // Standard Error: 53_000 + .saturating_add((14_801_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (54_122_000 as Weight) - // Standard Error: 19_000 - .saturating_add((15_803_000 as Weight).saturating_mul(r as Weight)) + (50_775_000 as Weight) + // Standard Error: 88_000 + .saturating_add((3_125_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (54_100_000 as Weight) - // Standard Error: 28_000 - .saturating_add((15_822_000 as Weight).saturating_mul(r as Weight)) + (50_748_000 as Weight) + // Standard Error: 191_000 + .saturating_add((3_785_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (54_143_000 as Weight) - // Standard Error: 19_000 - .saturating_add((15_868_000 as Weight).saturating_mul(r as Weight)) + (52_621_000 as Weight) + // Standard Error: 60_000 + .saturating_add((13_744_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (54_133_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_121_000 as Weight).saturating_mul(r as Weight)) + (51_486_000 as Weight) + // Standard Error: 71_000 + .saturating_add((21_786_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (54_177_000 as Weight) - // Standard Error: 14_000 - .saturating_add((21_003_000 as Weight).saturating_mul(r as Weight)) + (51_573_000 as Weight) + // Standard Error: 73_000 + .saturating_add((21_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (54_164_000 as Weight) - // Standard Error: 31_000 - .saturating_add((21_041_000 as Weight).saturating_mul(r as Weight)) + (51_445_000 as Weight) + // Standard Error: 24_000 + .saturating_add((21_838_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (54_171_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_101_000 as Weight).saturating_mul(r as Weight)) + (51_609_000 as Weight) + // Standard Error: 61_000 + .saturating_add((21_766_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (54_177_000 as Weight) - // Standard Error: 12_000 - .saturating_add((21_074_000 as Weight).saturating_mul(r as Weight)) + (51_374_000 as Weight) + // Standard Error: 73_000 + .saturating_add((22_062_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (54_073_000 as Weight) - // Standard Error: 13_000 - .saturating_add((21_136_000 as Weight).saturating_mul(r as Weight)) + (51_451_000 as Weight) + // Standard Error: 52_000 + .saturating_add((21_918_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (54_116_000 as Weight) - // Standard Error: 17_000 - .saturating_add((21_140_000 as Weight).saturating_mul(r as Weight)) + (51_276_000 as Weight) + // Standard Error: 30_000 + .saturating_add((22_040_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (54_115_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_164_000 as Weight).saturating_mul(r as Weight)) + (51_401_000 as Weight) + // Standard Error: 46_000 + .saturating_add((21_886_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (54_261_000 as Weight) - // Standard Error: 123_000 - .saturating_add((20_921_000 as Weight).saturating_mul(r as Weight)) + (51_480_000 as Weight) + // Standard Error: 35_000 + .saturating_add((21_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (54_090_000 as Weight) - // Standard Error: 38_000 - .saturating_add((21_171_000 as Weight).saturating_mul(r as Weight)) + (51_771_000 as Weight) + // Standard Error: 63_000 + .saturating_add((21_607_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (54_129_000 as Weight) - // Standard Error: 27_000 - .saturating_add((21_086_000 as Weight).saturating_mul(r as Weight)) + (51_506_000 as Weight) + // Standard Error: 62_000 + .saturating_add((21_743_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (54_126_000 as Weight) - // Standard Error: 11_000 - .saturating_add((21_051_000 as Weight).saturating_mul(r as Weight)) + (51_456_000 as Weight) + // Standard Error: 68_000 + .saturating_add((21_916_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (54_153_000 as Weight) - // Standard Error: 22_000 - .saturating_add((21_021_000 as Weight).saturating_mul(r as Weight)) + (52_595_000 as Weight) + // Standard Error: 31_000 + .saturating_add((20_604_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (54_168_000 as Weight) - // Standard Error: 19_000 - .saturating_add((27_336_000 as Weight).saturating_mul(r as Weight)) + (51_575_000 as Weight) + // Standard Error: 101_000 + .saturating_add((28_754_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (54_124_000 as Weight) - // Standard Error: 22_000 - .saturating_add((24_783_000 as Weight).saturating_mul(r as Weight)) + (51_396_000 as Weight) + // Standard Error: 57_000 + .saturating_add((26_422_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (54_203_000 as Weight) - // Standard Error: 21_000 - .saturating_add((27_539_000 as Weight).saturating_mul(r as Weight)) + (51_575_000 as Weight) + // Standard Error: 58_000 + .saturating_add((29_376_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (54_176_000 as Weight) - // Standard Error: 19_000 - .saturating_add((24_686_000 as Weight).saturating_mul(r as Weight)) + (51_649_000 as Weight) + // Standard Error: 73_000 + .saturating_add((26_067_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (54_111_000 as Weight) - // Standard Error: 356_000 - .saturating_add((22_077_000 as Weight).saturating_mul(r as Weight)) + (51_641_000 as Weight) + // Standard Error: 69_000 + .saturating_add((21_615_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (54_124_000 as Weight) - // Standard Error: 15_000 - .saturating_add((21_060_000 as Weight).saturating_mul(r as Weight)) + (51_246_000 as Weight) + // Standard Error: 35_000 + .saturating_add((22_115_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (54_153_000 as Weight) - // Standard Error: 24_000 - .saturating_add((21_064_000 as Weight).saturating_mul(r as Weight)) + (51_413_000 as Weight) + // Standard Error: 64_000 + .saturating_add((21_917_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (54_122_000 as Weight) - // Standard Error: 23_000 - .saturating_add((21_187_000 as Weight).saturating_mul(r as Weight)) + (51_315_000 as Weight) + // Standard Error: 35_000 + .saturating_add((22_099_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (54_149_000 as Weight) - // Standard Error: 18_000 - .saturating_add((21_110_000 as Weight).saturating_mul(r as Weight)) + (51_504_000 as Weight) + // Standard Error: 66_000 + .saturating_add((21_901_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (54_136_000 as Weight) - // Standard Error: 13_000 - .saturating_add((21_066_000 as Weight).saturating_mul(r as Weight)) + (51_487_000 as Weight) + // Standard Error: 68_000 + .saturating_add((21_941_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (54_231_000 as Weight) - // Standard Error: 30_000 - .saturating_add((21_073_000 as Weight).saturating_mul(r as Weight)) + (51_893_000 as Weight) + // Standard Error: 59_000 + .saturating_add((21_505_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (54_139_000 as Weight) - // Standard Error: 17_000 - .saturating_add((21_097_000 as Weight).saturating_mul(r as Weight)) + (51_307_000 as Weight) + // Standard Error: 65_000 + .saturating_add((22_056_000 as Weight).saturating_mul(r as Weight)) } } @@ -1061,499 +902,353 @@ impl WeightInfo for SubstrateWeight { impl WeightInfo for () { // Storage: Contracts DeletionQueue (r:1 w:0) fn on_initialize() -> Weight { - (3_227_000 as Weight) + (3_259_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 3_000 - .saturating_add((2_273_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_197_000 as Weight).saturating_mul(k as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } // Storage: Contracts DeletionQueue (r:1 w:0) fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (50_365_000 as Weight) - // Standard Error: 7_000 - .saturating_add((39_799_000 as Weight).saturating_mul(q as Weight)) + (81_940_000 as Weight) + // Standard Error: 2_000 + .saturating_add((354_000 as Weight).saturating_mul(q as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts PristineCode (r:1 w:0) // Storage: Contracts CodeStorage (r:0 w:1) fn instrument(c: u32, ) -> Weight { - (40_033_000 as Weight) - // Standard Error: 109_000 - .saturating_add((76_424_000 as Weight).saturating_mul(c as Weight)) + (32_129_000 as Weight) + // Standard Error: 95_000 + .saturating_add((65_706_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts CodeStorage (r:1 w:0) fn code_load(c: u32, ) -> Weight { - (6_675_000 as Weight) - // Standard Error: 1_000 - .saturating_add((1_668_000 as Weight).saturating_mul(c as Weight)) + (6_215_000 as Weight) + // Standard Error: 0 + .saturating_add((1_430_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) } // Storage: Contracts CodeStorage (r:1 w:1) fn code_refcount(c: u32, ) -> Weight { - (10_560_000 as Weight) - // Standard Error: 2_000 - .saturating_add((2_704_000 as Weight).saturating_mul(c as Weight)) + (10_499_000 as Weight) + // Standard Error: 0 + .saturating_add((2_278_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts AccountCounter (r:1 w:0) // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:1) // Storage: Contracts PristineCode (r:0 w:1) fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (479_578_000 as Weight) - // Standard Error: 166_000 - .saturating_add((187_167_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 10_000 - .saturating_add((2_450_000 as Weight).saturating_mul(s as Weight)) + (473_826_000 as Weight) + // Standard Error: 133_000 + .saturating_add((171_504_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 8_000 + .saturating_add((2_161_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } // Storage: Contracts CodeStorage (r:1 w:1) // Storage: Contracts AccountCounter (r:1 w:0) // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) fn instantiate(s: u32, ) -> Weight { - (237_664_000 as Weight) + (215_899_000 as Weight) // Standard Error: 2_000 - .saturating_add((2_249_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((1_991_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:1) fn call() -> Weight { - (223_426_000 as Weight) + (176_744_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Contracts DeletionQueue (r:1 w:1) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acafbc76efb655f52a2] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a45e3386f1a83f00b28] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a96e4ef3ab80b5c3a5f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3d24875569a319056f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a64ad561e495f01c762] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3b624bb134596373c1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aadbe519bace97698b4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7e33b1a343f33065bd] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a626f271ae6979bbffe] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7ce585fd4ae98b830b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ac889c022f51a43b527] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4f6353225ab0496d48] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ab578892d355575c3e4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a02b4c8040b81dc785d] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a8d13a70c1e380292ea] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a2e4d2fc709d989c778] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a6df81b28bd3ec99a3a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743af54f74589657eac0fd] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a1849a3092175db4a2f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4f05ecdc6c2c42c9fb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a24c3c0036dfb085bb9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a44d725ac77836eb10b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ad04db6c692ab73d90d] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a873009d6cdb99c5a4c] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aa958795fbfc2b5fa41] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a205b6f659d219c8cbc] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ade54b3bc3d3cdb1aeb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a538b748c1c5f92be98] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ad50de2ad89aaa1e067] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a0576917f19ecaf2a3f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a5b44bd2793555a71e7] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acc874645f7bbf62e62] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a7ae1b958a847e98bc8] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a396ae49d5311ee6bd1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aa5d56999a2ebd1c4c9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a72f370c054587f81a5] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a3a32934e459acb2ceb] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ac10fd56a5e084aae1c] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a2ba8e27fcdbc3ab4f2] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a4a75b804eec44f3f2a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a64ebb181fc616bfdb4] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a9aaf019a62fd907a8a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a19730285453eb7702a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acced4c24d0ebee7c29] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ae458a57da6a2a6280a] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a83b9f09b407c57d07e] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acc9fc095b3aaaef755] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a587ccf84053d9950ff] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a13d53bcf137f3784e9] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abb79d34fb381ebd7c1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a935ea70a3e699d23b6] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a109fcd63aefdae75a1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abca8d937a761f2eb46] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a314c97ff9e866a835b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a691e4b5f67da0dea8e] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a127c680b864ee61620] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a148df8dfd47b4493f3] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a57c606ebe91374fcee] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743acec20322704f7bec44] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abf6a27e09c6d0a9f0f] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ae2e8bdcf5850e20836] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743ab8399645bc39338a47] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743a658619de90cae5dbe1] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743aeb9db1dfeed3a7b47b] (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743abdc9db5edf43ffcb0d] (r:1 w:0) - fn claim_surcharge(c: u32, ) -> Weight { - (130_759_000 as Weight) - // Standard Error: 3_000 - .saturating_add((2_850_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_caller(r: u32, ) -> Weight { - (492_555_000 as Weight) - // Standard Error: 174_000 - .saturating_add((136_915_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (426_422_000 as Weight) + // Standard Error: 183_000 + .saturating_add((134_155_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_address(r: u32, ) -> Weight { - (487_655_000 as Weight) - // Standard Error: 165_000 - .saturating_add((137_827_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (424_450_000 as Weight) + // Standard Error: 157_000 + .saturating_add((134_814_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_gas_left(r: u32, ) -> Weight { - (488_993_000 as Weight) - // Standard Error: 195_000 - .saturating_add((137_040_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (423_245_000 as Weight) + // Standard Error: 158_000 + .saturating_add((133_566_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:1 w:0) fn seal_balance(r: u32, ) -> Weight { - (500_062_000 as Weight) - // Standard Error: 208_000 - .saturating_add((392_337_000 as Weight).saturating_mul(r as Weight)) + (438_039_000 as Weight) + // Standard Error: 216_000 + .saturating_add((383_624_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_value_transferred(r: u32, ) -> Weight { - (492_064_000 as Weight) - // Standard Error: 156_000 - .saturating_add((137_082_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (421_656_000 as Weight) + // Standard Error: 163_000 + .saturating_add((135_160_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_minimum_balance(r: u32, ) -> Weight { - (496_566_000 as Weight) - // Standard Error: 159_000 - .saturating_add((137_377_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (425_416_000 as Weight) + // Standard Error: 177_000 + .saturating_add((134_306_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_tombstone_deposit(r: u32, ) -> Weight { - (491_566_000 as Weight) - // Standard Error: 163_000 - .saturating_add((137_586_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (422_733_000 as Weight) + // Standard Error: 171_000 + .saturating_add((134_775_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_rent_allowance(r: u32, ) -> Weight { - (491_459_000 as Weight) - // Standard Error: 150_000 - .saturating_add((137_402_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_block_number(r: u32, ) -> Weight { - (488_379_000 as Weight) - // Standard Error: 170_000 - .saturating_add((136_564_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (425_223_000 as Weight) + // Standard Error: 193_000 + .saturating_add((133_823_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_now(r: u32, ) -> Weight { - (494_827_000 as Weight) - // Standard Error: 175_000 - .saturating_add((137_178_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (433_528_000 as Weight) + // Standard Error: 166_000 + .saturating_add((133_358_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) fn seal_weight_to_fee(r: u32, ) -> Weight { - (497_508_000 as Weight) - // Standard Error: 191_000 - .saturating_add((323_559_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (432_032_000 as Weight) + // Standard Error: 214_000 + .saturating_add((305_418_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_gas(r: u32, ) -> Weight { - (179_076_000 as Weight) - // Standard Error: 124_000 - .saturating_add((62_013_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (148_160_000 as Weight) + // Standard Error: 120_000 + .saturating_add((59_833_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) - fn seal_input(r: u32, ) -> Weight { - (480_920_000 as Weight) - // Standard Error: 182_000 - .saturating_add((3_254_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + fn seal_input(_r: u32, ) -> Weight { + (420_503_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_input_per_kb(n: u32, ) -> Weight { - (487_910_000 as Weight) + (424_727_000 as Weight) // Standard Error: 1_000 - .saturating_add((1_218_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add((1_017_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_return(r: u32, ) -> Weight { - (470_960_000 as Weight) - // Standard Error: 678_000 - .saturating_add((2_506_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (397_994_000 as Weight) + // Standard Error: 1_720_000 + .saturating_add((17_298_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_return_per_kb(n: u32, ) -> Weight { - (478_623_000 as Weight) + (414_811_000 as Weight) // Standard Error: 1_000 - .saturating_add((749_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add((637_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts DeletionQueue (r:1 w:1) + // Storage: System Account (r:2 w:2) fn seal_terminate(r: u32, ) -> Weight { - (481_930_000 as Weight) - // Standard Error: 511_000 - .saturating_add((84_726_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + (407_583_000 as Weight) + // Standard Error: 4_720_000 + .saturating_add((110_145_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - // Storage: unknown [0x3a6368696c645f73746f726167653a64656661756c743af3fd4cc2fc8d170b6d] (r:1 w:0) - fn seal_restore_to(r: u32, ) -> Weight { - (514_296_000 as Weight) - // Standard Error: 458_000 - .saturating_add((93_769_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) - } - // Storage: Skipped Metadata (r:0 w:0) - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (313_520_000 as Weight) - // Standard Error: 1_783_000 - .saturating_add((2_435_407_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) - .saturating_add(RocksDbWeight::get().writes(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) fn seal_random(r: u32, ) -> Weight { - (484_059_000 as Weight) - // Standard Error: 285_000 - .saturating_add((443_946_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_deposit_event(r: u32, ) -> Weight { - (491_593_000 as Weight) - // Standard Error: 386_000 - .saturating_add((733_958_000 as Weight).saturating_mul(r as Weight)) + (421_151_000 as Weight) + // Standard Error: 239_000 + .saturating_add((432_224_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) + // Storage: Timestamp Now (r:1 w:0) + fn seal_deposit_event(r: u32, ) -> Weight { + (417_192_000 as Weight) + // Standard Error: 312_000 + .saturating_add((752_443_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Contracts ContractInfoOf (r:1 w:1) + // Storage: Contracts CodeStorage (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: System EventTopics (r:100 w:100) fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_342_357_000 as Weight) - // Standard Error: 2_458_000 - .saturating_add((521_445_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 484_000 - .saturating_add((195_792_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (1_265_810_000 as Weight) + // Standard Error: 2_068_000 + .saturating_add((507_093_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 407_000 + .saturating_add((165_100_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) - // Storage: Timestamp Now (r:1 w:0) - fn seal_set_rent_allowance(r: u32, ) -> Weight { - (209_818_000 as Weight) - // Standard Error: 157_000 - .saturating_add((93_289_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - // Storage: Contracts ContractInfoOf (r:1 w:1) - // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_debug_message(r: u32, ) -> Weight { - (200_027_000 as Weight) - // Standard Error: 145_000 - .saturating_add((79_038_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (161_459_000 as Weight) + // Standard Error: 151_000 + .saturating_add((76_693_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn seal_set_storage(r: u32, ) -> Weight { - (477_211_000 as Weight) - // Standard Error: 709_000 - .saturating_add((407_264_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + (402_875_000 as Weight) + // Standard Error: 282_000 + .saturating_add((258_574_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) - // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:1 w:1) + // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:0 w:1) fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (832_538_000 as Weight) - // Standard Error: 262_000 - .saturating_add((87_211_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (666_594_000 as Weight) + // Standard Error: 264_000 + .saturating_add((70_365_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Skipped Metadata (r:0 w:0) fn seal_clear_storage(r: u32, ) -> Weight { - (199_686_000 as Weight) - // Standard Error: 1_610_000 - .saturating_add((905_125_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + (452_019_000 as Weight) + // Standard Error: 236_000 + .saturating_add((233_300_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } // Storage: Skipped Metadata (r:0 w:0) fn seal_get_storage(r: u32, ) -> Weight { - (335_052_000 as Weight) - // Standard Error: 885_000 - .saturating_add((545_754_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (303_530_000 as Weight) + // Standard Error: 801_000 + .saturating_add((532_265_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: unknown [0x7afa01283080ef247df84e0ba38ea5a587d25ce6633a6bfbba02068c14023441] (r:1 w:0) fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (800_556_000 as Weight) - // Standard Error: 337_000 - .saturating_add((133_492_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (734_714_000 as Weight) + // Standard Error: 246_000 + .saturating_add((112_631_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:101 w:101) fn seal_transfer(r: u32, ) -> Weight { - (317_531_000 as Weight) - // Standard Error: 1_627_000 - .saturating_add((4_748_591_000 as Weight).saturating_mul(r as Weight)) + (319_298_000 as Weight) + // Standard Error: 2_180_000 + .saturating_add((4_710_724_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) @@ -1561,42 +1256,42 @@ impl WeightInfo for () { } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 8_848_000 - .saturating_add((46_947_679_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) + // Standard Error: 10_059_000 + .saturating_add((40_188_894_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } // Storage: Contracts ContractInfoOf (r:101 w:101) // Storage: Contracts CodeStorage (r:2 w:0) - // Storage: System Account (r:101 w:0) // Storage: Timestamp Now (r:1 w:0) + // Storage: System Account (r:101 w:101) fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (47_469_660_000 as Weight) - // Standard Error: 45_192_000 - .saturating_add((3_691_145_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 16_000 - .saturating_add((75_339_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 17_000 - .saturating_add((121_494_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(RocksDbWeight::get().reads(205 as Weight)) + (39_972_999_000 as Weight) + // Standard Error: 56_397_000 + .saturating_add((3_858_600_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 20_000 + .saturating_add((62_963_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 21_000 + .saturating_add((101_497_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(RocksDbWeight::get().reads(104 as Weight)) + .saturating_add(RocksDbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes(101 as Weight)) .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts AccountCounter (r:1 w:1) + // Storage: System Account (r:101 w:101) fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 32_740_000 - .saturating_add((55_623_588_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 103_701_000 + .saturating_add((48_209_042_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) @@ -1604,361 +1299,353 @@ impl WeightInfo for () { } // Storage: Contracts ContractInfoOf (r:101 w:101) // Storage: Contracts CodeStorage (r:2 w:1) - // Storage: System Account (r:101 w:101) // Storage: Timestamp Now (r:1 w:0) // Storage: Contracts AccountCounter (r:1 w:1) + // Storage: System Account (r:101 w:101) fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (54_718_944_000 as Weight) - // Standard Error: 29_000 - .saturating_add((75_276_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 29_000 - .saturating_add((121_341_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 29_000 - .saturating_add((223_964_000 as Weight).saturating_mul(s as Weight)) + (45_662_002_000 as Weight) + // Standard Error: 30_000 + .saturating_add((63_978_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 30_000 + .saturating_add((101_724_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 30_000 + .saturating_add((201_820_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(206 as Weight)) .saturating_add(RocksDbWeight::get().writes(204 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_sha2_256(r: u32, ) -> Weight { - (485_310_000 as Weight) - // Standard Error: 169_000 - .saturating_add((143_364_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (422_425_000 as Weight) + // Standard Error: 164_000 + .saturating_add((139_580_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (632_820_000 as Weight) - // Standard Error: 29_000 - .saturating_add((511_722_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (691_929_000 as Weight) + // Standard Error: 26_000 + .saturating_add((499_602_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_keccak_256(r: u32, ) -> Weight { - (484_331_000 as Weight) - // Standard Error: 195_000 - .saturating_add((151_617_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (420_255_000 as Weight) + // Standard Error: 167_000 + .saturating_add((148_167_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (565_213_000 as Weight) - // Standard Error: 28_000 - .saturating_add((359_762_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (541_872_000 as Weight) + // Standard Error: 17_000 + .saturating_add((347_194_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_256(r: u32, ) -> Weight { - (481_843_000 as Weight) - // Standard Error: 186_000 - .saturating_add((122_838_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (419_267_000 as Weight) + // Standard Error: 139_000 + .saturating_add((119_855_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (582_445_000 as Weight) - // Standard Error: 28_000 - .saturating_add((176_329_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (547_517_000 as Weight) + // Standard Error: 16_000 + .saturating_add((164_328_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_128(r: u32, ) -> Weight { - (486_320_000 as Weight) - // Standard Error: 147_000 - .saturating_add((123_460_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (424_870_000 as Weight) + // Standard Error: 163_000 + .saturating_add((118_215_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Contracts ContractInfoOf (r:1 w:1) // Storage: Contracts CodeStorage (r:1 w:0) - // Storage: System Account (r:1 w:0) // Storage: Timestamp Now (r:1 w:0) fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (515_967_000 as Weight) - // Standard Error: 33_000 - .saturating_add((176_423_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + (514_057_000 as Weight) + // Standard Error: 14_000 + .saturating_add((164_390_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (54_127_000 as Weight) - // Standard Error: 25_000 - .saturating_add((10_198_000 as Weight).saturating_mul(r as Weight)) + (51_570_000 as Weight) + // Standard Error: 74_000 + .saturating_add((9_529_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (55_411_000 as Weight) - // Standard Error: 148_000 - .saturating_add((22_916_000 as Weight).saturating_mul(r as Weight)) + (38_616_000 as Weight) + // Standard Error: 24_000 + .saturating_add((37_349_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (55_462_000 as Weight) - // Standard Error: 134_000 - .saturating_add((24_449_000 as Weight).saturating_mul(r as Weight)) + (38_576_000 as Weight) + // Standard Error: 17_000 + .saturating_add((38_351_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (54_114_000 as Weight) - // Standard Error: 18_000 - .saturating_add((26_214_000 as Weight).saturating_mul(r as Weight)) + (51_383_000 as Weight) + // Standard Error: 60_000 + .saturating_add((27_099_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (54_118_000 as Weight) - // Standard Error: 18_000 - .saturating_add((26_492_000 as Weight).saturating_mul(r as Weight)) + (38_218_000 as Weight) + // Standard Error: 28_000 + .saturating_add((41_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (54_119_000 as Weight) - // Standard Error: 304_000 - .saturating_add((18_424_000 as Weight).saturating_mul(r as Weight)) + (38_216_000 as Weight) + // Standard Error: 33_000 + .saturating_add((28_483_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (55_352_000 as Weight) - // Standard Error: 13_000 - .saturating_add((32_291_000 as Weight).saturating_mul(r as Weight)) + (51_637_000 as Weight) + // Standard Error: 56_000 + .saturating_add((34_688_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (54_115_000 as Weight) - // Standard Error: 16_000 - .saturating_add((27_785_000 as Weight).saturating_mul(r as Weight)) + (51_490_000 as Weight) + // Standard Error: 71_000 + .saturating_add((27_683_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (86_048_000 as Weight) - // Standard Error: 1_000 - .saturating_add((82_000 as Weight).saturating_mul(e as Weight)) + (77_260_000 as Weight) + // Standard Error: 2_000 + .saturating_add((130_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (54_654_000 as Weight) - // Standard Error: 82_000 - .saturating_add((199_159_000 as Weight).saturating_mul(r as Weight)) + (52_012_000 as Weight) + // Standard Error: 564_000 + .saturating_add((188_018_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (67_478_000 as Weight) - // Standard Error: 113_000 - .saturating_add((302_597_000 as Weight).saturating_mul(r as Weight)) + (65_670_000 as Weight) + // Standard Error: 5_489_000 + .saturating_add((294_560_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (384_281_000 as Weight) - // Standard Error: 13_000 - .saturating_add((9_984_000 as Weight).saturating_mul(p as Weight)) + (368_428_000 as Weight) + // Standard Error: 26_000 + .saturating_add((10_469_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (55_473_000 as Weight) - // Standard Error: 16_000 - .saturating_add((9_287_000 as Weight).saturating_mul(r as Weight)) + (52_091_000 as Weight) + // Standard Error: 32_000 + .saturating_add((11_160_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (55_426_000 as Weight) - // Standard Error: 38_000 - .saturating_add((10_559_000 as Weight).saturating_mul(r as Weight)) + (52_145_000 as Weight) + // Standard Error: 18_000 + .saturating_add((12_086_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (55_332_000 as Weight) - // Standard Error: 8_000 - .saturating_add((15_640_000 as Weight).saturating_mul(r as Weight)) + (52_057_000 as Weight) + // Standard Error: 26_000 + .saturating_add((2_555_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (74_497_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_067_000 as Weight).saturating_mul(r as Weight)) + (73_126_000 as Weight) + // Standard Error: 35_000 + .saturating_add((16_004_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (74_445_000 as Weight) - // Standard Error: 49_000 - .saturating_add((17_650_000 as Weight).saturating_mul(r as Weight)) + (73_104_000 as Weight) + // Standard Error: 63_000 + .saturating_add((2_267_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (54_500_000 as Weight) - // Standard Error: 17_000 - .saturating_add((9_307_000 as Weight).saturating_mul(r as Weight)) + (38_596_000 as Weight) + // Standard Error: 27_000 + .saturating_add((22_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (54_382_000 as Weight) - // Standard Error: 5_644_000 - .saturating_add((748_424_000 as Weight).saturating_mul(r as Weight)) + (39_320_000 as Weight) + // Standard Error: 4_805_000 + .saturating_add((642_459_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (54_133_000 as Weight) - // Standard Error: 20_000 - .saturating_add((15_830_000 as Weight).saturating_mul(r as Weight)) + (51_634_000 as Weight) + // Standard Error: 65_000 + .saturating_add((14_706_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (54_129_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_894_000 as Weight).saturating_mul(r as Weight)) + (51_490_000 as Weight) + // Standard Error: 63_000 + .saturating_add((14_759_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (54_181_000 as Weight) - // Standard Error: 22_000 - .saturating_add((15_847_000 as Weight).saturating_mul(r as Weight)) + (51_278_000 as Weight) + // Standard Error: 37_000 + .saturating_add((15_084_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (54_130_000 as Weight) - // Standard Error: 17_000 - .saturating_add((15_825_000 as Weight).saturating_mul(r as Weight)) + (51_524_000 as Weight) + // Standard Error: 53_000 + .saturating_add((14_801_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (54_122_000 as Weight) - // Standard Error: 19_000 - .saturating_add((15_803_000 as Weight).saturating_mul(r as Weight)) + (50_775_000 as Weight) + // Standard Error: 88_000 + .saturating_add((3_125_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (54_100_000 as Weight) - // Standard Error: 28_000 - .saturating_add((15_822_000 as Weight).saturating_mul(r as Weight)) + (50_748_000 as Weight) + // Standard Error: 191_000 + .saturating_add((3_785_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (54_143_000 as Weight) - // Standard Error: 19_000 - .saturating_add((15_868_000 as Weight).saturating_mul(r as Weight)) + (52_621_000 as Weight) + // Standard Error: 60_000 + .saturating_add((13_744_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (54_133_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_121_000 as Weight).saturating_mul(r as Weight)) + (51_486_000 as Weight) + // Standard Error: 71_000 + .saturating_add((21_786_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (54_177_000 as Weight) - // Standard Error: 14_000 - .saturating_add((21_003_000 as Weight).saturating_mul(r as Weight)) + (51_573_000 as Weight) + // Standard Error: 73_000 + .saturating_add((21_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (54_164_000 as Weight) - // Standard Error: 31_000 - .saturating_add((21_041_000 as Weight).saturating_mul(r as Weight)) + (51_445_000 as Weight) + // Standard Error: 24_000 + .saturating_add((21_838_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (54_171_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_101_000 as Weight).saturating_mul(r as Weight)) + (51_609_000 as Weight) + // Standard Error: 61_000 + .saturating_add((21_766_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (54_177_000 as Weight) - // Standard Error: 12_000 - .saturating_add((21_074_000 as Weight).saturating_mul(r as Weight)) + (51_374_000 as Weight) + // Standard Error: 73_000 + .saturating_add((22_062_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (54_073_000 as Weight) - // Standard Error: 13_000 - .saturating_add((21_136_000 as Weight).saturating_mul(r as Weight)) + (51_451_000 as Weight) + // Standard Error: 52_000 + .saturating_add((21_918_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (54_116_000 as Weight) - // Standard Error: 17_000 - .saturating_add((21_140_000 as Weight).saturating_mul(r as Weight)) + (51_276_000 as Weight) + // Standard Error: 30_000 + .saturating_add((22_040_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (54_115_000 as Weight) - // Standard Error: 21_000 - .saturating_add((21_164_000 as Weight).saturating_mul(r as Weight)) + (51_401_000 as Weight) + // Standard Error: 46_000 + .saturating_add((21_886_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (54_261_000 as Weight) - // Standard Error: 123_000 - .saturating_add((20_921_000 as Weight).saturating_mul(r as Weight)) + (51_480_000 as Weight) + // Standard Error: 35_000 + .saturating_add((21_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (54_090_000 as Weight) - // Standard Error: 38_000 - .saturating_add((21_171_000 as Weight).saturating_mul(r as Weight)) + (51_771_000 as Weight) + // Standard Error: 63_000 + .saturating_add((21_607_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (54_129_000 as Weight) - // Standard Error: 27_000 - .saturating_add((21_086_000 as Weight).saturating_mul(r as Weight)) + (51_506_000 as Weight) + // Standard Error: 62_000 + .saturating_add((21_743_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (54_126_000 as Weight) - // Standard Error: 11_000 - .saturating_add((21_051_000 as Weight).saturating_mul(r as Weight)) + (51_456_000 as Weight) + // Standard Error: 68_000 + .saturating_add((21_916_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (54_153_000 as Weight) - // Standard Error: 22_000 - .saturating_add((21_021_000 as Weight).saturating_mul(r as Weight)) + (52_595_000 as Weight) + // Standard Error: 31_000 + .saturating_add((20_604_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (54_168_000 as Weight) - // Standard Error: 19_000 - .saturating_add((27_336_000 as Weight).saturating_mul(r as Weight)) + (51_575_000 as Weight) + // Standard Error: 101_000 + .saturating_add((28_754_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (54_124_000 as Weight) - // Standard Error: 22_000 - .saturating_add((24_783_000 as Weight).saturating_mul(r as Weight)) + (51_396_000 as Weight) + // Standard Error: 57_000 + .saturating_add((26_422_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (54_203_000 as Weight) - // Standard Error: 21_000 - .saturating_add((27_539_000 as Weight).saturating_mul(r as Weight)) + (51_575_000 as Weight) + // Standard Error: 58_000 + .saturating_add((29_376_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (54_176_000 as Weight) - // Standard Error: 19_000 - .saturating_add((24_686_000 as Weight).saturating_mul(r as Weight)) + (51_649_000 as Weight) + // Standard Error: 73_000 + .saturating_add((26_067_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (54_111_000 as Weight) - // Standard Error: 356_000 - .saturating_add((22_077_000 as Weight).saturating_mul(r as Weight)) + (51_641_000 as Weight) + // Standard Error: 69_000 + .saturating_add((21_615_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (54_124_000 as Weight) - // Standard Error: 15_000 - .saturating_add((21_060_000 as Weight).saturating_mul(r as Weight)) + (51_246_000 as Weight) + // Standard Error: 35_000 + .saturating_add((22_115_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (54_153_000 as Weight) - // Standard Error: 24_000 - .saturating_add((21_064_000 as Weight).saturating_mul(r as Weight)) + (51_413_000 as Weight) + // Standard Error: 64_000 + .saturating_add((21_917_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (54_122_000 as Weight) - // Standard Error: 23_000 - .saturating_add((21_187_000 as Weight).saturating_mul(r as Weight)) + (51_315_000 as Weight) + // Standard Error: 35_000 + .saturating_add((22_099_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (54_149_000 as Weight) - // Standard Error: 18_000 - .saturating_add((21_110_000 as Weight).saturating_mul(r as Weight)) + (51_504_000 as Weight) + // Standard Error: 66_000 + .saturating_add((21_901_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (54_136_000 as Weight) - // Standard Error: 13_000 - .saturating_add((21_066_000 as Weight).saturating_mul(r as Weight)) + (51_487_000 as Weight) + // Standard Error: 68_000 + .saturating_add((21_941_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (54_231_000 as Weight) - // Standard Error: 30_000 - .saturating_add((21_073_000 as Weight).saturating_mul(r as Weight)) + (51_893_000 as Weight) + // Standard Error: 59_000 + .saturating_add((21_505_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (54_139_000 as Weight) - // Standard Error: 17_000 - .saturating_add((21_097_000 as Weight).saturating_mul(r as Weight)) + (51_307_000 as Weight) + // Standard Error: 65_000 + .saturating_add((22_056_000 as Weight).saturating_mul(r as Weight)) } }