From e5ea4584cd85ec425b2ea89bce1f62db4e89652d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 23 Mar 2021 10:50:49 +0100 Subject: [PATCH 01/11] Move `Schedule` from Storage to Config --- bin/node/cli/src/chain_spec.rs | 13 +- bin/node/runtime/src/lib.rs | 10 +- bin/node/testing/src/genesis.rs | 5 +- bin/utils/chain-spec-builder/src/main.rs | 3 - frame/contracts/README.md | 13 +- frame/contracts/common/src/lib.rs | 26 +- frame/contracts/fixtures/caller_contract.wat | 1 - .../fixtures/debug_message_invalid_utf8.wat | 18 + .../debug_message_logging_disabled.wat | 28 + .../fixtures/debug_message_works.wat | 28 + frame/contracts/src/benchmarking/code.rs | 7 +- frame/contracts/src/benchmarking/mod.rs | 93 +- frame/contracts/src/exec.rs | 182 +- frame/contracts/src/lib.rs | 160 +- frame/contracts/src/migration.rs | 31 +- frame/contracts/src/schedule.rs | 81 +- frame/contracts/src/tests.rs | 147 +- frame/contracts/src/wasm/code_cache.rs | 4 +- frame/contracts/src/wasm/mod.rs | 79 + frame/contracts/src/wasm/prepare.rs | 42 +- frame/contracts/src/wasm/runtime.rs | 52 +- frame/contracts/src/weights.rs | 1460 +++++++++-------- 22 files changed, 1435 insertions(+), 1048 deletions(-) create mode 100644 frame/contracts/fixtures/debug_message_invalid_utf8.wat create mode 100644 frame/contracts/fixtures/debug_message_logging_disabled.wat create mode 100644 frame/contracts/fixtures/debug_message_works.wat diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 96888bd4ce1ed..d46a7797a702f 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -22,7 +22,7 @@ use sc_chain_spec::ChainSpecExtension; use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ - AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, + AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, CouncilConfig, DemocracyConfig, GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, wasm_binary_unwrap, MAX_NOMINATIONS, @@ -146,7 +146,7 @@ fn staging_testnet_config_genesis() -> GenesisConfig { let endowed_accounts: Vec = vec![root_key.clone()]; - testnet_genesis(initial_authorities, vec![], root_key, Some(endowed_accounts), false) + testnet_genesis(initial_authorities, vec![], root_key, Some(endowed_accounts)) } /// Staging testnet config. @@ -212,7 +212,6 @@ pub fn testnet_genesis( initial_nominators: Vec, root_key: AccountId, endowed_accounts: Option>, - enable_println: bool, ) -> GenesisConfig { let mut endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { vec![ @@ -308,11 +307,6 @@ pub fn testnet_genesis( .collect(), phantom: Default::default(), }, - pallet_contracts: ContractsConfig { - // println should only be enabled on development chains - current_schedule: pallet_contracts::Schedule::default() - .enable_println(enable_println), - }, pallet_sudo: SudoConfig { key: root_key, }, @@ -352,7 +346,6 @@ fn development_config_genesis() -> GenesisConfig { vec![], get_account_id_from_seed::("Alice"), None, - true, ) } @@ -380,7 +373,6 @@ fn local_testnet_genesis() -> GenesisConfig { vec![], get_account_id_from_seed::("Alice"), None, - false, ) } @@ -414,7 +406,6 @@ pub(crate) mod tests { vec![], get_account_id_from_seed::("Alice"), None, - false, ) } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 05f75b14b9603..cee51a63a2cfc 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -793,6 +793,7 @@ parameter_types! { ::WeightInfo::on_initialize_per_queue_item(0) )) / 5) as u32; pub MaxCodeSize: u32 = 128 * 1024; + pub Schedule: pallet_contracts::Schedule = Default::default(); } impl pallet_contracts::Config for Runtime { @@ -809,13 +810,12 @@ impl pallet_contracts::Config for Runtime { type RentFraction = RentFraction; type SurchargeReward = SurchargeReward; type CallStack = [pallet_contracts::Frame; 31]; - type MaxValueSize = MaxValueSize; type WeightPrice = pallet_transaction_payment::Module; type WeightInfo = pallet_contracts::weights::SubstrateWeight; type ChainExtension = (); type DeletionQueueDepth = DeletionQueueDepth; type DeletionWeightLimit = DeletionWeightLimit; - type MaxCodeSize = MaxCodeSize; + type Schedule = Schedule; } impl pallet_sudo::Config for Runtime { @@ -1113,7 +1113,7 @@ construct_runtime!( TechnicalMembership: pallet_membership::::{Pallet, Call, Storage, Event, Config}, Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned}, Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - Contracts: pallet_contracts::{Pallet, Call, Config, Storage, Event}, + Contracts: pallet_contracts::{Pallet, Call, Storage, Event}, Sudo: pallet_sudo::{Pallet, Call, Config, Storage, Event}, ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config}, AuthorityDiscovery: pallet_authority_discovery::{Pallet, Call, Config}, @@ -1353,7 +1353,7 @@ impl_runtime_apis! { gas_limit: u64, input_data: Vec, ) -> pallet_contracts_primitives::ContractExecResult { - Contracts::bare_call(origin, dest, value, gas_limit, input_data) + Contracts::bare_call(origin, dest, value, gas_limit, input_data, true) } fn instantiate( @@ -1365,7 +1365,7 @@ impl_runtime_apis! { salt: Vec, ) -> pallet_contracts_primitives::ContractInstantiateResult { - Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true) + Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true, true) } fn get_storage( diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 25b728ebe193e..905c2f4d70bb2 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -22,7 +22,7 @@ use crate::keyring::*; use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, wasm_binary_unwrap, + GrandpaConfig, IndicesConfig, SocietyConfig, wasm_binary_unwrap, AccountId, StakerStatus, BabeConfig, BABE_GENESIS_EPOCH_CONFIG, }; use node_runtime::constants::currency::*; @@ -97,9 +97,6 @@ pub fn config_endowed( invulnerables: vec![alice(), bob(), charlie()], .. Default::default() }, - pallet_contracts: ContractsConfig { - current_schedule: Default::default(), - }, pallet_babe: BabeConfig { authorities: vec![], epoch_config: Some(BABE_GENESIS_EPOCH_CONFIG), diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index 2aaef7c96d9ab..a3f8eaa1f8547 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -106,14 +106,11 @@ fn genesis_constructor( .map(chain_spec::authority_keys_from_seed) .collect::>(); - let enable_println = true; - chain_spec::testnet_genesis( authorities, nominator_accounts.to_vec(), sudo_account.clone(), Some(endowed_accounts.to_vec()), - enable_println, ) } diff --git a/frame/contracts/README.md b/frame/contracts/README.md index 6c987165990b8..5d34a35fc10db 100644 --- a/frame/contracts/README.md +++ b/frame/contracts/README.md @@ -59,17 +59,10 @@ writing WebAssembly based smart contracts in the Rust programming language. ## Debugging -Contracts can emit messages to the node console when run on a development chain through the -`seal_println` API. This is exposed in ink! via +Contracts can emit messages to the client when called as RPC through the `seal_debug_message` +API. This is exposed in ink! via [`ink_env::debug_println()`](https://docs.rs/ink_env/latest/ink_env/fn.debug_println.html). -In order to see these messages the log level for the `runtime::contracts` target needs to be raised -to at least the `info` level which is the default. However, those messages are easy to overlook -because of the noise generated by block production. A good starting point for contract debugging -could be: - -```bash -cargo run --release -- --dev --tmp -lerror,runtime::contracts -``` +It is up the the individual client if and how those messages are presented to the user. License: Apache-2.0 diff --git a/frame/contracts/common/src/lib.rs b/frame/contracts/common/src/lib.rs index 17d4bec06b7cf..6d8168de4ed79 100644 --- a/frame/contracts/common/src/lib.rs +++ b/frame/contracts/common/src/lib.rs @@ -37,18 +37,18 @@ use serde::{Serialize, Deserialize}; pub struct ContractResult { /// How much gas was consumed during execution. pub gas_consumed: u64, - /// An optional debug message. This message is only non-empty when explicitly requested - /// by the code that calls into the contract. + /// An optional debug message. This message is only filled when explicitly requested + /// by the code that calls into the contract. Otherwise it is empty. /// /// The contained bytes are valid UTF-8. This is not declared as `String` because - /// this type is not allowed within the runtime. A client should decode them in order - /// to present the message to its users. + /// this type is not allowed within the runtime. /// /// # Note /// /// The debug message is never generated during on-chain execution. It is reserved for /// RPC calls. - pub debug_message: Bytes, + #[cfg_attr(feature = "std", serde(with = "as_string"))] + pub debug_message: Vec, /// The execution result of the wasm code. pub result: T, } @@ -146,3 +146,19 @@ pub enum Code { /// The code hash of an on-chain wasm blob. Existing(Hash), } + +#[cfg(feature = "std")] +mod as_string { + use super::*; + use serde::{Serializer, Deserializer, ser::Error}; + + pub fn serialize(bytes: &Vec, serializer: S) -> Result { + std::str::from_utf8(bytes) + .map_err(|e| S::Error::custom(format!("Debug buffer contains invalid UTF8: {}", e)))? + .serialize(serializer) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + Ok(String::deserialize(deserializer)?.into_bytes()) + } +} diff --git a/frame/contracts/fixtures/caller_contract.wat b/frame/contracts/fixtures/caller_contract.wat index d6564117b721f..9c7cdf62abfc9 100644 --- a/frame/contracts/fixtures/caller_contract.wat +++ b/frame/contracts/fixtures/caller_contract.wat @@ -5,7 +5,6 @@ (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) )) - (import "seal0" "seal_println" (func $seal_println (param i32 i32))) (import "env" "memory" (memory 1 1)) (func $assert (param i32) diff --git a/frame/contracts/fixtures/debug_message_invalid_utf8.wat b/frame/contracts/fixtures/debug_message_invalid_utf8.wat new file mode 100644 index 0000000000000..c60371076440e --- /dev/null +++ b/frame/contracts/fixtures/debug_message_invalid_utf8.wat @@ -0,0 +1,18 @@ +;; Emit a "Hello World!" debug message +(module + (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (data (i32.const 0) "\fc") + + (func (export "call") + (call $seal_debug_message + (i32.const 0) ;; Pointer to the text buffer + (i32.const 12) ;; The size of the buffer + ) + ;; the above call traps because we supplied invalid utf8 + unreachable + ) + + (func (export "deploy")) +) diff --git a/frame/contracts/fixtures/debug_message_logging_disabled.wat b/frame/contracts/fixtures/debug_message_logging_disabled.wat new file mode 100644 index 0000000000000..9ae2ff439125e --- /dev/null +++ b/frame/contracts/fixtures/debug_message_logging_disabled.wat @@ -0,0 +1,28 @@ +;; Emit a "Hello World!" debug message but assume that logging is disabled. +(module + (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (data (i32.const 0) "Hello World!") + + (func $assert_eq (param i32 i32) + (block $ok + (br_if $ok + (i32.eq (get_local 0) (get_local 1)) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $assert_eq + (call $seal_debug_message + (i32.const 0) ;; Pointer to the text buffer + (i32.const 12) ;; The size of the buffer + ) + (i32.const 9) + ) + ) + + (func (export "deploy")) +) diff --git a/frame/contracts/fixtures/debug_message_works.wat b/frame/contracts/fixtures/debug_message_works.wat new file mode 100644 index 0000000000000..1d3009e97a4dc --- /dev/null +++ b/frame/contracts/fixtures/debug_message_works.wat @@ -0,0 +1,28 @@ +;; Emit a "Hello World!" debug message +(module + (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (data (i32.const 0) "Hello World!") + + (func $assert_eq (param i32 i32) + (block $ok + (br_if $ok + (i32.eq (get_local 0) (get_local 1)) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $assert_eq + (call $seal_debug_message + (i32.const 0) ;; Pointer to the text buffer + (i32.const 12) ;; The size of the buffer + ) + (i32.const 0) + ) + ) + + (func (export "deploy")) +) diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index 74c678f548741..811ba71bdea7f 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -24,7 +24,7 @@ //! we define this simple definition of a contract that can be passed to `create_code` that //! compiles it down into a `WasmModule` that can be used as a contract's code. -use crate::{Config, CurrentSchedule}; +use crate::Config; use parity_wasm::elements::{ Instruction, Instructions, FuncBody, ValueType, BlockType, Section, CustomSection, }; @@ -33,6 +33,7 @@ use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::Hash; use sp_sandbox::{EnvironmentDefinitionBuilder, Memory}; use sp_std::{prelude::*, convert::TryFrom, borrow::ToOwned}; +use frame_support::traits::Get; /// Pass to `create_code` in order to create a compiled `WasmModule`. /// @@ -223,7 +224,7 @@ where if def.inject_stack_metering { code = inject_limiter( code, - >::get().limits.stack_height + T::Schedule::get().limits.stack_height ) .unwrap(); } @@ -503,5 +504,5 @@ where T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { - >::get().limits.memory_pages + T::Schedule::get().limits.memory_pages } diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index 107f35e610813..cab80d63bbce0 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -290,7 +290,7 @@ benchmarks! { on_initialize_per_trie_key { let k in 0..1024; - let instance = ContractWithStorage::::new(k, T::MaxValueSize::get())?; + let instance = ContractWithStorage::::new(k, T::Schedule::get().limits.payload_len)?; Storage::::queue_trie_for_deletion(&instance.contract.alive_info()?)?; }: { Storage::::process_deletion_queue_batch(Weight::max_value()) @@ -311,23 +311,15 @@ benchmarks! { // first time after a new schedule was deployed: For every new schedule a contract needs // to re-run the instrumentation once. instrument { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let WasmModule { code, hash, .. } = WasmModule::::sized(c * 1024); Contracts::::store_code_raw(code)?; let mut module = PrefabWasmModule::from_storage_noinstr(hash)?; - let schedule = >::get(); + let schedule = T::Schedule::get(); }: { Contracts::::reinstrument_module(&mut module, &schedule)?; } - // This extrinsic is pretty much constant as it is only a simple setter. - update_schedule { - let schedule = Schedule { - version: 1, - .. Default::default() - }; - }: _(RawOrigin::Root, schedule) - // This constructs a contract that is maximal expensive to instrument. // It creates a maximum number of metering blocks per byte. // The size of the salt influences the runtime because is is hashed in order to @@ -340,7 +332,7 @@ benchmarks! { // We cannot let `c` grow to the maximum code size because the code is not allowed // to be larger than the maximum size **after instrumentation**. instantiate_with_code { - let c in 0 .. Perbill::from_percent(50).mul_ceil(T::MaxCodeSize::get() / 1024); + 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(); @@ -363,7 +355,7 @@ benchmarks! { // `c`: Size of the code in kilobytes. // `s`: Size of the salt in kilobytes. instantiate { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let s in 0 .. code::max_pages::() * 64; let salt = vec![42u8; (s * 1024) as usize]; let endowment = caller_funding::() / 3u32.into(); @@ -390,7 +382,7 @@ benchmarks! { // part of `seal_input`. // `c`: Size of the code in kilobytes. call { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let data = vec![42u8; 1024]; let instance = Contract::::with_caller( whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent @@ -423,7 +415,7 @@ benchmarks! { // the reward for removing them. // `c`: Size of the code of the contract that should be evicted. claim_surcharge { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let 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 )?; @@ -730,7 +722,7 @@ benchmarks! { } seal_terminate_per_code_kb { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let beneficiary = account::("beneficiary", 0, 0); let beneficiary_bytes = beneficiary.encode(); let beneficiary_len = beneficiary_bytes.len(); @@ -771,7 +763,7 @@ benchmarks! { // 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::MaxValueSize::get())?; + let mut tombstone = ContractWithStorage::::new(10, T::Schedule::get().limits.payload_len)?; tombstone.evict()?; let dest = tombstone.contract.account_id.encode(); @@ -847,14 +839,14 @@ benchmarks! { // `t`: Code size of tombstone contract // `d`: Number of supplied delta keys seal_restore_to_per_code_kb_delta { - let c in 0 .. T::MaxCodeSize::get() / 1024; - let t in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; + let t in 0 .. T::Schedule::get().limits.code_len / 1024; let d in 0 .. API_BENCHMARK_BATCHES; let mut tombstone = ContractWithStorage::::with_code( WasmModule::::dummy_with_bytes(t * 1024), 0, 0 )?; tombstone.evict()?; - let delta = create_storage::(d * API_BENCHMARK_BATCH_SIZE, T::MaxValueSize::get())?; + 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(); @@ -938,7 +930,7 @@ benchmarks! { seal_random { let r in 0 .. API_BENCHMARK_BATCHES; let pages = code::max_pages::(); - let subject_len = >::get().limits.subject_len; + let subject_len = T::Schedule::get().limits.subject_len; assert!(subject_len < 1024); let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), @@ -994,8 +986,8 @@ benchmarks! { // `t`: Number of topics // `n`: Size of event payload in kb seal_deposit_event_per_topic_and_kb { - let t in 0 .. >::get().limits.event_topics; - let n in 0 .. T::MaxValueSize::get() / 1024; + let t in 0 .. T::Schedule::get().limits.event_topics; + let n in 0 .. T::Schedule::get().limits.payload_len / 1024; let mut topics = (0..API_BENCHMARK_BATCH_SIZE) .map(|n| (n * t..n * t + t).map(|i| T::Hashing::hash_of(&i)).collect::>().encode()) .peekable(); @@ -1055,6 +1047,31 @@ benchmarks! { let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) + // The size of the supplied message does not influence the weight because as it is never + // processed during on-chain execution: It is only ever read during debugging which happens + // when the contract is called as RPC where weights do not matter. + seal_debug_message { + let r in 0 .. API_BENCHMARK_BATCHES; + let max_bytes = code::max_pages::() * 64 * 1024; + let code = WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory { min_pages: 1, max_pages: 1 }), + imported_functions: vec![ImportedFunction { + name: "seal_debug_message", + params: vec![ValueType::I32, ValueType::I32], + return_type: Some(ValueType::I32), + }], + call_body: Some(body::repeated(r * API_BENCHMARK_BATCH_SIZE, &[ + Instruction::I32Const(0), // value_ptr + Instruction::I32Const(max_bytes as i32), // value_len + Instruction::Call(0), + Instruction::Drop, + ])), + .. 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![]) + // Only the overhead of calling the function itself with minimal arguments. // The contract is a bit more complex because I needs to use different keys in order // to generate unique storage accesses. However, it is still dominated by the storage @@ -1091,7 +1108,7 @@ benchmarks! { }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) seal_set_storage_per_kb { - let n in 0 .. T::MaxValueSize::get() / 1024; + let n in 0 .. T::Schedule::get().limits.payload_len / 1024; let key = T::Hashing::hash_of(&1u32).as_ref().to_vec(); let key_len = key.len(); let code = WasmModule::::from(ModuleDefinition { @@ -1155,7 +1172,7 @@ benchmarks! { >::block_number(), &mut info, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, - Some(vec![42; T::MaxValueSize::get() as usize]) + Some(vec![42; T::Schedule::get().limits.payload_len as usize]) ) .map_err(|_| "Failed to write to storage during setup.")?; } @@ -1210,7 +1227,7 @@ benchmarks! { }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) seal_get_storage_per_kb { - let n in 0 .. T::MaxValueSize::get() / 1024; + let n in 0 .. T::Schedule::get().limits.payload_len / 1024; let key = T::Hashing::hash_of(&1u32).as_ref().to_vec(); let key_len = key.len(); let code = WasmModule::::from(ModuleDefinition { @@ -1227,7 +1244,7 @@ benchmarks! { }, DataSegment { offset: key_len as u32, - value: T::MaxValueSize::get().to_le_bytes().into(), + value: T::Schedule::get().limits.payload_len.to_le_bytes().into(), }, ], call_body: Some(body::repeated(API_BENCHMARK_BATCH_SIZE, &[ @@ -1363,7 +1380,7 @@ benchmarks! { }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) seal_call_per_code_transfer_input_output_kb { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let t in 0 .. 1; let i in 0 .. code::max_pages::() * 64; let o in 0 .. (code::max_pages::() - 1) * 64; @@ -1560,7 +1577,7 @@ benchmarks! { } seal_instantiate_per_code_input_output_salt_kb { - let c in 0 .. T::MaxCodeSize::get() / 1024; + let c in 0 .. T::Schedule::get().limits.code_len / 1024; let i in 0 .. (code::max_pages::() - 1) * 64; let o in 0 .. (code::max_pages::() - 1) * 64; let s in 0 .. (code::max_pages::() - 1) * 64; @@ -1927,7 +1944,7 @@ benchmarks! { // w_br_table_per_entry = w_bench instr_br_table_per_entry { - let e in 1 .. >::get().limits.br_table_size; + let e in 1 .. T::Schedule::get().limits.br_table_size; let entry: Vec = [0, 1].iter() .cloned() .cycle() @@ -1983,7 +2000,7 @@ benchmarks! { // w_call_indrect = w_bench - 3 * w_param instr_call_indirect { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let num_elements = >::get().limits.table_size; + let num_elements = T::Schedule::get().limits.table_size; use self::code::TableSegment; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { // We need to make use of the stack here in order to trigger stack height @@ -2013,8 +2030,8 @@ benchmarks! { // linearly depend on the amount of parameters to this function. // Please note that this is not necessary with a direct call. instr_call_indirect_per_param { - let p in 0 .. >::get().limits.parameters; - let num_elements = >::get().limits.table_size; + let p in 0 .. T::Schedule::get().limits.parameters; + let num_elements = T::Schedule::get().limits.table_size; use self::code::TableSegment; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { // We need to make use of the stack here in order to trigger stack height @@ -2044,7 +2061,7 @@ benchmarks! { // w_local_get = w_bench - 1 * w_param instr_local_get { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let max_locals = >::get().limits.stack_height; + let max_locals = T::Schedule::get().limits.stack_height; let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ RandomGetLocal(0, max_locals), Regular(Instruction::Drop), @@ -2061,7 +2078,7 @@ benchmarks! { // w_local_set = w_bench - 1 * w_param instr_local_set { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let max_locals = >::get().limits.stack_height; + let max_locals = T::Schedule::get().limits.stack_height; let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ RandomI64Repeated(1), RandomSetLocal(0, max_locals), @@ -2078,7 +2095,7 @@ benchmarks! { // w_local_tee = w_bench - 2 * w_param instr_local_tee { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let max_locals = >::get().limits.stack_height; + let max_locals = T::Schedule::get().limits.stack_height; let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ RandomI64Repeated(1), RandomTeeLocal(0, max_locals), @@ -2096,7 +2113,7 @@ benchmarks! { // w_global_get = w_bench - 1 * w_param instr_global_get { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let max_globals = >::get().limits.globals; + let max_globals = T::Schedule::get().limits.globals; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ RandomGetGlobal(0, max_globals), @@ -2112,7 +2129,7 @@ benchmarks! { // w_global_set = w_bench - 1 * w_param instr_global_set { let r in 0 .. INSTR_BENCHMARK_BATCHES; - let max_globals = >::get().limits.globals; + let max_globals = T::Schedule::get().limits.globals; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ RandomI64Repeated(1), diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index eea6acf1bfb4e..149e28780b2d9 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -315,6 +315,16 @@ pub trait Ext: sealing::Sealed { /// Get a mutable reference to the nested gas meter. fn gas_meter(&mut self) -> &mut GasMeter; + + /// Append a string to the debug buffer. + /// + /// It is added as-is without any additional new line. + /// + /// This is a no-op if debug message recording is disabled which is always the case + /// when the code is executing on-chain. + /// + /// Returns `true` if debug message recording is disabled. Otherwise `false` is returned. + fn append_debug_buffer(&mut self, msg: &str) -> bool; } /// Describes the different functions that can be exported by an [`Executable`]. @@ -434,6 +444,11 @@ pub struct Stack<'a, T: Config, E> { frames: SmallVec, /// Statically guarantee that each call stack has at least one frame. first_frame: Frame, + /// A text buffer used to output human readable information. + /// + /// All the bytes added to this field should be valid UTF-8. The buffer has no defined + /// structure and is intended to be shown to users as-is for debugging purposes. + debug_message: Option<&'a mut Vec>, /// No executable is held by the struct but influences its behaviour. _phantom: PhantomData, } @@ -442,6 +457,11 @@ pub struct Stack<'a, T: Config, E> { /// /// For each nested contract call or instantiate one frame is created. It holds specific /// information for the said call and caches the in-storage `ContractInfo` data structure. +/// +/// # Note +/// +/// This is an internal data structure. It is exposed to the public for the sole reason +/// of specifying [`Config::CallStack`]. pub struct Frame { /// The account id of the executing contract. account_id: T::AccountId, @@ -574,6 +594,11 @@ where { /// Create an run a new call stack by calling into `dest`. /// + /// # Note + /// + /// `debug_message` should only ever be set to `Some` when executing as an RPC because + /// it adds allocations and could be abused to drive the runtime into an OOM panic. + /// /// # Return Value /// /// Result<(ExecReturnValue, CodeSize), (ExecError, CodeSize)> @@ -584,6 +609,7 @@ where schedule: &'a Schedule, value: BalanceOf, input_data: Vec, + debug_message: Option<&'a mut Vec>, ) -> Result<(ExecReturnValue, u32), (ExecError, u32)> { let (mut stack, executable) = Self::new( FrameArgs::Call{dest, cached_info: None}, @@ -591,12 +617,18 @@ where gas_meter, schedule, value, + debug_message, )?; stack.run(executable, input_data) } /// Create and run a new call stack by instantiating a new contract. /// + /// # Note + /// + /// `debug_message` should only ever be set to `Some` when executing as an RPC because + /// it adds allocations and could be abused to drive the runtime into an OOM panic. + /// /// # Return Value /// /// Result<(NewContractAccountId, ExecReturnValue), ExecError)> @@ -608,6 +640,7 @@ where value: BalanceOf, input_data: Vec, salt: &[u8], + debug_message: Option<&'a mut Vec>, ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { let (mut stack, executable) = Self::new( FrameArgs::Instantiate { @@ -620,6 +653,7 @@ where gas_meter, schedule, value, + debug_message, ).map_err(|(e, _code_len)| e)?; let account_id = stack.top_frame().account_id.clone(); stack.run(executable, input_data) @@ -634,6 +668,7 @@ where gas_meter: &'a mut GasMeter, schedule: &'a Schedule, value: BalanceOf, + debug_message: Option<&'a mut Vec>, ) -> Result<(Self, E), (ExecError, u32)> { let (first_frame, executable) = Self::new_frame(args, value, gas_meter, 0, &schedule)?; let stack = Self { @@ -645,6 +680,7 @@ where account_counter: None, first_frame, frames: Default::default(), + debug_message, _phantom: Default::default(), }; @@ -1181,7 +1217,7 @@ where fn block_number(&self) -> T::BlockNumber { self.block_number } fn max_value_size(&self) -> u32 { - T::MaxValueSize::get() + T::Schedule::get().limits.payload_len } fn get_weight_price(&self, weight: Weight) -> BalanceOf { @@ -1199,6 +1235,17 @@ where fn gas_meter(&mut self) -> &mut GasMeter { &mut self.top_frame_mut().nested_meter } + + fn append_debug_buffer(&mut self, msg: &str) -> bool { + if let Some(buffer) = &mut self.debug_message { + if !msg.is_empty() { + buffer.extend(msg.as_bytes()); + } + true + } else { + false + } + } } fn deposit_event( @@ -1241,7 +1288,7 @@ mod tests { test_utils::{place_contract, set_balance, get_balance}, }, exec::ExportedFunction::*, - Error, Weight, CurrentSchedule, + Error, Weight, }; use sp_core::Bytes; use sp_runtime::DispatchError; @@ -1436,12 +1483,12 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, exec_ch); assert_matches!( MockStack::run_call( - ALICE, BOB, &mut gas_meter, &schedule, value, vec![], + ALICE, BOB, &mut gas_meter, &schedule, value, vec![], None, ), Ok(_) ); @@ -1487,7 +1534,7 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, return_ch); set_balance(&origin, 100); let balance = get_balance(&dest); @@ -1499,6 +1546,7 @@ mod tests { &schedule, 55, vec![], + None, ).unwrap(); assert!(!output.0.is_success()); @@ -1548,7 +1596,7 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, return_ch); let result = MockStack::run_call( @@ -1558,6 +1606,7 @@ mod tests { &schedule, 0, vec![], + None, ); let output = result.unwrap(); @@ -1578,8 +1627,8 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); - place_contract(&dest, return_ch); + let schedule = ::Schedule::get(); + place_contract(&BOB, return_ch); let result = MockStack::run_call( origin, @@ -1588,6 +1637,7 @@ mod tests { &schedule, 0, vec![], + None, ); let output = result.unwrap(); @@ -1605,7 +1655,7 @@ mod tests { // This one tests passing the input data into a contract via call. ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, input_data_ch); let result = MockStack::run_call( @@ -1615,6 +1665,7 @@ mod tests { &schedule, 0, vec![1, 2, 3, 4], + None, ); assert_matches!(result, Ok(_)); }); @@ -1629,7 +1680,7 @@ mod tests { // This one tests passing the input data into a contract via instantiate. ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let subsistence = Contracts::::subsistence_threshold(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( @@ -1646,6 +1697,7 @@ mod tests { subsistence * 3, vec![1, 2, 3, 4], &[], + None, ); assert_matches!(result, Ok(_)); }); @@ -1683,7 +1735,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); set_balance(&BOB, 1); place_contract(&BOB, recurse_ch); @@ -1694,6 +1746,7 @@ mod tests { &schedule, value, vec![], + None, ); assert_matches!(result, Ok(_)); @@ -1732,7 +1785,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&dest, bob_ch); place_contract(&CHARLIE, charlie_ch); @@ -1743,6 +1796,7 @@ mod tests { &schedule, 0, vec![], + None, ); assert_matches!(result, Ok(_)); @@ -1771,7 +1825,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, bob_ch); place_contract(&CHARLIE, charlie_ch); @@ -1782,6 +1836,7 @@ mod tests { &schedule, 0, vec![], + None, ); assert_matches!(result, Ok(_)); @@ -1793,7 +1848,7 @@ mod tests { let dummy_ch = MockLoader::insert(Constructor, |_, _| exec_success()); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( dummy_ch, &schedule, &mut gas_meter @@ -1808,6 +1863,7 @@ mod tests { 0, // <- zero endowment vec![], &[], + None, ), Err(_) ); @@ -1822,7 +1878,7 @@ mod tests { ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( dummy_ch, &schedule, &mut gas_meter @@ -1838,6 +1894,7 @@ mod tests { 100, vec![], &[], + None, ), Ok((address, ref output)) if output.data == Bytes(vec![80, 65, 83, 83]) => address ); @@ -1859,7 +1916,7 @@ mod tests { ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( dummy_ch, &schedule, &mut gas_meter @@ -1875,6 +1932,7 @@ mod tests { 100, vec![], &[], + None, ), Ok((address, ref output)) if output.data == Bytes(vec![70, 65, 73, 76]) => address ); @@ -1908,13 +1966,13 @@ mod tests { }); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); set_balance(&ALICE, Contracts::::subsistence_threshold() * 100); place_contract(&BOB, instantiator_ch); assert_matches!( MockStack::run_call( - ALICE, BOB, &mut GasMeter::::new(GAS_LIMIT), &schedule, 20, vec![], + ALICE, BOB, &mut GasMeter::::new(GAS_LIMIT), &schedule, 20, vec![], None, ), Ok(_) ); @@ -1958,14 +2016,14 @@ mod tests { }); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); set_balance(&ALICE, 1000); set_balance(&BOB, 100); place_contract(&BOB, instantiator_ch); assert_matches!( MockStack::run_call( - ALICE, BOB, &mut GasMeter::::new(GAS_LIMIT), &schedule, 20, vec![], + ALICE, BOB, &mut GasMeter::::new(GAS_LIMIT), &schedule, 20, vec![], None, ), Ok(_) ); @@ -1987,7 +2045,7 @@ mod tests { .existential_deposit(15) .build() .execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( terminate_ch, &schedule, &mut gas_meter @@ -2003,6 +2061,7 @@ mod tests { 100, vec![], &[], + None, ), Err(Error::::TerminatedInConstructor.into()) ); @@ -2027,7 +2086,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let subsistence = Contracts::::subsistence_threshold(); - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( rent_allowance_ch, &schedule, &mut gas_meter @@ -2042,6 +2101,7 @@ mod tests { subsistence * 5, vec![], &[], + None, ); assert_matches!(result, Ok(_)); }); @@ -2060,7 +2120,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let subsistence = Contracts::::subsistence_threshold(); - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); set_balance(&ALICE, subsistence * 10); place_contract(&BOB, code_hash); @@ -2071,6 +2131,7 @@ mod tests { &schedule, 0, vec![], + None, ).unwrap(); }); } @@ -2109,7 +2170,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let subsistence = Contracts::::subsistence_threshold(); - let schedule = >::get(); + let schedule = ::Schedule::get(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); set_balance(&ALICE, subsistence * 100); place_contract(&BOB, code_hash); @@ -2120,6 +2181,7 @@ mod tests { &schedule, subsistence * 50, vec![], + None, ).unwrap(); }); } @@ -2156,7 +2218,7 @@ mod tests { // This one tests passing the input data into a contract via call. ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); place_contract(&BOB, code_bob); place_contract(&CHARLIE, code_charlie); @@ -2167,6 +2229,7 @@ mod tests { &schedule, 0, vec![0], + None, ); assert_matches!(result, Ok(_)); }); @@ -2174,10 +2237,9 @@ mod tests { #[test] fn recursive_call_during_constructor_fails() { - let code = MockLoader::insert(Constructor, |ctx, executable| { - let my_hash = >::contract_address(&ALICE, &executable.code_hash, &[]); + let code = MockLoader::insert(Constructor, |ctx, _| { assert_matches!( - ctx.ext.call(0, my_hash, 0, vec![]), + ctx.ext.call(0, ctx.ext.address().clone(), 0, vec![]), Err((ExecError{error, ..}, _)) if error == >::NotCallable.into() ); exec_success() @@ -2185,7 +2247,7 @@ mod tests { // This one tests passing the input data into a contract via instantiate. ExtBuilder::default().build().execute_with(|| { - let schedule = >::get(); + let schedule = ::Schedule::get(); let subsistence = Contracts::::subsistence_threshold(); let mut gas_meter = GasMeter::::new(GAS_LIMIT); let executable = MockExecutable::from_storage( @@ -2202,8 +2264,70 @@ mod tests { subsistence * 3, vec![], &[], + None, ); assert_matches!(result, Ok(_)); }); } + + #[test] + fn printing_works() { + let code_hash = MockLoader::insert(Call, |ctx, _| { + ctx.ext.append_debug_buffer("This is a test"); + ctx.ext.append_debug_buffer("More text"); + exec_success() + }); + + let mut debug_buffer = Vec::new(); + + 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![], + Some(&mut debug_buffer), + ).unwrap(); + }); + + assert_eq!(&String::from_utf8(debug_buffer).unwrap(), "This is a testMore text"); + } + + #[test] + fn printing_works_on_fail() { + let code_hash = MockLoader::insert(Call, |ctx, _| { + ctx.ext.append_debug_buffer("This is a test"); + ctx.ext.append_debug_buffer("More text"); + exec_trapped() + }); + + let mut debug_buffer = Vec::new(); + + 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); + let result = MockStack::run_call( + ALICE, + BOB, + &mut gas_meter, + &schedule, + 0, + vec![], + Some(&mut debug_buffer), + ); + assert!(result.is_err()); + }); + + assert_eq!(&String::from_utf8(debug_buffer).unwrap(), "This is a testMore text"); + } } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 33844a41cc7c7..67c5acee8f4a4 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -59,9 +59,6 @@ //! //! ### Dispatchable functions //! -//! * [`Pallet::update_schedule`] - -//! ([Root Origin](https://substrate.dev/docs/en/knowledgebase/runtime/origin) Only) - -//! Set a new [`Schedule`]. //! * [`Pallet::instantiate_with_code`] - Deploys a new contract from the supplied wasm binary, //! optionally transferring //! some balance. This instantiates a new smart contract account with the supplied code and @@ -160,6 +157,21 @@ pub mod pallet { /// 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>; + + /// Describes the weights of the dispatchables of this module and is also used to + /// construct a default cost schedule. + type WeightInfo: WeightInfo; + + /// Type that allows the runtime authors to add new host functions for a contract to call. + type ChainExtension: chain_extension::ChainExtension; + + /// Cost schedule and limits. + #[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 @@ -217,21 +229,6 @@ pub mod pallet { /// In other words only the origin called "root contract" is allowed to execute then. type CallStack: smallvec::Array>; - /// The maximum size of a storage value and event payload in bytes. - #[pallet::constant] - type MaxValueSize: Get; - - /// 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>; - - /// Describes the weights of the dispatchables of this module and is also used to - /// construct a default cost schedule. - type WeightInfo: WeightInfo; - - /// Type that allows the runtime authors to add new host functions for a contract to call. - type ChainExtension: chain_extension::ChainExtension; - /// The maximum number of tries that can be queued for deletion. #[pallet::constant] type DeletionQueueDepth: Get; @@ -239,12 +236,6 @@ pub mod pallet { /// The maximum amount of weight that can be consumed per block for lazy trie removal. #[pallet::constant] type DeletionWeightLimit: Get; - - /// The maximum length of a contract code in bytes. This limit applies to the instrumented - /// version of the code. Therefore `instantiate_with_code` can fail even when supplying - /// a wasm binary below this maximum size. - #[pallet::constant] - type MaxCodeSize: Get; } #[pallet::pallet] @@ -277,26 +268,6 @@ pub mod pallet { T::AccountId: UncheckedFrom, T::AccountId: AsRef<[u8]>, { - /// Updates the schedule for metering contracts. - /// - /// The schedule's version cannot be less than the version of the stored schedule. - /// If a schedule does not change the instruction weights the version does not - /// need to be increased. Therefore we allow storing a schedule that has the same - /// version as the stored one. - #[pallet::weight(T::WeightInfo::update_schedule())] - pub fn update_schedule( - origin: OriginFor, - schedule: Schedule - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - if >::get().version > schedule.version { - Err(Error::::InvalidScheduleVersion)? - } - Self::deposit_event(Event::ScheduleUpdated(schedule.version)); - CurrentSchedule::put(schedule); - Ok(().into()) - } - /// Makes a call to an account, optionally transferring some balance. /// /// * If the account is a smart-contract account, the associated code will be @@ -304,7 +275,9 @@ pub mod pallet { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. - #[pallet::weight(T::WeightInfo::call(T::MaxCodeSize::get() / 1024).saturating_add(*gas_limit))] + #[pallet::weight(T::WeightInfo::call(T::Schedule::get().limits.code_len / 1024) + .saturating_add(*gas_limit) + )] pub fn call( origin: OriginFor, dest: ::Source, @@ -315,9 +288,9 @@ pub mod pallet { let origin = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; let mut gas_meter = GasMeter::new(gas_limit); - let schedule = >::get(); + let schedule = T::Schedule::get(); let (result, code_len) = match ExecStack::>::run_call( - origin, dest, &mut gas_meter, &schedule, value, data + origin, dest, &mut gas_meter, &schedule, value, data, None, ) { Ok((output, len)) => (Ok(output), len), Err((err, len)) => (Err(err), len), @@ -363,14 +336,14 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let origin = ensure_signed(origin)?; let code_len = code.len() as u32; - ensure!(code_len <= T::MaxCodeSize::get(), Error::::CodeTooLarge); + ensure!(code_len <= T::Schedule::get().limits.code_len, Error::::CodeTooLarge); let mut gas_meter = GasMeter::new(gas_limit); - let schedule = >::get(); + let schedule = T::Schedule::get(); let executable = PrefabWasmModule::from_code(code, &schedule)?; let code_len = executable.code_len(); - ensure!(code_len <= T::MaxCodeSize::get(), Error::::CodeTooLarge); + ensure!(code_len <= T::Schedule::get().limits.code_len, Error::::CodeTooLarge); let result = ExecStack::>::run_instantiate( - origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, + origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, None, ).map(|(_address, output)| output); gas_meter.into_dispatch_result( result, @@ -384,8 +357,10 @@ pub mod pallet { /// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary /// must be supplied. #[pallet::weight( - T::WeightInfo::instantiate(T::MaxCodeSize::get() / 1024, salt.len() as u32 / 1024) - .saturating_add(*gas_limit) + T::WeightInfo::instantiate( + T::Schedule::get().limits.code_len / 1024, salt.len() as u32 / 1024 + ) + .saturating_add(*gas_limit) )] pub fn instantiate( origin: OriginFor, @@ -397,11 +372,11 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let origin = ensure_signed(origin)?; let mut gas_meter = GasMeter::new(gas_limit); - let schedule = >::get(); + let schedule = T::Schedule::get(); let executable = PrefabWasmModule::from_storage(code_hash, &schedule, &mut gas_meter)?; let code_len = executable.code_len(); let result = ExecStack::>::run_instantiate( - origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, + origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, None, ).map(|(_address, output)| output); gas_meter.into_dispatch_result( result, @@ -418,7 +393,7 @@ pub mod pallet { /// /// 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::MaxCodeSize::get() / 1024))] + #[pallet::weight(T::WeightInfo::claim_surcharge(T::Schedule::get().limits.code_len / 1024))] pub fn claim_surcharge( origin: OriginFor, dest: T::AccountId, @@ -614,12 +589,10 @@ pub mod pallet { /// /// This can be triggered by a call to `seal_terminate` or `seal_restore_to`. TerminatedInConstructor, + /// The debug message specified to `seal_debug_message` does contain invalid UTF-8. + DebugMessageInvalidUTF8, } - /// Current cost schedule for contracts. - #[pallet::storage] - pub(crate) type CurrentSchedule = StorageValue<_, Schedule, ValueQuery>; - /// A mapping from an original code hash to the original code, untouched by instrumentation. #[pallet::storage] pub(crate) type PristineCode = StorageMap<_, Identity, CodeHash, Vec>; @@ -644,29 +617,6 @@ pub mod pallet { /// stored in said trie. Therefore this operation is performed lazily in `on_initialize`. #[pallet::storage] pub(crate) type DeletionQueue = StorageValue<_, Vec, ValueQuery>; - - - #[pallet::genesis_config] - pub struct GenesisConfig { - #[doc = "Current cost schedule for contracts."] - pub current_schedule: Schedule, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - current_schedule: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - >::put(&self.current_schedule); - } - } } impl Pallet @@ -678,6 +628,12 @@ where /// This function is similar to [`Self::call`], but doesn't perform any address lookups /// and better suitable for calling directly from Rust. /// + /// # Note + /// + /// `debug` should only ever be set to `true` when executing as an RPC because + /// it adds allocations and could be abused to drive the runtime into an OOM panic. + /// If set to `true` it returns additional human readable debugging information. + /// /// It returns the execution result and the amount of used weight. pub fn bare_call( origin: T::AccountId, @@ -685,17 +641,22 @@ where value: BalanceOf, gas_limit: Weight, input_data: Vec, + debug: bool, ) -> ContractExecResult { let mut gas_meter = GasMeter::new(gas_limit); - let schedule = >::get(); + let schedule = T::Schedule::get(); + let mut debug_message = if debug { + Some(Vec::new()) + } else { + None + }; let result = ExecStack::>::run_call( - origin, dest, &mut gas_meter, &schedule, value, input_data, + origin, dest, &mut gas_meter, &schedule, value, input_data, debug_message.as_mut(), ); - let gas_consumed = gas_meter.gas_spent(); ContractExecResult { result: result.map(|r| r.0).map_err(|r| r.0.error), - gas_consumed, - debug_message: Bytes(Vec::new()), + gas_consumed: gas_meter.gas_spent(), + debug_message: debug_message.unwrap_or_default(), } } @@ -709,6 +670,12 @@ where /// 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 + /// + /// `debug` should only ever be set to `true` when executing as an RPC because + /// it adds allocations and could be abused to drive the runtime into an OOM panic. + /// If set to `true` it returns additional human readable debugging information. pub fn bare_instantiate( origin: T::AccountId, endowment: BalanceOf, @@ -717,9 +684,10 @@ where data: Vec, salt: Vec, compute_projection: bool, + debug: bool, ) -> ContractInstantiateResult { let mut gas_meter = GasMeter::new(gas_limit); - let schedule = >::get(); + let schedule = T::Schedule::get(); let executable = match code { Code::Upload(Bytes(binary)) => PrefabWasmModule::from_code(binary, &schedule), Code::Existing(hash) => PrefabWasmModule::from_storage(hash, &schedule, &mut gas_meter), @@ -729,11 +697,17 @@ where Err(error) => return ContractInstantiateResult { result: Err(error.into()), gas_consumed: gas_meter.gas_spent(), - debug_message: Bytes(Vec::new()), + debug_message: Vec::new(), } }; + let mut debug_message = if debug { + Some(Vec::new()) + } else { + None + }; let result = ExecStack::>::run_instantiate( - origin, executable, &mut gas_meter, &schedule, endowment, data, &salt, + origin, executable, &mut gas_meter, &schedule, + endowment, data, &salt, debug_message.as_mut(), ).and_then(|(account_id, result)| { let rent_projection = if compute_projection { Some(Rent::>::compute_projection(&account_id) @@ -751,7 +725,7 @@ where ContractInstantiateResult { result: result.map_err(|e| e.error), gas_consumed: gas_meter.gas_spent(), - debug_message: Bytes(Vec::new()), + debug_message: debug_message.unwrap_or_default(), } } @@ -822,7 +796,7 @@ where /// Store code for benchmarks which does not check nor instrument the code. #[cfg(feature = "runtime-benchmarks")] fn store_code_raw(code: Vec) -> frame_support::dispatch::DispatchResult { - let schedule = >::get(); + let schedule = T::Schedule::get(); PrefabWasmModule::store_code_unchecked(code, &schedule)?; Ok(()) } diff --git a/frame/contracts/src/migration.rs b/frame/contracts/src/migration.rs index 4fc138d3f3daf..02de0225732b3 100644 --- a/frame/contracts/src/migration.rs +++ b/frame/contracts/src/migration.rs @@ -15,27 +15,34 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Config, Weight, CurrentSchedule, Pallet, Schedule}; -use frame_support::traits::{GetPalletVersion, PalletVersion, Get}; +use crate::{Config, Weight, Pallet, Schedule}; +use frame_support::{ + storage::StorageValue, + traits::{GetPalletVersion, PalletVersion, Get}, +}; pub fn migrate() -> Weight { let mut weight: Weight = 0; match >::storage_version() { - // Replace the schedule with the new default and increment its version. Some(version) if version == PalletVersion::new(3, 0, 0) => { - weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); - let _ = >::translate::(|version| { - version.map(|version| Schedule { - version: version.saturating_add(1), - // Default limits were not decreased. Therefore it is OK to overwrite - // the schedule with the new defaults. - .. Default::default() - }) - }); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + v3_0_0::CurrentSchedule::::kill(); } _ => (), } weight } + +mod v3_0_0 { + use super::*; + + struct Pallet(sp_std::marker::PhantomData); + + frame_support::decl_storage! { + trait Store for Pallet as Contracts { + pub CurrentSchedule: Schedule; + } + } +} diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index 90c396c627775..a94a08e27d795 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -42,27 +42,12 @@ pub const INSTR_BENCHMARK_BATCH_SIZE: u32 = 1_000; /// Definition of the cost schedule and other parameterizations for the wasm vm. /// /// Its fields are private to the crate in order to allow addition of new contract -/// callable functions without bumping to a new major version. A genesis config should -/// rely on public functions of this type. +/// callable functions without bumping to a new major version. The supplied [`Config::Schedule`] +/// should rely on public functions of this type. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(bound(serialize = "", deserialize = "")))] #[derive(Clone, Encode, Decode, PartialEq, Eq, ScheduleDebug)] pub struct Schedule { - /// Version of the schedule. - /// - /// # Note - /// - /// Must be incremented whenever the [`self.instruction_weights`] are changed. The - /// reason is that changes to instruction weights require a re-instrumentation - /// of all contracts which are triggered by a version comparison on call. - /// Changes to other parts of the schedule should not increment the version in - /// order to avoid unnecessary re-instrumentations. - pub(crate) version: u32, - - /// Whether the `seal_println` function is allowed to be used contracts. - /// MUST only be enabled for `dev` chains, NOT for production chains - pub(crate) enable_println: bool, - /// Describes the upper limits on various metrics. pub(crate) limits: Limits, @@ -73,12 +58,31 @@ pub struct Schedule { pub(crate) host_fn_weights: HostFnWeights, } +impl Schedule { + /// Set the version of the instruction weights. + /// + /// # Note + /// + /// Should be incremented whenever any instruction weight is changed. The + /// reason is that changes to instruction weights require a re-instrumentation + /// in order to apply the changes to an already deployed code. The re-instrumentation + /// is triggered by comparing the version of the current schedule with the the code was + /// instrumented with. Changes usually happen when pallet_contracts is re-benchmarked. + /// + /// Changes to other parts of the schedule should not increment the version in + /// order to avoid unnecessary re-instrumentations. + pub fn set_instruction_weights_version(&mut self, version: u32) { + self.instruction_weights.version = version; + } +} + /// Describes the upper limits on various metrics. /// /// # Note /// -/// The values in this struct should only ever be increased for a deployed chain. The reason -/// is that decreasing those values will break existing contracts which are above the new limits. +/// The values in this struct should never be decreased. The reason is that decreasing those +/// values will break existing contracts which are above the new limits when a +/// re-instrumentation is triggered. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct Limits { @@ -121,6 +125,17 @@ pub struct Limits { /// The maximum length of a subject in bytes used for PRNG generation. pub subject_len: u32, + + /// The maximum nesting level of the call stack. + pub call_depth: u32, + + /// The maximum size of a storage value and event payload in bytes. + pub payload_len: u32, + + /// The maximum length of a contract code in bytes. This limit applies to the instrumented + /// version of the code. Therefore `instantiate_with_code` can fail even when supplying + /// a wasm binary below this maximum size. + pub code_len: u32, } impl Limits { @@ -153,6 +168,10 @@ impl Limits { #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, PartialEq, Eq, WeightDebug)] pub struct InstructionWeights { + /// Version of the instruction weights. + /// + /// See [`Schedule::set_instruction_weights_version`]. + pub(crate) version: u32, pub i64const: u32, pub i64load: u32, pub i64store: u32, @@ -291,6 +310,9 @@ pub struct HostFnWeights { /// Weight per byte of an event deposited through `seal_deposit_event`. pub deposit_event_per_byte: Weight, + /// Weight of calling `seal_debug_message`. + pub debug_message: Weight, + /// Weight of calling `seal_set_rent_allowance`. pub set_rent_allowance: Weight, @@ -454,8 +476,6 @@ macro_rules! cost_byte_batched { impl Default for Schedule { fn default() -> Self { Self { - version: 0, - enable_println: false, limits: Default::default(), instruction_weights: Default::default(), host_fn_weights: Default::default(), @@ -476,6 +496,9 @@ impl Default for Limits { table_size: 4096, br_table_size: 256, subject_len: 32, + call_depth: 32, + payload_len: 16 * 1024, + code_len: 128 * 1024, } } } @@ -484,6 +507,7 @@ impl Default for InstructionWeights { fn default() -> Self { let max_pages = Limits::default().memory_pages; Self { + version: 2, i64const: cost_instr!(instr_i64const, 1), i64load: cost_instr!(instr_i64load, 2), i64store: cost_instr!(instr_i64store, 2), @@ -569,6 +593,7 @@ impl Default for HostFnWeights { deposit_event: cost_batched!(seal_deposit_event), deposit_event_per_topic: cost_batched_args!(seal_deposit_event_per_topic_and_kb, 1, 0), deposit_event_per_byte: cost_byte_batched_args!(seal_deposit_event_per_topic_and_kb, 0, 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), @@ -606,20 +631,6 @@ struct ScheduleRules<'a, T: Config> { } impl Schedule { - /// Allow contracts to call `seal_println` in order to print messages to the console. - /// - /// This should only ever be activated in development chains. The printed messages - /// can be observed on the console by setting the environment variable - /// `RUST_LOG=runtime=debug` when running the node. - /// - /// # Note - /// - /// Is set to `false` by default. - pub fn enable_println(mut self, enable: bool) -> Self { - self.enable_println = enable; - self - } - pub(crate) fn rules(&self, module: &elements::Module) -> impl rules::Rules + '_ { ScheduleRules { schedule: &self, diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index ef3d65f506c5b..44ac28a60034a 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -40,7 +40,7 @@ use sp_io::hashing::blake2_256; use frame_support::{ assert_ok, assert_err, assert_err_ignore_postinfo, parameter_types, assert_storage_noop, - traits::{Currency, ReservableCurrency, OnInitialize, GenesisBuild}, + traits::{Currency, ReservableCurrency, OnInitialize}, weights::{Weight, PostDispatchInfo, DispatchClass, constants::WEIGHT_PER_SECOND}, dispatch::DispatchErrorWithPostInfo, storage::child, @@ -63,7 +63,7 @@ frame_support::construct_runtime!( Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Randomness: pallet_randomness_collective_flip::{Pallet, Call, Storage}, - Contracts: pallet_contracts::{Pallet, Call, Config, Storage, Event}, + Contracts: pallet_contracts::{Pallet, Call, Storage, Event}, } ); @@ -265,6 +265,7 @@ parameter_types! { pub const DeletionQueueDepth: u32 = 1024; pub const DeletionWeightLimit: Weight = 500_000_000_000; pub const MaxCodeSize: u32 = 2 * 1024; + pub MySchedule: Schedule = >::default(); } parameter_types! { @@ -291,13 +292,12 @@ impl Config for Test { type RentFraction = RentFraction; type SurchargeReward = SurchargeReward; type CallStack = [Frame; 31]; - type MaxValueSize = MaxValueSize; type WeightPrice = Self; type WeightInfo = (); type ChainExtension = TestExtension; type DeletionQueueDepth = DeletionQueueDepth; type DeletionWeightLimit = DeletionWeightLimit; - type MaxCodeSize = MaxCodeSize; + type Schedule = MySchedule; } pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); @@ -331,12 +331,6 @@ impl ExtBuilder { pallet_balances::GenesisConfig:: { balances: vec![], }.assimilate_storage(&mut t).unwrap(); - pallet_contracts::GenesisConfig { - current_schedule: Schedule:: { - enable_println: true, - ..Default::default() - }, - }.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(|| System::set_block_number(1)); ext @@ -564,7 +558,7 @@ fn deposit_event_max_value_limit() { addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer, - ::MaxValueSize::get().encode(), + ::Schedule::get().limits.payload_len.encode(), )); // Call contract with too large a storage value. @@ -574,7 +568,7 @@ fn deposit_event_max_value_limit() { addr, 0, GAS_LIMIT, - (::MaxValueSize::get() + 1).encode(), + (::Schedule::get().limits.payload_len + 1).encode(), ), Error::::ValueTooLarge, ); @@ -1544,7 +1538,7 @@ fn storage_max_value_limit() { addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer - ::MaxValueSize::get().encode(), + ::Schedule::get().limits.payload_len.encode(), )); // Call contract with too large a storage value. @@ -1554,7 +1548,7 @@ fn storage_max_value_limit() { addr, 0, GAS_LIMIT, - (::MaxValueSize::get() + 1).encode(), + (::Schedule::get().limits.payload_len + 1).encode(), ), Error::::ValueTooLarge, ); @@ -1896,6 +1890,7 @@ fn crypto_hashes() { 0, GAS_LIMIT, params, + false, ).result.unwrap(); assert!(result.is_success()); let expected = hash_fn(input.as_ref()); @@ -1931,6 +1926,7 @@ fn transfer_return_code() { 0, GAS_LIMIT, vec![], + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); @@ -1945,6 +1941,7 @@ fn transfer_return_code() { 0, GAS_LIMIT, vec![], + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::TransferFailed); }); @@ -1979,6 +1976,7 @@ fn call_return_code() { 0, GAS_LIMIT, AsRef::<[u8]>::as_ref(&DJANGO).to_vec(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::NotCallable); @@ -2002,6 +2000,7 @@ fn call_return_code() { 0, GAS_LIMIT, AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); @@ -2016,6 +2015,7 @@ fn call_return_code() { 0, GAS_LIMIT, AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::TransferFailed); @@ -2027,6 +2027,7 @@ fn call_return_code() { 0, GAS_LIMIT, AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&1u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeReverted); @@ -2037,6 +2038,7 @@ fn call_return_code() { 0, GAS_LIMIT, AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&2u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); @@ -2084,6 +2086,7 @@ fn instantiate_return_code() { 0, GAS_LIMIT, callee_hash.clone(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); @@ -2098,6 +2101,7 @@ fn instantiate_return_code() { 0, GAS_LIMIT, callee_hash.clone(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::TransferFailed); @@ -2109,6 +2113,7 @@ fn instantiate_return_code() { 0, GAS_LIMIT, vec![0; 33], + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CodeNotFound); @@ -2119,6 +2124,7 @@ fn instantiate_return_code() { 0, GAS_LIMIT, callee_hash.iter().chain(&1u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeReverted); @@ -2129,6 +2135,7 @@ fn instantiate_return_code() { 0, GAS_LIMIT, callee_hash.iter().chain(&2u32.to_le_bytes()).cloned().collect(), + false, ).result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); @@ -2216,6 +2223,7 @@ fn chain_extension_works() { 0, GAS_LIMIT, vec![0, 99], + false, ); let gas_consumed = result.gas_consumed; assert_eq!(TestExtension::last_seen_buffer(), vec![0, 99]); @@ -2228,6 +2236,7 @@ fn chain_extension_works() { 0, GAS_LIMIT, vec![1], + false, ).result.unwrap(); // those values passed in the fixture assert_eq!(TestExtension::last_seen_inputs(), (4, 1, 16, 12)); @@ -2239,6 +2248,7 @@ fn chain_extension_works() { 0, GAS_LIMIT, vec![2, 42], + false, ); assert_ok!(result.result); assert_eq!(result.gas_consumed, gas_consumed + 42); @@ -2250,6 +2260,7 @@ fn chain_extension_works() { 0, GAS_LIMIT, vec![3], + false, ).result.unwrap(); assert_eq!(result.flags, ReturnFlags::REVERT); assert_eq!(result.data, Bytes(vec![42, 99])); @@ -2782,6 +2793,7 @@ fn reinstrument_does_charge() { 0, GAS_LIMIT, zero.clone(), + false, ); assert!(result0.result.unwrap().is_success()); @@ -2791,15 +2803,17 @@ fn reinstrument_does_charge() { 0, GAS_LIMIT, zero.clone(), + false, ); assert!(result1.result.unwrap().is_success()); // They should match because both where called with the same schedule. assert_eq!(result0.gas_consumed, result1.gas_consumed); - // Update the schedule version but keep the rest the same - crate::CurrentSchedule::mutate(|old: &mut Schedule| { - old.version += 1; + // We cannot change the schedule. Instead, we decrease the version of the deployed + // contract below the current schedule's version. + crate::CodeStorage::mutate(&code_hash, |code: &mut Option>| { + code.as_mut().unwrap().decrement_version(); }); // This call should trigger reinstrumentation @@ -2809,6 +2823,7 @@ fn reinstrument_does_charge() { 0, GAS_LIMIT, zero.clone(), + false, ); assert!(result2.result.unwrap().is_success()); assert!(result2.gas_consumed > result1.gas_consumed); @@ -2818,3 +2833,101 @@ fn reinstrument_does_charge() { ); }); } + +#[test] +fn debug_message_works() { + let (wasm, code_hash) = compile_module::("debug_message_works").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, + vec![], + vec![], + ), + ); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + let result = Contracts::bare_call( + ALICE, + addr, + 0, + GAS_LIMIT, + vec![], + true, + ); + + assert_matches!(result.result, Ok(_)); + assert_eq!(std::str::from_utf8(&result.debug_message).unwrap(), "Hello World!"); + }); +} + +#[test] +fn debug_message_logging_disabled() { + let (wasm, code_hash) = compile_module::("debug_message_logging_disabled").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, + vec![], + vec![], + ), + ); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + // disable logging by passing `false` + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + vec![], + false, + ); + assert_matches!(result.result, Ok(_)); + // the dispatchables always run without debugging + assert_ok!(Contracts::call( + Origin::signed(ALICE), + addr, + 0, + GAS_LIMIT, + vec![], + )); + }); +} + +#[test] +fn debug_message_invalid_utf8() { + let (wasm, code_hash) = compile_module::("debug_message_invalid_utf8").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, + vec![], + vec![], + ), + ); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + let result = Contracts::bare_call( + ALICE, + addr, + 0, + GAS_LIMIT, + vec![], + true, + ); + assert_err!(result.result, >::DebugMessageInvalidUTF8); + }); +} diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index e81e595697aa9..4b43105c9c153 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -132,7 +132,7 @@ where prefab_module.code_hash = code_hash; if let Some((schedule, gas_meter)) = reinstrument { - if prefab_module.schedule_version < schedule.version { + if prefab_module.schedule_version < schedule.instruction_weights.version { // The current schedule version is greater than the version of the one cached // in the storage. // @@ -158,7 +158,7 @@ mod private { let original_code = >::get(&prefab_module.code_hash) .ok_or_else(|| Error::::CodeNotFound)?; prefab_module.code = prepare::reinstrument_contract::(original_code, schedule)?; - prefab_module.schedule_version = schedule.version; + prefab_module.schedule_version = schedule.instruction_weights.version; >::insert(&prefab_module.code_hash, &*prefab_module); Ok(()) } diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index f30a30ae87250..81041e906748f 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -140,6 +140,12 @@ where pub fn refcount(&self) -> u64 { self.refcount } + + /// Decrement schedule_version by 1. Panics if it is already 0. + #[cfg(test)] + pub fn decrement_version(&mut self) { + self.schedule_version = self.schedule_version.checked_sub(1).unwrap(); + } } impl Executable for PrefabWasmModule @@ -297,6 +303,7 @@ mod tests { schedule: Schedule, rent_params: RentParams, gas_meter: GasMeter, + debug_buffer: Vec, } impl Default for MockExt { @@ -312,6 +319,7 @@ mod tests { schedule: Default::default(), rent_params: Default::default(), gas_meter: GasMeter::new(10_000_000_000), + debug_buffer: Default::default(), } } } @@ -447,6 +455,10 @@ mod tests { fn gas_meter(&mut self) -> &mut GasMeter { &mut self.gas_meter } + fn append_debug_buffer(&mut self, msg: &str) -> bool { + self.debug_buffer.extend(msg.as_bytes()); + true + } } fn execute>( @@ -1845,4 +1857,71 @@ mod tests { let rent_params = Bytes(>::default().encode()); assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_params }); } + + const CODE_DEBUG_MESSAGE: &str = r#" +(module + (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (data (i32.const 0) "Hello World!") + + (func (export "call") + (call $seal_debug_message + (i32.const 0) ;; Pointer to the text buffer + (i32.const 12) ;; The size of the buffer + ) + drop + ) + + (func (export "deploy")) +) +"#; + + #[test] + fn debug_message_works() { + let mut ext = MockExt::default(); + execute( + CODE_DEBUG_MESSAGE, + vec![], + &mut ext, + ).unwrap(); + + assert_eq!(std::str::from_utf8(&ext.debug_buffer).unwrap(), "Hello World!"); + } + + const CODE_DEBUG_MESSAGE_FAIL: &str = r#" + (module + (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + (data (i32.const 0) "\fc") + + (func (export "call") + (call $seal_debug_message + (i32.const 0) ;; Pointer to the text buffer + (i32.const 1) ;; The size of the buffer + ) + drop + ) + + (func (export "deploy")) + ) + "#; + + #[test] + fn debug_message_invalid_utf8_fails() { + let mut ext = MockExt::default(); + let result = execute( + CODE_DEBUG_MESSAGE_FAIL, + vec![], + &mut ext, + ); + assert_eq!( + result, + Err(ExecError { + error: Error::::DebugMessageInvalidUTF8.into(), + origin: ErrorOrigin::Caller, + }) + ); + } } diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 633edd4aaf8a4..97692c4917dbc 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -343,12 +343,6 @@ impl<'a, T: Config> ContractModule<'a, T> { .get(*type_idx as usize) .ok_or_else(|| "validation: import entry points to a non-existent type")?; - // We disallow importing `seal_println` unless debug features are enabled, - // which should only be allowed on a dev chain - if !self.schedule.enable_println && import.field().as_bytes() == b"seal_println" { - return Err("module imports `seal_println` but debug features disabled"); - } - if !T::ChainExtension::enabled() && import.field().as_bytes() == b"seal_call_chain_extension" { @@ -439,7 +433,7 @@ fn do_preparation( schedule, )?; Ok(PrefabWasmModule { - schedule_version: schedule.version, + schedule_version: schedule.instruction_weights.version, initial, maximum, _reserved: None, @@ -505,7 +499,7 @@ pub mod benchmarking { let contract_module = ContractModule::new(&original_code, schedule)?; let memory_limits = get_memory_limits(contract_module.scan_imports::<()>(&[])?, schedule)?; Ok(PrefabWasmModule { - schedule_version: schedule.version, + schedule_version: schedule.instruction_weights.version, initial: memory_limits.0, maximum: memory_limits.1, _reserved: None, @@ -547,8 +541,6 @@ mod tests { // new version of nop with other data type for argumebt [seal1] nop(_ctx, _unused: i32) => { unreachable!(); }, - - [seal0] seal_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, ); } @@ -938,36 +930,6 @@ mod tests { "#, Err("module imports a non-existent function") ); - - prepare_test!(seal_println_debug_disabled, - r#" - (module - (import "seal0" "seal_println" (func $seal_println (param i32 i32))) - - (func (export "call")) - (func (export "deploy")) - ) - "#, - Err("module imports `seal_println` but debug features disabled") - ); - - #[test] - fn seal_println_debug_enabled() { - let wasm = wat::parse_str( - r#" - (module - (import "seal0" "seal_println" (func $seal_println (param i32 i32))) - - (func (export "call")) - (func (export "deploy")) - ) - "# - ).unwrap(); - let mut schedule = Schedule::default(); - schedule.enable_println = true; - let r = do_preparation::(wasm, &schedule); - assert_matches::assert_matches!(r, Ok(_)); - } } mod entrypoints { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index da8784b23cdcb..7aa365555d7f2 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -71,6 +71,9 @@ pub enum ReturnCode { /// The contract that was called is either no contract at all (a plain account) /// or is a tombstone. NotCallable = 8, + /// The call to `seal_debug_message` had to effect because debug message + /// recording was disabled. + LoggingDisabled = 9, } impl ConvertibleToWasm for ReturnCode { @@ -175,6 +178,8 @@ pub enum RuntimeCosts { 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. @@ -255,6 +260,7 @@ impl RuntimeCosts { 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())), @@ -802,7 +808,7 @@ define_env!(Env, , ctx.charge_gas(RuntimeCosts::CallSurchargeTransfer)?; } let charged = ctx.charge_gas( - RuntimeCosts::CallSurchargeCodeSize(::MaxCodeSize::get()) + RuntimeCosts::CallSurchargeCodeSize(::Schedule::get().limits.code_len) )?; let ext = &mut ctx.ext; let call_outcome = ext.call(gas, callee, value, input_data); @@ -887,7 +893,9 @@ define_env!(Env, , let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?; let charged = ctx.charge_gas( - RuntimeCosts::InstantiateSurchargeCodeSize(::MaxCodeSize::get()) + RuntimeCosts::InstantiateSurchargeCodeSize( + ::Schedule::get().limits.code_len + ) )?; let ext = &mut ctx.ext; let instantiate_outcome = ext.instantiate(gas, code_hash, value, input_data, &salt); @@ -937,7 +945,9 @@ define_env!(Env, , ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; let charged = ctx.charge_gas( - RuntimeCosts::TerminateSurchargeCodeSize(::MaxCodeSize::get()) + RuntimeCosts::TerminateSurchargeCodeSize( + ::Schedule::get().limits.code_len + ) )?; let (result, code_len) = match ctx.ext.terminate(&beneficiary) { Ok(len) => (Ok(()), len), @@ -1266,7 +1276,7 @@ define_env!(Env, , delta }; - let max_len = ::MaxCodeSize::get(); + let max_len = ::Schedule::get().limits.code_len; let charged = ctx.charge_gas(RuntimeCosts::RestoreToSurchargeCodeSize { caller_code: max_len, tombstone_code: max_len, @@ -1380,15 +1390,33 @@ define_env!(Env, , )?) }, - // Prints utf8 encoded string from the data buffer. - // Only available on `--dev` chains. - // This function may be removed at any time, superseded by a more general contract debugging feature. - [seal0] seal_println(ctx, str_ptr: u32, str_len: u32) => { - let data = ctx.read_sandbox_memory(str_ptr, str_len)?; - if let Ok(utf8) = core::str::from_utf8(&data) { - log::info!(target: "runtime::contracts", "seal_println: {}", utf8); + // Emit a custom debug message. + // + // No newlines are added to the supplied message. + // Specifying invalid UTF-8 triggers a trap. + // + // This is a no-op if debug message recording is disabled which is always the case + // when the code is executing on-chain. The message is interpreted as UTF-8 and + // appended to the debug buffer which is then supplied to the calling RPC client. + // + // # Note + // + // Even though no action is taken when debug message recording is disabled there is still + // a non trivial overhead (and weight cost) associated with calling this function. Contract + // languages should remove calls to this function (either at runtime or compile time) when + // not being executed as an RPC. For example, they could allow users to disable logging + // through compile time flags (cargo features) for on-chain deployment. Additionally, the + // return value of this function can be cached in order to prevent further calls at runtime. + [seal0] seal_debug_message(ctx, str_ptr: u32, str_len: u32) -> ReturnCode => { + ctx.charge_gas(RuntimeCosts::DebugMessage)?; + if ctx.ext.append_debug_buffer("") { + let data = ctx.read_sandbox_memory(str_ptr, str_len)?; + let msg = core::str::from_utf8(&data) + .map_err(|_| >::DebugMessageInvalidUTF8)?; + ctx.ext.append_debug_buffer(msg); + return Ok(ReturnCode::Success); } - Ok(()) + Ok(ReturnCode::LoggingDisabled) }, // Stores the current block number of the current contract into the supplied buffer. diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index a4cf9b41553b6..ea3f424dd98c5 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_contracts //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-04-23, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-05-10, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -48,7 +48,6 @@ pub trait WeightInfo { fn on_initialize_per_trie_key(k: u32, ) -> Weight; fn on_initialize_per_queue_item(q: u32, ) -> Weight; fn instrument(c: u32, ) -> Weight; - fn update_schedule() -> Weight; fn instantiate_with_code(c: u32, s: u32, ) -> Weight; fn instantiate(c: u32, s: u32, ) -> Weight; fn call(c: u32, ) -> Weight; @@ -78,6 +77,7 @@ pub trait WeightInfo { 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; fn seal_clear_storage(r: u32, ) -> Weight; @@ -153,1321 +153,1325 @@ pub trait WeightInfo { pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn on_initialize() -> Weight { - (3_610_000 as Weight) + (3_676_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 2_000 - .saturating_add((2_307_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_259_000 as Weight).saturating_mul(k as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (18_635_000 as Weight) - // Standard Error: 8_000 - .saturating_add((33_246_000 as Weight).saturating_mul(q as Weight)) + (0 as Weight) + // Standard Error: 33_000 + .saturating_add((35_157_000 as Weight).saturating_mul(q as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instrument(c: u32, ) -> Weight { - (36_950_000 as Weight) - // Standard Error: 198_000 - .saturating_add((116_526_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn update_schedule() -> Weight { - (28_095_000 as Weight) + (42_341_000 as Weight) + // Standard Error: 190_000 + .saturating_add((95_696_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (230_039_000 as Weight) - // Standard Error: 143_000 - .saturating_add((157_483_000 as Weight).saturating_mul(c as Weight)) + (178_191_000 as Weight) + // Standard Error: 141_000 + .saturating_add((135_736_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 9_000 - .saturating_add((2_992_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add((1_867_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn instantiate(c: u32, s: u32, ) -> Weight { - (203_983_000 as Weight) + (183_874_000 as Weight) // Standard Error: 11_000 - .saturating_add((8_639_000 as Weight).saturating_mul(c as Weight)) + .saturating_add((8_659_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 1_000 - .saturating_add((2_918_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add((1_781_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn call(c: u32, ) -> Weight { - (198_905_000 as Weight) + (186_051_000 as Weight) // Standard Error: 1_000 - .saturating_add((3_913_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add((3_919_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn claim_surcharge(c: u32, ) -> Weight { - (132_586_000 as Weight) - // Standard Error: 1_000 - .saturating_add((4_732_000 as Weight).saturating_mul(c as Weight)) + (133_967_000 as Weight) + // Standard Error: 2_000 + .saturating_add((4_733_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (179_629_000 as Weight) - // Standard Error: 318_000 - .saturating_add((250_628_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (131_758_000 as Weight) + // Standard Error: 361_000 + .saturating_add((249_131_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (144_806_000 as Weight) - // Standard Error: 71_000 - .saturating_add((251_588_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (141_100_000 as Weight) + // Standard Error: 73_000 + .saturating_add((245_593_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (151_919_000 as Weight) - // Standard Error: 90_000 - .saturating_add((243_733_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (141_578_000 as Weight) + // Standard Error: 76_000 + .saturating_add((240_505_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (157_448_000 as Weight) - // Standard Error: 211_000 - .saturating_add((559_875_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (144_329_000 as Weight) + // Standard Error: 197_000 + .saturating_add((529_903_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (145_161_000 as Weight) - // Standard Error: 71_000 - .saturating_add((246_729_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (137_318_000 as Weight) + // Standard Error: 77_000 + .saturating_add((239_623_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (147_920_000 as Weight) - // Standard Error: 60_000 - .saturating_add((245_135_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (138_343_000 as Weight) + // Standard Error: 260_000 + .saturating_add((241_997_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (141_105_000 as Weight) - // Standard Error: 138_000 - .saturating_add((247_840_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (138_989_000 as Weight) + // Standard Error: 77_000 + .saturating_add((239_424_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (147_393_000 as Weight) - // Standard Error: 77_000 - .saturating_add((247_593_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (140_118_000 as Weight) + // Standard Error: 83_000 + .saturating_add((240_866_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (151_560_000 as Weight) - // Standard Error: 92_000 - .saturating_add((242_469_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (139_962_000 as Weight) + // Standard Error: 69_000 + .saturating_add((239_267_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (145_917_000 as Weight) - // Standard Error: 80_000 - .saturating_add((244_335_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (139_652_000 as Weight) + // Standard Error: 69_000 + .saturating_add((240_282_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_rent_params(r: u32, ) -> Weight { - (150_399_000 as Weight) - // Standard Error: 90_000 - .saturating_add((381_505_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (136_806_000 as Weight) + // Standard Error: 104_000 + .saturating_add((359_911_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (152_906_000 as Weight) - // Standard Error: 418_000 - .saturating_add((486_338_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + (148_086_000 as Weight) + // Standard Error: 116_000 + .saturating_add((470_271_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (130_020_000 as Weight) - // Standard Error: 48_000 - .saturating_add((120_792_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (123_560_000 as Weight) + // Standard Error: 295_000 + .saturating_add((119_119_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (142_031_000 as Weight) + (132_420_000 as Weight) // Standard Error: 83_000 - .saturating_add((7_205_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add((6_835_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (151_770_000 as Weight) + (142_119_000 as Weight) // Standard Error: 0 - .saturating_add((247_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add((245_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (131_023_000 as Weight) - // Standard Error: 69_000 - .saturating_add((4_823_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (121_030_000 as Weight) + // Standard Error: 68_000 + .saturating_add((4_444_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (142_885_000 as Weight) + (131_704_000 as Weight) // Standard Error: 1_000 - .saturating_add((751_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add((756_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (142_165_000 as Weight) - // Standard Error: 100_000 - .saturating_add((99_133_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (132_544_000 as Weight) + // Standard Error: 113_000 + .saturating_add((97_343_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_terminate_per_code_kb(c: u32, ) -> Weight { - (243_348_000 as Weight) - // Standard Error: 6_000 - .saturating_add((8_560_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) + (234_751_000 as Weight) + // Standard Error: 3_000 + .saturating_add((8_482_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } fn seal_restore_to(r: u32, ) -> Weight { - (171_766_000 as Weight) - // Standard Error: 372_000 - .saturating_add((100_243_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (156_439_000 as Weight) + // Standard Error: 1_068_000 + .saturating_add((96_724_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { - (112_646_000 as Weight) - // Standard Error: 142_000 - .saturating_add((7_922_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 142_000 - .saturating_add((3_590_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 1_255_000 - .saturating_add((3_716_501_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (101_920_000 as Weight) + // Standard Error: 162_000 + .saturating_add((7_588_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 162_000 + .saturating_add((3_475_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 1_431_000 + .saturating_add((3_733_137_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(7 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (152_470_000 as Weight) - // Standard Error: 146_000 - .saturating_add((619_676_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + (151_598_000 as Weight) + // Standard Error: 168_000 + .saturating_add((608_967_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (151_008_000 as Weight) - // Standard Error: 167_000 - .saturating_add((899_677_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (149_224_000 as Weight) + // Standard Error: 205_000 + .saturating_add((896_074_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_227_526_000 as Weight) - // Standard Error: 2_767_000 - .saturating_add((586_284_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 545_000 - .saturating_add((247_578_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (1_198_650_000 as Weight) + // Standard Error: 2_742_000 + .saturating_add((566_152_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 540_000 + .saturating_add((248_898_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (142_734_000 as Weight) - // Standard Error: 53_000 - .saturating_add((167_026_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (133_149_000 as Weight) + // Standard Error: 72_000 + .saturating_add((163_281_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn seal_debug_message(r: u32, ) -> Weight { + (126_413_000 as Weight) + // Standard Error: 127_000 + .saturating_add((128_176_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (21_198_000 as Weight) - // Standard Error: 2_062_000 - .saturating_add((3_836_800_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 1_710_000 + .saturating_add((3_933_779_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (589_829_000 as Weight) - // Standard Error: 223_000 - .saturating_add((71_242_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + (582_721_000 as Weight) + // Standard Error: 228_000 + .saturating_add((71_341_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_950_000 - .saturating_add((1_267_479_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + // Standard Error: 2_470_000 + .saturating_add((1_281_241_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (3_466_000 as Weight) - // Standard Error: 1_248_000 - .saturating_add((920_416_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (11_848_000 as Weight) + // Standard Error: 1_028_000 + .saturating_add((934_213_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (618_423_000 as Weight) - // Standard Error: 231_000 - .saturating_add((153_218_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + (602_494_000 as Weight) + // Standard Error: 255_000 + .saturating_add((152_885_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (76_247_000 as Weight) - // Standard Error: 2_153_000 - .saturating_add((5_509_779_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 1_746_000 + .saturating_add((5_264_601_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)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 8_294_000 - .saturating_add((11_951_311_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + // Standard Error: 13_325_000 + .saturating_add((11_706_784_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { - (10_875_657_000 as Weight) - // Standard Error: 253_000 - .saturating_add((392_140_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 105_395_000 - .saturating_add((3_581_966_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 33_000 - .saturating_add((59_352_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 35_000 - .saturating_add((79_149_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(T::DbWeight::get().reads(206 as Weight)) + (9_518_851_000 as Weight) + // Standard Error: 349_000 + .saturating_add((391_414_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 145_480_000 + .saturating_add((4_113_632_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 46_000 + .saturating_add((60_888_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 49_000 + .saturating_add((79_489_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(T::DbWeight::get().reads(205 as Weight)) .saturating_add(T::DbWeight::get().writes(101 as Weight)) .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 31_795_000 - .saturating_add((21_908_561_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + // Standard Error: 39_418_000 + .saturating_add((21_356_322_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { - (10_580_308_000 as Weight) - // Standard Error: 611_000 - .saturating_add((875_153_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 86_000 - .saturating_add((62_540_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 86_000 - .saturating_add((83_080_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 86_000 - .saturating_add((350_970_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(T::DbWeight::get().reads(207 as Weight)) + (12_419_243_000 as Weight) + // Standard Error: 1_454_000 + .saturating_add((848_075_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 206_000 + .saturating_add((61_500_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 206_000 + .saturating_add((82_895_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 206_000 + .saturating_add((236_893_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(T::DbWeight::get().reads(206 as Weight)) .saturating_add(T::DbWeight::get().writes(204 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (143_987_000 as Weight) - // Standard Error: 90_000 - .saturating_add((232_215_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (129_427_000 as Weight) + // Standard Error: 110_000 + .saturating_add((227_721_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (762_075_000 as Weight) - // Standard Error: 64_000 - .saturating_add((475_112_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 202_000 + .saturating_add((494_366_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (145_456_000 as Weight) - // Standard Error: 203_000 - .saturating_add((241_831_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (133_222_000 as Weight) + // Standard Error: 330_000 + .saturating_add((237_008_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (660_371_000 as Weight) - // Standard Error: 30_000 - .saturating_add((342_147_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (1_245_757_000 as Weight) + // Standard Error: 77_000 + .saturating_add((339_755_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (149_472_000 as Weight) - // Standard Error: 101_000 - .saturating_add((212_899_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (133_091_000 as Weight) + // Standard Error: 126_000 + .saturating_add((208_234_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (643_371_000 as Weight) - // Standard Error: 31_000 - .saturating_add((159_244_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (799_510_000 as Weight) + // Standard Error: 49_000 + .saturating_add((158_583_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (147_732_000 as Weight) - // Standard Error: 91_000 - .saturating_add((210_975_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (130_180_000 as Weight) + // Standard Error: 83_000 + .saturating_add((206_505_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (684_085_000 as Weight) - // Standard Error: 38_000 - .saturating_add((159_213_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (965_700_000 as Weight) + // Standard Error: 64_000 + .saturating_add((154_387_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (25_332_000 as Weight) - // Standard Error: 12_000 - .saturating_add((3_087_000 as Weight).saturating_mul(r as Weight)) + (20_233_000 as Weight) + // Standard Error: 21_000 + .saturating_add((3_445_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (27_404_000 as Weight) - // Standard Error: 22_000 - .saturating_add((136_046_000 as Weight).saturating_mul(r as Weight)) + (29_798_000 as Weight) + // Standard Error: 1_137_000 + .saturating_add((137_787_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (27_422_000 as Weight) - // Standard Error: 24_000 - .saturating_add((204_925_000 as Weight).saturating_mul(r as Weight)) + (22_914_000 as Weight) + // Standard Error: 701_000 + .saturating_add((205_918_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (25_289_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_375_000 as Weight).saturating_mul(r as Weight)) + (20_225_000 as Weight) + // Standard Error: 20_000 + .saturating_add((12_545_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (25_278_000 as Weight) - // Standard Error: 14_000 - .saturating_add((11_447_000 as Weight).saturating_mul(r as Weight)) + (20_196_000 as Weight) + // Standard Error: 19_000 + .saturating_add((12_677_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (25_283_000 as Weight) - // Standard Error: 15_000 - .saturating_add((5_615_000 as Weight).saturating_mul(r as Weight)) + (20_204_000 as Weight) + // Standard Error: 19_000 + .saturating_add((6_920_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (25_377_000 as Weight) - // Standard Error: 20_000 - .saturating_add((13_248_000 as Weight).saturating_mul(r as Weight)) + (20_220_000 as Weight) + // Standard Error: 30_000 + .saturating_add((15_209_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (25_318_000 as Weight) - // Standard Error: 14_000 - .saturating_add((14_962_000 as Weight).saturating_mul(r as Weight)) + (20_262_000 as Weight) + // Standard Error: 37_000 + .saturating_add((15_909_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (37_040_000 as Weight) - // Standard Error: 1_000 - .saturating_add((150_000 as Weight).saturating_mul(e as Weight)) + (35_644_000 as Weight) + // Standard Error: 0 + .saturating_add((82_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (25_529_000 as Weight) - // Standard Error: 114_000 - .saturating_add((91_613_000 as Weight).saturating_mul(r as Weight)) + (20_566_000 as Weight) + // Standard Error: 79_000 + .saturating_add((91_776_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (33_242_000 as Weight) - // Standard Error: 188_000 - .saturating_add((191_383_000 as Weight).saturating_mul(r as Weight)) + (28_243_000 as Weight) + // Standard Error: 207_000 + .saturating_add((169_342_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (228_146_000 as Weight) + (206_233_000 as Weight) // Standard Error: 4_000 - .saturating_add((3_917_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((4_685_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (44_304_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_146_000 as Weight).saturating_mul(r as Weight)) + (37_775_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_553_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (44_314_000 as Weight) - // Standard Error: 17_000 - .saturating_add((3_474_000 as Weight).saturating_mul(r as Weight)) + (37_836_000 as Weight) + // Standard Error: 19_000 + .saturating_add((3_745_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (44_234_000 as Weight) - // Standard Error: 14_000 - .saturating_add((4_725_000 as Weight).saturating_mul(r as Weight)) + (37_816_000 as Weight) + // Standard Error: 21_000 + .saturating_add((4_929_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (28_754_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_898_000 as Weight).saturating_mul(r as Weight)) + (23_385_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_494_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (28_737_000 as Weight) - // Standard Error: 26_000 - .saturating_add((8_531_000 as Weight).saturating_mul(r as Weight)) + (23_334_000 as Weight) + // Standard Error: 24_000 + .saturating_add((8_306_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (27_338_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_499_000 as Weight).saturating_mul(r as Weight)) + (22_311_000 as Weight) + // Standard Error: 27_000 + .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_943_000 as Weight) - // Standard Error: 299_000 - .saturating_add((2_094_164_000 as Weight).saturating_mul(r as Weight)) + (20_789_000 as Weight) + // Standard Error: 269_000 + .saturating_add((2_070_923_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (25_269_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_135_000 as Weight).saturating_mul(r as Weight)) + (20_196_000 as Weight) + // Standard Error: 20_000 + .saturating_add((5_132_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (25_281_000 as Weight) - // Standard Error: 16_000 - .saturating_add((5_069_000 as Weight).saturating_mul(r as Weight)) + (20_215_000 as Weight) + // Standard Error: 7_000 + .saturating_add((5_053_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (25_243_000 as Weight) - // Standard Error: 9_000 - .saturating_add((5_809_000 as Weight).saturating_mul(r as Weight)) + (20_257_000 as Weight) + // Standard Error: 22_000 + .saturating_add((5_891_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (25_259_000 as Weight) + (20_263_000 as Weight) // Standard Error: 13_000 - .saturating_add((5_120_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((5_438_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (25_249_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_167_000 as Weight).saturating_mul(r as Weight)) + (20_214_000 as Weight) + // Standard Error: 12_000 + .saturating_add((4_882_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (25_247_000 as Weight) - // Standard Error: 10_000 - .saturating_add((5_118_000 as Weight).saturating_mul(r as Weight)) + (20_152_000 as Weight) + // Standard Error: 17_000 + .saturating_add((4_946_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (25_285_000 as Weight) - // Standard Error: 19_000 - .saturating_add((5_051_000 as Weight).saturating_mul(r as Weight)) + (20_216_000 as Weight) + // Standard Error: 18_000 + .saturating_add((4_974_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (25_312_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_207_000 as Weight).saturating_mul(r as Weight)) + (20_195_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_463_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (25_311_000 as Weight) - // Standard Error: 14_000 - .saturating_add((6_982_000 as Weight).saturating_mul(r as Weight)) + (20_170_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_425_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (25_327_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_009_000 as Weight).saturating_mul(r as Weight)) + (20_208_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_424_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (25_318_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_180_000 as Weight).saturating_mul(r as Weight)) + (20_244_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (25_330_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_065_000 as Weight).saturating_mul(r as Weight)) + (20_218_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_384_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (25_284_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_192_000 as Weight).saturating_mul(r as Weight)) + (20_208_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (25_310_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_080_000 as Weight).saturating_mul(r as Weight)) + (20_201_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_375_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (25_262_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_079_000 as Weight).saturating_mul(r as Weight)) + (20_213_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_460_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (25_295_000 as Weight) - // Standard Error: 10_000 - .saturating_add((7_151_000 as Weight).saturating_mul(r as Weight)) + (20_141_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_498_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (25_326_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_200_000 as Weight).saturating_mul(r as Weight)) + (20_213_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_373_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (25_320_000 as Weight) - // Standard Error: 23_000 - .saturating_add((7_020_000 as Weight).saturating_mul(r as Weight)) + (20_137_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_325_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (25_303_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_189_000 as Weight).saturating_mul(r as Weight)) + (20_148_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (25_311_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_054_000 as Weight).saturating_mul(r as Weight)) + (20_152_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_264_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (25_342_000 as Weight) - // Standard Error: 10_000 - .saturating_add((12_860_000 as Weight).saturating_mul(r as Weight)) + (20_153_000 as Weight) + // Standard Error: 16_000 + .saturating_add((13_755_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (25_307_000 as Weight) - // Standard Error: 17_000 - .saturating_add((12_162_000 as Weight).saturating_mul(r as Weight)) + (20_135_000 as Weight) + // Standard Error: 19_000 + .saturating_add((12_845_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (25_354_000 as Weight) - // Standard Error: 12_000 - .saturating_add((12_855_000 as Weight).saturating_mul(r as Weight)) + (20_203_000 as Weight) + // Standard Error: 16_000 + .saturating_add((13_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (25_319_000 as Weight) - // Standard Error: 16_000 - .saturating_add((11_982_000 as Weight).saturating_mul(r as Weight)) + (20_110_000 as Weight) + // Standard Error: 30_000 + .saturating_add((12_880_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (25_351_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_124_000 as Weight).saturating_mul(r as Weight)) + (20_098_000 as Weight) + // Standard Error: 12_000 + .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (25_333_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_060_000 as Weight).saturating_mul(r as Weight)) + (20_156_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_428_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (25_332_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_080_000 as Weight).saturating_mul(r as Weight)) + (20_163_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_343_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (25_279_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_193_000 as Weight).saturating_mul(r as Weight)) + (20_167_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_610_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (25_315_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_157_000 as Weight).saturating_mul(r as Weight)) + (20_192_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_660_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (25_354_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_238_000 as Weight).saturating_mul(r as Weight)) + (20_162_000 as Weight) + // Standard Error: 26_000 + .saturating_add((7_652_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (25_353_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_160_000 as Weight).saturating_mul(r as Weight)) + (20_151_000 as Weight) + // Standard Error: 12_000 + .saturating_add((7_890_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (25_363_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_192_000 as Weight).saturating_mul(r as Weight)) + (20_154_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_434_000 as Weight).saturating_mul(r as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { fn on_initialize() -> Weight { - (3_610_000 as Weight) + (3_676_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) } fn on_initialize_per_trie_key(k: u32, ) -> Weight { (0 as Weight) // Standard Error: 2_000 - .saturating_add((2_307_000 as Weight).saturating_mul(k as Weight)) + .saturating_add((2_259_000 as Weight).saturating_mul(k as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } fn on_initialize_per_queue_item(q: u32, ) -> Weight { - (18_635_000 as Weight) - // Standard Error: 8_000 - .saturating_add((33_246_000 as Weight).saturating_mul(q as Weight)) + (0 as Weight) + // Standard Error: 33_000 + .saturating_add((35_157_000 as Weight).saturating_mul(q as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instrument(c: u32, ) -> Weight { - (36_950_000 as Weight) - // Standard Error: 198_000 - .saturating_add((116_526_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - fn update_schedule() -> Weight { - (28_095_000 as Weight) + (42_341_000 as Weight) + // Standard Error: 190_000 + .saturating_add((95_696_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instantiate_with_code(c: u32, s: u32, ) -> Weight { - (230_039_000 as Weight) - // Standard Error: 143_000 - .saturating_add((157_483_000 as Weight).saturating_mul(c as Weight)) + (178_191_000 as Weight) + // Standard Error: 141_000 + .saturating_add((135_736_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 9_000 - .saturating_add((2_992_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add((1_867_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } fn instantiate(c: u32, s: u32, ) -> Weight { - (203_983_000 as Weight) + (183_874_000 as Weight) // Standard Error: 11_000 - .saturating_add((8_639_000 as Weight).saturating_mul(c as Weight)) + .saturating_add((8_659_000 as Weight).saturating_mul(c as Weight)) // Standard Error: 1_000 - .saturating_add((2_918_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add((1_781_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn call(c: u32, ) -> Weight { - (198_905_000 as Weight) + (186_051_000 as Weight) // Standard Error: 1_000 - .saturating_add((3_913_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add((3_919_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn claim_surcharge(c: u32, ) -> Weight { - (132_586_000 as Weight) - // Standard Error: 1_000 - .saturating_add((4_732_000 as Weight).saturating_mul(c as Weight)) + (133_967_000 as Weight) + // Standard Error: 2_000 + .saturating_add((4_733_000 as Weight).saturating_mul(c as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (179_629_000 as Weight) - // Standard Error: 318_000 - .saturating_add((250_628_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (131_758_000 as Weight) + // Standard Error: 361_000 + .saturating_add((249_131_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (144_806_000 as Weight) - // Standard Error: 71_000 - .saturating_add((251_588_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (141_100_000 as Weight) + // Standard Error: 73_000 + .saturating_add((245_593_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (151_919_000 as Weight) - // Standard Error: 90_000 - .saturating_add((243_733_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (141_578_000 as Weight) + // Standard Error: 76_000 + .saturating_add((240_505_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (157_448_000 as Weight) - // Standard Error: 211_000 - .saturating_add((559_875_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (144_329_000 as Weight) + // Standard Error: 197_000 + .saturating_add((529_903_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (145_161_000 as Weight) - // Standard Error: 71_000 - .saturating_add((246_729_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (137_318_000 as Weight) + // Standard Error: 77_000 + .saturating_add((239_623_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (147_920_000 as Weight) - // Standard Error: 60_000 - .saturating_add((245_135_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (138_343_000 as Weight) + // Standard Error: 260_000 + .saturating_add((241_997_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (141_105_000 as Weight) - // Standard Error: 138_000 - .saturating_add((247_840_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (138_989_000 as Weight) + // Standard Error: 77_000 + .saturating_add((239_424_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (147_393_000 as Weight) - // Standard Error: 77_000 - .saturating_add((247_593_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (140_118_000 as Weight) + // Standard Error: 83_000 + .saturating_add((240_866_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (151_560_000 as Weight) - // Standard Error: 92_000 - .saturating_add((242_469_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (139_962_000 as Weight) + // Standard Error: 69_000 + .saturating_add((239_267_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (145_917_000 as Weight) - // Standard Error: 80_000 - .saturating_add((244_335_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (139_652_000 as Weight) + // Standard Error: 69_000 + .saturating_add((240_282_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_rent_params(r: u32, ) -> Weight { - (150_399_000 as Weight) - // Standard Error: 90_000 - .saturating_add((381_505_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (136_806_000 as Weight) + // Standard Error: 104_000 + .saturating_add((359_911_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (152_906_000 as Weight) - // Standard Error: 418_000 - .saturating_add((486_338_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + (148_086_000 as Weight) + // Standard Error: 116_000 + .saturating_add((470_271_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (130_020_000 as Weight) - // Standard Error: 48_000 - .saturating_add((120_792_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (123_560_000 as Weight) + // Standard Error: 295_000 + .saturating_add((119_119_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (142_031_000 as Weight) + (132_420_000 as Weight) // Standard Error: 83_000 - .saturating_add((7_205_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add((6_835_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (151_770_000 as Weight) + (142_119_000 as Weight) // Standard Error: 0 - .saturating_add((247_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add((245_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (131_023_000 as Weight) - // Standard Error: 69_000 - .saturating_add((4_823_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (121_030_000 as Weight) + // Standard Error: 68_000 + .saturating_add((4_444_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (142_885_000 as Weight) + (131_704_000 as Weight) // Standard Error: 1_000 - .saturating_add((751_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add((756_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (142_165_000 as Weight) - // Standard Error: 100_000 - .saturating_add((99_133_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (132_544_000 as Weight) + // Standard Error: 113_000 + .saturating_add((97_343_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_terminate_per_code_kb(c: u32, ) -> Weight { - (243_348_000 as Weight) - // Standard Error: 6_000 - .saturating_add((8_560_000 as Weight).saturating_mul(c as Weight)) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + (234_751_000 as Weight) + // Standard Error: 3_000 + .saturating_add((8_482_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } fn seal_restore_to(r: u32, ) -> Weight { - (171_766_000 as Weight) - // Standard Error: 372_000 - .saturating_add((100_243_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (156_439_000 as Weight) + // Standard Error: 1_068_000 + .saturating_add((96_724_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((5 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_code_kb_delta(c: u32, t: u32, d: u32, ) -> Weight { - (112_646_000 as Weight) - // Standard Error: 142_000 - .saturating_add((7_922_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 142_000 - .saturating_add((3_590_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 1_255_000 - .saturating_add((3_716_501_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + (101_920_000 as Weight) + // Standard Error: 162_000 + .saturating_add((7_588_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 162_000 + .saturating_add((3_475_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 1_431_000 + .saturating_add((3_733_137_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (152_470_000 as Weight) - // Standard Error: 146_000 - .saturating_add((619_676_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + (151_598_000 as Weight) + // Standard Error: 168_000 + .saturating_add((608_967_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (151_008_000 as Weight) - // Standard Error: 167_000 - .saturating_add((899_677_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (149_224_000 as Weight) + // Standard Error: 205_000 + .saturating_add((896_074_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_227_526_000 as Weight) - // Standard Error: 2_767_000 - .saturating_add((586_284_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 545_000 - .saturating_add((247_578_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (1_198_650_000 as Weight) + // Standard Error: 2_742_000 + .saturating_add((566_152_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 540_000 + .saturating_add((248_898_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (142_734_000 as Weight) - // Standard Error: 53_000 - .saturating_add((167_026_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (133_149_000 as Weight) + // Standard Error: 72_000 + .saturating_add((163_281_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn seal_debug_message(r: u32, ) -> Weight { + (126_413_000 as Weight) + // Standard Error: 127_000 + .saturating_add((128_176_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (21_198_000 as Weight) - // Standard Error: 2_062_000 - .saturating_add((3_836_800_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 1_710_000 + .saturating_add((3_933_779_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (589_829_000 as Weight) - // Standard Error: 223_000 - .saturating_add((71_242_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + (582_721_000 as Weight) + // Standard Error: 228_000 + .saturating_add((71_341_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 1_950_000 - .saturating_add((1_267_479_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + // Standard Error: 2_470_000 + .saturating_add((1_281_241_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (3_466_000 as Weight) - // Standard Error: 1_248_000 - .saturating_add((920_416_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (11_848_000 as Weight) + // Standard Error: 1_028_000 + .saturating_add((934_213_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (618_423_000 as Weight) - // Standard Error: 231_000 - .saturating_add((153_218_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + (602_494_000 as Weight) + // Standard Error: 255_000 + .saturating_add((152_885_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (76_247_000 as Weight) - // Standard Error: 2_153_000 - .saturating_add((5_509_779_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 1_746_000 + .saturating_add((5_264_601_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)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 8_294_000 - .saturating_add((11_951_311_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + // Standard Error: 13_325_000 + .saturating_add((11_706_784_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((200 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call_per_code_transfer_input_output_kb(c: u32, t: u32, i: u32, o: u32, ) -> Weight { - (10_875_657_000 as Weight) - // Standard Error: 253_000 - .saturating_add((392_140_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 105_395_000 - .saturating_add((3_581_966_000 as Weight).saturating_mul(t as Weight)) - // Standard Error: 33_000 - .saturating_add((59_352_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 35_000 - .saturating_add((79_149_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(RocksDbWeight::get().reads(206 as Weight)) + (9_518_851_000 as Weight) + // Standard Error: 349_000 + .saturating_add((391_414_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 145_480_000 + .saturating_add((4_113_632_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 46_000 + .saturating_add((60_888_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 49_000 + .saturating_add((79_489_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(RocksDbWeight::get().reads(205 as Weight)) .saturating_add(RocksDbWeight::get().writes(101 as Weight)) .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - // Standard Error: 31_795_000 - .saturating_add((21_908_561_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + // Standard Error: 39_418_000 + .saturating_add((21_356_322_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) .saturating_add(RocksDbWeight::get().writes((300 as Weight).saturating_mul(r as Weight))) } fn seal_instantiate_per_code_input_output_salt_kb(c: u32, i: u32, o: u32, s: u32, ) -> Weight { - (10_580_308_000 as Weight) - // Standard Error: 611_000 - .saturating_add((875_153_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 86_000 - .saturating_add((62_540_000 as Weight).saturating_mul(i as Weight)) - // Standard Error: 86_000 - .saturating_add((83_080_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 86_000 - .saturating_add((350_970_000 as Weight).saturating_mul(s as Weight)) - .saturating_add(RocksDbWeight::get().reads(207 as Weight)) + (12_419_243_000 as Weight) + // Standard Error: 1_454_000 + .saturating_add((848_075_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 206_000 + .saturating_add((61_500_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 206_000 + .saturating_add((82_895_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 206_000 + .saturating_add((236_893_000 as Weight).saturating_mul(s as Weight)) + .saturating_add(RocksDbWeight::get().reads(206 as Weight)) .saturating_add(RocksDbWeight::get().writes(204 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (143_987_000 as Weight) - // Standard Error: 90_000 - .saturating_add((232_215_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (129_427_000 as Weight) + // Standard Error: 110_000 + .saturating_add((227_721_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (762_075_000 as Weight) - // Standard Error: 64_000 - .saturating_add((475_112_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (0 as Weight) + // Standard Error: 202_000 + .saturating_add((494_366_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (145_456_000 as Weight) - // Standard Error: 203_000 - .saturating_add((241_831_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (133_222_000 as Weight) + // Standard Error: 330_000 + .saturating_add((237_008_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (660_371_000 as Weight) - // Standard Error: 30_000 - .saturating_add((342_147_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (1_245_757_000 as Weight) + // Standard Error: 77_000 + .saturating_add((339_755_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (149_472_000 as Weight) - // Standard Error: 101_000 - .saturating_add((212_899_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (133_091_000 as Weight) + // Standard Error: 126_000 + .saturating_add((208_234_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (643_371_000 as Weight) - // Standard Error: 31_000 - .saturating_add((159_244_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (799_510_000 as Weight) + // Standard Error: 49_000 + .saturating_add((158_583_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (147_732_000 as Weight) - // Standard Error: 91_000 - .saturating_add((210_975_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (130_180_000 as Weight) + // Standard Error: 83_000 + .saturating_add((206_505_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (684_085_000 as Weight) - // Standard Error: 38_000 - .saturating_add((159_213_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (965_700_000 as Weight) + // Standard Error: 64_000 + .saturating_add((154_387_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (25_332_000 as Weight) - // Standard Error: 12_000 - .saturating_add((3_087_000 as Weight).saturating_mul(r as Weight)) + (20_233_000 as Weight) + // Standard Error: 21_000 + .saturating_add((3_445_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (27_404_000 as Weight) - // Standard Error: 22_000 - .saturating_add((136_046_000 as Weight).saturating_mul(r as Weight)) + (29_798_000 as Weight) + // Standard Error: 1_137_000 + .saturating_add((137_787_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (27_422_000 as Weight) - // Standard Error: 24_000 - .saturating_add((204_925_000 as Weight).saturating_mul(r as Weight)) + (22_914_000 as Weight) + // Standard Error: 701_000 + .saturating_add((205_918_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (25_289_000 as Weight) - // Standard Error: 16_000 - .saturating_add((12_375_000 as Weight).saturating_mul(r as Weight)) + (20_225_000 as Weight) + // Standard Error: 20_000 + .saturating_add((12_545_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (25_278_000 as Weight) - // Standard Error: 14_000 - .saturating_add((11_447_000 as Weight).saturating_mul(r as Weight)) + (20_196_000 as Weight) + // Standard Error: 19_000 + .saturating_add((12_677_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (25_283_000 as Weight) - // Standard Error: 15_000 - .saturating_add((5_615_000 as Weight).saturating_mul(r as Weight)) + (20_204_000 as Weight) + // Standard Error: 19_000 + .saturating_add((6_920_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (25_377_000 as Weight) - // Standard Error: 20_000 - .saturating_add((13_248_000 as Weight).saturating_mul(r as Weight)) + (20_220_000 as Weight) + // Standard Error: 30_000 + .saturating_add((15_209_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (25_318_000 as Weight) - // Standard Error: 14_000 - .saturating_add((14_962_000 as Weight).saturating_mul(r as Weight)) + (20_262_000 as Weight) + // Standard Error: 37_000 + .saturating_add((15_909_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (37_040_000 as Weight) - // Standard Error: 1_000 - .saturating_add((150_000 as Weight).saturating_mul(e as Weight)) + (35_644_000 as Weight) + // Standard Error: 0 + .saturating_add((82_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (25_529_000 as Weight) - // Standard Error: 114_000 - .saturating_add((91_613_000 as Weight).saturating_mul(r as Weight)) + (20_566_000 as Weight) + // Standard Error: 79_000 + .saturating_add((91_776_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (33_242_000 as Weight) - // Standard Error: 188_000 - .saturating_add((191_383_000 as Weight).saturating_mul(r as Weight)) + (28_243_000 as Weight) + // Standard Error: 207_000 + .saturating_add((169_342_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (228_146_000 as Weight) + (206_233_000 as Weight) // Standard Error: 4_000 - .saturating_add((3_917_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((4_685_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (44_304_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_146_000 as Weight).saturating_mul(r as Weight)) + (37_775_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_553_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (44_314_000 as Weight) - // Standard Error: 17_000 - .saturating_add((3_474_000 as Weight).saturating_mul(r as Weight)) + (37_836_000 as Weight) + // Standard Error: 19_000 + .saturating_add((3_745_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (44_234_000 as Weight) - // Standard Error: 14_000 - .saturating_add((4_725_000 as Weight).saturating_mul(r as Weight)) + (37_816_000 as Weight) + // Standard Error: 21_000 + .saturating_add((4_929_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (28_754_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_898_000 as Weight).saturating_mul(r as Weight)) + (23_385_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_494_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (28_737_000 as Weight) - // Standard Error: 26_000 - .saturating_add((8_531_000 as Weight).saturating_mul(r as Weight)) + (23_334_000 as Weight) + // Standard Error: 24_000 + .saturating_add((8_306_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (27_338_000 as Weight) - // Standard Error: 22_000 - .saturating_add((3_499_000 as Weight).saturating_mul(r as Weight)) + (22_311_000 as Weight) + // Standard Error: 27_000 + .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_943_000 as Weight) - // Standard Error: 299_000 - .saturating_add((2_094_164_000 as Weight).saturating_mul(r as Weight)) + (20_789_000 as Weight) + // Standard Error: 269_000 + .saturating_add((2_070_923_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (25_269_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_135_000 as Weight).saturating_mul(r as Weight)) + (20_196_000 as Weight) + // Standard Error: 20_000 + .saturating_add((5_132_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (25_281_000 as Weight) - // Standard Error: 16_000 - .saturating_add((5_069_000 as Weight).saturating_mul(r as Weight)) + (20_215_000 as Weight) + // Standard Error: 7_000 + .saturating_add((5_053_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (25_243_000 as Weight) - // Standard Error: 9_000 - .saturating_add((5_809_000 as Weight).saturating_mul(r as Weight)) + (20_257_000 as Weight) + // Standard Error: 22_000 + .saturating_add((5_891_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (25_259_000 as Weight) + (20_263_000 as Weight) // Standard Error: 13_000 - .saturating_add((5_120_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((5_438_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (25_249_000 as Weight) - // Standard Error: 14_000 - .saturating_add((5_167_000 as Weight).saturating_mul(r as Weight)) + (20_214_000 as Weight) + // Standard Error: 12_000 + .saturating_add((4_882_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (25_247_000 as Weight) - // Standard Error: 10_000 - .saturating_add((5_118_000 as Weight).saturating_mul(r as Weight)) + (20_152_000 as Weight) + // Standard Error: 17_000 + .saturating_add((4_946_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (25_285_000 as Weight) - // Standard Error: 19_000 - .saturating_add((5_051_000 as Weight).saturating_mul(r as Weight)) + (20_216_000 as Weight) + // Standard Error: 18_000 + .saturating_add((4_974_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (25_312_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_207_000 as Weight).saturating_mul(r as Weight)) + (20_195_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_463_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (25_311_000 as Weight) - // Standard Error: 14_000 - .saturating_add((6_982_000 as Weight).saturating_mul(r as Weight)) + (20_170_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_425_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (25_327_000 as Weight) - // Standard Error: 19_000 - .saturating_add((7_009_000 as Weight).saturating_mul(r as Weight)) + (20_208_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_424_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (25_318_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_180_000 as Weight).saturating_mul(r as Weight)) + (20_244_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_391_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (25_330_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_065_000 as Weight).saturating_mul(r as Weight)) + (20_218_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_384_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (25_284_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_192_000 as Weight).saturating_mul(r as Weight)) + (20_208_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (25_310_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_080_000 as Weight).saturating_mul(r as Weight)) + (20_201_000 as Weight) + // Standard Error: 25_000 + .saturating_add((7_375_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (25_262_000 as Weight) - // Standard Error: 11_000 - .saturating_add((7_079_000 as Weight).saturating_mul(r as Weight)) + (20_213_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_460_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (25_295_000 as Weight) - // Standard Error: 10_000 - .saturating_add((7_151_000 as Weight).saturating_mul(r as Weight)) + (20_141_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_498_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (25_326_000 as Weight) - // Standard Error: 18_000 - .saturating_add((7_200_000 as Weight).saturating_mul(r as Weight)) + (20_213_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_373_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (25_320_000 as Weight) - // Standard Error: 23_000 - .saturating_add((7_020_000 as Weight).saturating_mul(r as Weight)) + (20_137_000 as Weight) + // Standard Error: 24_000 + .saturating_add((7_325_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (25_303_000 as Weight) - // Standard Error: 15_000 - .saturating_add((7_189_000 as Weight).saturating_mul(r as Weight)) + (20_148_000 as Weight) + // Standard Error: 23_000 + .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (25_311_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_054_000 as Weight).saturating_mul(r as Weight)) + (20_152_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_264_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (25_342_000 as Weight) - // Standard Error: 10_000 - .saturating_add((12_860_000 as Weight).saturating_mul(r as Weight)) + (20_153_000 as Weight) + // Standard Error: 16_000 + .saturating_add((13_755_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (25_307_000 as Weight) - // Standard Error: 17_000 - .saturating_add((12_162_000 as Weight).saturating_mul(r as Weight)) + (20_135_000 as Weight) + // Standard Error: 19_000 + .saturating_add((12_845_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (25_354_000 as Weight) - // Standard Error: 12_000 - .saturating_add((12_855_000 as Weight).saturating_mul(r as Weight)) + (20_203_000 as Weight) + // Standard Error: 16_000 + .saturating_add((13_792_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (25_319_000 as Weight) - // Standard Error: 16_000 - .saturating_add((11_982_000 as Weight).saturating_mul(r as Weight)) + (20_110_000 as Weight) + // Standard Error: 30_000 + .saturating_add((12_880_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (25_351_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_124_000 as Weight).saturating_mul(r as Weight)) + (20_098_000 as Weight) + // Standard Error: 12_000 + .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (25_333_000 as Weight) - // Standard Error: 20_000 - .saturating_add((7_060_000 as Weight).saturating_mul(r as Weight)) + (20_156_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_428_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (25_332_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_080_000 as Weight).saturating_mul(r as Weight)) + (20_163_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_343_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (25_279_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_193_000 as Weight).saturating_mul(r as Weight)) + (20_167_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_610_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (25_315_000 as Weight) - // Standard Error: 13_000 - .saturating_add((7_157_000 as Weight).saturating_mul(r as Weight)) + (20_192_000 as Weight) + // Standard Error: 21_000 + .saturating_add((7_660_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (25_354_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_238_000 as Weight).saturating_mul(r as Weight)) + (20_162_000 as Weight) + // Standard Error: 26_000 + .saturating_add((7_652_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (25_353_000 as Weight) - // Standard Error: 14_000 - .saturating_add((7_160_000 as Weight).saturating_mul(r as Weight)) + (20_151_000 as Weight) + // Standard Error: 12_000 + .saturating_add((7_890_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (25_363_000 as Weight) - // Standard Error: 16_000 - .saturating_add((7_192_000 as Weight).saturating_mul(r as Weight)) + (20_154_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_434_000 as Weight).saturating_mul(r as Weight)) } } From 964c0e024f500779b99e34c0d44981f62898767f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 11 May 2021 08:59:12 +0200 Subject: [PATCH 02/11] Updated CHANGELOG --- frame/contracts/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frame/contracts/CHANGELOG.md b/frame/contracts/CHANGELOG.md index 9660d903bfe8d..80615aaec8793 100644 --- a/frame/contracts/CHANGELOG.md +++ b/frame/contracts/CHANGELOG.md @@ -20,7 +20,11 @@ In other words: Upgrading this pallet will not break pre-existing contracts. ### Added +- Replaced `seal_println` with `seal_debug_message` which allows output to an RPC client. +[1](https://github.com/paritytech/substrate/pull/8773) + - Add new `instantiate` RPC that allows clients to dry-run contract instantiation. +[1](https://github.com/paritytech/substrate/pull/8451) - Make storage and fields of `Schedule` private to the crate. [1](https://github.com/paritytech/substrate/pull/8359) From a9860dd10fafb4485b5f1110f2e65168c34b57d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 11 May 2021 15:40:26 +0200 Subject: [PATCH 03/11] Fix nits from review --- bin/node/runtime/src/lib.rs | 1 - frame/contracts/src/exec.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index cee51a63a2cfc..445df81ae052e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -792,7 +792,6 @@ parameter_types! { ::WeightInfo::on_initialize_per_queue_item(1) - ::WeightInfo::on_initialize_per_queue_item(0) )) / 5) as u32; - pub MaxCodeSize: u32 = 128 * 1024; pub Schedule: pallet_contracts::Schedule = Default::default(); } diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 149e28780b2d9..f46f9b38048b5 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -323,7 +323,7 @@ pub trait Ext: sealing::Sealed { /// This is a no-op if debug message recording is disabled which is always the case /// when the code is executing on-chain. /// - /// Returns `true` if debug message recording is disabled. Otherwise `false` is returned. + /// Returns `true` if debug message recording is enabled. Otherwise `false` is returned. fn append_debug_buffer(&mut self, msg: &str) -> bool; } From f98a4d064df773495ca17d274d22a3c22c8e5320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 10:22:20 +0200 Subject: [PATCH 04/11] Fix migration --- frame/contracts/src/migration.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/frame/contracts/src/migration.rs b/frame/contracts/src/migration.rs index 02de0225732b3..8c5c06fde7ab1 100644 --- a/frame/contracts/src/migration.rs +++ b/frame/contracts/src/migration.rs @@ -15,10 +15,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Config, Weight, Pallet, Schedule}; +use crate::{Config, Weight, Pallet}; use frame_support::{ - storage::StorageValue, - traits::{GetPalletVersion, PalletVersion, Get}, + storage::migration, + traits::{GetPalletVersion, PalletVersion, PalletInfoAccess, Get}, }; pub fn migrate() -> Weight { @@ -27,22 +27,14 @@ pub fn migrate() -> Weight { match >::storage_version() { Some(version) if version == PalletVersion::new(3, 0, 0) => { weight = weight.saturating_add(T::DbWeight::get().writes(1)); - v3_0_0::CurrentSchedule::::kill(); + migration::remove_storage_prefix( + >::name().as_bytes(), + b"CurrentSchedule", + b"", + ); } _ => (), } weight } - -mod v3_0_0 { - use super::*; - - struct Pallet(sp_std::marker::PhantomData); - - frame_support::decl_storage! { - trait Store for Pallet as Contracts { - pub CurrentSchedule: Schedule; - } - } -} From c69b0892cb71dda2267b9fb309ebf6d4c783a294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 10:31:22 +0200 Subject: [PATCH 05/11] Print the debug buffer as tracing message --- frame/contracts/src/exec.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index f46f9b38048b5..c754e338b72e8 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -877,6 +877,7 @@ where // Pop the current frame from the stack and return it in case it needs to interact // with duplicates that might exist on the stack. + // A `None` means that we are returning from the `first_frame`. let frame = self.frames.pop(); if let Some(frame) = frame { @@ -908,6 +909,13 @@ where } } } else { + if let Some(message) = &self.debug_message { + log::trace!( + target: "runtime::contracts", + "Debug Message: {}", + core::str::from_utf8(message).unwrap_or(""), + ); + } // Write back to the root gas meter. self.gas_meter.absorb_nested(mem::take(&mut self.first_frame.nested_meter)); // Only gas counter changes are persisted in case of a failure. From 968fc039e5fbd4af70533181129e8f4974fd51a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 14:34:47 +0200 Subject: [PATCH 06/11] Use `debug` instead of `trace` and update README --- frame/contracts/README.md | 16 ++++++++++++++++ frame/contracts/src/exec.rs | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/frame/contracts/README.md b/frame/contracts/README.md index 5d34a35fc10db..0b34a55ff42f9 100644 --- a/frame/contracts/README.md +++ b/frame/contracts/README.md @@ -63,6 +63,22 @@ Contracts can emit messages to the client when called as RPC through the `seal_d API. This is exposed in ink! via [`ink_env::debug_println()`](https://docs.rs/ink_env/latest/ink_env/fn.debug_println.html). +Those messages are gathered into an internal buffer and send to the RPC client. It is up the the individual client if and how those messages are presented to the user. +This buffer is also printed as a debug message. In order to see these messages on the node +console the log level for the `runtime::contracts` target needs to be raised to at least +the `debug` level. However, those messages are easy to overlook because of the noise generated +by block production. A good starting point for observing them on the console is: + +```bash +cargo run --release -- --dev --tmp -lerror,runtime::contracts=debug +``` + +This raises the log level of `runtime::contracts` to `debug` and all other targets +to `error` in order to prevent them from spamming the console. + +`--dev`: Use a dev chain spec +`--tmp`: Use temporary storage for chain data (the chain state is deleted on exit) + License: Apache-2.0 diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index c754e338b72e8..793b4c4bf291a 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -910,7 +910,7 @@ where } } else { if let Some(message) = &self.debug_message { - log::trace!( + log::debug!( target: "runtime::contracts", "Debug Message: {}", core::str::from_utf8(message).unwrap_or(""), From c71542bcc70c0319fc364448f401197b4b6cd103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 14:36:16 +0200 Subject: [PATCH 07/11] Add additional assert to test --- frame/contracts/src/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 44ac28a60034a..a1308767fb657 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -2900,6 +2900,7 @@ fn debug_message_logging_disabled() { GAS_LIMIT, vec![], )); + assert!(result.debug_message.is_empty()); }); } From af39f5ee414f8d5878934e272896dfdb8797de27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 14:44:51 +0200 Subject: [PATCH 08/11] Rename `schedule_version` to `instruction_weights_version` --- frame/contracts/src/wasm/code_cache.rs | 10 ++++------ frame/contracts/src/wasm/mod.rs | 16 ++++++++-------- frame/contracts/src/wasm/prepare.rs | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index 4b43105c9c153..8df604cdb0e1c 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -132,11 +132,9 @@ where prefab_module.code_hash = code_hash; if let Some((schedule, gas_meter)) = reinstrument { - if prefab_module.schedule_version < schedule.instruction_weights.version { - // The current schedule version is greater than the version of the one cached - // in the storage. - // - // We need to re-instrument the code with the latest schedule here. + if prefab_module.instruction_weights_version < schedule.instruction_weights.version { + // The instruction weights have changed. + // We need to re-instrument the code with the new instruction weights. gas_meter.charge(InstrumentToken(prefab_module.original_code_len))?; private::reinstrument(&mut prefab_module, schedule)?; } @@ -158,7 +156,7 @@ mod private { let original_code = >::get(&prefab_module.code_hash) .ok_or_else(|| Error::::CodeNotFound)?; prefab_module.code = prepare::reinstrument_contract::(original_code, schedule)?; - prefab_module.schedule_version = schedule.instruction_weights.version; + prefab_module.instruction_weights_version = schedule.instruction_weights.version; >::insert(&prefab_module.code_hash, &*prefab_module); Ok(()) } diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 81041e906748f..04e9bf2d905bb 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -45,16 +45,16 @@ pub use tests::MockExt; /// # Note /// /// This data structure is mostly immutable once created and stored. The exceptions that -/// can be changed by calling a contract are `refcount`, `schedule_version` and `code`. +/// can be changed by calling a contract are `refcount`, `instruction_weights_version` and `code`. /// `refcount` can change when a contract instantiates a new contract or self terminates. -/// `schedule_version` and `code` when a contract with an outdated instrumention is called. -/// Therefore one must be careful when holding any in-memory representation of this type while -/// calling into a contract as those fields can get out of date. +/// `instruction_weights_version` and `code` when a contract with an outdated instrumention is +/// called. Therefore one must be careful when holding any in-memory representation of this +/// type while calling into a contract as those fields can get out of date. #[derive(Clone, Encode, Decode)] pub struct PrefabWasmModule { - /// Version of the schedule with which the code was instrumented. + /// Version of the instruction weights with which the code was instrumented. #[codec(compact)] - schedule_version: u32, + instruction_weights_version: u32, /// Initial memory size of a contract's sandbox. #[codec(compact)] initial: u32, @@ -141,10 +141,10 @@ where self.refcount } - /// Decrement schedule_version by 1. Panics if it is already 0. + /// Decrement instruction_weights_version by 1. Panics if it is already 0. #[cfg(test)] pub fn decrement_version(&mut self) { - self.schedule_version = self.schedule_version.checked_sub(1).unwrap(); + self.instruction_weights_version = self.instruction_weights_version.checked_sub(1).unwrap(); } } diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 97692c4917dbc..e595c32555936 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -433,7 +433,7 @@ fn do_preparation( schedule, )?; Ok(PrefabWasmModule { - schedule_version: schedule.instruction_weights.version, + instruction_weights_version: schedule.instruction_weights.version, initial, maximum, _reserved: None, @@ -499,7 +499,7 @@ pub mod benchmarking { let contract_module = ContractModule::new(&original_code, schedule)?; let memory_limits = get_memory_limits(contract_module.scan_imports::<()>(&[])?, schedule)?; Ok(PrefabWasmModule { - schedule_version: schedule.instruction_weights.version, + instruction_weights_version: schedule.instruction_weights.version, initial: memory_limits.0, maximum: memory_limits.1, _reserved: None, From d9203b2f0c7598c10706fce18ae7e76f31f3b772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 14:47:24 +0200 Subject: [PATCH 09/11] Fixed typo --- frame/contracts/src/wasm/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 7aa365555d7f2..0935dbe9cbe3f 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -71,7 +71,7 @@ pub enum ReturnCode { /// The contract that was called is either no contract at all (a plain account) /// or is a tombstone. NotCallable = 8, - /// The call to `seal_debug_message` had to effect because debug message + /// The call to `seal_debug_message` had no effect because debug message /// recording was disabled. LoggingDisabled = 9, } From 05e1b7ecd36612e4aeca179143a20694e7da3517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 14:48:31 +0200 Subject: [PATCH 10/11] Added more comments to wat fixtures --- frame/contracts/fixtures/debug_message_logging_disabled.wat | 2 +- frame/contracts/fixtures/debug_message_works.wat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/contracts/fixtures/debug_message_logging_disabled.wat b/frame/contracts/fixtures/debug_message_logging_disabled.wat index 9ae2ff439125e..cfe238943ad06 100644 --- a/frame/contracts/fixtures/debug_message_logging_disabled.wat +++ b/frame/contracts/fixtures/debug_message_logging_disabled.wat @@ -20,7 +20,7 @@ (i32.const 0) ;; Pointer to the text buffer (i32.const 12) ;; The size of the buffer ) - (i32.const 9) + (i32.const 9) ;; LoggingDisabled return code ) ) diff --git a/frame/contracts/fixtures/debug_message_works.wat b/frame/contracts/fixtures/debug_message_works.wat index 1d3009e97a4dc..61933c2329611 100644 --- a/frame/contracts/fixtures/debug_message_works.wat +++ b/frame/contracts/fixtures/debug_message_works.wat @@ -20,7 +20,7 @@ (i32.const 0) ;; Pointer to the text buffer (i32.const 12) ;; The size of the buffer ) - (i32.const 0) + (i32.const 0) ;; success return code ) ) From 644b6edf750429ac708852d278d3678512685d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 12 May 2021 19:31:06 +0200 Subject: [PATCH 11/11] Add clarification for the `debug_message` field --- frame/contracts/common/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frame/contracts/common/src/lib.rs b/frame/contracts/common/src/lib.rs index 6d8168de4ed79..04c541a59a39f 100644 --- a/frame/contracts/common/src/lib.rs +++ b/frame/contracts/common/src/lib.rs @@ -43,6 +43,10 @@ pub struct ContractResult { /// The contained bytes are valid UTF-8. This is not declared as `String` because /// this type is not allowed within the runtime. /// + /// Clients should not make any assumptions about the format of the buffer. + /// They should just display it as-is. It is **not** only a collection of log lines + /// provided by a contract but a formatted buffer with different sections. + /// /// # Note /// /// The debug message is never generated during on-chain execution. It is reserved for