diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 093a0bb415d09..470ce2ce3180e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,12 +50,13 @@ variables: ARCH: "x86_64" CI_IMAGE: "paritytech/ci-linux:production" BUILDAH_IMAGE: "quay.io/buildah/stable:v1.27" + RELENG_SCRIPTS_BRANCH: "master" RUSTY_CACHIER_SINGLE_BRANCH: master RUSTY_CACHIER_DONT_OPERATE_ON_MAIN_BRANCH: "true" RUSTY_CACHIER_COMPRESSION_METHOD: zstd NEXTEST_FAILURE_OUTPUT: immediate-final NEXTEST_SUCCESS_OUTPUT: final - ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.37" + ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.43" .shared-default: &shared-default retry: diff --git a/Cargo.lock b/Cargo.lock index 33bca4005483c..1e9a87e818641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -490,12 +490,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - [[package]] name = "base64" version = "0.13.1" @@ -1479,9 +1473,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0-rc.0" +version = "4.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da00a7a9a4eb92a0a0f8e75660926d48f0d0f3c537e455c457bcdaa1e16b1ac" +checksum = "8d4ba9852b42210c7538b75484f9daa0655e9a3ac04f693747bb0f02cf3cfe16" dependencies = [ "cfg-if", "fiat-crypto", @@ -8961,6 +8955,7 @@ dependencies = [ "serde", "serde_json", "smallvec", + "snow", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -9134,6 +9129,7 @@ dependencies = [ "sc-network-light", "sc-network-sync", "sc-service", + "sc-utils", "sp-blockchain", "sp-consensus", "sp-consensus-babe", @@ -10039,14 +10035,14 @@ checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" [[package]] name = "snow" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ba5f4d4ff12bdb6a169ed51b7c48c0e0ac4b0b4b31012b2571e97d78d3201d" +checksum = "5ccba027ba85743e09d15c03296797cad56395089b832b48b5a5217880f57733" dependencies = [ "aes-gcm 0.9.4", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0-rc.0", + "curve25519-dalek 4.0.0-rc.1", "rand_core 0.6.4", "ring", "rustc_version 0.4.0", @@ -10357,10 +10353,10 @@ name = "sp-core" version = "7.0.0" dependencies = [ "array-bytes", - "base58", "bitflags", "blake2", "bounded-collections", + "bs58", "criterion", "dyn-clonable", "ed25519-zebra", @@ -10474,6 +10470,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", + "rustversion", "secp256k1", "sp-core", "sp-externalities", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 16f1d0a4cb532..bc9f3af9d879a 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -46,7 +46,7 @@ sp-io = { version = "7.0.0", default-features = false, path = "../../../primitiv frame-executive = { version = "4.0.0-dev", default-features = false, path = "../../../frame/executive" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../../../frame/benchmarking" } frame-benchmarking-pallet-pov = { version = "4.0.0-dev", default-features = false, path = "../../../frame/benchmarking/pov" } -frame-support = { version = "4.0.0-dev", default-features = false, path = "../../../frame/support" } +frame-support = { version = "4.0.0-dev", default-features = false, path = "../../../frame/support", features = ["tuples-96"] } frame-system = { version = "4.0.0-dev", default-features = false, path = "../../../frame/system" } frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../../../frame/system/benchmarking", optional = true } frame-election-provider-support = { version = "4.0.0-dev", default-features = false, path = "../../../frame/election-provider-support" } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 48bea5ddc101f..433ca8e8b839e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -364,7 +364,10 @@ impl pallet_scheduler::Config for Runtime { type RuntimeCall = RuntimeCall; type MaximumWeight = MaximumSchedulerWeight; type ScheduleOrigin = EnsureRoot; + #[cfg(feature = "runtime-benchmarks")] type MaxScheduledPerBlock = ConstU32<512>; + #[cfg(not(feature = "runtime-benchmarks"))] + type MaxScheduledPerBlock = ConstU32<50>; type WeightInfo = pallet_scheduler::weights::SubstrateWeight; type OriginPrivilegeCmp = EqualPrivilegeOnly; type Preimages = Preimage; @@ -1198,13 +1201,6 @@ impl pallet_tips::Config for Runtime { parameter_types! { pub const DepositPerItem: Balance = deposit(1, 0); pub const DepositPerByte: Balance = deposit(0, 1); - pub const DeletionQueueDepth: u32 = 128; - // The lazy deletion runs inside on_initialize. - pub DeletionWeightLimit: Weight = RuntimeBlockWeights::get() - .per_class - .get(DispatchClass::Normal) - .max_total - .unwrap_or(RuntimeBlockWeights::get().max_block); pub Schedule: pallet_contracts::Schedule = Default::default(); } @@ -1227,8 +1223,6 @@ impl pallet_contracts::Config for Runtime { type WeightPrice = pallet_transaction_payment::Pallet; type WeightInfo = pallet_contracts::weights::SubstrateWeight; type ChainExtension = (); - type DeletionQueueDepth = DeletionQueueDepth; - type DeletionWeightLimit = DeletionWeightLimit; type Schedule = Schedule; type AddressGenerator = pallet_contracts::DefaultAddressGenerator; type MaxCodeLen = ConstU32<{ 123 * 1024 }>; diff --git a/client/consensus/aura/src/import_queue.rs b/client/consensus/aura/src/import_queue.rs index 46e0ccb4e302a..ef7a2a1cc865b 100644 --- a/client/consensus/aura/src/import_queue.rs +++ b/client/consensus/aura/src/import_queue.rs @@ -19,7 +19,7 @@ //! Module implementing the logic for verifying and importing AuRa blocks. use crate::{ - aura_err, authorities, find_pre_digest, slot_author, AuthorityId, CompatibilityMode, Error, + authorities, standalone::SealVerificationError, AuthorityId, CompatibilityMode, Error, LOG_TARGET, }; use codec::{Codec, Decode, Encode}; @@ -36,7 +36,7 @@ use sp_api::{ApiExt, ProvideRuntimeApi}; use sp_block_builder::BlockBuilder as BlockBuilderApi; use sp_blockchain::HeaderBackend; use sp_consensus::Error as ConsensusError; -use sp_consensus_aura::{digests::CompatibleDigestItem, inherents::AuraInherentData, AuraApi}; +use sp_consensus_aura::{inherents::AuraInherentData, AuraApi}; use sp_consensus_slots::Slot; use sp_core::{crypto::Pair, ExecutionContext}; use sp_inherents::{CreateInherentDataProviders, InherentDataProvider as _}; @@ -54,7 +54,7 @@ use std::{fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc}; fn check_header( client: &C, slot_now: Slot, - mut header: B::Header, + header: B::Header, hash: B::Hash, authorities: &[AuthorityId

], check_for_equivocation: CheckForEquivocation, @@ -64,27 +64,16 @@ where C: sc_client_api::backend::AuxStore, P::Public: Encode + Decode + PartialEq + Clone, { - let seal = header.digest_mut().pop().ok_or(Error::HeaderUnsealed(hash))?; - - let sig = seal.as_aura_seal().ok_or_else(|| aura_err(Error::HeaderBadSeal(hash)))?; - - let slot = find_pre_digest::(&header)?; - - if slot > slot_now { - header.digest_mut().push(seal); - Ok(CheckedHeader::Deferred(header, slot)) - } else { - // check the signature is valid under the expected authority and - // chain state. - let expected_author = - slot_author::

(slot, authorities).ok_or(Error::SlotAuthorNotFound)?; - - let pre_hash = header.hash(); - - if P::verify(&sig, pre_hash.as_ref(), expected_author) { - if check_for_equivocation.check_for_equivocation() { + let check_result = + crate::standalone::check_header_slot_and_seal::(slot_now, header, authorities); + + match check_result { + Ok((header, slot, seal)) => { + let expected_author = crate::standalone::slot_author::

(slot, &authorities); + let should_equiv_check = check_for_equivocation.check_for_equivocation(); + if let (true, Some(expected)) = (should_equiv_check, expected_author) { if let Some(equivocation_proof) = - check_equivocation(client, slot_now, slot, &header, expected_author) + check_equivocation(client, slot_now, slot, &header, expected) .map_err(Error::Client)? { info!( @@ -98,9 +87,14 @@ where } Ok(CheckedHeader::Checked(header, (slot, seal))) - } else { - Err(Error::BadSignature(hash)) - } + }, + Err(SealVerificationError::Deferred(header, slot)) => + Ok(CheckedHeader::Deferred(header, slot)), + Err(SealVerificationError::Unsealed) => Err(Error::HeaderUnsealed(hash)), + Err(SealVerificationError::BadSeal) => Err(Error::HeaderBadSeal(hash)), + Err(SealVerificationError::BadSignature) => Err(Error::BadSignature(hash)), + Err(SealVerificationError::SlotAuthorNotFound) => Err(Error::SlotAuthorNotFound), + Err(SealVerificationError::InvalidPreDigest(e)) => Err(Error::from(e)), } } diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index a48eeac5ce8b2..1dc364283d5b6 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -33,11 +33,10 @@ use std::{fmt::Debug, hash::Hash, marker::PhantomData, pin::Pin, sync::Arc}; use futures::prelude::*; -use log::{debug, trace}; use codec::{Codec, Decode, Encode}; -use sc_client_api::{backend::AuxStore, BlockOf, UsageProvider}; +use sc_client_api::{backend::AuxStore, BlockOf}; use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy, StateAction}; use sc_consensus_slots::{ BackoffAuthoringBlocksStrategy, InherentDataProviderExt, SimpleSlotWorkerToSlotWorker, @@ -45,20 +44,19 @@ use sc_consensus_slots::{ }; use sc_telemetry::TelemetryHandle; use sp_api::{Core, ProvideRuntimeApi}; -use sp_application_crypto::{AppCrypto, AppPublic}; -use sp_blockchain::{HeaderBackend, Result as CResult}; +use sp_application_crypto::AppPublic; +use sp_blockchain::HeaderBackend; use sp_consensus::{BlockOrigin, Environment, Error as ConsensusError, Proposer, SelectChain}; use sp_consensus_slots::Slot; -use sp_core::crypto::{ByteArray, Pair, Public}; +use sp_core::crypto::{Pair, Public}; use sp_inherents::CreateInherentDataProviders; use sp_keystore::KeystorePtr; -use sp_runtime::{ - traits::{Block as BlockT, Header, Member, NumberFor, Zero}, - DigestItem, -}; +use sp_runtime::traits::{Block as BlockT, Header, Member, NumberFor}; mod import_queue; +pub mod standalone; +pub use crate::standalone::{find_pre_digest, slot_duration}; pub use import_queue::{ build_verifier, import_queue, AuraVerifier, BuildVerifierParams, CheckForEquivocation, ImportQueueParams, @@ -112,39 +110,6 @@ impl Default for CompatibilityMode { } } -/// Get the slot duration for Aura. -pub fn slot_duration(client: &C) -> CResult -where - A: Codec, - B: BlockT, - C: AuxStore + ProvideRuntimeApi + UsageProvider, - C::Api: AuraApi, -{ - client - .runtime_api() - .slot_duration(client.usage_info().chain.best_hash) - .map_err(|err| err.into()) -} - -/// Get slot author for given block along with authorities. -fn slot_author(slot: Slot, authorities: &[AuthorityId

]) -> Option<&AuthorityId

> { - if authorities.is_empty() { - return None - } - - let idx = *slot % (authorities.len() as u64); - assert!( - idx <= usize::MAX as u64, - "It is impossible to have a vector with length beyond the address space; qed", - ); - - let current_author = authorities.get(idx as usize).expect( - "authorities not empty; index constrained to list length;this is a valid index; qed", - ); - - Some(current_author) -} - /// Parameters of [`start_aura`]. pub struct StartAuraParams { /// The duration of a slot. @@ -412,21 +377,11 @@ where slot: Slot, authorities: &Self::AuxData, ) -> Option { - let expected_author = slot_author::

(slot, authorities); - expected_author.and_then(|p| { - if self - .keystore - .has_keys(&[(p.to_raw_vec(), sp_application_crypto::key_types::AURA)]) - { - Some(p.clone()) - } else { - None - } - }) + crate::standalone::claim_slot::

(slot, authorities, &self.keystore).await } fn pre_digest_data(&self, slot: Slot, _claim: &Self::Claim) -> Vec { - vec![>::aura_pre_digest(slot)] + vec![crate::standalone::pre_digest::

(slot)] } async fn block_import_params( @@ -441,28 +396,8 @@ where sc_consensus::BlockImportParams>::Transaction>, ConsensusError, > { - let signature = self - .keystore - .sign_with( - as AppCrypto>::ID, - as AppCrypto>::CRYPTO_ID, - public.as_slice(), - header_hash.as_ref(), - ) - .map_err(|e| ConsensusError::CannotSign(format!("{}. Key: {:?}", e, public)))? - .ok_or_else(|| { - ConsensusError::CannotSign(format!( - "Could not find key in keystore. Key: {:?}", - public - )) - })?; - let signature = signature - .clone() - .try_into() - .map_err(|_| ConsensusError::InvalidSignature(signature, public.to_raw_vec()))?; - let signature_digest_item = - >::aura_seal(signature); + crate::standalone::seal::<_, P>(header_hash, &public, &self.keystore)?; let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); import_block.post_digests.push(signature_digest_item); @@ -526,11 +461,6 @@ where } } -fn aura_err(error: Error) -> Error { - debug!(target: LOG_TARGET, "{}", error); - error -} - /// Aura Errors #[derive(Debug, thiserror::Error)] pub enum Error { @@ -569,22 +499,13 @@ impl From> for String { } } -/// Get pre-digests from the header -pub fn find_pre_digest(header: &B::Header) -> Result> { - if header.number().is_zero() { - return Ok(0.into()) - } - - let mut pre_digest: Option = None; - for log in header.digest().logs() { - trace!(target: LOG_TARGET, "Checking log {:?}", log); - match (CompatibleDigestItem::::as_aura_pre_digest(log), pre_digest.is_some()) { - (Some(_), true) => return Err(aura_err(Error::MultipleHeaders)), - (None, _) => trace!(target: LOG_TARGET, "Ignoring digest not meant for us"), - (s, false) => pre_digest = s, +impl From for Error { + fn from(e: crate::standalone::PreDigestLookupError) -> Self { + match e { + crate::standalone::PreDigestLookupError::MultipleHeaders => Error::MultipleHeaders, + crate::standalone::PreDigestLookupError::NoDigestFound => Error::NoDigestFound, } } - pre_digest.ok_or_else(|| aura_err(Error::NoDigestFound)) } fn authorities( @@ -637,7 +558,7 @@ mod tests { use sc_consensus_slots::{BackoffAuthoringOnFinalizedHeadLagging, SimpleSlotWorker}; use sc_keystore::LocalKeystore; use sc_network_test::{Block as TestBlock, *}; - use sp_application_crypto::key_types::AURA; + use sp_application_crypto::{key_types::AURA, AppCrypto}; use sp_consensus::{DisableProofRecording, NoNetwork as DummyOracle, Proposal}; use sp_consensus_aura::sr25519::AuthorityPair; use sp_inherents::InherentData; @@ -851,22 +772,6 @@ mod tests { .await; } - #[test] - fn authorities_call_works() { - let client = substrate_test_runtime_client::new(); - - assert_eq!(client.chain_info().best_number, 0); - assert_eq!( - authorities(&client, client.chain_info().best_hash, 1, &CompatibilityMode::None) - .unwrap(), - vec![ - Keyring::Alice.public().into(), - Keyring::Bob.public().into(), - Keyring::Charlie.public().into() - ] - ); - } - #[tokio::test] async fn current_node_authority_should_claim_slot() { let net = AuraTestNet::new(4); diff --git a/client/consensus/aura/src/standalone.rs b/client/consensus/aura/src/standalone.rs new file mode 100644 index 0000000000000..0f9b8668d4478 --- /dev/null +++ b/client/consensus/aura/src/standalone.rs @@ -0,0 +1,357 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Standalone functions used within the implementation of Aura. + +use std::fmt::Debug; + +use log::trace; + +use codec::Codec; + +use sc_client_api::{backend::AuxStore, UsageProvider}; +use sp_api::{Core, ProvideRuntimeApi}; +use sp_application_crypto::{AppCrypto, AppPublic}; +use sp_blockchain::Result as CResult; +use sp_consensus::Error as ConsensusError; +use sp_consensus_slots::Slot; +use sp_core::crypto::{ByteArray, Pair}; +use sp_keystore::KeystorePtr; +use sp_runtime::{ + traits::{Block as BlockT, Header, NumberFor, Zero}, + DigestItem, +}; + +pub use sc_consensus_slots::check_equivocation; + +use super::{ + AuraApi, AuthorityId, CompatibilityMode, CompatibleDigestItem, SlotDuration, LOG_TARGET, +}; + +/// Get the slot duration for Aura by reading from a runtime API at the best block's state. +pub fn slot_duration(client: &C) -> CResult +where + A: Codec, + B: BlockT, + C: AuxStore + ProvideRuntimeApi + UsageProvider, + C::Api: AuraApi, +{ + slot_duration_at(client, client.usage_info().chain.best_hash) +} + +/// Get the slot duration for Aura by reading from a runtime API at a given block's state. +pub fn slot_duration_at(client: &C, block_hash: B::Hash) -> CResult +where + A: Codec, + B: BlockT, + C: AuxStore + ProvideRuntimeApi, + C::Api: AuraApi, +{ + client.runtime_api().slot_duration(block_hash).map_err(|err| err.into()) +} + +/// Get the slot author for given block along with authorities. +pub fn slot_author(slot: Slot, authorities: &[AuthorityId

]) -> Option<&AuthorityId

> { + if authorities.is_empty() { + return None + } + + let idx = *slot % (authorities.len() as u64); + assert!( + idx <= usize::MAX as u64, + "It is impossible to have a vector with length beyond the address space; qed", + ); + + let current_author = authorities.get(idx as usize).expect( + "authorities not empty; index constrained to list length;this is a valid index; qed", + ); + + Some(current_author) +} + +/// Attempt to claim a slot using a keystore. +/// +/// This returns `None` if the slot author is not locally controlled, and `Some` if it is, +/// with the public key of the slot author. +pub async fn claim_slot( + slot: Slot, + authorities: &[AuthorityId

], + keystore: &KeystorePtr, +) -> Option { + let expected_author = slot_author::

(slot, authorities); + expected_author.and_then(|p| { + if keystore.has_keys(&[(p.to_raw_vec(), sp_application_crypto::key_types::AURA)]) { + Some(p.clone()) + } else { + None + } + }) +} + +/// Produce the pre-runtime digest containing the slot info. +/// +/// This is intended to be put into the block header prior to runtime execution, +/// so the runtime can read the slot in this way. +pub fn pre_digest(slot: Slot) -> sp_runtime::DigestItem +where + P::Signature: Codec, +{ + >::aura_pre_digest(slot) +} + +/// Produce the seal digest item by signing the hash of a block. +/// +/// Note that after this is added to a block header, the hash of the block will change. +pub fn seal( + header_hash: &Hash, + public: &P::Public, + keystore: &KeystorePtr, +) -> Result +where + Hash: AsRef<[u8]>, + P: Pair, + P::Signature: Codec + TryFrom>, + P::Public: AppPublic, +{ + let signature = keystore + .sign_with( + as AppCrypto>::ID, + as AppCrypto>::CRYPTO_ID, + public.as_slice(), + header_hash.as_ref(), + ) + .map_err(|e| ConsensusError::CannotSign(format!("{}. Key: {:?}", e, public)))? + .ok_or_else(|| { + ConsensusError::CannotSign(format!("Could not find key in keystore. Key: {:?}", public)) + })?; + + let signature = signature + .clone() + .try_into() + .map_err(|_| ConsensusError::InvalidSignature(signature, public.to_raw_vec()))?; + + let signature_digest_item = + >::aura_seal(signature); + + Ok(signature_digest_item) +} + +/// Errors in pre-digest lookup. +#[derive(Debug, thiserror::Error)] +pub enum PreDigestLookupError { + /// Multiple Aura pre-runtime headers + #[error("Multiple Aura pre-runtime headers")] + MultipleHeaders, + /// No Aura pre-runtime digest found + #[error("No Aura pre-runtime digest found")] + NoDigestFound, +} + +/// Extract a pre-digest from a block header. +/// +/// This fails if there is no pre-digest or there are multiple. +/// +/// Returns the `slot` stored in the pre-digest or an error if no pre-digest was found. +pub fn find_pre_digest( + header: &B::Header, +) -> Result { + if header.number().is_zero() { + return Ok(0.into()) + } + + let mut pre_digest: Option = None; + for log in header.digest().logs() { + trace!(target: LOG_TARGET, "Checking log {:?}", log); + match (CompatibleDigestItem::::as_aura_pre_digest(log), pre_digest.is_some()) { + (Some(_), true) => return Err(PreDigestLookupError::MultipleHeaders), + (None, _) => trace!(target: LOG_TARGET, "Ignoring digest not meant for us"), + (s, false) => pre_digest = s, + } + } + pre_digest.ok_or_else(|| PreDigestLookupError::NoDigestFound) +} + +/// Fetch the current set of authorities from the runtime at a specific block. +/// +/// The compatibility mode and context block number informs this function whether +/// to initialize the hypothetical block created by the runtime API as backwards compatibility +/// for older chains. +pub fn fetch_authorities_with_compatibility_mode( + client: &C, + parent_hash: B::Hash, + context_block_number: NumberFor, + compatibility_mode: &CompatibilityMode>, +) -> Result, ConsensusError> +where + A: Codec + Debug, + B: BlockT, + C: ProvideRuntimeApi, + C::Api: AuraApi, +{ + let runtime_api = client.runtime_api(); + + match compatibility_mode { + CompatibilityMode::None => {}, + // Use `initialize_block` until we hit the block that should disable the mode. + CompatibilityMode::UseInitializeBlock { until } => + if *until > context_block_number { + runtime_api + .initialize_block( + parent_hash, + &B::Header::new( + context_block_number, + Default::default(), + Default::default(), + parent_hash, + Default::default(), + ), + ) + .map_err(|_| ConsensusError::InvalidAuthoritiesSet)?; + }, + } + + runtime_api + .authorities(parent_hash) + .ok() + .ok_or(ConsensusError::InvalidAuthoritiesSet) +} + +/// Load the current set of authorities from a runtime at a specific block. +pub fn fetch_authorities( + client: &C, + parent_hash: B::Hash, +) -> Result, ConsensusError> +where + A: Codec + Debug, + B: BlockT, + C: ProvideRuntimeApi, + C::Api: AuraApi, +{ + client + .runtime_api() + .authorities(parent_hash) + .ok() + .ok_or(ConsensusError::InvalidAuthoritiesSet) +} + +/// Errors in slot and seal verification. +#[derive(Debug, thiserror::Error)] +pub enum SealVerificationError

{ + /// Header is deferred to the future. + #[error("Header slot is in the future")] + Deferred(Header, Slot), + + /// The header has no seal digest. + #[error("Header is unsealed.")] + Unsealed, + + /// The header has a malformed seal. + #[error("Header has a malformed seal")] + BadSeal, + + /// The header has a bad signature. + #[error("Header has a bad signature")] + BadSignature, + + /// No slot author found. + #[error("No slot author for provided slot")] + SlotAuthorNotFound, + + /// Header has no valid slot pre-digest. + #[error("Header has no valid slot pre-digest")] + InvalidPreDigest(PreDigestLookupError), +} + +/// Check a header has been signed by the right key. If the slot is too far in the future, an error +/// will be returned. If it's successful, returns the pre-header (i.e. without the seal), +/// the slot, and the digest item containing the seal. +/// +/// Note that this does not check for equivocations, and [`check_equivocation`] is recommended +/// for that purpose. +/// +/// This digest item will always return `Some` when used with `as_aura_seal`. +pub fn check_header_slot_and_seal( + slot_now: Slot, + mut header: B::Header, + authorities: &[AuthorityId

], +) -> Result<(B::Header, Slot, DigestItem), SealVerificationError> +where + P::Signature: Codec, + P::Public: Codec + PartialEq + Clone, +{ + let seal = header.digest_mut().pop().ok_or(SealVerificationError::Unsealed)?; + + let sig = seal.as_aura_seal().ok_or(SealVerificationError::BadSeal)?; + + let slot = find_pre_digest::(&header) + .map_err(SealVerificationError::InvalidPreDigest)?; + + if slot > slot_now { + header.digest_mut().push(seal); + return Err(SealVerificationError::Deferred(header, slot)) + } else { + // check the signature is valid under the expected authority and + // chain state. + let expected_author = + slot_author::

(slot, authorities).ok_or(SealVerificationError::SlotAuthorNotFound)?; + + let pre_hash = header.hash(); + + if P::verify(&sig, pre_hash.as_ref(), expected_author) { + Ok((header, slot, seal)) + } else { + Err(SealVerificationError::BadSignature) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_keyring::sr25519::Keyring; + + #[test] + fn authorities_call_works() { + let client = substrate_test_runtime_client::new(); + + assert_eq!(client.chain_info().best_number, 0); + assert_eq!( + fetch_authorities_with_compatibility_mode( + &client, + client.chain_info().best_hash, + 1, + &CompatibilityMode::None + ) + .unwrap(), + vec![ + Keyring::Alice.public().into(), + Keyring::Bob.public().into(), + Keyring::Charlie.public().into() + ] + ); + + assert_eq!( + fetch_authorities(&client, client.chain_info().best_hash).unwrap(), + vec![ + Keyring::Alice.public().into(), + Keyring::Bob.public().into(), + Keyring::Charlie.public().into() + ] + ); + } +} diff --git a/client/consensus/beefy/src/communication/gossip.rs b/client/consensus/beefy/src/communication/gossip.rs index 2b5e772c0578f..376172fc23370 100644 --- a/client/consensus/beefy/src/communication/gossip.rs +++ b/client/consensus/beefy/src/communication/gossip.rs @@ -28,10 +28,17 @@ use log::{debug, trace}; use parking_lot::{Mutex, RwLock}; use wasm_timer::Instant; -use crate::{communication::peers::KnownPeers, keystore::BeefyKeystore, LOG_TARGET}; +use crate::{ + communication::peers::KnownPeers, + justification::{ + proof_block_num_and_set_id, verify_with_validator_set, BeefyVersionedFinalityProof, + }, + keystore::BeefyKeystore, + LOG_TARGET, +}; use sp_consensus_beefy::{ - crypto::{Public, Signature}, - ValidatorSetId, VoteMessage, + crypto::{AuthorityId, Signature}, + ValidatorSet, ValidatorSetId, VoteMessage, }; // Timeout for rebroadcasting messages. @@ -40,59 +47,128 @@ const REBROADCAST_AFTER: Duration = Duration::from_secs(60); #[cfg(test)] const REBROADCAST_AFTER: Duration = Duration::from_secs(5); -/// Gossip engine messages topic -pub(crate) fn topic() -> B::Hash +/// BEEFY gossip message type that gets encoded and sent on the network. +#[derive(Debug, Encode, Decode)] +pub(crate) enum GossipMessage { + /// BEEFY message with commitment and single signature. + Vote(VoteMessage, AuthorityId, Signature>), + /// BEEFY justification with commitment and signatures. + FinalityProof(BeefyVersionedFinalityProof), +} + +impl GossipMessage { + /// Return inner vote if this message is a Vote. + pub fn unwrap_vote(self) -> Option, AuthorityId, Signature>> { + match self { + GossipMessage::Vote(vote) => Some(vote), + GossipMessage::FinalityProof(_) => None, + } + } + + /// Return inner finality proof if this message is a FinalityProof. + pub fn unwrap_finality_proof(self) -> Option> { + match self { + GossipMessage::Vote(_) => None, + GossipMessage::FinalityProof(proof) => Some(proof), + } + } +} + +/// Gossip engine votes messages topic +pub(crate) fn votes_topic() -> B::Hash where B: Block, { - <::Hashing as Hash>::hash(b"beefy") + <::Hashing as Hash>::hash(b"beefy-votes") } -#[derive(Debug)] -pub(crate) struct GossipVoteFilter { - pub start: NumberFor, - pub end: NumberFor, - pub validator_set_id: ValidatorSetId, +/// Gossip engine justifications messages topic +pub(crate) fn proofs_topic() -> B::Hash +where + B: Block, +{ + <::Hashing as Hash>::hash(b"beefy-justifications") } /// A type that represents hash of the message. pub type MessageHash = [u8; 8]; -struct VotesFilter { - filter: Option>, - live: BTreeMap, fnv::FnvHashSet>, +#[derive(Clone, Debug)] +pub(crate) struct GossipFilterCfg<'a, B: Block> { + pub start: NumberFor, + pub end: NumberFor, + pub validator_set: &'a ValidatorSet, +} + +#[derive(Clone, Debug)] +struct FilterInner { + pub start: NumberFor, + pub end: NumberFor, + pub validator_set: ValidatorSet, +} + +struct Filter { + inner: Option>, + live_votes: BTreeMap, fnv::FnvHashSet>, } -impl VotesFilter { +impl Filter { pub fn new() -> Self { - Self { filter: None, live: BTreeMap::new() } + Self { inner: None, live_votes: BTreeMap::new() } } /// Update filter to new `start` and `set_id`. - fn update(&mut self, filter: GossipVoteFilter) { - self.live.retain(|&round, _| round >= filter.start && round <= filter.end); - self.filter = Some(filter); + fn update(&mut self, cfg: GossipFilterCfg) { + self.live_votes.retain(|&round, _| round >= cfg.start && round <= cfg.end); + // only clone+overwrite big validator_set if set_id changed + match self.inner.as_mut() { + Some(f) if f.validator_set.id() == cfg.validator_set.id() => { + f.start = cfg.start; + f.end = cfg.end; + }, + _ => + self.inner = Some(FilterInner { + start: cfg.start, + end: cfg.end, + validator_set: cfg.validator_set.clone(), + }), + } + } + + /// Return true if `max(session_start, best_beefy) <= round <= best_grandpa`, + /// and vote `set_id` matches session set id. + /// + /// Latest concluded round is still considered alive to allow proper gossiping for it. + fn is_vote_accepted(&self, round: NumberFor, set_id: ValidatorSetId) -> bool { + self.inner + .as_ref() + .map(|f| set_id == f.validator_set.id() && round >= f.start && round <= f.end) + .unwrap_or(false) } /// Return true if `round` is >= than `max(session_start, best_beefy)`, - /// and vote set id matches session set id. + /// and proof `set_id` matches session set id. /// /// Latest concluded round is still considered alive to allow proper gossiping for it. - fn is_live(&self, round: NumberFor, set_id: ValidatorSetId) -> bool { - self.filter + fn is_finality_proof_accepted(&self, round: NumberFor, set_id: ValidatorSetId) -> bool { + self.inner .as_ref() - .map(|f| set_id == f.validator_set_id && round >= f.start && round <= f.end) + .map(|f| set_id == f.validator_set.id() && round >= f.start) .unwrap_or(false) } /// Add new _known_ `hash` to the round's known votes. - fn add_known(&mut self, round: NumberFor, hash: MessageHash) { - self.live.entry(round).or_default().insert(hash); + fn add_known_vote(&mut self, round: NumberFor, hash: MessageHash) { + self.live_votes.entry(round).or_default().insert(hash); } /// Check if `hash` is already part of round's known votes. - fn is_known(&self, round: NumberFor, hash: &MessageHash) -> bool { - self.live.get(&round).map(|known| known.contains(hash)).unwrap_or(false) + fn is_known_vote(&self, round: NumberFor, hash: &MessageHash) -> bool { + self.live_votes.get(&round).map(|known| known.contains(hash)).unwrap_or(false) + } + + fn validator_set(&self) -> Option<&ValidatorSet> { + self.inner.as_ref().map(|f| &f.validator_set) } } @@ -108,8 +184,9 @@ pub(crate) struct GossipValidator where B: Block, { - topic: B::Hash, - votes_filter: RwLock>, + votes_topic: B::Hash, + justifs_topic: B::Hash, + gossip_filter: RwLock>, next_rebroadcast: Mutex, known_peers: Arc>>, } @@ -120,8 +197,9 @@ where { pub fn new(known_peers: Arc>>) -> GossipValidator { GossipValidator { - topic: topic::(), - votes_filter: RwLock::new(VotesFilter::new()), + votes_topic: votes_topic::(), + justifs_topic: proofs_topic::(), + gossip_filter: RwLock::new(Filter::new()), next_rebroadcast: Mutex::new(Instant::now() + REBROADCAST_AFTER), known_peers, } @@ -130,9 +208,79 @@ where /// Update gossip validator filter. /// /// Only votes for `set_id` and rounds `start <= round <= end` will be accepted. - pub(crate) fn update_filter(&self, filter: GossipVoteFilter) { + pub(crate) fn update_filter(&self, filter: GossipFilterCfg) { debug!(target: LOG_TARGET, "🥩 New gossip filter {:?}", filter); - self.votes_filter.write().update(filter); + self.gossip_filter.write().update(filter); + } + + fn validate_vote( + &self, + vote: VoteMessage, AuthorityId, Signature>, + sender: &PeerId, + data: &[u8], + ) -> ValidationResult { + let msg_hash = twox_64(data); + let round = vote.commitment.block_number; + let set_id = vote.commitment.validator_set_id; + self.known_peers.lock().note_vote_for(*sender, round); + + // Verify general usefulness of the message. + // We are going to discard old votes right away (without verification) + // Also we keep track of already received votes to avoid verifying duplicates. + { + let filter = self.gossip_filter.read(); + + if !filter.is_vote_accepted(round, set_id) { + return ValidationResult::Discard + } + + if filter.is_known_vote(round, &msg_hash) { + return ValidationResult::ProcessAndKeep(self.votes_topic) + } + } + + if BeefyKeystore::verify(&vote.id, &vote.signature, &vote.commitment.encode()) { + self.gossip_filter.write().add_known_vote(round, msg_hash); + ValidationResult::ProcessAndKeep(self.votes_topic) + } else { + // TODO: report peer + debug!( + target: LOG_TARGET, + "🥩 Bad signature on message: {:?}, from: {:?}", vote, sender + ); + ValidationResult::Discard + } + } + + fn validate_finality_proof( + &self, + proof: BeefyVersionedFinalityProof, + sender: &PeerId, + ) -> ValidationResult { + let (round, set_id) = proof_block_num_and_set_id::(&proof); + self.known_peers.lock().note_vote_for(*sender, round); + + let guard = self.gossip_filter.read(); + // Verify general usefulness of the justifications. + if !guard.is_finality_proof_accepted(round, set_id) { + return ValidationResult::Discard + } + // Verify justification signatures. + guard + .validator_set() + .map(|validator_set| { + if let Ok(()) = verify_with_validator_set::(round, validator_set, &proof) { + ValidationResult::ProcessAndKeep(self.justifs_topic) + } else { + // TODO: report peer + debug!( + target: LOG_TARGET, + "🥩 Bad signatures on message: {:?}, from: {:?}", proof, sender + ); + ValidationResult::Discard + } + }) + .unwrap_or(ValidationResult::Discard) } } @@ -150,57 +298,38 @@ where sender: &PeerId, mut data: &[u8], ) -> ValidationResult { - if let Ok(msg) = VoteMessage::, Public, Signature>::decode(&mut data) { - let msg_hash = twox_64(data); - let round = msg.commitment.block_number; - let set_id = msg.commitment.validator_set_id; - self.known_peers.lock().note_vote_for(*sender, round); - - // Verify general usefulness of the message. - // We are going to discard old votes right away (without verification) - // Also we keep track of already received votes to avoid verifying duplicates. - { - let filter = self.votes_filter.read(); - - if !filter.is_live(round, set_id) { - return ValidationResult::Discard - } - - if filter.is_known(round, &msg_hash) { - return ValidationResult::ProcessAndKeep(self.topic) - } - } - - if BeefyKeystore::verify(&msg.id, &msg.signature, &msg.commitment.encode()) { - self.votes_filter.write().add_known(round, msg_hash); - return ValidationResult::ProcessAndKeep(self.topic) - } else { - // TODO: report peer - debug!( - target: LOG_TARGET, - "🥩 Bad signature on message: {:?}, from: {:?}", msg, sender - ); - } + match GossipMessage::::decode(&mut data) { + Ok(GossipMessage::Vote(msg)) => self.validate_vote(msg, sender, data), + Ok(GossipMessage::FinalityProof(proof)) => self.validate_finality_proof(proof, sender), + Err(e) => { + debug!(target: LOG_TARGET, "Error decoding message: {}", e); + ValidationResult::Discard + }, } - - ValidationResult::Discard } fn message_expired<'a>(&'a self) -> Box bool + 'a> { - let filter = self.votes_filter.read(); - Box::new(move |_topic, mut data| { - let msg = match VoteMessage::, Public, Signature>::decode(&mut data) { - Ok(vote) => vote, - Err(_) => return true, - }; - - let round = msg.commitment.block_number; - let set_id = msg.commitment.validator_set_id; - let expired = !filter.is_live(round, set_id); - - trace!(target: LOG_TARGET, "🥩 Message for round #{} expired: {}", round, expired); - - expired + let filter = self.gossip_filter.read(); + Box::new(move |_topic, mut data| match GossipMessage::::decode(&mut data) { + Ok(GossipMessage::Vote(msg)) => { + let round = msg.commitment.block_number; + let set_id = msg.commitment.validator_set_id; + let expired = !filter.is_vote_accepted(round, set_id); + trace!(target: LOG_TARGET, "🥩 Vote for round #{} expired: {}", round, expired); + expired + }, + Ok(GossipMessage::FinalityProof(proof)) => { + let (round, set_id) = proof_block_num_and_set_id::(&proof); + let expired = !filter.is_finality_proof_accepted(round, set_id); + trace!( + target: LOG_TARGET, + "🥩 Finality proof for round #{} expired: {}", + round, + expired + ); + expired + }, + Err(_) => true, }) } @@ -219,68 +348,80 @@ where } }; - let filter = self.votes_filter.read(); + let filter = self.gossip_filter.read(); Box::new(move |_who, intent, _topic, mut data| { if let MessageIntent::PeriodicRebroadcast = intent { return do_rebroadcast } - let msg = match VoteMessage::, Public, Signature>::decode(&mut data) { - Ok(vote) => vote, - Err(_) => return false, - }; - - let round = msg.commitment.block_number; - let set_id = msg.commitment.validator_set_id; - let allowed = filter.is_live(round, set_id); - - trace!(target: LOG_TARGET, "🥩 Message for round #{} allowed: {}", round, allowed); - - allowed + match GossipMessage::::decode(&mut data) { + Ok(GossipMessage::Vote(msg)) => { + let round = msg.commitment.block_number; + let set_id = msg.commitment.validator_set_id; + let allowed = filter.is_vote_accepted(round, set_id); + trace!(target: LOG_TARGET, "🥩 Vote for round #{} allowed: {}", round, allowed); + allowed + }, + Ok(GossipMessage::FinalityProof(proof)) => { + let (round, set_id) = proof_block_num_and_set_id::(&proof); + let allowed = filter.is_finality_proof_accepted(round, set_id); + trace!( + target: LOG_TARGET, + "🥩 Finality proof for round #{} allowed: {}", + round, + allowed + ); + allowed + }, + Err(_) => false, + } }) } } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; use crate::keystore::BeefyKeystore; use sc_network_test::Block; use sp_consensus_beefy::{ - crypto::Signature, known_payloads, Commitment, Keyring, MmrRootHash, Payload, VoteMessage, - KEY_TYPE, + crypto::Signature, known_payloads, Commitment, Keyring, MmrRootHash, Payload, + SignedCommitment, VoteMessage, KEY_TYPE, }; use sp_keystore::{testing::MemoryKeystore, Keystore}; #[test] fn known_votes_insert_remove() { - let mut kv = VotesFilter::::new(); + let mut filter = Filter::::new(); let msg_hash = twox_64(b"data"); - - kv.add_known(1, msg_hash); - kv.add_known(1, msg_hash); - kv.add_known(2, msg_hash); - assert_eq!(kv.live.len(), 2); - - kv.add_known(3, msg_hash); - assert!(kv.is_known(3, &msg_hash)); - assert!(!kv.is_known(3, &twox_64(b"other"))); - assert!(!kv.is_known(4, &msg_hash)); - assert_eq!(kv.live.len(), 3); - - assert!(kv.filter.is_none()); - assert!(!kv.is_live(1, 1)); - - kv.update(GossipVoteFilter { start: 3, end: 10, validator_set_id: 1 }); - assert_eq!(kv.live.len(), 1); - assert!(kv.live.contains_key(&3)); - assert!(!kv.is_live(2, 1)); - assert!(kv.is_live(3, 1)); - assert!(kv.is_live(4, 1)); - assert!(!kv.is_live(4, 2)); - - kv.update(GossipVoteFilter { start: 5, end: 10, validator_set_id: 2 }); - assert!(kv.live.is_empty()); + let keys = vec![Keyring::Alice.public()]; + let validator_set = ValidatorSet::::new(keys.clone(), 1).unwrap(); + + filter.add_known_vote(1, msg_hash); + filter.add_known_vote(1, msg_hash); + filter.add_known_vote(2, msg_hash); + assert_eq!(filter.live_votes.len(), 2); + + filter.add_known_vote(3, msg_hash); + assert!(filter.is_known_vote(3, &msg_hash)); + assert!(!filter.is_known_vote(3, &twox_64(b"other"))); + assert!(!filter.is_known_vote(4, &msg_hash)); + assert_eq!(filter.live_votes.len(), 3); + + assert!(filter.inner.is_none()); + assert!(!filter.is_vote_accepted(1, 1)); + + filter.update(GossipFilterCfg { start: 3, end: 10, validator_set: &validator_set }); + assert_eq!(filter.live_votes.len(), 1); + assert!(filter.live_votes.contains_key(&3)); + assert!(!filter.is_vote_accepted(2, 1)); + assert!(filter.is_vote_accepted(3, 1)); + assert!(filter.is_vote_accepted(4, 1)); + assert!(!filter.is_vote_accepted(4, 2)); + + let validator_set = ValidatorSet::::new(keys, 2).unwrap(); + filter.update(GossipFilterCfg { start: 5, end: 10, validator_set: &validator_set }); + assert!(filter.live_votes.is_empty()); } struct TestContext; @@ -302,14 +443,14 @@ mod tests { } } - fn sign_commitment(who: &Keyring, commitment: &Commitment) -> Signature { + pub fn sign_commitment(who: &Keyring, commitment: &Commitment) -> Signature { let store = MemoryKeystore::new(); store.ecdsa_generate_new(KEY_TYPE, Some(&who.to_seed())).unwrap(); let beefy_keystore: BeefyKeystore = Some(store.into()).into(); beefy_keystore.sign(&who.public(), &commitment.encode()).unwrap() } - fn dummy_vote(block_number: u64) -> VoteMessage { + fn dummy_vote(block_number: u64) -> VoteMessage { let payload = Payload::from_single_entry( known_payloads::MMR_ROOT_ID, MmrRootHash::default().encode(), @@ -320,51 +461,111 @@ mod tests { VoteMessage { commitment, id: Keyring::Alice.public(), signature } } + pub fn dummy_proof( + block_number: u64, + validator_set: &ValidatorSet, + ) -> BeefyVersionedFinalityProof { + let payload = Payload::from_single_entry( + known_payloads::MMR_ROOT_ID, + MmrRootHash::default().encode(), + ); + let commitment = Commitment { payload, block_number, validator_set_id: validator_set.id() }; + let signatures = validator_set + .validators() + .iter() + .map(|validator: &AuthorityId| { + Some(sign_commitment(&Keyring::from_public(validator).unwrap(), &commitment)) + }) + .collect(); + + BeefyVersionedFinalityProof::::V1(SignedCommitment { commitment, signatures }) + } + #[test] - fn should_avoid_verifying_signatures_twice() { + fn should_validate_messages() { + let keys = vec![Keyring::Alice.public()]; + let validator_set = ValidatorSet::::new(keys.clone(), 0).unwrap(); let gv = GossipValidator::::new(Arc::new(Mutex::new(KnownPeers::new()))); - gv.update_filter(GossipVoteFilter { start: 0, end: 10, validator_set_id: 0 }); + gv.update_filter(GossipFilterCfg { start: 0, end: 10, validator_set: &validator_set }); let sender = sc_network::PeerId::random(); let mut context = TestContext; let vote = dummy_vote(3); + let gossip_vote = GossipMessage::::Vote(vote.clone()); // first time the cache should be populated - let res = gv.validate(&mut context, &sender, &vote.encode()); + let res = gv.validate(&mut context, &sender, &gossip_vote.encode()); assert!(matches!(res, ValidationResult::ProcessAndKeep(_))); assert_eq!( - gv.votes_filter.read().live.get(&vote.commitment.block_number).map(|x| x.len()), + gv.gossip_filter + .read() + .live_votes + .get(&vote.commitment.block_number) + .map(|x| x.len()), Some(1) ); // second time we should hit the cache - let res = gv.validate(&mut context, &sender, &vote.encode()); - + let res = gv.validate(&mut context, &sender, &gossip_vote.encode()); assert!(matches!(res, ValidationResult::ProcessAndKeep(_))); // next we should quickly reject if the round is not live - gv.update_filter(GossipVoteFilter { start: 7, end: 10, validator_set_id: 0 }); + gv.update_filter(GossipFilterCfg { start: 7, end: 10, validator_set: &validator_set }); let number = vote.commitment.block_number; let set_id = vote.commitment.validator_set_id; - assert!(!gv.votes_filter.read().is_live(number, set_id)); + assert!(!gv.gossip_filter.read().is_vote_accepted(number, set_id)); let res = gv.validate(&mut context, &sender, &vote.encode()); + assert!(matches!(res, ValidationResult::Discard)); + + // reject old proof + let proof = dummy_proof(5, &validator_set); + let encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + let res = gv.validate(&mut context, &sender, &encoded_proof); + assert!(matches!(res, ValidationResult::Discard)); + + // accept next proof with good set_id + let proof = dummy_proof(7, &validator_set); + let encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + let res = gv.validate(&mut context, &sender, &encoded_proof); + assert!(matches!(res, ValidationResult::ProcessAndKeep(_))); + + // accept future proof with good set_id + let proof = dummy_proof(20, &validator_set); + let encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + let res = gv.validate(&mut context, &sender, &encoded_proof); + assert!(matches!(res, ValidationResult::ProcessAndKeep(_))); + // reject proof, wrong set_id + let bad_validator_set = ValidatorSet::::new(keys, 1).unwrap(); + let proof = dummy_proof(20, &bad_validator_set); + let encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + let res = gv.validate(&mut context, &sender, &encoded_proof); + assert!(matches!(res, ValidationResult::Discard)); + + // reject proof, bad signatures (Bob instead of Alice) + let bad_validator_set = + ValidatorSet::::new(vec![Keyring::Bob.public()], 0).unwrap(); + let proof = dummy_proof(20, &bad_validator_set); + let encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + let res = gv.validate(&mut context, &sender, &encoded_proof); assert!(matches!(res, ValidationResult::Discard)); } #[test] fn messages_allowed_and_expired() { + let keys = vec![Keyring::Alice.public()]; + let validator_set = ValidatorSet::::new(keys.clone(), 0).unwrap(); let gv = GossipValidator::::new(Arc::new(Mutex::new(KnownPeers::new()))); - gv.update_filter(GossipVoteFilter { start: 0, end: 10, validator_set_id: 0 }); + gv.update_filter(GossipFilterCfg { start: 0, end: 10, validator_set: &validator_set }); let sender = sc_network::PeerId::random(); let topic = Default::default(); let intent = MessageIntent::Broadcast; // conclude 2 - gv.update_filter(GossipVoteFilter { start: 2, end: 10, validator_set_id: 0 }); + gv.update_filter(GossipFilterCfg { start: 2, end: 10, validator_set: &validator_set }); let mut allowed = gv.message_allowed(); let mut expired = gv.message_expired(); @@ -374,33 +575,68 @@ mod tests { // inactive round 1 -> expired let vote = dummy_vote(1); - let mut encoded_vote = vote.encode(); + let mut encoded_vote = GossipMessage::::Vote(vote).encode(); assert!(!allowed(&sender, intent, &topic, &mut encoded_vote)); assert!(expired(topic, &mut encoded_vote)); + let proof = dummy_proof(1, &validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(!allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(expired(topic, &mut encoded_proof)); // active round 2 -> !expired - concluded but still gossiped let vote = dummy_vote(2); - let mut encoded_vote = vote.encode(); + let mut encoded_vote = GossipMessage::::Vote(vote).encode(); assert!(allowed(&sender, intent, &topic, &mut encoded_vote)); assert!(!expired(topic, &mut encoded_vote)); + let proof = dummy_proof(2, &validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(!expired(topic, &mut encoded_proof)); + // using wrong set_id -> !allowed, expired + let bad_validator_set = ValidatorSet::::new(keys.clone(), 1).unwrap(); + let proof = dummy_proof(2, &bad_validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(!allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(expired(topic, &mut encoded_proof)); // in progress round 3 -> !expired let vote = dummy_vote(3); - let mut encoded_vote = vote.encode(); + let mut encoded_vote = GossipMessage::::Vote(vote).encode(); assert!(allowed(&sender, intent, &topic, &mut encoded_vote)); assert!(!expired(topic, &mut encoded_vote)); + let proof = dummy_proof(3, &validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(!expired(topic, &mut encoded_proof)); // unseen round 4 -> !expired - let vote = dummy_vote(3); - let mut encoded_vote = vote.encode(); + let vote = dummy_vote(4); + let mut encoded_vote = GossipMessage::::Vote(vote).encode(); assert!(allowed(&sender, intent, &topic, &mut encoded_vote)); assert!(!expired(topic, &mut encoded_vote)); + let proof = dummy_proof(4, &validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(!expired(topic, &mut encoded_proof)); + + // future round 11 -> expired + let vote = dummy_vote(11); + let mut encoded_vote = GossipMessage::::Vote(vote).encode(); + assert!(!allowed(&sender, intent, &topic, &mut encoded_vote)); + assert!(expired(topic, &mut encoded_vote)); + // future proofs allowed while same set_id -> allowed + let proof = dummy_proof(11, &validator_set); + let mut encoded_proof = GossipMessage::::FinalityProof(proof).encode(); + assert!(allowed(&sender, intent, &topic, &mut encoded_proof)); + assert!(!expired(topic, &mut encoded_proof)); } #[test] fn messages_rebroadcast() { + let keys = vec![Keyring::Alice.public()]; + let validator_set = ValidatorSet::::new(keys.clone(), 0).unwrap(); let gv = GossipValidator::::new(Arc::new(Mutex::new(KnownPeers::new()))); - gv.update_filter(GossipVoteFilter { start: 0, end: 10, validator_set_id: 0 }); + gv.update_filter(GossipFilterCfg { start: 0, end: 10, validator_set: &validator_set }); let sender = sc_network::PeerId::random(); let topic = Default::default(); diff --git a/client/consensus/beefy/src/communication/mod.rs b/client/consensus/beefy/src/communication/mod.rs index 295d549bb1ba8..13735a9d3211b 100644 --- a/client/consensus/beefy/src/communication/mod.rs +++ b/client/consensus/beefy/src/communication/mod.rs @@ -29,7 +29,7 @@ pub(crate) mod beefy_protocol_name { use sc_network::ProtocolName; /// BEEFY votes gossip protocol name suffix. - const GOSSIP_NAME: &str = "/beefy/1"; + const GOSSIP_NAME: &str = "/beefy/2"; /// BEEFY justifications protocol name suffix. const JUSTIFICATIONS_NAME: &str = "/beefy/justifications/1"; @@ -86,7 +86,7 @@ mod tests { let genesis_hash = H256::random(); let genesis_hex = array_bytes::bytes2hex("", genesis_hash.as_ref()); - let expected_gossip_name = format!("/{}/beefy/1", genesis_hex); + let expected_gossip_name = format!("/{}/beefy/2", genesis_hex); let gossip_proto_name = gossip_protocol_name(&genesis_hash, None); assert_eq!(gossip_proto_name.to_string(), expected_gossip_name); @@ -101,7 +101,7 @@ mod tests { ]; let genesis_hex = "32043c7b3a6ad8f6c2bc8bc121d4caab09377b5e082b0cfbbb39ad13bc4acd93"; - let expected_gossip_name = format!("/{}/beefy/1", genesis_hex); + let expected_gossip_name = format!("/{}/beefy/2", genesis_hex); let gossip_proto_name = gossip_protocol_name(&genesis_hash, None); assert_eq!(gossip_proto_name.to_string(), expected_gossip_name); diff --git a/client/consensus/beefy/src/justification.rs b/client/consensus/beefy/src/justification.rs index 1bd250b2a25f3..5175fd17d4ea3 100644 --- a/client/consensus/beefy/src/justification.rs +++ b/client/consensus/beefy/src/justification.rs @@ -21,13 +21,21 @@ use codec::{Decode, Encode}; use sp_consensus::Error as ConsensusError; use sp_consensus_beefy::{ crypto::{AuthorityId, Signature}, - ValidatorSet, VersionedFinalityProof, + ValidatorSet, ValidatorSetId, VersionedFinalityProof, }; use sp_runtime::traits::{Block as BlockT, NumberFor}; /// A finality proof with matching BEEFY authorities' signatures. -pub type BeefyVersionedFinalityProof = - sp_consensus_beefy::VersionedFinalityProof, Signature>; +pub type BeefyVersionedFinalityProof = VersionedFinalityProof, Signature>; + +pub(crate) fn proof_block_num_and_set_id( + proof: &BeefyVersionedFinalityProof, +) -> (NumberFor, ValidatorSetId) { + match proof { + VersionedFinalityProof::V1(sc) => + (sc.commitment.block_number, sc.commitment.validator_set_id), + } +} /// Decode and verify a Beefy FinalityProof. pub(crate) fn decode_and_verify_finality_proof( @@ -41,7 +49,7 @@ pub(crate) fn decode_and_verify_finality_proof( } /// Verify the Beefy finality proof against the validator set at the block it was generated. -fn verify_with_validator_set( +pub(crate) fn verify_with_validator_set( target_number: NumberFor, validator_set: &ValidatorSet, proof: &BeefyVersionedFinalityProof, diff --git a/client/consensus/beefy/src/lib.rs b/client/consensus/beefy/src/lib.rs index b84fa45e7e2f3..3c66cc6eb716d 100644 --- a/client/consensus/beefy/src/lib.rs +++ b/client/consensus/beefy/src/lib.rs @@ -288,7 +288,7 @@ pub async fn start_beefy_gadget( }; // Update the gossip validator with the right starting round and set id. if let Err(e) = persisted_state - .current_gossip_filter() + .gossip_filter_config() .map(|f| gossip_validator.update_filter(f)) { error!(target: LOG_TARGET, "Error: {:?}. Terminating.", e); diff --git a/client/consensus/beefy/src/round.rs b/client/consensus/beefy/src/round.rs index 64d03beeee854..d8948ff98c552 100644 --- a/client/consensus/beefy/src/round.rs +++ b/client/consensus/beefy/src/round.rs @@ -21,7 +21,7 @@ use crate::LOG_TARGET; use codec::{Decode, Encode}; use log::debug; use sp_consensus_beefy::{ - crypto::{AuthorityId, Public, Signature}, + crypto::{AuthorityId, Signature}, Commitment, EquivocationProof, SignedCommitment, ValidatorSet, ValidatorSetId, VoteMessage, }; use sp_runtime::traits::{Block, NumberFor}; @@ -33,11 +33,11 @@ use std::collections::BTreeMap; /// Does not do any validation on votes or signatures, layers above need to handle that (gossip). #[derive(Debug, Decode, Default, Encode, PartialEq)] pub(crate) struct RoundTracker { - votes: BTreeMap, + votes: BTreeMap, } impl RoundTracker { - fn add_vote(&mut self, vote: (Public, Signature)) -> bool { + fn add_vote(&mut self, vote: (AuthorityId, Signature)) -> bool { if self.votes.contains_key(&vote.0) { return false } @@ -61,7 +61,7 @@ pub fn threshold(authorities: usize) -> usize { pub enum VoteImportResult { Ok, RoundConcluded(SignedCommitment, Signature>), - Equivocation(EquivocationProof, Public, Signature>), + Equivocation(EquivocationProof, AuthorityId, Signature>), Invalid, Stale, } @@ -73,9 +73,10 @@ pub enum VoteImportResult { #[derive(Debug, Decode, Encode, PartialEq)] pub(crate) struct Rounds { rounds: BTreeMap>, RoundTracker>, - previous_votes: BTreeMap<(Public, NumberFor), VoteMessage, Public, Signature>>, + previous_votes: + BTreeMap<(AuthorityId, NumberFor), VoteMessage, AuthorityId, Signature>>, session_start: NumberFor, - validator_set: ValidatorSet, + validator_set: ValidatorSet, mandatory_done: bool, best_done: Option>, } @@ -84,7 +85,10 @@ impl Rounds where B: Block, { - pub(crate) fn new(session_start: NumberFor, validator_set: ValidatorSet) -> Self { + pub(crate) fn new( + session_start: NumberFor, + validator_set: ValidatorSet, + ) -> Self { Rounds { rounds: BTreeMap::new(), previous_votes: BTreeMap::new(), @@ -95,7 +99,7 @@ where } } - pub(crate) fn validator_set(&self) -> &ValidatorSet { + pub(crate) fn validator_set(&self) -> &ValidatorSet { &self.validator_set } @@ -103,7 +107,7 @@ where self.validator_set.id() } - pub(crate) fn validators(&self) -> &[Public] { + pub(crate) fn validators(&self) -> &[AuthorityId] { self.validator_set.validators() } @@ -199,11 +203,11 @@ mod tests { use sc_network_test::Block; use sp_consensus_beefy::{ - crypto::Public, known_payloads::MMR_ROOT_ID, Commitment, EquivocationProof, Keyring, - Payload, SignedCommitment, ValidatorSet, VoteMessage, + known_payloads::MMR_ROOT_ID, Commitment, EquivocationProof, Keyring, Payload, + SignedCommitment, ValidatorSet, VoteMessage, }; - use super::{threshold, Block as BlockT, RoundTracker, Rounds}; + use super::{threshold, AuthorityId, Block as BlockT, RoundTracker, Rounds}; use crate::round::VoteImportResult; impl Rounds @@ -251,7 +255,7 @@ mod tests { fn new_rounds() { sp_tracing::try_init_simple(); - let validators = ValidatorSet::::new( + let validators = ValidatorSet::::new( vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()], 42, ) @@ -272,7 +276,7 @@ mod tests { fn add_and_conclude_votes() { sp_tracing::try_init_simple(); - let validators = ValidatorSet::::new( + let validators = ValidatorSet::::new( vec![ Keyring::Alice.public(), Keyring::Bob.public(), @@ -338,7 +342,7 @@ mod tests { fn old_rounds_not_accepted() { sp_tracing::try_init_simple(); - let validators = ValidatorSet::::new( + let validators = ValidatorSet::::new( vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()], 42, ) @@ -384,7 +388,7 @@ mod tests { fn multiple_rounds() { sp_tracing::try_init_simple(); - let validators = ValidatorSet::::new( + let validators = ValidatorSet::::new( vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()], Default::default(), ) @@ -459,7 +463,7 @@ mod tests { fn should_provide_equivocation_proof() { sp_tracing::try_init_simple(); - let validators = ValidatorSet::::new( + let validators = ValidatorSet::::new( vec![Keyring::Alice.public(), Keyring::Bob.public()], Default::default(), ) diff --git a/client/consensus/beefy/src/tests.rs b/client/consensus/beefy/src/tests.rs index 0ad5f10886093..f36c2cd68f97f 100644 --- a/client/consensus/beefy/src/tests.rs +++ b/client/consensus/beefy/src/tests.rs @@ -21,15 +21,18 @@ use crate::{ aux_schema::{load_persistent, tests::verify_persisted_version}, beefy_block_import_and_links, - communication::request_response::{ - on_demand_justifications_protocol_config, BeefyJustifsRequestHandler, + communication::{ + gossip::{ + proofs_topic, tests::sign_commitment, votes_topic, GossipFilterCfg, GossipMessage, + }, + request_response::{on_demand_justifications_protocol_config, BeefyJustifsRequestHandler}, }, gossip_protocol_name, justification::*, load_or_init_voter_state, wait_for_runtime_pallet, BeefyRPCLinks, BeefyVoterLinks, KnownPeers, PersistedState, }; -use futures::{future, stream::FuturesUnordered, Future, StreamExt}; +use futures::{future, stream::FuturesUnordered, Future, FutureExt, StreamExt}; use parking_lot::Mutex; use sc_client_api::{Backend as BackendT, BlockchainEvents, FinalityNotifications, HeaderBackend}; use sc_consensus::{ @@ -48,16 +51,16 @@ use sp_consensus::BlockOrigin; use sp_consensus_beefy::{ crypto::{AuthorityId, Signature}, known_payloads, - mmr::MmrRootProvider, + mmr::{find_mmr_root_digest, MmrRootProvider}, BeefyApi, Commitment, ConsensusLog, EquivocationProof, Keyring as BeefyKeyring, MmrRootHash, OpaqueKeyOwnershipProof, Payload, SignedCommitment, ValidatorSet, ValidatorSetId, - VersionedFinalityProof, BEEFY_ENGINE_ID, KEY_TYPE as BeefyKeyType, + VersionedFinalityProof, VoteMessage, BEEFY_ENGINE_ID, KEY_TYPE as BeefyKeyType, }; use sp_core::H256; use sp_keystore::{testing::MemoryKeystore, Keystore, KeystorePtr}; use sp_mmr_primitives::{Error as MmrError, MmrApi}; use sp_runtime::{ - codec::Encode, + codec::{Decode, Encode}, traits::{Header as HeaderT, NumberFor}, BuildStorage, DigestItem, EncodedJustification, Justifications, Storage, }; @@ -503,16 +506,15 @@ async fn wait_for_beefy_signed_commitments( run_until(wait_for, net).await; } -async fn streams_empty_after_timeout( +async fn streams_empty_after_future( streams: Vec>, - net: &Arc>, - timeout: Option, + future: Option, ) where T: std::fmt::Debug, T: std::cmp::PartialEq, { - if let Some(timeout) = timeout { - run_for(timeout, net).await; + if let Some(future) = future { + future.await; } for mut stream in streams.into_iter() { future::poll_fn(move |cx| { @@ -523,6 +525,18 @@ async fn streams_empty_after_timeout( } } +async fn streams_empty_after_timeout( + streams: Vec>, + net: &Arc>, + timeout: Option, +) where + T: std::fmt::Debug, + T: std::cmp::PartialEq, +{ + let timeout = timeout.map(|timeout| Box::pin(run_for(timeout, net))); + streams_empty_after_future(streams, timeout).await; +} + async fn finalize_block_and_wait_for_beefy( net: &Arc>, // peer index and key @@ -1229,3 +1243,143 @@ async fn beefy_reports_equivocations() { assert_eq!(equivocation_proof.first.id, BeefyKeyring::Bob.public()); assert_eq!(equivocation_proof.first.commitment.block_number, 1); } + +#[tokio::test] +async fn gossipped_finality_proofs() { + sp_tracing::try_init_simple(); + + let validators = [BeefyKeyring::Alice, BeefyKeyring::Bob, BeefyKeyring::Charlie]; + // Only Alice and Bob are running the voter -> finality threshold not reached + let peers = [BeefyKeyring::Alice, BeefyKeyring::Bob]; + let validator_set = ValidatorSet::new(make_beefy_ids(&validators), 0).unwrap(); + let session_len = 30; + let min_block_delta = 1; + + let mut net = BeefyTestNet::new(3); + let api = Arc::new(TestApi::with_validator_set(&validator_set)); + let beefy_peers = peers.iter().enumerate().map(|(id, key)| (id, key, api.clone())).collect(); + + let charlie = &net.peers[2]; + let known_peers = Arc::new(Mutex::new(KnownPeers::::new())); + // Charlie will run just the gossip engine and not the full voter. + let charlie_gossip_validator = + Arc::new(crate::communication::gossip::GossipValidator::new(known_peers)); + charlie_gossip_validator.update_filter(GossipFilterCfg:: { + start: 1, + end: 10, + validator_set: &validator_set, + }); + let mut charlie_gossip_engine = sc_network_gossip::GossipEngine::new( + charlie.network_service().clone(), + charlie.sync_service().clone(), + beefy_gossip_proto_name(), + charlie_gossip_validator.clone(), + None, + ); + + // Alice and Bob run full voter. + tokio::spawn(initialize_beefy(&mut net, beefy_peers, min_block_delta)); + + let net = Arc::new(Mutex::new(net)); + + // Pump net + Charlie gossip to see peers. + let timeout = Box::pin(tokio::time::sleep(Duration::from_millis(200))); + let gossip_engine_pump = &mut charlie_gossip_engine; + let pump_with_timeout = future::select(gossip_engine_pump, timeout); + run_until(pump_with_timeout, &net).await; + + // push 10 blocks + let hashes = net.lock().generate_blocks_and_sync(10, session_len, &validator_set, true).await; + + let peers = peers.into_iter().enumerate(); + + // Alice, Bob and Charlie finalize #1, Alice and Bob vote on it, but not Charlie. + let finalize = hashes[1]; + let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers.clone()); + net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap(); + net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap(); + net.lock().peer(2).client().as_client().finalize_block(finalize, None).unwrap(); + // verify nothing gets finalized by BEEFY + let timeout = Box::pin(tokio::time::sleep(Duration::from_millis(100))); + let pump_net = futures::future::poll_fn(|cx| { + net.lock().poll(cx); + Poll::<()>::Pending + }); + let pump_gossip = &mut charlie_gossip_engine; + let pump_with_timeout = future::select(pump_gossip, future::select(pump_net, timeout)); + streams_empty_after_future(best_blocks, Some(pump_with_timeout)).await; + streams_empty_after_timeout(versioned_finality_proof, &net, None).await; + + let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers.clone()); + // Charlie gossips finality proof for #1 -> Alice and Bob also finalize. + let proof = crate::communication::gossip::tests::dummy_proof(1, &validator_set); + let gossip_proof = GossipMessage::::FinalityProof(proof); + let encoded_proof = gossip_proof.encode(); + charlie_gossip_engine.gossip_message(proofs_topic::(), encoded_proof, true); + // Expect #1 is finalized. + wait_for_best_beefy_blocks(best_blocks, &net, &[1]).await; + wait_for_beefy_signed_commitments(versioned_finality_proof, &net, &[1]).await; + + // Code above verifies gossipped finality proofs are correctly imported and consumed by voters. + // Next, let's verify finality proofs are correctly generated and gossipped by voters. + + // Everyone finalizes #2 + let block_number = 2u64; + let finalize = hashes[block_number as usize]; + let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers.clone()); + net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap(); + net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap(); + net.lock().peer(2).client().as_client().finalize_block(finalize, None).unwrap(); + + // Simulate Charlie vote on #2 + let header = net.lock().peer(2).client().as_client().expect_header(finalize).unwrap(); + let mmr_root = find_mmr_root_digest::(&header).unwrap(); + let payload = Payload::from_single_entry(known_payloads::MMR_ROOT_ID, mmr_root.encode()); + let commitment = Commitment { payload, block_number, validator_set_id: validator_set.id() }; + let signature = sign_commitment(&BeefyKeyring::Charlie, &commitment); + let vote_message = VoteMessage { commitment, id: BeefyKeyring::Charlie.public(), signature }; + let encoded_vote = GossipMessage::::Vote(vote_message).encode(); + charlie_gossip_engine.gossip_message(votes_topic::(), encoded_vote, true); + + // Expect #2 is finalized. + wait_for_best_beefy_blocks(best_blocks, &net, &[2]).await; + wait_for_beefy_signed_commitments(versioned_finality_proof, &net, &[2]).await; + + // Now verify Charlie also sees the gossipped proof generated by either Alice or Bob. + let mut charlie_gossip_proofs = Box::pin( + charlie_gossip_engine + .messages_for(proofs_topic::()) + .filter_map(|notification| async move { + GossipMessage::::decode(&mut ¬ification.message[..]).ok().and_then( + |message| match message { + GossipMessage::::Vote(_) => unreachable!(), + GossipMessage::::FinalityProof(proof) => Some(proof), + }, + ) + }) + .fuse(), + ); + loop { + let pump_net = futures::future::poll_fn(|cx| { + net.lock().poll(cx); + Poll::<()>::Pending + }); + let mut gossip_engine = &mut charlie_gossip_engine; + futures::select! { + // pump gossip engine + _ = gossip_engine => unreachable!(), + // pump network + _ = pump_net.fuse() => unreachable!(), + // verify finality proof has been gossipped + proof = charlie_gossip_proofs.next() => { + let proof = proof.unwrap(); + let (round, _) = proof_block_num_and_set_id::(&proof); + match round { + 1 => continue, // finality proof generated by Charlie in the previous round + 2 => break, // finality proof generated by Alice or Bob and gossiped to Charlie + _ => panic!("Charlie got unexpected finality proof"), + } + }, + } + } +} diff --git a/client/consensus/beefy/src/worker.rs b/client/consensus/beefy/src/worker.rs index 0260d7693c654..19225ec214578 100644 --- a/client/consensus/beefy/src/worker.rs +++ b/client/consensus/beefy/src/worker.rs @@ -18,7 +18,7 @@ use crate::{ communication::{ - gossip::{topic, GossipValidator, GossipVoteFilter}, + gossip::{proofs_topic, votes_topic, GossipFilterCfg, GossipMessage, GossipValidator}, request_response::outgoing_requests_engine::OnDemandJustificationsEngine, }, error::Error, @@ -42,7 +42,7 @@ use sp_consensus_beefy::{ check_equivocation_proof, crypto::{AuthorityId, Signature}, BeefyApi, Commitment, ConsensusLog, EquivocationProof, PayloadProvider, ValidatorSet, - ValidatorSetId, VersionedFinalityProof, VoteMessage, BEEFY_ENGINE_ID, + VersionedFinalityProof, VoteMessage, BEEFY_ENGINE_ID, }; use sp_runtime::{ generic::OpaqueDigestItemId, @@ -158,8 +158,8 @@ impl VoterOracle { self.sessions.front_mut().ok_or(Error::UninitSession) } - fn current_validator_set_id(&self) -> Result { - self.active_rounds().map(|r| r.validator_set_id()) + fn current_validator_set(&self) -> Result<&ValidatorSet, Error> { + self.active_rounds().map(|r| r.validator_set()) } // Prune the sessions queue to keep the Oracle in one of the expected three states. @@ -301,10 +301,10 @@ impl PersistedState { self.voting_oracle.best_grandpa_block_header = best_grandpa; } - pub(crate) fn current_gossip_filter(&self) -> Result, Error> { + pub(crate) fn gossip_filter_config(&self) -> Result, Error> { let (start, end) = self.voting_oracle.accepted_interval()?; - let validator_set_id = self.voting_oracle.current_validator_set_id()?; - Ok(GossipVoteFilter { start, end, validator_set_id }) + let validator_set = self.voting_oracle.current_validator_set()?; + Ok(GossipFilterCfg { start, end, validator_set }) } } @@ -494,7 +494,7 @@ where // Update gossip validator votes filter. if let Err(e) = self .persisted_state - .current_gossip_filter() + .gossip_filter_config() .map(|filter| self.gossip_validator.update_filter(filter)) { error!(target: LOG_TARGET, "🥩 Voter error: {:?}", e); @@ -509,7 +509,12 @@ where ) -> Result<(), Error> { let block_num = vote.commitment.block_number; match self.voting_oracle().triage_round(block_num)? { - RoundAction::Process => self.handle_vote(vote)?, + RoundAction::Process => + if let Some(finality_proof) = self.handle_vote(vote)? { + let gossip_proof = GossipMessage::::FinalityProof(finality_proof); + let encoded_proof = gossip_proof.encode(); + self.gossip_engine.gossip_message(proofs_topic::(), encoded_proof, true); + }, RoundAction::Drop => metric_inc!(self, beefy_stale_votes), RoundAction::Enqueue => error!(target: LOG_TARGET, "🥩 unexpected vote: {:?}.", vote), }; @@ -554,7 +559,7 @@ where fn handle_vote( &mut self, vote: VoteMessage, AuthorityId, Signature>, - ) -> Result<(), Error> { + ) -> Result>, Error> { let rounds = self.persisted_state.voting_oracle.active_rounds_mut()?; let block_number = vote.commitment.block_number; @@ -567,8 +572,9 @@ where ); // We created the `finality_proof` and know to be valid. // New state is persisted after finalization. - self.finalize(finality_proof)?; + self.finalize(finality_proof.clone())?; metric_inc!(self, beefy_good_votes_processed); + return Ok(Some(finality_proof)) }, VoteImportResult::Ok => { // Persist state after handling mandatory block vote. @@ -590,7 +596,7 @@ where VoteImportResult::Invalid => metric_inc!(self, beefy_invalid_votes), VoteImportResult::Stale => metric_inc!(self, beefy_stale_votes), }; - Ok(()) + Ok(None) } /// Provide BEEFY finality for block based on `finality_proof`: @@ -643,7 +649,7 @@ where // Update gossip validator votes filter. self.persisted_state - .current_gossip_filter() + .gossip_filter_config() .map(|filter| self.gossip_validator.update_filter(filter))?; Ok(()) } @@ -758,20 +764,20 @@ where BeefyKeystore::verify(&authority_id, &signature, &encoded_commitment) ); - let message = VoteMessage { commitment, id: authority_id, signature }; - - let encoded_message = message.encode(); - - metric_inc!(self, beefy_votes_sent); - - debug!(target: LOG_TARGET, "🥩 Sent vote message: {:?}", message); - - if let Err(err) = self.handle_vote(message) { + let vote = VoteMessage { commitment, id: authority_id, signature }; + if let Some(finality_proof) = self.handle_vote(vote.clone()).map_err(|err| { error!(target: LOG_TARGET, "🥩 Error handling self vote: {}", err); + err + })? { + let encoded_proof = GossipMessage::::FinalityProof(finality_proof).encode(); + self.gossip_engine.gossip_message(proofs_topic::(), encoded_proof, true); + } else { + metric_inc!(self, beefy_votes_sent); + debug!(target: LOG_TARGET, "🥩 Sent vote message: {:?}", vote); + let encoded_vote = GossipMessage::::Vote(vote).encode(); + self.gossip_engine.gossip_message(votes_topic::(), encoded_vote, false); } - self.gossip_engine.gossip_message(topic::(), encoded_message, false); - // Persist state after vote to avoid double voting in case of voter restarts. self.persisted_state.best_voted = target_number; metric_set!(self, beefy_best_voted, target_number); @@ -816,17 +822,28 @@ where let mut votes = Box::pin( self.gossip_engine - .messages_for(topic::()) + .messages_for(votes_topic::()) .filter_map(|notification| async move { - let vote = VoteMessage::, AuthorityId, Signature>::decode( - &mut ¬ification.message[..], - ) - .ok(); + let vote = GossipMessage::::decode(&mut ¬ification.message[..]) + .ok() + .and_then(|message| message.unwrap_vote()); trace!(target: LOG_TARGET, "🥩 Got vote message: {:?}", vote); vote }) .fuse(), ); + let mut gossip_proofs = Box::pin( + self.gossip_engine + .messages_for(proofs_topic::()) + .filter_map(|notification| async move { + let proof = GossipMessage::::decode(&mut ¬ification.message[..]) + .ok() + .and_then(|message| message.unwrap_finality_proof()); + trace!(target: LOG_TARGET, "🥩 Got gossip proof message: {:?}", proof); + proof + }) + .fuse(), + ); loop { // Act on changed 'state'. @@ -872,6 +889,20 @@ where return; } }, + justif = gossip_proofs.next() => { + if let Some(justif) = justif { + // Gossiped justifications have already been verified by `GossipValidator`. + if let Err(err) = self.triage_incoming_justif(justif) { + debug!(target: LOG_TARGET, "🥩 {}", err); + } + } else { + error!( + target: LOG_TARGET, + "🥩 Finality proofs gossiping stream terminated, closing worker." + ); + return; + } + }, // Finally process incoming votes. vote = votes.next() => { if let Some(vote) = vote { @@ -880,7 +911,10 @@ where debug!(target: LOG_TARGET, "🥩 {}", err); } } else { - error!(target: LOG_TARGET, "🥩 Votes gossiping stream terminated, closing worker."); + error!( + target: LOG_TARGET, + "🥩 Votes gossiping stream terminated, closing worker." + ); return; } }, diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index abdf97bb22aad..2486b2fd045d5 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -63,21 +63,50 @@ impl LocalKeystore { ) -> Result> { self.0.read().key_pair::(public) } -} -impl Keystore for LocalKeystore { - fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec { + fn public_keys(&self, key_type: KeyTypeId) -> Vec { self.0 .read() .raw_public_keys(key_type) .map(|v| { - v.into_iter() - .filter_map(|k| sr25519::Public::from_slice(k.as_slice()).ok()) - .collect() + v.into_iter().filter_map(|k| T::Public::from_slice(k.as_slice()).ok()).collect() }) .unwrap_or_default() } + fn generate_new( + &self, + key_type: KeyTypeId, + seed: Option<&str>, + ) -> std::result::Result { + let pair = match seed { + Some(seed) => self.0.write().insert_ephemeral_from_seed_by_type::(seed, key_type), + None => self.0.write().generate_by_type::(key_type), + } + .map_err(|e| -> TraitError { e.into() })?; + Ok(pair.public()) + } + + fn sign( + &self, + key_type: KeyTypeId, + public: &T::Public, + msg: &[u8], + ) -> std::result::Result, TraitError> { + let signature = self + .0 + .read() + .key_pair_by_type::(public, key_type)? + .map(|pair| pair.sign(msg)); + Ok(signature) + } +} + +impl Keystore for LocalKeystore { + fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec { + self.public_keys::(key_type) + } + /// Generate a new pair compatible with the 'ed25519' signature scheme. /// /// If the `[seed]` is `Some` then the key will be ephemeral and stored in memory. @@ -86,16 +115,7 @@ impl Keystore for LocalKeystore { key_type: KeyTypeId, seed: Option<&str>, ) -> std::result::Result { - let pair = match seed { - Some(seed) => self - .0 - .write() - .insert_ephemeral_from_seed_by_type::(seed, key_type), - None => self.0.write().generate_by_type::(key_type), - } - .map_err(|e| -> TraitError { e.into() })?; - - Ok(pair.public()) + self.generate_new::(key_type, seed) } fn sr25519_sign( @@ -104,12 +124,7 @@ impl Keystore for LocalKeystore { public: &sr25519::Public, msg: &[u8], ) -> std::result::Result, TraitError> { - let res = self - .0 - .read() - .key_pair_by_type::(public, key_type)? - .map(|pair| pair.sign(msg)); - Ok(res) + self.sign::(key_type, public, msg) } fn sr25519_vrf_sign( @@ -118,24 +133,16 @@ impl Keystore for LocalKeystore { public: &sr25519::Public, transcript_data: VRFTranscriptData, ) -> std::result::Result, TraitError> { - let res = self.0.read().key_pair_by_type::(public, key_type)?.map(|pair| { + let sig = self.0.read().key_pair_by_type::(public, key_type)?.map(|pair| { let transcript = make_transcript(transcript_data); let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); VRFSignature { output: inout.to_output(), proof } }); - Ok(res) + Ok(sig) } fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.0 - .read() - .raw_public_keys(key_type) - .map(|v| { - v.into_iter() - .filter_map(|k| ed25519::Public::from_slice(k.as_slice()).ok()) - .collect() - }) - .unwrap_or_default() + self.public_keys::(key_type) } /// Generate a new pair compatible with the 'sr25519' signature scheme. @@ -146,16 +153,7 @@ impl Keystore for LocalKeystore { key_type: KeyTypeId, seed: Option<&str>, ) -> std::result::Result { - let pair = match seed { - Some(seed) => self - .0 - .write() - .insert_ephemeral_from_seed_by_type::(seed, key_type), - None => self.0.write().generate_by_type::(key_type), - } - .map_err(|e| -> TraitError { e.into() })?; - - Ok(pair.public()) + self.generate_new::(key_type, seed) } fn ed25519_sign( @@ -164,24 +162,11 @@ impl Keystore for LocalKeystore { public: &ed25519::Public, msg: &[u8], ) -> std::result::Result, TraitError> { - let res = self - .0 - .read() - .key_pair_by_type::(public, key_type)? - .map(|pair| pair.sign(msg)); - Ok(res) + self.sign::(key_type, public, msg) } fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.0 - .read() - .raw_public_keys(key_type) - .map(|v| { - v.into_iter() - .filter_map(|k| ecdsa::Public::from_slice(k.as_slice()).ok()) - .collect() - }) - .unwrap_or_default() + self.public_keys::(key_type) } /// Generate a new pair compatible with the 'ecdsa' signature scheme. @@ -192,14 +177,7 @@ impl Keystore for LocalKeystore { key_type: KeyTypeId, seed: Option<&str>, ) -> std::result::Result { - let pair = match seed { - Some(seed) => - self.0.write().insert_ephemeral_from_seed_by_type::(seed, key_type), - None => self.0.write().generate_by_type::(key_type), - } - .map_err(|e| -> TraitError { e.into() })?; - - Ok(pair.public()) + self.generate_new::(key_type, seed) } fn ecdsa_sign( @@ -208,12 +186,7 @@ impl Keystore for LocalKeystore { public: &ecdsa::Public, msg: &[u8], ) -> std::result::Result, TraitError> { - let res = self - .0 - .read() - .key_pair_by_type::(public, key_type)? - .map(|pair| pair.sign(msg)); - Ok(res) + self.sign::(key_type, public, msg) } fn ecdsa_sign_prehashed( @@ -222,12 +195,12 @@ impl Keystore for LocalKeystore { public: &ecdsa::Public, msg: &[u8; 32], ) -> std::result::Result, TraitError> { - let res = self + let sig = self .0 .read() .key_pair_by_type::(public, key_type)? .map(|pair| pair.sign_prehashed(msg)); - Ok(res) + Ok(sig) } fn insert( diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 90b5ce871ef1a..6fc4131f74e10 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -51,6 +51,10 @@ sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" } sp-consensus = { version = "0.10.0-dev", path = "../../primitives/consensus/common" } sp-core = { version = "7.0.0", path = "../../primitives/core" } sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" } +# Force 0.9.2 as snow release to fix the compilation. +# +# When libp2p also enforces this version, we can get rid off this extra dep here. +snow = "0.9.2" [dev-dependencies] assert_matches = "1.3" diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 3c6801f22a35c..781ae9c786694 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -22,6 +22,7 @@ //! See the documentation of [`Params`]. pub use crate::{ + protocol::NotificationsSink, request_responses::{ IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig, }, @@ -31,7 +32,12 @@ pub use crate::{ use codec::Encode; use libp2p::{identity::Keypair, multiaddr, Multiaddr, PeerId}; use prometheus_endpoint::Registry; -pub use sc_network_common::{role::Role, sync::warp::WarpSyncProvider, ExHashT}; +pub use sc_network_common::{ + role::{Role, Roles}, + sync::warp::WarpSyncProvider, + ExHashT, +}; +use sc_utils::mpsc::TracingUnboundedSender; use zeroize::Zeroize; use sp_runtime::traits::Block as BlockT; @@ -714,6 +720,9 @@ pub struct Params { /// Block announce protocol configuration pub block_announce_config: NonDefaultSetConfig, + /// TX channel for direct communication with `SyncingEngine` and `Protocol`. + pub tx: TracingUnboundedSender>, + /// Request response protocol configurations pub request_response_protocol_configs: Vec, } diff --git a/client/network/src/event.rs b/client/network/src/event.rs index 3ecd8f9311429..975fde0e40a28 100644 --- a/client/network/src/event.rs +++ b/client/network/src/event.rs @@ -19,12 +19,14 @@ //! Network event types. These are are not the part of the protocol, but rather //! events that happen on the network like DHT get/put results received. -use crate::types::ProtocolName; +use crate::{types::ProtocolName, NotificationsSink}; use bytes::Bytes; +use futures::channel::oneshot; use libp2p::{core::PeerId, kad::record::Key}; -use sc_network_common::role::ObservedRole; +use sc_network_common::{role::ObservedRole, sync::message::BlockAnnouncesHandshake}; +use sp_runtime::traits::Block as BlockT; /// Events generated by DHT as a response to get_value and put_value requests. #[derive(Debug, Clone)] @@ -90,3 +92,44 @@ pub enum Event { messages: Vec<(ProtocolName, Bytes)>, }, } + +/// Event sent to `SyncingEngine` +// TODO: remove once `NotificationService` is implemented. +pub enum SyncEvent { + /// Opened a substream with the given node with the given notifications protocol. + /// + /// The protocol is always one of the notification protocols that have been registered. + NotificationStreamOpened { + /// Node we opened the substream with. + remote: PeerId, + /// Received handshake. + received_handshake: BlockAnnouncesHandshake, + /// Notification sink. + sink: NotificationsSink, + /// Channel for reporting accept/reject of the substream. + tx: oneshot::Sender, + }, + + /// Closed a substream with the given node. Always matches a corresponding previous + /// `NotificationStreamOpened` message. + NotificationStreamClosed { + /// Node we closed the substream with. + remote: PeerId, + }, + + /// Notification sink was replaced. + NotificationSinkReplaced { + /// Node we closed the substream with. + remote: PeerId, + /// Notification sink. + sink: NotificationsSink, + }, + + /// Received one or more messages from the given node using the given protocol. + NotificationsReceived { + /// Node we received the message from. + remote: PeerId, + /// Concerned protocol and associated message. + messages: Vec, + }, +} diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index c290f4b94db53..5374ac13435be 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -259,7 +259,7 @@ pub mod request_responses; pub mod types; pub mod utils; -pub use event::{DhtEvent, Event}; +pub use event::{DhtEvent, Event, SyncEvent}; #[doc(inline)] pub use libp2p::{multiaddr, Multiaddr, PeerId}; pub use request_responses::{IfDisconnected, RequestFailure, RequestResponseConfig}; @@ -278,8 +278,8 @@ pub use service::{ NetworkStatusProvider, NetworkSyncForkRequest, NotificationSender as NotificationSenderT, NotificationSenderError, NotificationSenderReady, }, - DecodingError, Keypair, NetworkService, NetworkWorker, NotificationSender, OutboundFailure, - PublicKey, + DecodingError, Keypair, NetworkService, NetworkWorker, NotificationSender, NotificationsSink, + OutboundFailure, PublicKey, }; pub use types::ProtocolName; diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 06ca02c0ca8d5..a7e6f36ef6215 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -24,6 +24,7 @@ use crate::{ use bytes::Bytes; use codec::{DecodeAll, Encode}; +use futures::{channel::oneshot, stream::FuturesUnordered, StreamExt}; use libp2p::{ core::connection::ConnectionId, swarm::{ @@ -35,11 +36,14 @@ use libp2p::{ use log::{debug, error, warn}; use sc_network_common::{role::Roles, sync::message::BlockAnnouncesHandshake}; +use sc_utils::mpsc::TracingUnboundedSender; use sp_runtime::traits::Block as BlockT; use std::{ collections::{HashMap, HashSet, VecDeque}, + future::Future, iter, + pin::Pin, task::Poll, }; @@ -68,6 +72,9 @@ mod rep { pub const BAD_MESSAGE: Rep = Rep::new(-(1 << 12), "Bad message"); } +type PendingSyncSubstreamValidation = + Pin> + Send>>; + // Lock must always be taken in order declared here. pub struct Protocol { /// Pending list of messages to return from `poll` as a priority. @@ -87,6 +94,8 @@ pub struct Protocol { bad_handshake_substreams: HashSet<(PeerId, sc_peerset::SetId)>, /// Connected peers. peers: HashMap, + sync_substream_validations: FuturesUnordered, + tx: TracingUnboundedSender>, _marker: std::marker::PhantomData, } @@ -96,6 +105,7 @@ impl Protocol { roles: Roles, network_config: &config::NetworkConfiguration, block_announces_protocol: config::NonDefaultSetConfig, + tx: TracingUnboundedSender>, ) -> error::Result<(Self, sc_peerset::PeersetHandle, Vec<(PeerId, Multiaddr)>)> { let mut known_addresses = Vec::new(); @@ -179,6 +189,8 @@ impl Protocol { .collect(), bad_handshake_substreams: Default::default(), peers: HashMap::new(), + sync_substream_validations: FuturesUnordered::new(), + tx, // TODO: remove when `BlockAnnouncesHandshake` is moved away from `Protocol` _marker: Default::default(), }; @@ -418,6 +430,23 @@ impl NetworkBehaviour for Protocol { return Poll::Ready(NetworkBehaviourAction::CloseConnection { peer_id, connection }), }; + while let Poll::Ready(Some(validation_result)) = + self.sync_substream_validations.poll_next_unpin(cx) + { + match validation_result { + Ok((peer, roles)) => { + self.peers.insert(peer, roles); + }, + Err(peer) => { + log::debug!( + target: "sub-libp2p", + "`SyncingEngine` rejected stream" + ); + self.behaviour.disconnect_peer(&peer, HARDCODED_PEERSETS_SYNC); + }, + } + } + let outcome = match event { NotificationsOut::CustomProtocolOpen { peer_id, @@ -440,16 +469,29 @@ impl NetworkBehaviour for Protocol { best_hash: handshake.best_hash, genesis_hash: handshake.genesis_hash, }; - self.peers.insert(peer_id, roles); - CustomMessageOutcome::NotificationStreamOpened { - remote: peer_id, - protocol: self.notification_protocols[usize::from(set_id)].clone(), - negotiated_fallback, - received_handshake: handshake.encode(), - roles, - notifications_sink, - } + let (tx, rx) = oneshot::channel(); + let _ = self.tx.unbounded_send( + crate::SyncEvent::NotificationStreamOpened { + remote: peer_id, + received_handshake: handshake, + sink: notifications_sink, + tx, + }, + ); + self.sync_substream_validations.push(Box::pin(async move { + match rx.await { + Ok(accepted) => + if accepted { + Ok((peer_id, roles)) + } else { + Err(peer_id) + }, + Err(_) => Err(peer_id), + } + })); + + CustomMessageOutcome::None }, Ok(msg) => { debug!( @@ -469,15 +511,27 @@ impl NetworkBehaviour for Protocol { let roles = handshake.roles; self.peers.insert(peer_id, roles); - CustomMessageOutcome::NotificationStreamOpened { - remote: peer_id, - protocol: self.notification_protocols[usize::from(set_id)] - .clone(), - negotiated_fallback, - received_handshake, - roles, - notifications_sink, - } + let (tx, rx) = oneshot::channel(); + let _ = self.tx.unbounded_send( + crate::SyncEvent::NotificationStreamOpened { + remote: peer_id, + received_handshake: handshake, + sink: notifications_sink, + tx, + }, + ); + self.sync_substream_validations.push(Box::pin(async move { + match rx.await { + Ok(accepted) => + if accepted { + Ok((peer_id, roles)) + } else { + Err(peer_id) + }, + Err(_) => Err(peer_id), + } + })); + CustomMessageOutcome::None }, Err(err2) => { log::debug!( @@ -535,6 +589,12 @@ impl NetworkBehaviour for Protocol { NotificationsOut::CustomProtocolReplaced { peer_id, notifications_sink, set_id } => if self.bad_handshake_substreams.contains(&(peer_id, set_id)) { CustomMessageOutcome::None + } else if set_id == HARDCODED_PEERSETS_SYNC { + let _ = self.tx.unbounded_send(crate::SyncEvent::NotificationSinkReplaced { + remote: peer_id, + sink: notifications_sink, + }); + CustomMessageOutcome::None } else { CustomMessageOutcome::NotificationStreamReplaced { remote: peer_id, @@ -548,6 +608,12 @@ impl NetworkBehaviour for Protocol { // handshake. The outer layers have never received an opening event about this // substream, and consequently shouldn't receive a closing event either. CustomMessageOutcome::None + } else if set_id == HARDCODED_PEERSETS_SYNC { + let _ = self.tx.unbounded_send(crate::SyncEvent::NotificationStreamClosed { + remote: peer_id, + }); + self.peers.remove(&peer_id); + CustomMessageOutcome::None } else { CustomMessageOutcome::NotificationStreamClosed { remote: peer_id, @@ -558,6 +624,12 @@ impl NetworkBehaviour for Protocol { NotificationsOut::Notification { peer_id, set_id, message } => { if self.bad_handshake_substreams.contains(&(peer_id, set_id)) { CustomMessageOutcome::None + } else if set_id == HARDCODED_PEERSETS_SYNC { + let _ = self.tx.unbounded_send(crate::SyncEvent::NotificationsReceived { + remote: peer_id, + messages: vec![message.freeze()], + }); + CustomMessageOutcome::None } else { let protocol_name = self.notification_protocols[usize::from(set_id)].clone(); CustomMessageOutcome::NotificationsReceived { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 5f60f51321b42..9708b24d29b52 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -36,7 +36,7 @@ use crate::{ network_state::{ NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, }, - protocol::{self, NotificationsSink, NotifsHandlerError, Protocol, Ready}, + protocol::{self, NotifsHandlerError, Protocol, Ready}, request_responses::{IfDisconnected, RequestFailure}, service::{ signature::{Signature, SigningError}, @@ -91,6 +91,7 @@ use std::{ pub use behaviour::{InboundFailure, OutboundFailure, ResponseFailure}; pub use libp2p::identity::{error::DecodingError, Keypair, PublicKey}; +pub use protocol::NotificationsSink; mod metrics; mod out_events; @@ -146,7 +147,7 @@ where /// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. - pub fn new(mut params: Params) -> Result { + pub fn new(mut params: Params) -> Result { // Private and public keys configuration. let local_identity = params.network_config.node_key.clone().into_keypair()?; let local_public = local_identity.public(); @@ -227,6 +228,7 @@ where From::from(¶ms.role), ¶ms.network_config, params.block_announce_config, + params.tx, )?; // List of multiaddresses that we know in the network. diff --git a/client/network/sync/src/engine.rs b/client/network/sync/src/engine.rs index b4c1a2ed05bb0..e3d45a980a0b4 100644 --- a/client/network/sync/src/engine.rs +++ b/client/network/sync/src/engine.rs @@ -24,8 +24,8 @@ use crate::{ ChainSync, ClientError, SyncingService, }; -use codec::{Decode, DecodeAll, Encode}; -use futures::{FutureExt, Stream, StreamExt}; +use codec::{Decode, Encode}; +use futures::{FutureExt, StreamExt}; use futures_timer::Delay; use libp2p::PeerId; use lru::LruCache; @@ -39,9 +39,8 @@ use sc_network::{ config::{ NetworkConfiguration, NonDefaultSetConfig, ProtocolId, SyncMode as SyncOperationMode, }, - event::Event, utils::LruHashSet, - ProtocolName, + NotificationsSink, ProtocolName, }; use sc_network_common::{ role::Roles, @@ -63,7 +62,6 @@ use sp_runtime::traits::{Block as BlockT, Header, NumberFor, Zero}; use std::{ collections::{HashMap, HashSet}, num::NonZeroUsize, - pin::Pin, sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, @@ -79,8 +77,6 @@ const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead mod rep { use sc_peerset::ReputationChange as Rep; - /// We received a message that failed to decode. - pub const BAD_MESSAGE: Rep = Rep::new(-(1 << 12), "Bad message"); /// Peer has different genesis. pub const GENESIS_MISMATCH: Rep = Rep::new_fatal("Genesis mismatch"); /// Peer send us a block announcement that failed at validation. @@ -162,6 +158,8 @@ pub struct Peer { pub info: ExtendedPeerInfo, /// Holds a set of blocks known to this peer. pub known_blocks: LruHashSet, + /// Notification sink. + sink: NotificationsSink, } pub struct SyncingEngine { @@ -184,6 +182,9 @@ pub struct SyncingEngine { /// Channel for receiving service commands service_rx: TracingUnboundedReceiver>, + /// Channel for receiving inbound connections from `Protocol`. + rx: sc_utils::mpsc::TracingUnboundedReceiver>, + /// Assigned roles. roles: Roles, @@ -254,6 +255,7 @@ where block_request_protocol_name: ProtocolName, state_request_protocol_name: ProtocolName, warp_sync_protocol_name: Option, + rx: sc_utils::mpsc::TracingUnboundedReceiver>, ) -> Result<(Self, SyncingService, NonDefaultSetConfig), ClientError> { let mode = match network_config.sync_mode { SyncOperationMode::Full => SyncMode::Full, @@ -347,6 +349,7 @@ where num_connected: num_connected.clone(), is_major_syncing: is_major_syncing.clone(), service_rx, + rx, genesis_hash, important_peers, default_peers_set_no_slot_connected_peers: HashSet::new(), @@ -554,11 +557,7 @@ where data: Some(data.clone()), }; - self.network_service.write_notification( - *who, - self.block_announce_protocol_name.clone(), - message.encode(), - ); + peer.sink.send_sync_notification(message.encode()); } } } @@ -575,17 +574,13 @@ where ) } - pub async fn run(mut self, mut stream: Pin + Send>>) { + pub async fn run(mut self) { loop { - futures::future::poll_fn(|cx| self.poll(cx, &mut stream)).await; + futures::future::poll_fn(|cx| self.poll(cx)).await; } } - pub fn poll( - &mut self, - cx: &mut std::task::Context, - event_stream: &mut Pin + Send>>, - ) -> Poll<()> { + pub fn poll(&mut self, cx: &mut std::task::Context) -> Poll<()> { self.num_connected.store(self.peers.len(), Ordering::Relaxed); self.is_major_syncing .store(self.chain_sync.status().state.is_major_syncing(), Ordering::Relaxed); @@ -595,84 +590,6 @@ where self.tick_timeout.reset(TICK_TIMEOUT); } - while let Poll::Ready(Some(event)) = event_stream.poll_next_unpin(cx) { - match event { - Event::NotificationStreamOpened { - remote, protocol, received_handshake, .. - } => { - if protocol != self.block_announce_protocol_name { - continue - } - - match as DecodeAll>::decode_all( - &mut &received_handshake[..], - ) { - Ok(handshake) => { - if self.on_sync_peer_connected(remote, handshake).is_err() { - log::debug!( - target: "sync", - "Failed to register peer {remote:?}: {received_handshake:?}", - ); - } - }, - Err(err) => { - log::debug!( - target: "sync", - "Couldn't decode handshake sent by {}: {:?}: {}", - remote, - received_handshake, - err, - ); - self.network_service.report_peer(remote, rep::BAD_MESSAGE); - }, - } - }, - Event::NotificationStreamClosed { remote, protocol } => { - if protocol != self.block_announce_protocol_name { - continue - } - - if self.on_sync_peer_disconnected(remote).is_err() { - log::trace!( - target: "sync", - "Disconnected peer which had earlier been refused by on_sync_peer_connected {}", - remote - ); - } - }, - Event::NotificationsReceived { remote, messages } => { - for (protocol, message) in messages { - if protocol != self.block_announce_protocol_name { - continue - } - - if self.peers.contains_key(&remote) { - if let Ok(announce) = BlockAnnounce::decode(&mut message.as_ref()) { - self.push_block_announce_validation(remote, announce); - - // Make sure that the newly added block announce validation future - // was polled once to be registered in the task. - if let Poll::Ready(res) = - self.chain_sync.poll_block_announce_validation(cx) - { - self.process_block_announce_validation_result(res) - } - } else { - log::warn!(target: "sub-libp2p", "Failed to decode block announce"); - } - } else { - log::trace!( - target: "sync", - "Received sync for peer earlier refused by sync layer: {}", - remote - ); - } - } - }, - _ => {}, - } - } - while let Poll::Ready(Some(event)) = self.service_rx.poll_next_unpin(cx) { match event { ToServiceCommand::SetSyncForkRequest(peers, hash, number) => { @@ -746,6 +663,70 @@ where } } + while let Poll::Ready(Some(event)) = self.rx.poll_next_unpin(cx) { + match event { + sc_network::SyncEvent::NotificationStreamOpened { + remote, + received_handshake, + sink, + tx, + } => match self.on_sync_peer_connected(remote, &received_handshake, sink) { + Ok(()) => { + let _ = tx.send(true); + }, + Err(()) => { + log::debug!( + target: "sync", + "Failed to register peer {remote:?}: {received_handshake:?}", + ); + let _ = tx.send(false); + }, + }, + sc_network::SyncEvent::NotificationStreamClosed { remote } => { + if self.on_sync_peer_disconnected(remote).is_err() { + log::trace!( + target: "sync", + "Disconnected peer which had earlier been refused by on_sync_peer_connected {}", + remote + ); + } + }, + sc_network::SyncEvent::NotificationsReceived { remote, messages } => { + for message in messages { + if self.peers.contains_key(&remote) { + if let Ok(announce) = BlockAnnounce::decode(&mut message.as_ref()) { + self.push_block_announce_validation(remote, announce); + + // Make sure that the newly added block announce validation future + // was polled once to be registered in the task. + if let Poll::Ready(res) = + self.chain_sync.poll_block_announce_validation(cx) + { + self.process_block_announce_validation_result(res) + } + } else { + log::warn!(target: "sub-libp2p", "Failed to decode block announce"); + } + } else { + log::trace!( + target: "sync", + "Received sync for peer earlier refused by sync layer: {}", + remote + ); + } + } + }, + sc_network::SyncEvent::NotificationSinkReplaced { remote, sink } => { + if let Some(peer) = self.peers.get_mut(&remote) { + peer.sink = sink; + } + }, + } + } + + // poll `ChainSync` last because of a block announcement was received through the + // event stream between `SyncingEngine` and `Protocol` and the validation finished + // right after it as queued, the resulting block request (if any) can be sent right away. while let Poll::Ready(result) = self.chain_sync.poll(cx) { self.process_block_announce_validation_result(result); } @@ -757,13 +738,13 @@ where /// /// Returns a result if the handshake of this peer was indeed accepted. pub fn on_sync_peer_disconnected(&mut self, peer: PeerId) -> Result<(), ()> { - if self.important_peers.contains(&peer) { - log::warn!(target: "sync", "Reserved peer {} disconnected", peer); - } else { - log::debug!(target: "sync", "{} disconnected", peer); - } - if self.peers.remove(&peer).is_some() { + if self.important_peers.contains(&peer) { + log::warn!(target: "sync", "Reserved peer {} disconnected", peer); + } else { + log::debug!(target: "sync", "{} disconnected", peer); + } + self.chain_sync.peer_disconnected(&peer); self.default_peers_set_no_slot_connected_peers.remove(&peer); self.event_streams @@ -782,7 +763,8 @@ where pub fn on_sync_peer_connected( &mut self, who: PeerId, - status: BlockAnnouncesHandshake, + status: &BlockAnnouncesHandshake, + sink: NotificationsSink, ) -> Result<(), ()> { log::trace!(target: "sync", "New peer {} {:?}", who, status); @@ -794,8 +776,6 @@ where if status.genesis_hash != self.genesis_hash { self.network_service.report_peer(who, rep::GENESIS_MISMATCH); - self.network_service - .disconnect_peer(who, self.block_announce_protocol_name.clone()); if self.important_peers.contains(&who) { log::error!( @@ -834,8 +814,6 @@ where this_peer_reserved_slot { log::debug!(target: "sync", "Too many full nodes, rejecting {}", who); - self.network_service - .disconnect_peer(who, self.block_announce_protocol_name.clone()); return Err(()) } @@ -844,8 +822,6 @@ where { // Make sure that not all slots are occupied by light clients. log::debug!(target: "sync", "Too many light nodes, rejecting {}", who); - self.network_service - .disconnect_peer(who, self.block_announce_protocol_name.clone()); return Err(()) } @@ -858,14 +834,13 @@ where known_blocks: LruHashSet::new( NonZeroUsize::new(MAX_KNOWN_BLOCKS).expect("Constant is nonzero"), ), + sink, }; let req = if peer.info.roles.is_full() { match self.chain_sync.new_peer(who, peer.info.best_hash, peer.info.best_number) { Ok(req) => req, Err(BadPeer(id, repu)) => { - self.network_service - .disconnect_peer(id, self.block_announce_protocol_name.clone()); self.network_service.report_peer(id, repu); return Err(()) }, diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 8368fa278712a..9763feed5ea54 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -26,6 +26,7 @@ sc-client-api = { version = "4.0.0-dev", path = "../../api" } sc-consensus = { version = "0.10.0-dev", path = "../../consensus/common" } sc-network = { version = "0.10.0-dev", path = "../" } sc-network-common = { version = "0.10.0-dev", path = "../common" } +sc-utils = { version = "4.0.0-dev", path = "../../utils" } sc-network-light = { version = "0.10.0-dev", path = "../light" } sc-network-sync = { version = "0.10.0-dev", path = "../sync" } sc-service = { version = "0.10.0-dev", default-features = false, features = ["test-helpers"], path = "../../service" } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 6a99304035ab8..f85d6ed63c247 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -55,8 +55,8 @@ use sc_network::{ }, request_responses::ProtocolConfig as RequestResponseConfig, types::ProtocolName, - Multiaddr, NetworkBlock, NetworkEventStream, NetworkService, NetworkStateInfo, - NetworkSyncForkRequest, NetworkWorker, + Multiaddr, NetworkBlock, NetworkService, NetworkStateInfo, NetworkSyncForkRequest, + NetworkWorker, }; use sc_network_common::{ role::Roles, @@ -896,6 +896,7 @@ where let (chain_sync_network_provider, chain_sync_network_handle) = NetworkServiceProvider::new(); + let (tx, rx) = sc_utils::mpsc::tracing_unbounded("mpsc_syncing_engine_protocol", 100_000); let (engine, sync_service, block_announce_config) = sc_network_sync::engine::SyncingEngine::new( Roles::from(if config.is_authority { &Role::Authority } else { &Role::Full }), @@ -911,6 +912,7 @@ where block_request_protocol_config.name.clone(), state_request_protocol_config.name.clone(), Some(warp_protocol_config.name.clone()), + rx, ) .unwrap(); let sync_service_import_queue = Box::new(sync_service.clone()); @@ -918,7 +920,7 @@ where let genesis_hash = client.hash(Zero::zero()).ok().flatten().expect("Genesis block exists; qed"); - let network = NetworkWorker::new::(sc_network::config::Params { + let network = NetworkWorker::new(sc_network::config::Params { role: if config.is_authority { Role::Authority } else { Role::Full }, executor: Box::new(|f| { tokio::spawn(f); @@ -929,6 +931,7 @@ where fork_id, metrics_registry: None, block_announce_config, + tx, request_response_protocol_configs: [ block_request_protocol_config, state_request_protocol_config, @@ -950,9 +953,8 @@ where import_queue.run(sync_service_import_queue).await; }); - let service = network.service().clone(); tokio::spawn(async move { - engine.run(service.event_stream("syncing")).await; + engine.run().await; }); self.mut_peers(move |peers| { diff --git a/client/network/test/src/service.rs b/client/network/test/src/service.rs index 67915c38637ed..5871860a7c4a6 100644 --- a/client/network/test/src/service.rs +++ b/client/network/test/src/service.rs @@ -177,6 +177,7 @@ impl TestNetworkBuilder { let (chain_sync_network_provider, chain_sync_network_handle) = self.chain_sync_network.unwrap_or(NetworkServiceProvider::new()); + let (tx, rx) = sc_utils::mpsc::tracing_unbounded("mpsc_syncing_engine_protocol", 100_000); let (engine, chain_sync_service, block_announce_config) = SyncingEngine::new( Roles::from(&config::Role::Full), @@ -192,6 +193,7 @@ impl TestNetworkBuilder { block_request_protocol_config.name.clone(), state_request_protocol_config.name.clone(), None, + rx, ) .unwrap(); let mut link = self.link.unwrap_or(Box::new(chain_sync_service.clone())); @@ -217,6 +219,7 @@ impl TestNetworkBuilder { light_client_request_protocol_config, ] .to_vec(), + tx, }) .unwrap(); @@ -234,8 +237,7 @@ impl TestNetworkBuilder { tokio::time::sleep(std::time::Duration::from_millis(250)).await; } }); - let stream = worker.service().event_stream("syncing"); - tokio::spawn(engine.run(stream)); + tokio::spawn(engine.run()); TestNetwork::new(worker) } diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index d87b03fb3a78c..af46d15a2bacd 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -414,7 +414,7 @@ async fn can_sync_small_non_best_forks() { // poll until the two nodes connect, otherwise announcing the block will not work futures::future::poll_fn::<(), _>(|cx| { net.poll(cx); - if net.peer(0).num_peers() == 0 { + if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 { Poll::Pending } else { Poll::Ready(()) diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index ebc1eb9b4ff52..dbc2a505456a5 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -33,7 +33,7 @@ pub use self::helpers::ReadProof; /// Substrate state API #[rpc(client, server)] pub trait StateApi { - /// Call a contract at a block's state. + /// Call a method from the runtime API at a block's state. #[method(name = "state_call", aliases = ["state_callAt"], blocking)] fn call(&self, name: String, bytes: Bytes, hash: Option) -> RpcResult; @@ -85,8 +85,10 @@ pub trait StateApi { /// Query historical storage entries (by key) starting from a block given as the second /// parameter. /// - /// NOTE This first returned result contains the initial state of storage for all keys. + /// NOTE: The first returned result contains the initial state of storage for all keys. /// Subsequent values in the vector represent changes to the previous state (diffs). + /// WARNING: The time complexity of this query is O(|keys|*dist(block, hash)), and the + /// memory complexity is O(dist(block, hash)) -- use with caution. #[method(name = "state_queryStorage", blocking)] fn query_storage( &self, @@ -95,7 +97,9 @@ pub trait StateApi { hash: Option, ) -> RpcResult>>; - /// Query storage entries (by key) starting at block hash given as the second parameter. + /// Query storage entries (by key) at a block hash given as the second parameter. + /// NOTE: Each StorageChangeSet in the result corresponds to exactly one element -- + /// the storage value under an input key at the input block hash. #[method(name = "state_queryStorageAt", blocking)] fn query_storage_at( &self, diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 7cbbf2a4dda0f..b04228e6bfc34 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -38,9 +38,7 @@ use sc_client_db::{Backend, DatabaseSettings}; use sc_consensus::import_queue::ImportQueue; use sc_executor::RuntimeVersionOf; use sc_keystore::LocalKeystore; -use sc_network::{ - config::SyncMode, NetworkEventStream, NetworkService, NetworkStateInfo, NetworkStatusProvider, -}; +use sc_network::{config::SyncMode, NetworkService, NetworkStateInfo, NetworkStatusProvider}; use sc_network_bitswap::BitswapRequestHandler; use sc_network_common::{role::Roles, sync::warp::WarpSyncParams}; use sc_network_light::light_client_requests::handler::LightClientRequestHandler; @@ -825,6 +823,7 @@ where protocol_config }; + let (tx, rx) = sc_utils::mpsc::tracing_unbounded("mpsc_syncing_engine_protocol", 100_000); let (chain_sync_network_provider, chain_sync_network_handle) = NetworkServiceProvider::new(); let (engine, sync_service, block_announce_config) = SyncingEngine::new( Roles::from(&config.role), @@ -840,6 +839,7 @@ where block_request_protocol_config.name.clone(), state_request_protocol_config.name.clone(), warp_sync_protocol_config.as_ref().map(|config| config.name.clone()), + rx, )?; let sync_service_import_queue = sync_service.clone(); let sync_service = Arc::new(sync_service); @@ -865,6 +865,7 @@ where fork_id: config.chain_spec.fork_id().map(ToOwned::to_owned), metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()), block_announce_config, + tx, request_response_protocol_configs: request_response_protocol_configs .into_iter() .chain([ @@ -904,15 +905,13 @@ where )?; spawn_handle.spawn("network-transactions-handler", Some("networking"), tx_handler.run()); - spawn_handle.spawn( + spawn_handle.spawn_blocking( "chain-sync-network-service-provider", Some("networking"), chain_sync_network_provider.run(network.clone()), ); spawn_handle.spawn("import-queue", None, import_queue.run(Box::new(sync_service_import_queue))); - - let event_stream = network.event_stream("syncing"); - spawn_handle.spawn("syncing", None, engine.run(event_stream)); + spawn_handle.spawn_blocking("syncing", None, engine.run()); let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc", 10_000); spawn_handle.spawn( diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index d4be806982dfe..dcf602cd5e0bf 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -786,7 +786,12 @@ pub mod pallet { // Gah!! We have a non-zero reserve balance but no provider refs :( // This shouldn't practically happen, but we need a failsafe anyway: let's give // them enough for an ED. - a.free = a.free.min(Self::ed()); + log::warn!( + target: LOG_TARGET, + "account with a non-zero reserve balance has no provider refs, account_id: '{:?}'.", + who + ); + a.free = a.free.max(Self::ed()); system::Pallet::::inc_providers(who); } let _ = system::Pallet::::inc_consumers(who).defensive(); diff --git a/frame/contracts/README.md b/frame/contracts/README.md index 4f5f10a3af333..68fa49debc580 100644 --- a/frame/contracts/README.md +++ b/frame/contracts/README.md @@ -5,7 +5,7 @@ The Contract module provides functionality for the runtime to deploy and execute - [`Call`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/enum.Call.html) - [`Config`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/trait.Config.html) - [`Error`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/enum.Error.html) -- [`Event`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/enum.Error.html) +- [`Event`](https://paritytech.github.io/substrate/master/pallet_contracts/pallet/enum.Event.html) ## Overview diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index 5494b57b65a2a..1bb6f3395fcef 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -214,19 +214,7 @@ benchmarks! { on_initialize_per_trie_key { let k in 0..1024; let instance = Contract::::with_storage(WasmModule::dummy(), k, T::Schedule::get().limits.payload_len)?; - instance.info()?.queue_trie_for_deletion()?; - }: { - ContractInfo::::process_deletion_queue_batch(Weight::MAX) - } - - #[pov_mode = Measured] - on_initialize_per_queue_item { - let q in 0..1024.min(T::DeletionQueueDepth::get()); - for i in 0 .. q { - let instance = Contract::::with_index(i, WasmModule::dummy(), vec![])?; - instance.info()?.queue_trie_for_deletion()?; - ContractInfoOf::::remove(instance.account_id); - } + instance.info()?.queue_trie_for_deletion(); }: { ContractInfo::::process_deletion_queue_batch(Weight::MAX) } @@ -3020,16 +3008,12 @@ benchmarks! { print_schedule { #[cfg(feature = "std")] { - let weight_limit = T::DeletionWeightLimit::get(); - let max_queue_depth = T::DeletionQueueDepth::get() as usize; - let empty_queue_throughput = ContractInfo::::deletion_budget(0, weight_limit); - let full_queue_throughput = ContractInfo::::deletion_budget(max_queue_depth, weight_limit); + let max_weight = ::BlockWeights::get().max_block; + let (weight_per_key, key_budget) = ContractInfo::::deletion_budget(max_weight); println!("{:#?}", Schedule::::default()); println!("###############################################"); - println!("Lazy deletion weight per key: {}", empty_queue_throughput.0); - println!("Lazy deletion throughput per block (empty queue, full queue): {}, {}", - empty_queue_throughput.1, full_queue_throughput.1, - ); + println!("Lazy deletion weight per key: {weight_per_key}"); + println!("Lazy deletion throughput per block: {key_budget}"); } #[cfg(not(feature = "std"))] Err("Run this bench with a native runtime in order to see the schedule.")?; diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 51ea234f27376..03e1c4fd32585 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -1204,7 +1204,7 @@ where T::Currency::reducible_balance(&frame.account_id, Expendable, Polite), ExistenceRequirement::AllowDeath, )?; - info.queue_trie_for_deletion()?; + info.queue_trie_for_deletion(); ContractInfoOf::::remove(&frame.account_id); E::remove_user(info.code_hash); Contracts::::deposit_event( diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index cd4b7daa6da0f..dc93a7f06ff2d 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -102,7 +102,7 @@ mod tests; use crate::{ exec::{AccountIdOf, ErrorOrigin, ExecError, Executable, Key, Stack as ExecStack}, gas::GasMeter, - storage::{meter::Meter as StorageMeter, ContractInfo, DeletedContract}, + storage::{meter::Meter as StorageMeter, ContractInfo, DeletionQueueManager}, wasm::{OwnerInfo, PrefabWasmModule, TryInstantiate}, weights::WeightInfo, }; @@ -245,33 +245,6 @@ pub mod pallet { /// memory usage of your runtime. type CallStack: Array>; - /// The maximum number of contracts that can be pending for deletion. - /// - /// When a contract is deleted by calling `seal_terminate` it becomes inaccessible - /// immediately, but the deletion of the storage items it has accumulated is performed - /// later. The contract is put into the deletion queue. This defines how many - /// contracts can be queued up at the same time. If that limit is reached `seal_terminate` - /// will fail. The action must be retried in a later block in that case. - /// - /// The reasons for limiting the queue depth are: - /// - /// 1. The queue is in storage in order to be persistent between blocks. We want to limit - /// the amount of storage that can be consumed. - /// 2. The queue is stored in a vector and needs to be decoded as a whole when reading - /// it at the end of each block. Longer queues take more weight to decode and hence - /// limit the amount of items that can be deleted per block. - #[pallet::constant] - type DeletionQueueDepth: Get; - - /// The maximum amount of weight that can be consumed per block for lazy trie removal. - /// - /// The amount of weight that is dedicated per block to work on the deletion queue. Larger - /// values allow more trie keys to be deleted in each block but reduce the amount of - /// weight that is left for transactions. See [`Self::DeletionQueueDepth`] for more - /// information about the deletion queue. - #[pallet::constant] - type DeletionWeightLimit: Get; - /// The amount of balance a caller has to pay for each byte of storage. /// /// # Note @@ -329,25 +302,6 @@ pub mod pallet { .saturating_add(T::WeightInfo::on_process_deletion_queue_batch()) } - fn on_initialize(_block: T::BlockNumber) -> Weight { - // We want to process the deletion_queue in the on_idle hook. Only in the case - // that the queue length has reached its maximal depth, we process it here. - let max_len = T::DeletionQueueDepth::get() as usize; - let queue_len = >::decode_len().unwrap_or(0); - if queue_len >= max_len { - // We do not want to go above the block limit and rather avoid lazy deletion - // in that case. This should only happen on runtime upgrades. - let weight_limit = T::BlockWeights::get() - .max_block - .saturating_sub(System::::block_weight().total()) - .min(T::DeletionWeightLimit::get()); - ContractInfo::::process_deletion_queue_batch(weight_limit) - .saturating_add(T::WeightInfo::on_process_deletion_queue_batch()) - } else { - T::WeightInfo::on_process_deletion_queue_batch() - } - } - fn integrity_test() { // Total runtime memory is expected to have 128Mb upper limit const MAX_RUNTIME_MEM: u32 = 1024 * 1024 * 128; @@ -860,12 +814,6 @@ pub mod pallet { /// in this error. Note that this usually shouldn't happen as deploying such contracts /// is rejected. NoChainExtension, - /// Removal of a contract failed because the deletion queue is full. - /// - /// This can happen when calling `seal_terminate`. - /// The queue is filled by deleting contracts and emptied by a fixed amount each block. - /// Trying again during another block is the only way to resolve this issue. - DeletionQueueFull, /// A contract with the same AccountId already exists. DuplicateContract, /// A contract self destructed in its constructor. @@ -949,10 +897,15 @@ pub mod pallet { /// Evicted contracts that await child trie deletion. /// /// Child trie deletion is a heavy operation depending on the amount of storage items - /// stored in said trie. Therefore this operation is performed lazily in `on_initialize`. + /// stored in said trie. Therefore this operation is performed lazily in `on_idle`. + #[pallet::storage] + pub(crate) type DeletionQueue = StorageMap<_, Twox64Concat, u32, TrieId>; + + /// A pair of monotonic counters used to track the latest contract marked for deletion + /// and the latest deleted contract in queue. #[pallet::storage] - pub(crate) type DeletionQueue = - StorageValue<_, BoundedVec, ValueQuery>; + pub(crate) type DeletionQueueCounter = + StorageValue<_, DeletionQueueManager, ValueQuery>; } /// Context of a contract invocation. diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index 19c5f391d670b..769caef0736fe 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -22,15 +22,15 @@ pub mod meter; use crate::{ exec::{AccountIdOf, Key}, weights::WeightInfo, - AddressGenerator, BalanceOf, CodeHash, Config, ContractInfoOf, DeletionQueue, Error, Pallet, - TrieId, SENTINEL, + AddressGenerator, BalanceOf, CodeHash, Config, ContractInfoOf, DeletionQueue, + DeletionQueueCounter, Error, Pallet, TrieId, SENTINEL, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ - dispatch::{DispatchError, DispatchResult}, + dispatch::DispatchError, storage::child::{self, ChildInfo}, weights::Weight, - RuntimeDebugNoBound, + DefaultNoBound, RuntimeDebugNoBound, }; use scale_info::TypeInfo; use sp_io::KillStorageResult; @@ -38,7 +38,7 @@ use sp_runtime::{ traits::{Hash, Saturating, Zero}, RuntimeDebug, }; -use sp_std::{ops::Deref, prelude::*}; +use sp_std::{marker::PhantomData, ops::Deref, prelude::*}; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. @@ -204,27 +204,21 @@ impl ContractInfo { /// Push a contract's trie to the deletion queue for lazy removal. /// /// You must make sure that the contract is also removed when queuing the trie for deletion. - pub fn queue_trie_for_deletion(&self) -> DispatchResult { - >::try_append(DeletedContract { trie_id: self.trie_id.clone() }) - .map_err(|_| >::DeletionQueueFull.into()) + pub fn queue_trie_for_deletion(&self) { + DeletionQueueManager::::load().insert(self.trie_id.clone()); } /// Calculates the weight that is necessary to remove one key from the trie and how many - /// of those keys can be deleted from the deletion queue given the supplied queue length - /// and weight limit. - pub fn deletion_budget(queue_len: usize, weight_limit: Weight) -> (Weight, u32) { + /// of those keys can be deleted from the deletion queue given the supplied weight limit. + pub fn deletion_budget(weight_limit: Weight) -> (Weight, u32) { let base_weight = T::WeightInfo::on_process_deletion_queue_batch(); - let weight_per_queue_item = T::WeightInfo::on_initialize_per_queue_item(1) - - T::WeightInfo::on_initialize_per_queue_item(0); let weight_per_key = T::WeightInfo::on_initialize_per_trie_key(1) - T::WeightInfo::on_initialize_per_trie_key(0); - let decoding_weight = weight_per_queue_item.saturating_mul(queue_len as u64); // `weight_per_key` being zero makes no sense and would constitute a failure to // benchmark properly. We opt for not removing any keys at all in this case. let key_budget = weight_limit .saturating_sub(base_weight) - .saturating_sub(decoding_weight) .checked_div_per_component(&weight_per_key) .unwrap_or(0) as u32; @@ -235,13 +229,13 @@ impl ContractInfo { /// /// It returns the amount of weight used for that task. pub fn process_deletion_queue_batch(weight_limit: Weight) -> Weight { - let queue_len = >::decode_len().unwrap_or(0); - if queue_len == 0 { + let mut queue = >::load(); + + if queue.is_empty() { return Weight::zero() } - let (weight_per_key, mut remaining_key_budget) = - Self::deletion_budget(queue_len, weight_limit); + let (weight_per_key, mut remaining_key_budget) = Self::deletion_budget(weight_limit); // We want to check whether we have enough weight to decode the queue before // proceeding. Too little weight for decoding might happen during runtime upgrades @@ -250,30 +244,25 @@ impl ContractInfo { return weight_limit } - let mut queue = >::get(); + while remaining_key_budget > 0 { + let Some(entry) = queue.next() else { break }; - while !queue.is_empty() && remaining_key_budget > 0 { - // Cannot panic due to loop condition - let trie = &mut queue[0]; #[allow(deprecated)] let outcome = child::kill_storage( - &ChildInfo::new_default(&trie.trie_id), + &ChildInfo::new_default(&entry.trie_id), Some(remaining_key_budget), ); - let keys_removed = match outcome { + + match outcome { // This happens when our budget wasn't large enough to remove all keys. - KillStorageResult::SomeRemaining(c) => c, - KillStorageResult::AllRemoved(c) => { - // We do not care to preserve order. The contract is deleted already and - // no one waits for the trie to be deleted. - queue.swap_remove(0); - c + KillStorageResult::SomeRemaining(_) => return weight_limit, + KillStorageResult::AllRemoved(keys_removed) => { + entry.remove(); + remaining_key_budget = remaining_key_budget.saturating_sub(keys_removed); }, }; - remaining_key_budget = remaining_key_budget.saturating_sub(keys_removed); } - >::put(queue); weight_limit.saturating_sub(weight_per_key.saturating_mul(u64::from(remaining_key_budget))) } @@ -281,25 +270,9 @@ impl ContractInfo { pub fn load_code_hash(account: &AccountIdOf) -> Option> { >::get(account).map(|i| i.code_hash) } - - /// Fill up the queue in order to exercise the limits during testing. - #[cfg(test)] - pub fn fill_queue_with_dummies() { - use frame_support::{traits::Get, BoundedVec}; - let queue: Vec = (0..T::DeletionQueueDepth::get()) - .map(|_| DeletedContract { trie_id: TrieId::default() }) - .collect(); - let bounded: BoundedVec<_, _> = queue.try_into().map_err(|_| ()).unwrap(); - >::put(bounded); - } } -#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct DeletedContract { - pub(crate) trie_id: TrieId, -} - -/// Information about what happended to the pre-existing value when calling [`ContractInfo::write`]. +/// Information about what happened to the pre-existing value when calling [`ContractInfo::write`]. #[cfg_attr(test, derive(Debug, PartialEq))] pub enum WriteOutcome { /// No value existed at the specified key. @@ -352,3 +325,84 @@ impl Deref for DepositAccount { &self.0 } } + +/// Manage the removal of contracts storage that are marked for deletion. +/// +/// When a contract is deleted by calling `seal_terminate` it becomes inaccessible +/// immediately, but the deletion of the storage items it has accumulated is performed +/// later by pulling the contract from the queue in the `on_idle` hook. +#[derive(Encode, Decode, TypeInfo, MaxEncodedLen, DefaultNoBound, Clone)] +#[scale_info(skip_type_params(T))] +pub struct DeletionQueueManager { + /// Counter used as a key for inserting a new deleted contract in the queue. + /// The counter is incremented after each insertion. + insert_counter: u32, + /// The index used to read the next element to be deleted in the queue. + /// The counter is incremented after each deletion. + delete_counter: u32, + + _phantom: PhantomData, +} + +/// View on a contract that is marked for deletion. +struct DeletionQueueEntry<'a, T: Config> { + /// the trie id of the contract to delete. + trie_id: TrieId, + + /// A mutable reference on the queue so that the contract can be removed, and none can be added + /// or read in the meantime. + queue: &'a mut DeletionQueueManager, +} + +impl<'a, T: Config> DeletionQueueEntry<'a, T> { + /// Remove the contract from the deletion queue. + fn remove(self) { + >::remove(self.queue.delete_counter); + self.queue.delete_counter = self.queue.delete_counter.wrapping_add(1); + >::set(self.queue.clone()); + } +} + +impl DeletionQueueManager { + /// Load the `DeletionQueueCounter`, so we can perform read or write operations on the + /// DeletionQueue storage. + fn load() -> Self { + >::get() + } + + /// Returns `true` if the queue contains no elements. + fn is_empty(&self) -> bool { + self.insert_counter.wrapping_sub(self.delete_counter) == 0 + } + + /// Insert a contract in the deletion queue. + fn insert(&mut self, trie_id: TrieId) { + >::insert(self.insert_counter, trie_id); + self.insert_counter = self.insert_counter.wrapping_add(1); + >::set(self.clone()); + } + + /// Fetch the next contract to be deleted. + /// + /// Note: + /// we use the delete counter to get the next value to read from the queue and thus don't pay + /// the cost of an extra call to `sp_io::storage::next_key` to lookup the next entry in the map + fn next(&mut self) -> Option> { + if self.is_empty() { + return None + } + + let entry = >::get(self.delete_counter); + entry.map(|trie_id| DeletionQueueEntry { trie_id, queue: self }) + } +} + +#[cfg(test)] +impl DeletionQueueManager { + pub fn from_test_values(insert_counter: u32, delete_counter: u32) -> Self { + Self { insert_counter, delete_counter, _phantom: Default::default() } + } + pub fn as_test_tuple(&self) -> (u32, u32) { + (self.insert_counter, self.delete_counter) + } +} diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 146e5fd24ad07..bae6c1946e183 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -22,26 +22,27 @@ use crate::{ Result as ExtensionResult, RetVal, ReturnFlags, SysConfig, }, exec::{Frame, Key}, + storage::DeletionQueueManager, tests::test_utils::{get_contract, get_contract_checked}, wasm::{Determinism, PrefabWasmModule, ReturnCode as RuntimeReturnCode}, weights::WeightInfo, BalanceOf, Code, CodeStorage, Config, ContractInfo, ContractInfoOf, DefaultAddressGenerator, - DeletionQueue, Error, Pallet, Schedule, + DeletionQueueCounter, Error, Pallet, Schedule, }; use assert_matches::assert_matches; use codec::Encode; use frame_support::{ assert_err, assert_err_ignore_postinfo, assert_noop, assert_ok, - dispatch::{DispatchClass, DispatchErrorWithPostInfo, PostDispatchInfo}, + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, parameter_types, storage::child, traits::{ - ConstU32, ConstU64, Contains, Currency, ExistenceRequirement, Get, LockableCurrency, - OnIdle, OnInitialize, WithdrawReasons, + ConstU32, ConstU64, Contains, Currency, ExistenceRequirement, LockableCurrency, OnIdle, + OnInitialize, WithdrawReasons, }, weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, }; -use frame_system::{self as system, EventRecord, Phase}; +use frame_system::{EventRecord, Phase}; use pretty_assertions::{assert_eq, assert_ne}; use sp_io::hashing::blake2_256; use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; @@ -383,7 +384,6 @@ impl Contains for TestFilter { } parameter_types! { - pub const DeletionWeightLimit: Weight = GAS_LIMIT; pub static UnstableInterface: bool = true; } @@ -399,8 +399,6 @@ impl Config for Test { type WeightInfo = (); type ChainExtension = (TestExtension, DisabledExtension, RevertingExtension, TempStorageExtension); - type DeletionQueueDepth = ConstU32<1024>; - type DeletionWeightLimit = DeletionWeightLimit; type Schedule = MySchedule; type DepositPerByte = DepositPerByte; type DepositPerItem = DepositPerItem; @@ -458,7 +456,14 @@ fn compile_module(fixture_name: &str) -> wat::Result<(Vec, ::fill_queue_with_dummies(); - - let queue_len_initial = >::decode_len().unwrap_or(0); - - // Run the lazy removal - Contracts::on_initialize(System::block_number()); - - let queue_len_after_on_initialize = >::decode_len().unwrap_or(0); - - // Queue length should be decreased after call of on_initialize() - assert!(queue_len_initial - queue_len_after_on_initialize > 0); - }); -} - #[test] fn lazy_batch_removal_works() { let (code, _hash) = compile_module::("self_destruct").unwrap(); @@ -2054,7 +2040,7 @@ fn lazy_removal_partial_remove_works() { // We create a contract with some extra keys above the weight limit let extra_keys = 7u32; let weight_limit = Weight::from_parts(5_000_000_000, 0); - let (_, max_keys) = ContractInfo::::deletion_budget(1, weight_limit); + let (_, max_keys) = ContractInfo::::deletion_budget(weight_limit); let vals: Vec<_> = (0..max_keys + extra_keys) .map(|i| (blake2_256(&i.encode()), (i as u32), (i as u32).encode())) .collect(); @@ -2139,33 +2125,6 @@ fn lazy_removal_partial_remove_works() { }); } -#[test] -fn lazy_removal_does_no_run_on_full_queue_and_full_block() { - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Fill up the block which should prevent the lazy storage removal from running. - System::register_extra_weight_unchecked( - ::BlockWeights::get().max_block, - DispatchClass::Mandatory, - ); - - // Fill the deletion queue with dummy values, so that on_initialize attempts - // to clear the queue - ContractInfo::::fill_queue_with_dummies(); - - // Check that on_initialize() tries to perform lazy removal but removes nothing - // as no more weight is left for that. - let weight_used = Contracts::on_initialize(System::block_number()); - let base = <::WeightInfo as WeightInfo>::on_process_deletion_queue_batch(); - assert_eq!(weight_used, base); - - // Check that the deletion queue is still full after execution of the - // on_initialize() hook. - let max_len: u32 = ::DeletionQueueDepth::get(); - let queue_len: u32 = >::decode_len().unwrap_or(0).try_into().unwrap(); - assert_eq!(max_len, queue_len); - }); -} - #[test] fn lazy_removal_does_no_run_on_low_remaining_weight() { let (code, _hash) = compile_module::("self_destruct").unwrap(); @@ -2209,7 +2168,7 @@ fn lazy_removal_does_no_run_on_low_remaining_weight() { // But value should be still there as the lazy removal did not run, yet. assert_matches!(child::get(trie, &[99]), Some(42)); - // Assign a remaining weight which is too low for a successfull deletion of the contract + // Assign a remaining weight which is too low for a successful deletion of the contract let low_remaining_weight = <::WeightInfo as WeightInfo>::on_process_deletion_queue_batch(); @@ -2259,7 +2218,7 @@ fn lazy_removal_does_not_use_all_weight() { .account_id; let info = get_contract(&addr); - let (weight_per_key, max_keys) = ContractInfo::::deletion_budget(1, weight_limit); + let (weight_per_key, max_keys) = ContractInfo::::deletion_budget(weight_limit); // We create a contract with one less storage item than we can remove within the limit let vals: Vec<_> = (0..max_keys - 1) @@ -2314,40 +2273,75 @@ fn lazy_removal_does_not_use_all_weight() { } #[test] -fn deletion_queue_full() { +fn deletion_queue_ring_buffer_overflow() { let (code, _hash) = compile_module::("self_destruct").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let mut ext = ExtBuilder::default().existential_deposit(50).build(); + + // setup the deletion queue with custom counters + ext.execute_with(|| { + let queue = DeletionQueueManager::from_test_values(u32::MAX - 1, u32::MAX - 1); + >::set(queue); + }); + + // commit the changes to the storage + ext.commit_all().unwrap(); + + ext.execute_with(|| { let min_balance = ::Currency::minimum_balance(); let _ = Balances::deposit_creating(&ALICE, 1000 * min_balance); + let mut tries: Vec = vec![]; - let addr = Contracts::bare_instantiate( - ALICE, - min_balance * 100, - GAS_LIMIT, - None, - Code::Upload(code), - vec![], - vec![], - false, - ) - .result - .unwrap() - .account_id; + // add 3 contracts to the deletion queue + for i in 0..3u8 { + let addr = Contracts::bare_instantiate( + ALICE, + min_balance * 100, + GAS_LIMIT, + None, + Code::Upload(code.clone()), + vec![], + vec![i], + false, + ) + .result + .unwrap() + .account_id; - // fill the deletion queue up until its limit - ContractInfo::::fill_queue_with_dummies(); + let info = get_contract(&addr); + let trie = &info.child_trie_info(); - // Terminate the contract should fail - assert_err_ignore_postinfo!( - Contracts::call(RuntimeOrigin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, None, vec![],), - Error::::DeletionQueueFull, - ); + // Put value into the contracts child trie + child::put(trie, &[99], &42); - // Contract should exist because removal failed - get_contract(&addr); - }); -} + // Terminate the contract. Contract info should be gone, but value should be still + // there as the lazy removal did not run, yet. + assert_ok!(Contracts::call( + RuntimeOrigin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + None, + vec![] + )); + + assert!(!>::contains_key(&addr)); + assert_matches!(child::get(trie, &[99]), Some(42)); + + tries.push(trie.clone()) + } + + // Run single lazy removal + Contracts::on_idle(System::block_number(), Weight::MAX); + // The single lazy removal should have removed all queued tries + for trie in tries.iter() { + assert_matches!(child::get::(trie, &[99]), None); + } + + // insert and delete counter values should go from u32::MAX - 1 to 1 + assert_eq!(>::get().as_test_tuple(), (1, 1)); + }) +} #[test] fn refcounter() { let (wasm, code_hash) = compile_module::("self_destruct").unwrap(); diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index 9e37a238b7d59..22a24aa27fe01 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 4.0.0-dev -//! DATE: 2023-03-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-03-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -51,7 +51,6 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn on_process_deletion_queue_batch() -> Weight; fn on_initialize_per_trie_key(k: u32, ) -> Weight; - fn on_initialize_per_queue_item(q: u32, ) -> Weight; fn reinstrument(c: u32, ) -> Weight; fn call_with_code_per_byte(c: u32, ) -> Weight; fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight; @@ -171,14 +170,14 @@ pub trait WeightInfo { /// Weights for pallet_contracts using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Contracts DeletionQueue (r:1 w:0) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) + /// Storage: Contracts DeletionQueueCounter (r:1 w:0) + /// Proof: Contracts DeletionQueueCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) fn on_process_deletion_queue_batch() -> Weight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `1594` - // Minimum execution time: 2_713_000 picoseconds. - Weight::from_parts(2_811_000, 1594) + // Minimum execution time: 2_677_000 picoseconds. + Weight::from_parts(2_899_000, 1594) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: Skipped Metadata (r:0 w:0) @@ -186,33 +185,18 @@ impl WeightInfo for SubstrateWeight { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `450 + k * (69 ±0)` - // Estimated: `440 + k * (70 ±0)` - // Minimum execution time: 11_011_000 picoseconds. - Weight::from_parts(7_025_244, 440) - // Standard Error: 1_217 - .saturating_add(Weight::from_parts(980_818, 0).saturating_mul(k.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Measured: `488 + k * (69 ±0)` + // Estimated: `478 + k * (70 ±0)` + // Minimum execution time: 14_006_000 picoseconds. + Weight::from_parts(8_735_946, 478) + // Standard Error: 1_370 + .saturating_add(Weight::from_parts(989_501, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(k.into())) } - /// Storage: Contracts DeletionQueue (r:1 w:1) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) - /// The range of component `q` is `[0, 128]`. - fn on_initialize_per_queue_item(q: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `250 + q * (33 ±0)` - // Estimated: `1725 + q * (33 ±0)` - // Minimum execution time: 2_802_000 picoseconds. - Weight::from_parts(10_768_336, 1725) - // Standard Error: 3_424 - .saturating_add(Weight::from_parts(1_323_649, 0).saturating_mul(q.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(q.into())) - } /// Storage: Contracts PristineCode (r:1 w:0) /// Proof: Contracts PristineCode (max_values: None, max_size: Some(125988), added: 128463, mode: Measured) /// Storage: Contracts CodeStorage (r:0 w:1) @@ -222,10 +206,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `238 + c * (1 ±0)` // Estimated: `3951 + c * (2 ±0)` - // Minimum execution time: 30_299_000 picoseconds. - Weight::from_parts(24_608_986, 3951) - // Standard Error: 75 - .saturating_add(Weight::from_parts(54_619, 0).saturating_mul(c.into())) + // Minimum execution time: 30_951_000 picoseconds. + Weight::from_parts(25_988_560, 3951) + // Standard Error: 57 + .saturating_add(Weight::from_parts(54_692, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2).saturating_mul(c.into())) @@ -245,10 +229,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `707` // Estimated: `21400 + c * (5 ±0)` - // Minimum execution time: 265_835_000 picoseconds. - Weight::from_parts(275_985_164, 21400) - // Standard Error: 36 - .saturating_add(Weight::from_parts(37_980, 0).saturating_mul(c.into())) + // Minimum execution time: 263_107_000 picoseconds. + Weight::from_parts(268_289_665, 21400) + // Standard Error: 33 + .saturating_add(Weight::from_parts(38_534, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 5).saturating_mul(c.into())) @@ -276,14 +260,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `270` // Estimated: `26207` - // Minimum execution time: 3_124_508_000 picoseconds. - Weight::from_parts(617_467_897, 26207) - // Standard Error: 293 - .saturating_add(Weight::from_parts(106_971, 0).saturating_mul(c.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_156, 0).saturating_mul(i.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_395, 0).saturating_mul(s.into())) + // Minimum execution time: 3_122_319_000 picoseconds. + Weight::from_parts(487_802_180, 26207) + // Standard Error: 345 + .saturating_add(Weight::from_parts(108_237, 0).saturating_mul(c.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_166, 0).saturating_mul(i.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_505, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -307,12 +291,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `482` // Estimated: `28521` - // Minimum execution time: 1_649_483_000 picoseconds. - Weight::from_parts(287_642_416, 28521) + // Minimum execution time: 1_650_623_000 picoseconds. + Weight::from_parts(286_494_456, 28521) // Standard Error: 8 - .saturating_add(Weight::from_parts(1_450, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_438, 0).saturating_mul(i.into())) // Standard Error: 8 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_453, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -330,8 +314,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `759` // Estimated: `21615` - // Minimum execution time: 192_302_000 picoseconds. - Weight::from_parts(193_192_000, 21615) + // Minimum execution time: 191_046_000 picoseconds. + Weight::from_parts(192_544_000, 21615) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -348,10 +332,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `7366` - // Minimum execution time: 246_401_000 picoseconds. - Weight::from_parts(261_505_456, 7366) - // Standard Error: 83 - .saturating_add(Weight::from_parts(109_136, 0).saturating_mul(c.into())) + // Minimum execution time: 244_260_000 picoseconds. + Weight::from_parts(254_693_985, 7366) + // Standard Error: 80 + .saturating_add(Weight::from_parts(108_246, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -367,8 +351,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `255` // Estimated: `7950` - // Minimum execution time: 33_913_000 picoseconds. - Weight::from_parts(34_186_000, 7950) + // Minimum execution time: 33_492_000 picoseconds. + Weight::from_parts(34_079_000, 7950) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -382,8 +366,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `570` // Estimated: `19530` - // Minimum execution time: 33_801_000 picoseconds. - Weight::from_parts(34_877_000, 19530) + // Minimum execution time: 33_475_000 picoseconds. + Weight::from_parts(33_856_000, 19530) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -402,10 +386,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `781 + r * (6 ±0)` // Estimated: `21730 + r * (30 ±0)` - // Minimum execution time: 237_679_000 picoseconds. - Weight::from_parts(243_022_905, 21730) - // Standard Error: 940 - .saturating_add(Weight::from_parts(324_389, 0).saturating_mul(r.into())) + // Minimum execution time: 234_197_000 picoseconds. + Weight::from_parts(236_830_305, 21730) + // Standard Error: 818 + .saturating_add(Weight::from_parts(336_446, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -425,10 +409,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `839 + r * (240 ±0)` // Estimated: `21835 + r * (3675 ±0)` - // Minimum execution time: 235_635_000 picoseconds. - Weight::from_parts(76_942_144, 21835) - // Standard Error: 6_214 - .saturating_add(Weight::from_parts(3_328_756, 0).saturating_mul(r.into())) + // Minimum execution time: 235_872_000 picoseconds. + Weight::from_parts(78_877_890, 21835) + // Standard Error: 6_405 + .saturating_add(Weight::from_parts(3_358_341, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -449,10 +433,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `831 + r * (244 ±0)` // Estimated: `21855 + r * (3695 ±0)` - // Minimum execution time: 237_123_000 picoseconds. - Weight::from_parts(77_880_739, 21855) - // Standard Error: 5_970 - .saturating_add(Weight::from_parts(4_103_281, 0).saturating_mul(r.into())) + // Minimum execution time: 239_035_000 picoseconds. + Weight::from_parts(93_255_085, 21855) + // Standard Error: 5_922 + .saturating_add(Weight::from_parts(4_144_910, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -473,10 +457,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `788 + r * (6 ±0)` // Estimated: `21770 + r * (30 ±0)` - // Minimum execution time: 236_621_000 picoseconds. - Weight::from_parts(238_240_015, 21770) - // Standard Error: 742 - .saturating_add(Weight::from_parts(404_691, 0).saturating_mul(r.into())) + // Minimum execution time: 236_507_000 picoseconds. + Weight::from_parts(238_253_211, 21770) + // Standard Error: 975 + .saturating_add(Weight::from_parts(413_919, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -496,10 +480,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `778 + r * (3 ±0)` // Estimated: `21735 + r * (15 ±0)` - // Minimum execution time: 233_274_000 picoseconds. - Weight::from_parts(239_596_227, 21735) - // Standard Error: 551 - .saturating_add(Weight::from_parts(164_429, 0).saturating_mul(r.into())) + // Minimum execution time: 235_521_000 picoseconds. + Weight::from_parts(238_397_362, 21735) + // Standard Error: 452 + .saturating_add(Weight::from_parts(160_860, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(r.into())) @@ -519,10 +503,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `782 + r * (6 ±0)` // Estimated: `21740 + r * (30 ±0)` - // Minimum execution time: 235_661_000 picoseconds. - Weight::from_parts(239_063_406, 21740) - // Standard Error: 933 - .saturating_add(Weight::from_parts(327_679, 0).saturating_mul(r.into())) + // Minimum execution time: 234_722_000 picoseconds. + Weight::from_parts(242_936_096, 21740) + // Standard Error: 1_178 + .saturating_add(Weight::from_parts(329_075, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -542,10 +526,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `783 + r * (6 ±0)` // Estimated: `21725 + r * (30 ±0)` - // Minimum execution time: 235_583_000 picoseconds. - Weight::from_parts(251_641_549, 21725) - // Standard Error: 1_104 - .saturating_add(Weight::from_parts(315_873, 0).saturating_mul(r.into())) + // Minimum execution time: 235_654_000 picoseconds. + Weight::from_parts(245_887_792, 21725) + // Standard Error: 903 + .saturating_add(Weight::from_parts(325_168, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -565,10 +549,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `922 + r * (6 ±0)` // Estimated: `24633 + r * (30 ±0)` - // Minimum execution time: 235_325_000 picoseconds. - Weight::from_parts(256_582_010, 24633) - // Standard Error: 1_349 - .saturating_add(Weight::from_parts(1_483_116, 0).saturating_mul(r.into())) + // Minimum execution time: 233_599_000 picoseconds. + Weight::from_parts(251_561_602, 24633) + // Standard Error: 3_348 + .saturating_add(Weight::from_parts(1_475_443, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -588,10 +572,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `792 + r * (6 ±0)` // Estimated: `21825 + r * (30 ±0)` - // Minimum execution time: 235_358_000 picoseconds. - Weight::from_parts(233_421_484, 21825) - // Standard Error: 1_178 - .saturating_add(Weight::from_parts(337_947, 0).saturating_mul(r.into())) + // Minimum execution time: 235_087_000 picoseconds. + Weight::from_parts(235_855_322, 21825) + // Standard Error: 867 + .saturating_add(Weight::from_parts(346_707, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -611,10 +595,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `790 + r * (6 ±0)` // Estimated: `21815 + r * (30 ±0)` - // Minimum execution time: 236_570_000 picoseconds. - Weight::from_parts(245_853_078, 21815) - // Standard Error: 1_947 - .saturating_add(Weight::from_parts(319_972, 0).saturating_mul(r.into())) + // Minimum execution time: 237_103_000 picoseconds. + Weight::from_parts(239_272_188, 21815) + // Standard Error: 892 + .saturating_add(Weight::from_parts(328_334, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -634,10 +618,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `787 + r * (6 ±0)` // Estimated: `21805 + r * (30 ±0)` - // Minimum execution time: 235_027_000 picoseconds. - Weight::from_parts(239_719_689, 21805) - // Standard Error: 654 - .saturating_add(Weight::from_parts(326_988, 0).saturating_mul(r.into())) + // Minimum execution time: 234_761_000 picoseconds. + Weight::from_parts(238_601_784, 21805) + // Standard Error: 725 + .saturating_add(Weight::from_parts(325_758, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -657,10 +641,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `778 + r * (6 ±0)` // Estimated: `21735 + r * (30 ±0)` - // Minimum execution time: 236_547_000 picoseconds. - Weight::from_parts(239_390_326, 21735) - // Standard Error: 912 - .saturating_add(Weight::from_parts(327_495, 0).saturating_mul(r.into())) + // Minimum execution time: 235_249_000 picoseconds. + Weight::from_parts(239_861_242, 21735) + // Standard Error: 751 + .saturating_add(Weight::from_parts(325_795, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -682,10 +666,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `856 + r * (10 ±0)` // Estimated: `24446 + r * (60 ±0)` - // Minimum execution time: 235_710_000 picoseconds. - Weight::from_parts(238_998_789, 24446) - // Standard Error: 2_055 - .saturating_add(Weight::from_parts(1_373_992, 0).saturating_mul(r.into())) + // Minimum execution time: 234_912_000 picoseconds. + Weight::from_parts(254_783_734, 24446) + // Standard Error: 1_610 + .saturating_add(Weight::from_parts(1_307_506, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 60).saturating_mul(r.into())) @@ -705,10 +689,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `745 + r * (4 ±0)` // Estimated: `21555 + r * (20 ±0)` - // Minimum execution time: 161_133_000 picoseconds. - Weight::from_parts(167_097_346, 21555) - // Standard Error: 245 - .saturating_add(Weight::from_parts(128_503, 0).saturating_mul(r.into())) + // Minimum execution time: 160_125_000 picoseconds. + Weight::from_parts(164_915_574, 21555) + // Standard Error: 332 + .saturating_add(Weight::from_parts(132_326, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 20).saturating_mul(r.into())) @@ -728,10 +712,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `780 + r * (6 ±0)` // Estimated: `21740 + r * (30 ±0)` - // Minimum execution time: 234_790_000 picoseconds. - Weight::from_parts(242_392_710, 21740) - // Standard Error: 2_506 - .saturating_add(Weight::from_parts(273_470, 0).saturating_mul(r.into())) + // Minimum execution time: 234_717_000 picoseconds. + Weight::from_parts(238_540_521, 21740) + // Standard Error: 599 + .saturating_add(Weight::from_parts(277_303, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -751,10 +735,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `784` // Estimated: `21740` - // Minimum execution time: 236_837_000 picoseconds. - Weight::from_parts(237_860_073, 21740) - // Standard Error: 2 - .saturating_add(Weight::from_parts(602, 0).saturating_mul(n.into())) + // Minimum execution time: 235_792_000 picoseconds. + Weight::from_parts(244_114_692, 21740) + // Standard Error: 1 + .saturating_add(Weight::from_parts(589, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -773,10 +757,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `768 + r * (45 ±0)` // Estimated: `21660 + r * (225 ±0)` - // Minimum execution time: 232_047_000 picoseconds. - Weight::from_parts(234_629_293, 21660) - // Standard Error: 171_808 - .saturating_add(Weight::from_parts(663_306, 0).saturating_mul(r.into())) + // Minimum execution time: 231_166_000 picoseconds. + Weight::from_parts(233_339_177, 21660) + // Standard Error: 155_889 + .saturating_add(Weight::from_parts(3_124_322, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 225).saturating_mul(r.into())) @@ -796,10 +780,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `778` // Estimated: `21775` - // Minimum execution time: 235_035_000 picoseconds. - Weight::from_parts(234_442_091, 21775) + // Minimum execution time: 235_721_000 picoseconds. + Weight::from_parts(237_413_703, 21775) // Standard Error: 1 - .saturating_add(Weight::from_parts(185, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(177, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -811,26 +795,28 @@ impl WeightInfo for SubstrateWeight { /// Proof: Contracts CodeStorage (max_values: None, max_size: Some(126001), added: 128476, mode: Measured) /// Storage: Timestamp Now (r:1 w:0) /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) - /// Storage: Contracts DeletionQueue (r:1 w:1) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) + /// Storage: Contracts DeletionQueueCounter (r:1 w:1) + /// Proof: Contracts DeletionQueueCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) /// Storage: Contracts OwnerInfoOf (r:1 w:1) /// Proof: Contracts OwnerInfoOf (max_values: None, max_size: Some(88), added: 2563, mode: Measured) /// Storage: System EventTopics (r:3 w:3) /// Proof Skipped: System EventTopics (max_values: None, max_size: None, mode: Measured) + /// Storage: Contracts DeletionQueue (r:0 w:1) + /// Proof: Contracts DeletionQueue (max_values: None, max_size: Some(142), added: 2617, mode: Measured) /// The range of component `r` is `[0, 1]`. fn seal_terminate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `810 + r * (356 ±0)` - // Estimated: `25511 + r * (15321 ±0)` - // Minimum execution time: 234_140_000 picoseconds. - Weight::from_parts(236_805_906, 25511) - // Standard Error: 435_181 - .saturating_add(Weight::from_parts(118_144_693, 0).saturating_mul(r.into())) + // Estimated: `26094 + r * (15904 ±0)` + // Minimum execution time: 233_525_000 picoseconds. + Weight::from_parts(235_871_034, 26094) + // Standard Error: 235_338 + .saturating_add(Weight::from_parts(118_659_865, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) - .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 15321).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().writes((8_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 15904).saturating_mul(r.into())) } /// Storage: System Account (r:1 w:0) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: Measured) @@ -849,10 +835,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `825 + r * (10 ±0)` // Estimated: `24283 + r * (60 ±0)` - // Minimum execution time: 235_271_000 picoseconds. - Weight::from_parts(256_019_682, 24283) - // Standard Error: 2_016 - .saturating_add(Weight::from_parts(1_862_085, 0).saturating_mul(r.into())) + // Minimum execution time: 235_007_000 picoseconds. + Weight::from_parts(248_419_686, 24283) + // Standard Error: 1_847 + .saturating_add(Weight::from_parts(1_815_822, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 60).saturating_mul(r.into())) @@ -872,10 +858,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `778 + r * (10 ±0)` // Estimated: `21735 + r * (50 ±0)` - // Minimum execution time: 233_092_000 picoseconds. - Weight::from_parts(248_483_473, 21735) - // Standard Error: 2_182 - .saturating_add(Weight::from_parts(3_551_674, 0).saturating_mul(r.into())) + // Minimum execution time: 232_912_000 picoseconds. + Weight::from_parts(256_142_885, 21735) + // Standard Error: 2_741 + .saturating_add(Weight::from_parts(3_542_482, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 50).saturating_mul(r.into())) @@ -896,12 +882,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `797 + t * (32 ±0)` // Estimated: `21840 + t * (2640 ±0)` - // Minimum execution time: 252_307_000 picoseconds. - Weight::from_parts(245_237_726, 21840) - // Standard Error: 79_824 - .saturating_add(Weight::from_parts(2_364_618, 0).saturating_mul(t.into())) - // Standard Error: 22 - .saturating_add(Weight::from_parts(636, 0).saturating_mul(n.into())) + // Minimum execution time: 251_018_000 picoseconds. + Weight::from_parts(245_280_765, 21840) + // Standard Error: 90_317 + .saturating_add(Weight::from_parts(2_434_496, 0).saturating_mul(t.into())) + // Standard Error: 25 + .saturating_add(Weight::from_parts(599, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -923,10 +909,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `777 + r * (7 ±0)` // Estimated: `21725 + r * (35 ±0)` - // Minimum execution time: 165_367_000 picoseconds. - Weight::from_parts(170_164_725, 21725) - // Standard Error: 487 - .saturating_add(Weight::from_parts(237_281, 0).saturating_mul(r.into())) + // Minimum execution time: 164_022_000 picoseconds. + Weight::from_parts(168_658_387, 21725) + // Standard Error: 685 + .saturating_add(Weight::from_parts(238_133, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 35).saturating_mul(r.into())) @@ -946,10 +932,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125728` // Estimated: `269977` - // Minimum execution time: 350_914_000 picoseconds. - Weight::from_parts(354_461_646, 269977) - // Standard Error: 1 - .saturating_add(Weight::from_parts(747, 0).saturating_mul(i.into())) + // Minimum execution time: 351_043_000 picoseconds. + Weight::from_parts(353_707_344, 269977) + // Standard Error: 3 + .saturating_add(Weight::from_parts(752, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -960,10 +946,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `845 + r * (292 ±0)` // Estimated: `843 + r * (293 ±0)` - // Minimum execution time: 236_273_000 picoseconds. - Weight::from_parts(137_922_946, 843) - // Standard Error: 10_363 - .saturating_add(Weight::from_parts(6_034_776, 0).saturating_mul(r.into())) + // Minimum execution time: 235_854_000 picoseconds. + Weight::from_parts(133_986_225, 843) + // Standard Error: 9_550 + .saturating_add(Weight::from_parts(6_093_051, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -977,10 +963,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1304` // Estimated: `1280` - // Minimum execution time: 251_462_000 picoseconds. - Weight::from_parts(287_009_907, 1280) - // Standard Error: 62 - .saturating_add(Weight::from_parts(384, 0).saturating_mul(n.into())) + // Minimum execution time: 252_321_000 picoseconds. + Weight::from_parts(285_820_577, 1280) + // Standard Error: 60 + .saturating_add(Weight::from_parts(600, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -991,10 +977,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1167 + n * (1 ±0)` // Estimated: `1167 + n * (1 ±0)` - // Minimum execution time: 250_985_000 picoseconds. - Weight::from_parts(253_693_249, 1167) - // Standard Error: 21 - .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) + // Minimum execution time: 252_047_000 picoseconds. + Weight::from_parts(254_244_310, 1167) + // Standard Error: 15 + .saturating_add(Weight::from_parts(144, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1006,10 +992,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `841 + r * (288 ±0)` // Estimated: `845 + r * (289 ±0)` - // Minimum execution time: 235_462_000 picoseconds. - Weight::from_parts(141_240_297, 845) - // Standard Error: 9_687 - .saturating_add(Weight::from_parts(5_906_737, 0).saturating_mul(r.into())) + // Minimum execution time: 235_697_000 picoseconds. + Weight::from_parts(143_200_942, 845) + // Standard Error: 11_358 + .saturating_add(Weight::from_parts(5_934_318, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1023,10 +1009,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1163 + n * (1 ±0)` // Estimated: `1163 + n * (1 ±0)` - // Minimum execution time: 250_887_000 picoseconds. - Weight::from_parts(253_321_064, 1163) - // Standard Error: 28 - .saturating_add(Weight::from_parts(169, 0).saturating_mul(n.into())) + // Minimum execution time: 250_360_000 picoseconds. + Weight::from_parts(252_712_722, 1163) + // Standard Error: 15 + .saturating_add(Weight::from_parts(130, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1038,10 +1024,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `835 + r * (296 ±0)` // Estimated: `840 + r * (297 ±0)` - // Minimum execution time: 236_542_000 picoseconds. - Weight::from_parts(147_992_508, 840) - // Standard Error: 8_849 - .saturating_add(Weight::from_parts(4_946_692, 0).saturating_mul(r.into())) + // Minimum execution time: 235_613_000 picoseconds. + Weight::from_parts(150_213_792, 840) + // Standard Error: 8_617 + .saturating_add(Weight::from_parts(4_962_874, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1054,10 +1040,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1179 + n * (1 ±0)` // Estimated: `1179 + n * (1 ±0)` - // Minimum execution time: 249_987_000 picoseconds. - Weight::from_parts(254_866_627, 1179) - // Standard Error: 53 - .saturating_add(Weight::from_parts(554, 0).saturating_mul(n.into())) + // Minimum execution time: 249_137_000 picoseconds. + Weight::from_parts(253_529_386, 1179) + // Standard Error: 41 + .saturating_add(Weight::from_parts(612, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1069,10 +1055,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `856 + r * (288 ±0)` // Estimated: `857 + r * (289 ±0)` - // Minimum execution time: 236_635_000 picoseconds. - Weight::from_parts(157_805_789, 857) - // Standard Error: 7_699 - .saturating_add(Weight::from_parts(4_709_422, 0).saturating_mul(r.into())) + // Minimum execution time: 235_659_000 picoseconds. + Weight::from_parts(158_846_683, 857) + // Standard Error: 7_806 + .saturating_add(Weight::from_parts(4_728_537, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1085,10 +1071,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1166 + n * (1 ±0)` // Estimated: `1166 + n * (1 ±0)` - // Minimum execution time: 252_660_000 picoseconds. - Weight::from_parts(255_250_747, 1166) - // Standard Error: 14 - .saturating_add(Weight::from_parts(133, 0).saturating_mul(n.into())) + // Minimum execution time: 248_553_000 picoseconds. + Weight::from_parts(250_703_269, 1166) + // Standard Error: 17 + .saturating_add(Weight::from_parts(163, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1100,10 +1086,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `829 + r * (296 ±0)` // Estimated: `836 + r * (297 ±0)` - // Minimum execution time: 240_198_000 picoseconds. - Weight::from_parts(133_188_357, 836) - // Standard Error: 10_661 - .saturating_add(Weight::from_parts(6_147_538, 0).saturating_mul(r.into())) + // Minimum execution time: 236_431_000 picoseconds. + Weight::from_parts(131_745_419, 836) + // Standard Error: 10_161 + .saturating_add(Weight::from_parts(6_182_174, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1117,10 +1103,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1180 + n * (1 ±0)` // Estimated: `1180 + n * (1 ±0)` - // Minimum execution time: 252_131_000 picoseconds. - Weight::from_parts(259_960_286, 1180) - // Standard Error: 121 - .saturating_add(Weight::from_parts(192, 0).saturating_mul(n.into())) + // Minimum execution time: 252_551_000 picoseconds. + Weight::from_parts(254_517_030, 1180) + // Standard Error: 16 + .saturating_add(Weight::from_parts(712, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1140,10 +1126,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1373 + r * (45 ±0)` // Estimated: `26753 + r * (2700 ±0)` - // Minimum execution time: 235_860_000 picoseconds. - Weight::from_parts(124_993_651, 26753) - // Standard Error: 22_811 - .saturating_add(Weight::from_parts(36_467_740, 0).saturating_mul(r.into())) + // Minimum execution time: 236_663_000 picoseconds. + Weight::from_parts(237_485_000, 26753) + // Standard Error: 42_414 + .saturating_add(Weight::from_parts(36_849_514, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1165,10 +1151,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1237 + r * (256 ±0)` // Estimated: `26028 + r * (6235 ±0)` - // Minimum execution time: 237_221_000 picoseconds. - Weight::from_parts(237_632_000, 26028) - // Standard Error: 89_502 - .saturating_add(Weight::from_parts(212_211_534, 0).saturating_mul(r.into())) + // Minimum execution time: 237_101_000 picoseconds. + Weight::from_parts(237_827_000, 26028) + // Standard Error: 82_878 + .saturating_add(Weight::from_parts(211_777_724, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1190,10 +1176,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (502 ±0)` // Estimated: `21755 + r * (6329 ±3)` - // Minimum execution time: 236_965_000 picoseconds. - Weight::from_parts(238_110_000, 21755) - // Standard Error: 101_332 - .saturating_add(Weight::from_parts(206_790_203, 0).saturating_mul(r.into())) + // Minimum execution time: 241_213_000 picoseconds. + Weight::from_parts(241_900_000, 21755) + // Standard Error: 99_976 + .saturating_add(Weight::from_parts(207_520_077, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1216,12 +1202,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1154 + t * (204 ±0)` // Estimated: `31015 + t * (5970 ±0)` - // Minimum execution time: 411_974_000 picoseconds. - Weight::from_parts(391_387_689, 31015) - // Standard Error: 1_320_695 - .saturating_add(Weight::from_parts(29_766_122, 0).saturating_mul(t.into())) + // Minimum execution time: 414_784_000 picoseconds. + Weight::from_parts(384_902_379, 31015) + // Standard Error: 1_228_593 + .saturating_add(Weight::from_parts(33_226_901, 0).saturating_mul(t.into())) // Standard Error: 1 - .saturating_add(Weight::from_parts(597, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(601, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -1247,10 +1233,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1301 + r * (254 ±0)` // Estimated: `30977 + r * (16635 ±0)` - // Minimum execution time: 237_595_000 picoseconds. - Weight::from_parts(238_068_000, 30977) - // Standard Error: 254_409 - .saturating_add(Weight::from_parts(346_436_154, 0).saturating_mul(r.into())) + // Minimum execution time: 236_963_000 picoseconds. + Weight::from_parts(237_711_000, 30977) + // Standard Error: 265_576 + .saturating_add(Weight::from_parts(347_359_908, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1278,14 +1264,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1071 + t * (187 ±0)` // Estimated: `42684 + t * (3588 ±2)` - // Minimum execution time: 1_616_768_000 picoseconds. - Weight::from_parts(363_003_254, 42684) - // Standard Error: 4_398_669 - .saturating_add(Weight::from_parts(104_529_967, 0).saturating_mul(t.into())) + // Minimum execution time: 1_615_191_000 picoseconds. + Weight::from_parts(337_408_450, 42684) + // Standard Error: 4_581_951 + .saturating_add(Weight::from_parts(115_730_776, 0).saturating_mul(t.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_162, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(i.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_333, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_346, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(10_u64)) @@ -1307,10 +1293,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `777 + r * (8 ±0)` // Estimated: `21710 + r * (40 ±0)` - // Minimum execution time: 233_814_000 picoseconds. - Weight::from_parts(241_291_041, 21710) - // Standard Error: 1_422 - .saturating_add(Weight::from_parts(575_846, 0).saturating_mul(r.into())) + // Minimum execution time: 233_601_000 picoseconds. + Weight::from_parts(246_594_905, 21710) + // Standard Error: 2_840 + .saturating_add(Weight::from_parts(578_751, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -1330,10 +1316,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `785` // Estimated: `21745` - // Minimum execution time: 236_572_000 picoseconds. - Weight::from_parts(235_648_055, 21745) + // Minimum execution time: 233_735_000 picoseconds. + Weight::from_parts(243_432_330, 21745) // Standard Error: 3 - .saturating_add(Weight::from_parts(3_947, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_927, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1352,10 +1338,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21725 + r * (40 ±0)` - // Minimum execution time: 234_473_000 picoseconds. - Weight::from_parts(239_805_309, 21725) - // Standard Error: 1_113 - .saturating_add(Weight::from_parts(752_507, 0).saturating_mul(r.into())) + // Minimum execution time: 232_173_000 picoseconds. + Weight::from_parts(239_806_011, 21725) + // Standard Error: 1_530 + .saturating_add(Weight::from_parts(749_641, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -1375,10 +1361,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21765` - // Minimum execution time: 235_209_000 picoseconds. - Weight::from_parts(228_548_524, 21765) + // Minimum execution time: 235_046_000 picoseconds. + Weight::from_parts(229_500_792, 21765) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_171, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_166, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1397,10 +1383,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21740 + r * (40 ±0)` - // Minimum execution time: 233_282_000 picoseconds. - Weight::from_parts(240_864_680, 21740) - // Standard Error: 958 - .saturating_add(Weight::from_parts(418_308, 0).saturating_mul(r.into())) + // Minimum execution time: 231_708_000 picoseconds. + Weight::from_parts(235_347_566, 21740) + // Standard Error: 987 + .saturating_add(Weight::from_parts(428_819, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -1420,10 +1406,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21785` - // Minimum execution time: 234_667_000 picoseconds. - Weight::from_parts(227_810_077, 21785) - // Standard Error: 2 - .saturating_add(Weight::from_parts(925, 0).saturating_mul(n.into())) + // Minimum execution time: 234_068_000 picoseconds. + Weight::from_parts(226_519_852, 21785) + // Standard Error: 1 + .saturating_add(Weight::from_parts(916, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1442,10 +1428,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21745 + r * (40 ±0)` - // Minimum execution time: 234_040_000 picoseconds. - Weight::from_parts(237_970_694, 21745) - // Standard Error: 979 - .saturating_add(Weight::from_parts(416_562, 0).saturating_mul(r.into())) + // Minimum execution time: 231_872_000 picoseconds. + Weight::from_parts(236_694_763, 21745) + // Standard Error: 870 + .saturating_add(Weight::from_parts(420_853, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -1465,10 +1451,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21755` - // Minimum execution time: 234_840_000 picoseconds. - Weight::from_parts(227_849_778, 21755) + // Minimum execution time: 233_707_000 picoseconds. + Weight::from_parts(226_312_559, 21755) // Standard Error: 2 - .saturating_add(Weight::from_parts(923, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(924, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1487,10 +1473,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `822 + r * (76 ±0)` // Estimated: `21705 + r * (385 ±0)` - // Minimum execution time: 236_174_000 picoseconds. - Weight::from_parts(252_457_690, 21705) - // Standard Error: 20_130 - .saturating_add(Weight::from_parts(37_792_805, 0).saturating_mul(r.into())) + // Minimum execution time: 234_962_000 picoseconds. + Weight::from_parts(252_611_292, 21705) + // Standard Error: 20_134 + .saturating_add(Weight::from_parts(37_745_358, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 385).saturating_mul(r.into())) @@ -1509,11 +1495,11 @@ impl WeightInfo for SubstrateWeight { fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `792 + r * (42 ±0)` - // Estimated: `21780 + r * (210 ±0)` - // Minimum execution time: 236_251_000 picoseconds. - Weight::from_parts(242_254_305, 21780) - // Standard Error: 9_765 - .saturating_add(Weight::from_parts(9_341_334, 0).saturating_mul(r.into())) + // Estimated: `21775 + r * (210 ±0)` + // Minimum execution time: 234_869_000 picoseconds. + Weight::from_parts(240_188_331, 21775) + // Standard Error: 9_910 + .saturating_add(Weight::from_parts(9_332_432, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 210).saturating_mul(r.into())) @@ -1534,11 +1520,11 @@ impl WeightInfo for SubstrateWeight { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (964 ±0)` - // Estimated: `29920 + r * (11544 ±7)` - // Minimum execution time: 236_462_000 picoseconds. - Weight::from_parts(236_997_000, 29920) - // Standard Error: 46_527 - .saturating_add(Weight::from_parts(21_858_761, 0).saturating_mul(r.into())) + // Estimated: `29920 + r * (11544 ±10)` + // Minimum execution time: 235_036_000 picoseconds. + Weight::from_parts(235_538_000, 29920) + // Standard Error: 47_360 + .saturating_add(Weight::from_parts(22_113_144, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1560,10 +1546,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `773 + r * (3 ±0)` // Estimated: `21735 + r * (15 ±0)` - // Minimum execution time: 235_085_000 picoseconds. - Weight::from_parts(239_410_836, 21735) - // Standard Error: 414 - .saturating_add(Weight::from_parts(167_067, 0).saturating_mul(r.into())) + // Minimum execution time: 237_884_000 picoseconds. + Weight::from_parts(243_315_095, 21735) + // Standard Error: 560 + .saturating_add(Weight::from_parts(162_206, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(r.into())) @@ -1583,10 +1569,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1975 + r * (39 ±0)` // Estimated: `27145 + r * (200 ±0)` - // Minimum execution time: 236_690_000 picoseconds. - Weight::from_parts(268_793_030, 27145) - // Standard Error: 1_210 - .saturating_add(Weight::from_parts(263_330, 0).saturating_mul(r.into())) + // Minimum execution time: 239_402_000 picoseconds. + Weight::from_parts(267_214_783, 27145) + // Standard Error: 1_166 + .saturating_add(Weight::from_parts(261_915, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 200).saturating_mul(r.into())) @@ -1608,10 +1594,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `776 + r * (3 ±0)` // Estimated: `24004 + r * (18 ±0)` - // Minimum execution time: 236_289_000 picoseconds. - Weight::from_parts(246_581_099, 24004) - // Standard Error: 1_300 - .saturating_add(Weight::from_parts(137_499, 0).saturating_mul(r.into())) + // Minimum execution time: 233_153_000 picoseconds. + Weight::from_parts(238_999_965, 24004) + // Standard Error: 291 + .saturating_add(Weight::from_parts(143_971, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 18).saturating_mul(r.into())) @@ -1621,9 +1607,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_679_000 picoseconds. - Weight::from_parts(1_934_194, 0) - // Standard Error: 1 + // Minimum execution time: 1_706_000 picoseconds. + Weight::from_parts(1_962_558, 0) + // Standard Error: 2 .saturating_add(Weight::from_parts(3_000, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. @@ -1631,513 +1617,513 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_872_000 picoseconds. - Weight::from_parts(2_605_712, 0) - // Standard Error: 43 - .saturating_add(Weight::from_parts(6_321, 0).saturating_mul(r.into())) + // Minimum execution time: 1_870_000 picoseconds. + Weight::from_parts(2_481_243, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(6_346, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_837_000 picoseconds. - Weight::from_parts(2_035_143, 0) - // Standard Error: 65 - .saturating_add(Weight::from_parts(6_202, 0).saturating_mul(r.into())) + // Minimum execution time: 1_830_000 picoseconds. + Weight::from_parts(2_389_658, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(5_997, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_select(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_684_000 picoseconds. - Weight::from_parts(2_044_218, 0) - // Standard Error: 5 - .saturating_add(Weight::from_parts(7_929, 0).saturating_mul(r.into())) + // Minimum execution time: 1_734_000 picoseconds. + Weight::from_parts(2_170_618, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(7_919, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_if(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_635_000 picoseconds. - Weight::from_parts(2_009_851, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(10_724, 0).saturating_mul(r.into())) + // Minimum execution time: 1_661_000 picoseconds. + Weight::from_parts(1_945_771, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(10_840, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_667_000 picoseconds. - Weight::from_parts(1_869_395, 0) - // Standard Error: 12 - .saturating_add(Weight::from_parts(4_618, 0).saturating_mul(r.into())) + // Minimum execution time: 1_682_000 picoseconds. + Weight::from_parts(1_970_774, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(4_569, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br_if(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_698_000 picoseconds. - Weight::from_parts(2_184_182, 0) - // Standard Error: 16 - .saturating_add(Weight::from_parts(6_833, 0).saturating_mul(r.into())) + // Minimum execution time: 1_668_000 picoseconds. + Weight::from_parts(1_227_080, 0) + // Standard Error: 76 + .saturating_add(Weight::from_parts(8_066, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br_table(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_670_000 picoseconds. - Weight::from_parts(1_471_988, 0) - // Standard Error: 30 - .saturating_add(Weight::from_parts(9_550, 0).saturating_mul(r.into())) + // Minimum execution time: 1_653_000 picoseconds. + Weight::from_parts(1_394_759, 0) + // Standard Error: 39 + .saturating_add(Weight::from_parts(9_566, 0).saturating_mul(r.into())) } /// The range of component `e` is `[1, 256]`. fn instr_br_table_per_entry(e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_778_000 picoseconds. - Weight::from_parts(1_925_086, 0) - // Standard Error: 136 - .saturating_add(Weight::from_parts(502, 0).saturating_mul(e.into())) + // Minimum execution time: 1_771_000 picoseconds. + Weight::from_parts(1_905_594, 0) + // Standard Error: 147 + .saturating_add(Weight::from_parts(925, 0).saturating_mul(e.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_759_000 picoseconds. - Weight::from_parts(2_372_048, 0) - // Standard Error: 16 - .saturating_add(Weight::from_parts(17_953, 0).saturating_mul(r.into())) + // Minimum execution time: 1_863_000 picoseconds. + Weight::from_parts(2_472_635, 0) + // Standard Error: 13 + .saturating_add(Weight::from_parts(17_892, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_call_indirect(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_852_000 picoseconds. - Weight::from_parts(3_125_003, 0) - // Standard Error: 25 - .saturating_add(Weight::from_parts(24_218, 0).saturating_mul(r.into())) + // Minimum execution time: 2_013_000 picoseconds. + Weight::from_parts(3_077_100, 0) + // Standard Error: 18 + .saturating_add(Weight::from_parts(24_287, 0).saturating_mul(r.into())) } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_795_000 picoseconds. - Weight::from_parts(2_121_763, 0) - // Standard Error: 45 - .saturating_add(Weight::from_parts(1_207, 0).saturating_mul(l.into())) + // Minimum execution time: 1_818_000 picoseconds. + Weight::from_parts(2_109_143, 0) + // Standard Error: 34 + .saturating_add(Weight::from_parts(1_249, 0).saturating_mul(l.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_get(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_019_000 picoseconds. - Weight::from_parts(3_267_108, 0) - // Standard Error: 55 - .saturating_add(Weight::from_parts(2_527, 0).saturating_mul(r.into())) + // Minimum execution time: 3_083_000 picoseconds. + Weight::from_parts(3_291_328, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(2_505, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_set(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_944_000 picoseconds. - Weight::from_parts(3_183_331, 0) + // Minimum execution time: 2_987_000 picoseconds. + Weight::from_parts(3_276_863, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_618, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_617, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_tee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_009_000 picoseconds. - Weight::from_parts(3_178_158, 0) - // Standard Error: 41 - .saturating_add(Weight::from_parts(4_075, 0).saturating_mul(r.into())) + // Minimum execution time: 2_942_000 picoseconds. + Weight::from_parts(3_350_581, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(3_976, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_global_get(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_748_000 picoseconds. - Weight::from_parts(2_371_911, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(8_378, 0).saturating_mul(r.into())) + // Minimum execution time: 1_867_000 picoseconds. + Weight::from_parts(2_920_748, 0) + // Standard Error: 44 + .saturating_add(Weight::from_parts(8_229, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_global_set(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_795_000 picoseconds. - Weight::from_parts(1_311_997, 0) - // Standard Error: 157 - .saturating_add(Weight::from_parts(9_410, 0).saturating_mul(r.into())) + // Minimum execution time: 1_757_000 picoseconds. + Weight::from_parts(2_235_198, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(8_815, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_memory_current(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_059_000 picoseconds. - Weight::from_parts(2_416_611, 0) - // Standard Error: 5 - .saturating_add(Weight::from_parts(3_775, 0).saturating_mul(r.into())) + // Minimum execution time: 1_824_000 picoseconds. + Weight::from_parts(1_941_816, 0) + // Standard Error: 86 + .saturating_add(Weight::from_parts(4_043, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 16]`. fn instr_memory_grow(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_764_000 picoseconds. - Weight::from_parts(1_414_442, 0) - // Standard Error: 142_321 - .saturating_add(Weight::from_parts(13_210_495, 0).saturating_mul(r.into())) + // Minimum execution time: 1_793_000 picoseconds. + Weight::from_parts(1_104_829, 0) + // Standard Error: 137_800 + .saturating_add(Weight::from_parts(13_336_784, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64clz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_665_000 picoseconds. - Weight::from_parts(2_047_968, 0) + // Minimum execution time: 1_693_000 picoseconds. + Weight::from_parts(2_037_305, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(4_035, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(4_044, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ctz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_696_000 picoseconds. - Weight::from_parts(2_101_548, 0) - // Standard Error: 13 - .saturating_add(Weight::from_parts(3_754, 0).saturating_mul(r.into())) + // Minimum execution time: 1_751_000 picoseconds. + Weight::from_parts(2_082_016, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(3_767, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64popcnt(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_023_482, 0) + // Minimum execution time: 1_751_000 picoseconds. + Weight::from_parts(2_110_625, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_770, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_754, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64eqz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_700_000 picoseconds. - Weight::from_parts(2_035_759, 0) + // Minimum execution time: 1_756_000 picoseconds. + Weight::from_parts(2_100_327, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_660, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_664, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64extendsi32(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_682_000 picoseconds. - Weight::from_parts(2_015_828, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(3_977, 0).saturating_mul(r.into())) + // Minimum execution time: 1_643_000 picoseconds. + Weight::from_parts(2_169_153, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(3_961, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64extendui32(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_660_000 picoseconds. - Weight::from_parts(2_032_387, 0) + // Minimum execution time: 1_704_000 picoseconds. + Weight::from_parts(2_049_172, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_826, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_833, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i32wrapi64(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_635_000 picoseconds. - Weight::from_parts(2_013_228, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(3_752, 0).saturating_mul(r.into())) + // Minimum execution time: 1_726_000 picoseconds. + Weight::from_parts(2_064_387, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(3_745, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64eq(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_698_000 picoseconds. - Weight::from_parts(2_844_817, 0) + // Minimum execution time: 1_696_000 picoseconds. + Weight::from_parts(2_426_905, 0) // Standard Error: 56 - .saturating_add(Weight::from_parts(5_746, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_915, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ne(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_208_884, 0) - // Standard Error: 138 - .saturating_add(Weight::from_parts(6_032, 0).saturating_mul(r.into())) + // Minimum execution time: 1_617_000 picoseconds. + Weight::from_parts(2_035_161, 0) + // Standard Error: 94 + .saturating_add(Weight::from_parts(6_073, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64lts(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_695_000 picoseconds. - Weight::from_parts(2_060_880, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_966, 0).saturating_mul(r.into())) + // Minimum execution time: 1_756_000 picoseconds. + Weight::from_parts(2_098_926, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(6_002, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ltu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_700_000 picoseconds. - Weight::from_parts(2_143_484, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_932, 0).saturating_mul(r.into())) + // Minimum execution time: 1_706_000 picoseconds. + Weight::from_parts(2_257_972, 0) + // Standard Error: 23 + .saturating_add(Weight::from_parts(5_982, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64gts(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_081_646, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_813, 0).saturating_mul(r.into())) + // Minimum execution time: 1_761_000 picoseconds. + Weight::from_parts(2_114_141, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(5_815, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64gtu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_476_000 picoseconds. - Weight::from_parts(2_161_801, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(6_078, 0).saturating_mul(r.into())) + // Minimum execution time: 1_700_000 picoseconds. + Weight::from_parts(2_053_201, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(6_137, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64les(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_043_451, 0) + // Minimum execution time: 1_705_000 picoseconds. + Weight::from_parts(2_101_782, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(5_988, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(6_014, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64leu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_694_000 picoseconds. - Weight::from_parts(2_058_196, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(6_058, 0).saturating_mul(r.into())) + // Minimum execution time: 1_856_000 picoseconds. + Weight::from_parts(2_149_707, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(6_086, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ges(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_675_000 picoseconds. - Weight::from_parts(2_036_798, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_956, 0).saturating_mul(r.into())) + // Minimum execution time: 1_739_000 picoseconds. + Weight::from_parts(2_143_216, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(5_934, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64geu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_712_000 picoseconds. - Weight::from_parts(2_121_407, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_944, 0).saturating_mul(r.into())) + // Minimum execution time: 1_716_000 picoseconds. + Weight::from_parts(2_065_762, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(6_009, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64add(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_675_000 picoseconds. - Weight::from_parts(2_061_053, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(5_823, 0).saturating_mul(r.into())) + // Minimum execution time: 1_664_000 picoseconds. + Weight::from_parts(3_062_283, 0) + // Standard Error: 94 + .saturating_add(Weight::from_parts(5_645, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64sub(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_023_347, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(6_126, 0).saturating_mul(r.into())) + // Minimum execution time: 1_671_000 picoseconds. + Weight::from_parts(2_011_145, 0) + // Standard Error: 44 + .saturating_add(Weight::from_parts(6_220, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64mul(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_678_000 picoseconds. - Weight::from_parts(2_390_920, 0) - // Standard Error: 55 - .saturating_add(Weight::from_parts(5_635, 0).saturating_mul(r.into())) + // Minimum execution time: 1_759_000 picoseconds. + Weight::from_parts(2_095_420, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(5_723, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64divs(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_728_000 picoseconds. - Weight::from_parts(1_944_457, 0) - // Standard Error: 7 - .saturating_add(Weight::from_parts(11_848, 0).saturating_mul(r.into())) + // Minimum execution time: 1_672_000 picoseconds. + Weight::from_parts(2_184_044, 0) + // Standard Error: 5 + .saturating_add(Weight::from_parts(11_782, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64divu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_649_000 picoseconds. - Weight::from_parts(1_881_148, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(10_618, 0).saturating_mul(r.into())) + // Minimum execution time: 1_752_000 picoseconds. + Weight::from_parts(2_276_209, 0) + // Standard Error: 5 + .saturating_add(Weight::from_parts(10_513, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rems(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_708_000 picoseconds. - Weight::from_parts(1_767_912, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(12_099, 0).saturating_mul(r.into())) + // Minimum execution time: 1_711_000 picoseconds. + Weight::from_parts(2_720_989, 0) + // Standard Error: 24 + .saturating_add(Weight::from_parts(11_884, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64remu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_650_000 picoseconds. - Weight::from_parts(1_998_575, 0) + // Minimum execution time: 1_713_000 picoseconds. + Weight::from_parts(2_091_403, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(10_632, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(10_628, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64and(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_633_000 picoseconds. - Weight::from_parts(2_029_981, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_662, 0).saturating_mul(r.into())) + // Minimum execution time: 1_704_000 picoseconds. + Weight::from_parts(2_054_652, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(5_672, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64or(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_621_000 picoseconds. - Weight::from_parts(2_029_743, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_762, 0).saturating_mul(r.into())) + // Minimum execution time: 1_743_000 picoseconds. + Weight::from_parts(2_032_806, 0) + // Standard Error: 19 + .saturating_add(Weight::from_parts(5_795, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64xor(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_641_000 picoseconds. - Weight::from_parts(2_127_132, 0) + // Minimum execution time: 1_667_000 picoseconds. + Weight::from_parts(2_031_702, 0) // Standard Error: 5 - .saturating_add(Weight::from_parts(5_818, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_923, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shl(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_690_000 picoseconds. - Weight::from_parts(2_021_035, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(5_917, 0).saturating_mul(r.into())) + // Minimum execution time: 1_735_000 picoseconds. + Weight::from_parts(2_946_634, 0) + // Standard Error: 54 + .saturating_add(Weight::from_parts(5_685, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shrs(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_661_000 picoseconds. - Weight::from_parts(2_055_069, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(6_094, 0).saturating_mul(r.into())) + // Minimum execution time: 1_652_000 picoseconds. + Weight::from_parts(2_023_049, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(6_146, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shru(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_024_748, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_862, 0).saturating_mul(r.into())) + // Minimum execution time: 1_654_000 picoseconds. + Weight::from_parts(2_148_951, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(5_869, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rotl(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_651_000 picoseconds. - Weight::from_parts(2_005_814, 0) + // Minimum execution time: 1_730_000 picoseconds. + Weight::from_parts(2_130_543, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(6_007, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_999, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rotr(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_703_000 picoseconds. - Weight::from_parts(2_019_636, 0) + // Minimum execution time: 1_728_000 picoseconds. + Weight::from_parts(2_172_886, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(5_862, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_843, 0).saturating_mul(r.into())) } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: Contracts DeletionQueue (r:1 w:0) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) + /// Storage: Contracts DeletionQueueCounter (r:1 w:0) + /// Proof: Contracts DeletionQueueCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) fn on_process_deletion_queue_batch() -> Weight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `1594` - // Minimum execution time: 2_713_000 picoseconds. - Weight::from_parts(2_811_000, 1594) + // Minimum execution time: 2_677_000 picoseconds. + Weight::from_parts(2_899_000, 1594) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: Skipped Metadata (r:0 w:0) @@ -2145,33 +2131,18 @@ impl WeightInfo for () { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `450 + k * (69 ±0)` - // Estimated: `440 + k * (70 ±0)` - // Minimum execution time: 11_011_000 picoseconds. - Weight::from_parts(7_025_244, 440) - // Standard Error: 1_217 - .saturating_add(Weight::from_parts(980_818, 0).saturating_mul(k.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Measured: `488 + k * (69 ±0)` + // Estimated: `478 + k * (70 ±0)` + // Minimum execution time: 14_006_000 picoseconds. + Weight::from_parts(8_735_946, 478) + // Standard Error: 1_370 + .saturating_add(Weight::from_parts(989_501, 0).saturating_mul(k.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(k.into())) } - /// Storage: Contracts DeletionQueue (r:1 w:1) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) - /// The range of component `q` is `[0, 128]`. - fn on_initialize_per_queue_item(q: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `250 + q * (33 ±0)` - // Estimated: `1725 + q * (33 ±0)` - // Minimum execution time: 2_802_000 picoseconds. - Weight::from_parts(10_768_336, 1725) - // Standard Error: 3_424 - .saturating_add(Weight::from_parts(1_323_649, 0).saturating_mul(q.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(q.into())) - } /// Storage: Contracts PristineCode (r:1 w:0) /// Proof: Contracts PristineCode (max_values: None, max_size: Some(125988), added: 128463, mode: Measured) /// Storage: Contracts CodeStorage (r:0 w:1) @@ -2181,10 +2152,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `238 + c * (1 ±0)` // Estimated: `3951 + c * (2 ±0)` - // Minimum execution time: 30_299_000 picoseconds. - Weight::from_parts(24_608_986, 3951) - // Standard Error: 75 - .saturating_add(Weight::from_parts(54_619, 0).saturating_mul(c.into())) + // Minimum execution time: 30_951_000 picoseconds. + Weight::from_parts(25_988_560, 3951) + // Standard Error: 57 + .saturating_add(Weight::from_parts(54_692, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2).saturating_mul(c.into())) @@ -2204,10 +2175,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `707` // Estimated: `21400 + c * (5 ±0)` - // Minimum execution time: 265_835_000 picoseconds. - Weight::from_parts(275_985_164, 21400) - // Standard Error: 36 - .saturating_add(Weight::from_parts(37_980, 0).saturating_mul(c.into())) + // Minimum execution time: 263_107_000 picoseconds. + Weight::from_parts(268_289_665, 21400) + // Standard Error: 33 + .saturating_add(Weight::from_parts(38_534, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 5).saturating_mul(c.into())) @@ -2235,14 +2206,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `270` // Estimated: `26207` - // Minimum execution time: 3_124_508_000 picoseconds. - Weight::from_parts(617_467_897, 26207) - // Standard Error: 293 - .saturating_add(Weight::from_parts(106_971, 0).saturating_mul(c.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_156, 0).saturating_mul(i.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_395, 0).saturating_mul(s.into())) + // Minimum execution time: 3_122_319_000 picoseconds. + Weight::from_parts(487_802_180, 26207) + // Standard Error: 345 + .saturating_add(Weight::from_parts(108_237, 0).saturating_mul(c.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_166, 0).saturating_mul(i.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_505, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2266,12 +2237,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `482` // Estimated: `28521` - // Minimum execution time: 1_649_483_000 picoseconds. - Weight::from_parts(287_642_416, 28521) + // Minimum execution time: 1_650_623_000 picoseconds. + Weight::from_parts(286_494_456, 28521) // Standard Error: 8 - .saturating_add(Weight::from_parts(1_450, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_438, 0).saturating_mul(i.into())) // Standard Error: 8 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_453, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2289,8 +2260,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `759` // Estimated: `21615` - // Minimum execution time: 192_302_000 picoseconds. - Weight::from_parts(193_192_000, 21615) + // Minimum execution time: 191_046_000 picoseconds. + Weight::from_parts(192_544_000, 21615) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2307,10 +2278,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `7366` - // Minimum execution time: 246_401_000 picoseconds. - Weight::from_parts(261_505_456, 7366) - // Standard Error: 83 - .saturating_add(Weight::from_parts(109_136, 0).saturating_mul(c.into())) + // Minimum execution time: 244_260_000 picoseconds. + Weight::from_parts(254_693_985, 7366) + // Standard Error: 80 + .saturating_add(Weight::from_parts(108_246, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2326,8 +2297,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `255` // Estimated: `7950` - // Minimum execution time: 33_913_000 picoseconds. - Weight::from_parts(34_186_000, 7950) + // Minimum execution time: 33_492_000 picoseconds. + Weight::from_parts(34_079_000, 7950) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2341,8 +2312,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `570` // Estimated: `19530` - // Minimum execution time: 33_801_000 picoseconds. - Weight::from_parts(34_877_000, 19530) + // Minimum execution time: 33_475_000 picoseconds. + Weight::from_parts(33_856_000, 19530) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2361,10 +2332,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `781 + r * (6 ±0)` // Estimated: `21730 + r * (30 ±0)` - // Minimum execution time: 237_679_000 picoseconds. - Weight::from_parts(243_022_905, 21730) - // Standard Error: 940 - .saturating_add(Weight::from_parts(324_389, 0).saturating_mul(r.into())) + // Minimum execution time: 234_197_000 picoseconds. + Weight::from_parts(236_830_305, 21730) + // Standard Error: 818 + .saturating_add(Weight::from_parts(336_446, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2384,10 +2355,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `839 + r * (240 ±0)` // Estimated: `21835 + r * (3675 ±0)` - // Minimum execution time: 235_635_000 picoseconds. - Weight::from_parts(76_942_144, 21835) - // Standard Error: 6_214 - .saturating_add(Weight::from_parts(3_328_756, 0).saturating_mul(r.into())) + // Minimum execution time: 235_872_000 picoseconds. + Weight::from_parts(78_877_890, 21835) + // Standard Error: 6_405 + .saturating_add(Weight::from_parts(3_358_341, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2408,10 +2379,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `831 + r * (244 ±0)` // Estimated: `21855 + r * (3695 ±0)` - // Minimum execution time: 237_123_000 picoseconds. - Weight::from_parts(77_880_739, 21855) - // Standard Error: 5_970 - .saturating_add(Weight::from_parts(4_103_281, 0).saturating_mul(r.into())) + // Minimum execution time: 239_035_000 picoseconds. + Weight::from_parts(93_255_085, 21855) + // Standard Error: 5_922 + .saturating_add(Weight::from_parts(4_144_910, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2432,10 +2403,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `788 + r * (6 ±0)` // Estimated: `21770 + r * (30 ±0)` - // Minimum execution time: 236_621_000 picoseconds. - Weight::from_parts(238_240_015, 21770) - // Standard Error: 742 - .saturating_add(Weight::from_parts(404_691, 0).saturating_mul(r.into())) + // Minimum execution time: 236_507_000 picoseconds. + Weight::from_parts(238_253_211, 21770) + // Standard Error: 975 + .saturating_add(Weight::from_parts(413_919, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2455,10 +2426,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `778 + r * (3 ±0)` // Estimated: `21735 + r * (15 ±0)` - // Minimum execution time: 233_274_000 picoseconds. - Weight::from_parts(239_596_227, 21735) - // Standard Error: 551 - .saturating_add(Weight::from_parts(164_429, 0).saturating_mul(r.into())) + // Minimum execution time: 235_521_000 picoseconds. + Weight::from_parts(238_397_362, 21735) + // Standard Error: 452 + .saturating_add(Weight::from_parts(160_860, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(r.into())) @@ -2478,10 +2449,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `782 + r * (6 ±0)` // Estimated: `21740 + r * (30 ±0)` - // Minimum execution time: 235_661_000 picoseconds. - Weight::from_parts(239_063_406, 21740) - // Standard Error: 933 - .saturating_add(Weight::from_parts(327_679, 0).saturating_mul(r.into())) + // Minimum execution time: 234_722_000 picoseconds. + Weight::from_parts(242_936_096, 21740) + // Standard Error: 1_178 + .saturating_add(Weight::from_parts(329_075, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2501,10 +2472,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `783 + r * (6 ±0)` // Estimated: `21725 + r * (30 ±0)` - // Minimum execution time: 235_583_000 picoseconds. - Weight::from_parts(251_641_549, 21725) - // Standard Error: 1_104 - .saturating_add(Weight::from_parts(315_873, 0).saturating_mul(r.into())) + // Minimum execution time: 235_654_000 picoseconds. + Weight::from_parts(245_887_792, 21725) + // Standard Error: 903 + .saturating_add(Weight::from_parts(325_168, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2524,10 +2495,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `922 + r * (6 ±0)` // Estimated: `24633 + r * (30 ±0)` - // Minimum execution time: 235_325_000 picoseconds. - Weight::from_parts(256_582_010, 24633) - // Standard Error: 1_349 - .saturating_add(Weight::from_parts(1_483_116, 0).saturating_mul(r.into())) + // Minimum execution time: 233_599_000 picoseconds. + Weight::from_parts(251_561_602, 24633) + // Standard Error: 3_348 + .saturating_add(Weight::from_parts(1_475_443, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2547,10 +2518,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `792 + r * (6 ±0)` // Estimated: `21825 + r * (30 ±0)` - // Minimum execution time: 235_358_000 picoseconds. - Weight::from_parts(233_421_484, 21825) - // Standard Error: 1_178 - .saturating_add(Weight::from_parts(337_947, 0).saturating_mul(r.into())) + // Minimum execution time: 235_087_000 picoseconds. + Weight::from_parts(235_855_322, 21825) + // Standard Error: 867 + .saturating_add(Weight::from_parts(346_707, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2570,10 +2541,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `790 + r * (6 ±0)` // Estimated: `21815 + r * (30 ±0)` - // Minimum execution time: 236_570_000 picoseconds. - Weight::from_parts(245_853_078, 21815) - // Standard Error: 1_947 - .saturating_add(Weight::from_parts(319_972, 0).saturating_mul(r.into())) + // Minimum execution time: 237_103_000 picoseconds. + Weight::from_parts(239_272_188, 21815) + // Standard Error: 892 + .saturating_add(Weight::from_parts(328_334, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2593,10 +2564,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `787 + r * (6 ±0)` // Estimated: `21805 + r * (30 ±0)` - // Minimum execution time: 235_027_000 picoseconds. - Weight::from_parts(239_719_689, 21805) - // Standard Error: 654 - .saturating_add(Weight::from_parts(326_988, 0).saturating_mul(r.into())) + // Minimum execution time: 234_761_000 picoseconds. + Weight::from_parts(238_601_784, 21805) + // Standard Error: 725 + .saturating_add(Weight::from_parts(325_758, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2616,10 +2587,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `778 + r * (6 ±0)` // Estimated: `21735 + r * (30 ±0)` - // Minimum execution time: 236_547_000 picoseconds. - Weight::from_parts(239_390_326, 21735) - // Standard Error: 912 - .saturating_add(Weight::from_parts(327_495, 0).saturating_mul(r.into())) + // Minimum execution time: 235_249_000 picoseconds. + Weight::from_parts(239_861_242, 21735) + // Standard Error: 751 + .saturating_add(Weight::from_parts(325_795, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2641,10 +2612,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `856 + r * (10 ±0)` // Estimated: `24446 + r * (60 ±0)` - // Minimum execution time: 235_710_000 picoseconds. - Weight::from_parts(238_998_789, 24446) - // Standard Error: 2_055 - .saturating_add(Weight::from_parts(1_373_992, 0).saturating_mul(r.into())) + // Minimum execution time: 234_912_000 picoseconds. + Weight::from_parts(254_783_734, 24446) + // Standard Error: 1_610 + .saturating_add(Weight::from_parts(1_307_506, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 60).saturating_mul(r.into())) @@ -2664,10 +2635,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `745 + r * (4 ±0)` // Estimated: `21555 + r * (20 ±0)` - // Minimum execution time: 161_133_000 picoseconds. - Weight::from_parts(167_097_346, 21555) - // Standard Error: 245 - .saturating_add(Weight::from_parts(128_503, 0).saturating_mul(r.into())) + // Minimum execution time: 160_125_000 picoseconds. + Weight::from_parts(164_915_574, 21555) + // Standard Error: 332 + .saturating_add(Weight::from_parts(132_326, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 20).saturating_mul(r.into())) @@ -2687,10 +2658,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `780 + r * (6 ±0)` // Estimated: `21740 + r * (30 ±0)` - // Minimum execution time: 234_790_000 picoseconds. - Weight::from_parts(242_392_710, 21740) - // Standard Error: 2_506 - .saturating_add(Weight::from_parts(273_470, 0).saturating_mul(r.into())) + // Minimum execution time: 234_717_000 picoseconds. + Weight::from_parts(238_540_521, 21740) + // Standard Error: 599 + .saturating_add(Weight::from_parts(277_303, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 30).saturating_mul(r.into())) @@ -2710,10 +2681,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `784` // Estimated: `21740` - // Minimum execution time: 236_837_000 picoseconds. - Weight::from_parts(237_860_073, 21740) - // Standard Error: 2 - .saturating_add(Weight::from_parts(602, 0).saturating_mul(n.into())) + // Minimum execution time: 235_792_000 picoseconds. + Weight::from_parts(244_114_692, 21740) + // Standard Error: 1 + .saturating_add(Weight::from_parts(589, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2732,10 +2703,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `768 + r * (45 ±0)` // Estimated: `21660 + r * (225 ±0)` - // Minimum execution time: 232_047_000 picoseconds. - Weight::from_parts(234_629_293, 21660) - // Standard Error: 171_808 - .saturating_add(Weight::from_parts(663_306, 0).saturating_mul(r.into())) + // Minimum execution time: 231_166_000 picoseconds. + Weight::from_parts(233_339_177, 21660) + // Standard Error: 155_889 + .saturating_add(Weight::from_parts(3_124_322, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 225).saturating_mul(r.into())) @@ -2755,10 +2726,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `778` // Estimated: `21775` - // Minimum execution time: 235_035_000 picoseconds. - Weight::from_parts(234_442_091, 21775) + // Minimum execution time: 235_721_000 picoseconds. + Weight::from_parts(237_413_703, 21775) // Standard Error: 1 - .saturating_add(Weight::from_parts(185, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(177, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2770,26 +2741,28 @@ impl WeightInfo for () { /// Proof: Contracts CodeStorage (max_values: None, max_size: Some(126001), added: 128476, mode: Measured) /// Storage: Timestamp Now (r:1 w:0) /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) - /// Storage: Contracts DeletionQueue (r:1 w:1) - /// Proof: Contracts DeletionQueue (max_values: Some(1), max_size: Some(16642), added: 17137, mode: Measured) + /// Storage: Contracts DeletionQueueCounter (r:1 w:1) + /// Proof: Contracts DeletionQueueCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: Measured) /// Storage: Contracts OwnerInfoOf (r:1 w:1) /// Proof: Contracts OwnerInfoOf (max_values: None, max_size: Some(88), added: 2563, mode: Measured) /// Storage: System EventTopics (r:3 w:3) /// Proof Skipped: System EventTopics (max_values: None, max_size: None, mode: Measured) + /// Storage: Contracts DeletionQueue (r:0 w:1) + /// Proof: Contracts DeletionQueue (max_values: None, max_size: Some(142), added: 2617, mode: Measured) /// The range of component `r` is `[0, 1]`. fn seal_terminate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `810 + r * (356 ±0)` - // Estimated: `25511 + r * (15321 ±0)` - // Minimum execution time: 234_140_000 picoseconds. - Weight::from_parts(236_805_906, 25511) - // Standard Error: 435_181 - .saturating_add(Weight::from_parts(118_144_693, 0).saturating_mul(r.into())) + // Estimated: `26094 + r * (15904 ±0)` + // Minimum execution time: 233_525_000 picoseconds. + Weight::from_parts(235_871_034, 26094) + // Standard Error: 235_338 + .saturating_add(Weight::from_parts(118_659_865, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) - .saturating_add(RocksDbWeight::get().writes((7_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 15321).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().writes((8_u64).saturating_mul(r.into()))) + .saturating_add(Weight::from_parts(0, 15904).saturating_mul(r.into())) } /// Storage: System Account (r:1 w:0) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: Measured) @@ -2808,10 +2781,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `825 + r * (10 ±0)` // Estimated: `24283 + r * (60 ±0)` - // Minimum execution time: 235_271_000 picoseconds. - Weight::from_parts(256_019_682, 24283) - // Standard Error: 2_016 - .saturating_add(Weight::from_parts(1_862_085, 0).saturating_mul(r.into())) + // Minimum execution time: 235_007_000 picoseconds. + Weight::from_parts(248_419_686, 24283) + // Standard Error: 1_847 + .saturating_add(Weight::from_parts(1_815_822, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 60).saturating_mul(r.into())) @@ -2831,10 +2804,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `778 + r * (10 ±0)` // Estimated: `21735 + r * (50 ±0)` - // Minimum execution time: 233_092_000 picoseconds. - Weight::from_parts(248_483_473, 21735) - // Standard Error: 2_182 - .saturating_add(Weight::from_parts(3_551_674, 0).saturating_mul(r.into())) + // Minimum execution time: 232_912_000 picoseconds. + Weight::from_parts(256_142_885, 21735) + // Standard Error: 2_741 + .saturating_add(Weight::from_parts(3_542_482, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 50).saturating_mul(r.into())) @@ -2855,12 +2828,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `797 + t * (32 ±0)` // Estimated: `21840 + t * (2640 ±0)` - // Minimum execution time: 252_307_000 picoseconds. - Weight::from_parts(245_237_726, 21840) - // Standard Error: 79_824 - .saturating_add(Weight::from_parts(2_364_618, 0).saturating_mul(t.into())) - // Standard Error: 22 - .saturating_add(Weight::from_parts(636, 0).saturating_mul(n.into())) + // Minimum execution time: 251_018_000 picoseconds. + Weight::from_parts(245_280_765, 21840) + // Standard Error: 90_317 + .saturating_add(Weight::from_parts(2_434_496, 0).saturating_mul(t.into())) + // Standard Error: 25 + .saturating_add(Weight::from_parts(599, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2882,10 +2855,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `777 + r * (7 ±0)` // Estimated: `21725 + r * (35 ±0)` - // Minimum execution time: 165_367_000 picoseconds. - Weight::from_parts(170_164_725, 21725) - // Standard Error: 487 - .saturating_add(Weight::from_parts(237_281, 0).saturating_mul(r.into())) + // Minimum execution time: 164_022_000 picoseconds. + Weight::from_parts(168_658_387, 21725) + // Standard Error: 685 + .saturating_add(Weight::from_parts(238_133, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 35).saturating_mul(r.into())) @@ -2905,10 +2878,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125728` // Estimated: `269977` - // Minimum execution time: 350_914_000 picoseconds. - Weight::from_parts(354_461_646, 269977) - // Standard Error: 1 - .saturating_add(Weight::from_parts(747, 0).saturating_mul(i.into())) + // Minimum execution time: 351_043_000 picoseconds. + Weight::from_parts(353_707_344, 269977) + // Standard Error: 3 + .saturating_add(Weight::from_parts(752, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2919,10 +2892,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `845 + r * (292 ±0)` // Estimated: `843 + r * (293 ±0)` - // Minimum execution time: 236_273_000 picoseconds. - Weight::from_parts(137_922_946, 843) - // Standard Error: 10_363 - .saturating_add(Weight::from_parts(6_034_776, 0).saturating_mul(r.into())) + // Minimum execution time: 235_854_000 picoseconds. + Weight::from_parts(133_986_225, 843) + // Standard Error: 9_550 + .saturating_add(Weight::from_parts(6_093_051, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2936,10 +2909,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1304` // Estimated: `1280` - // Minimum execution time: 251_462_000 picoseconds. - Weight::from_parts(287_009_907, 1280) - // Standard Error: 62 - .saturating_add(Weight::from_parts(384, 0).saturating_mul(n.into())) + // Minimum execution time: 252_321_000 picoseconds. + Weight::from_parts(285_820_577, 1280) + // Standard Error: 60 + .saturating_add(Weight::from_parts(600, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2950,10 +2923,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1167 + n * (1 ±0)` // Estimated: `1167 + n * (1 ±0)` - // Minimum execution time: 250_985_000 picoseconds. - Weight::from_parts(253_693_249, 1167) - // Standard Error: 21 - .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) + // Minimum execution time: 252_047_000 picoseconds. + Weight::from_parts(254_244_310, 1167) + // Standard Error: 15 + .saturating_add(Weight::from_parts(144, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -2965,10 +2938,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `841 + r * (288 ±0)` // Estimated: `845 + r * (289 ±0)` - // Minimum execution time: 235_462_000 picoseconds. - Weight::from_parts(141_240_297, 845) - // Standard Error: 9_687 - .saturating_add(Weight::from_parts(5_906_737, 0).saturating_mul(r.into())) + // Minimum execution time: 235_697_000 picoseconds. + Weight::from_parts(143_200_942, 845) + // Standard Error: 11_358 + .saturating_add(Weight::from_parts(5_934_318, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2982,10 +2955,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1163 + n * (1 ±0)` // Estimated: `1163 + n * (1 ±0)` - // Minimum execution time: 250_887_000 picoseconds. - Weight::from_parts(253_321_064, 1163) - // Standard Error: 28 - .saturating_add(Weight::from_parts(169, 0).saturating_mul(n.into())) + // Minimum execution time: 250_360_000 picoseconds. + Weight::from_parts(252_712_722, 1163) + // Standard Error: 15 + .saturating_add(Weight::from_parts(130, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -2997,10 +2970,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `835 + r * (296 ±0)` // Estimated: `840 + r * (297 ±0)` - // Minimum execution time: 236_542_000 picoseconds. - Weight::from_parts(147_992_508, 840) - // Standard Error: 8_849 - .saturating_add(Weight::from_parts(4_946_692, 0).saturating_mul(r.into())) + // Minimum execution time: 235_613_000 picoseconds. + Weight::from_parts(150_213_792, 840) + // Standard Error: 8_617 + .saturating_add(Weight::from_parts(4_962_874, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3013,10 +2986,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1179 + n * (1 ±0)` // Estimated: `1179 + n * (1 ±0)` - // Minimum execution time: 249_987_000 picoseconds. - Weight::from_parts(254_866_627, 1179) - // Standard Error: 53 - .saturating_add(Weight::from_parts(554, 0).saturating_mul(n.into())) + // Minimum execution time: 249_137_000 picoseconds. + Weight::from_parts(253_529_386, 1179) + // Standard Error: 41 + .saturating_add(Weight::from_parts(612, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3028,10 +3001,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `856 + r * (288 ±0)` // Estimated: `857 + r * (289 ±0)` - // Minimum execution time: 236_635_000 picoseconds. - Weight::from_parts(157_805_789, 857) - // Standard Error: 7_699 - .saturating_add(Weight::from_parts(4_709_422, 0).saturating_mul(r.into())) + // Minimum execution time: 235_659_000 picoseconds. + Weight::from_parts(158_846_683, 857) + // Standard Error: 7_806 + .saturating_add(Weight::from_parts(4_728_537, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3044,10 +3017,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1166 + n * (1 ±0)` // Estimated: `1166 + n * (1 ±0)` - // Minimum execution time: 252_660_000 picoseconds. - Weight::from_parts(255_250_747, 1166) - // Standard Error: 14 - .saturating_add(Weight::from_parts(133, 0).saturating_mul(n.into())) + // Minimum execution time: 248_553_000 picoseconds. + Weight::from_parts(250_703_269, 1166) + // Standard Error: 17 + .saturating_add(Weight::from_parts(163, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3059,10 +3032,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `829 + r * (296 ±0)` // Estimated: `836 + r * (297 ±0)` - // Minimum execution time: 240_198_000 picoseconds. - Weight::from_parts(133_188_357, 836) - // Standard Error: 10_661 - .saturating_add(Weight::from_parts(6_147_538, 0).saturating_mul(r.into())) + // Minimum execution time: 236_431_000 picoseconds. + Weight::from_parts(131_745_419, 836) + // Standard Error: 10_161 + .saturating_add(Weight::from_parts(6_182_174, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3076,10 +3049,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1180 + n * (1 ±0)` // Estimated: `1180 + n * (1 ±0)` - // Minimum execution time: 252_131_000 picoseconds. - Weight::from_parts(259_960_286, 1180) - // Standard Error: 121 - .saturating_add(Weight::from_parts(192, 0).saturating_mul(n.into())) + // Minimum execution time: 252_551_000 picoseconds. + Weight::from_parts(254_517_030, 1180) + // Standard Error: 16 + .saturating_add(Weight::from_parts(712, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3099,10 +3072,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1373 + r * (45 ±0)` // Estimated: `26753 + r * (2700 ±0)` - // Minimum execution time: 235_860_000 picoseconds. - Weight::from_parts(124_993_651, 26753) - // Standard Error: 22_811 - .saturating_add(Weight::from_parts(36_467_740, 0).saturating_mul(r.into())) + // Minimum execution time: 236_663_000 picoseconds. + Weight::from_parts(237_485_000, 26753) + // Standard Error: 42_414 + .saturating_add(Weight::from_parts(36_849_514, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3124,10 +3097,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1237 + r * (256 ±0)` // Estimated: `26028 + r * (6235 ±0)` - // Minimum execution time: 237_221_000 picoseconds. - Weight::from_parts(237_632_000, 26028) - // Standard Error: 89_502 - .saturating_add(Weight::from_parts(212_211_534, 0).saturating_mul(r.into())) + // Minimum execution time: 237_101_000 picoseconds. + Weight::from_parts(237_827_000, 26028) + // Standard Error: 82_878 + .saturating_add(Weight::from_parts(211_777_724, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3149,10 +3122,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (502 ±0)` // Estimated: `21755 + r * (6329 ±3)` - // Minimum execution time: 236_965_000 picoseconds. - Weight::from_parts(238_110_000, 21755) - // Standard Error: 101_332 - .saturating_add(Weight::from_parts(206_790_203, 0).saturating_mul(r.into())) + // Minimum execution time: 241_213_000 picoseconds. + Weight::from_parts(241_900_000, 21755) + // Standard Error: 99_976 + .saturating_add(Weight::from_parts(207_520_077, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3175,12 +3148,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1154 + t * (204 ±0)` // Estimated: `31015 + t * (5970 ±0)` - // Minimum execution time: 411_974_000 picoseconds. - Weight::from_parts(391_387_689, 31015) - // Standard Error: 1_320_695 - .saturating_add(Weight::from_parts(29_766_122, 0).saturating_mul(t.into())) + // Minimum execution time: 414_784_000 picoseconds. + Weight::from_parts(384_902_379, 31015) + // Standard Error: 1_228_593 + .saturating_add(Weight::from_parts(33_226_901, 0).saturating_mul(t.into())) // Standard Error: 1 - .saturating_add(Weight::from_parts(597, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(601, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -3206,10 +3179,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1301 + r * (254 ±0)` // Estimated: `30977 + r * (16635 ±0)` - // Minimum execution time: 237_595_000 picoseconds. - Weight::from_parts(238_068_000, 30977) - // Standard Error: 254_409 - .saturating_add(Weight::from_parts(346_436_154, 0).saturating_mul(r.into())) + // Minimum execution time: 236_963_000 picoseconds. + Weight::from_parts(237_711_000, 30977) + // Standard Error: 265_576 + .saturating_add(Weight::from_parts(347_359_908, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3237,14 +3210,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1071 + t * (187 ±0)` // Estimated: `42684 + t * (3588 ±2)` - // Minimum execution time: 1_616_768_000 picoseconds. - Weight::from_parts(363_003_254, 42684) - // Standard Error: 4_398_669 - .saturating_add(Weight::from_parts(104_529_967, 0).saturating_mul(t.into())) + // Minimum execution time: 1_615_191_000 picoseconds. + Weight::from_parts(337_408_450, 42684) + // Standard Error: 4_581_951 + .saturating_add(Weight::from_parts(115_730_776, 0).saturating_mul(t.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_162, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(i.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_333, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_346, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(10_u64)) @@ -3266,10 +3239,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `777 + r * (8 ±0)` // Estimated: `21710 + r * (40 ±0)` - // Minimum execution time: 233_814_000 picoseconds. - Weight::from_parts(241_291_041, 21710) - // Standard Error: 1_422 - .saturating_add(Weight::from_parts(575_846, 0).saturating_mul(r.into())) + // Minimum execution time: 233_601_000 picoseconds. + Weight::from_parts(246_594_905, 21710) + // Standard Error: 2_840 + .saturating_add(Weight::from_parts(578_751, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3289,10 +3262,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `785` // Estimated: `21745` - // Minimum execution time: 236_572_000 picoseconds. - Weight::from_parts(235_648_055, 21745) + // Minimum execution time: 233_735_000 picoseconds. + Weight::from_parts(243_432_330, 21745) // Standard Error: 3 - .saturating_add(Weight::from_parts(3_947, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_927, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3311,10 +3284,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21725 + r * (40 ±0)` - // Minimum execution time: 234_473_000 picoseconds. - Weight::from_parts(239_805_309, 21725) - // Standard Error: 1_113 - .saturating_add(Weight::from_parts(752_507, 0).saturating_mul(r.into())) + // Minimum execution time: 232_173_000 picoseconds. + Weight::from_parts(239_806_011, 21725) + // Standard Error: 1_530 + .saturating_add(Weight::from_parts(749_641, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3334,10 +3307,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21765` - // Minimum execution time: 235_209_000 picoseconds. - Weight::from_parts(228_548_524, 21765) + // Minimum execution time: 235_046_000 picoseconds. + Weight::from_parts(229_500_792, 21765) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_171, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(3_166, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3356,10 +3329,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21740 + r * (40 ±0)` - // Minimum execution time: 233_282_000 picoseconds. - Weight::from_parts(240_864_680, 21740) - // Standard Error: 958 - .saturating_add(Weight::from_parts(418_308, 0).saturating_mul(r.into())) + // Minimum execution time: 231_708_000 picoseconds. + Weight::from_parts(235_347_566, 21740) + // Standard Error: 987 + .saturating_add(Weight::from_parts(428_819, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3379,10 +3352,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21785` - // Minimum execution time: 234_667_000 picoseconds. - Weight::from_parts(227_810_077, 21785) - // Standard Error: 2 - .saturating_add(Weight::from_parts(925, 0).saturating_mul(n.into())) + // Minimum execution time: 234_068_000 picoseconds. + Weight::from_parts(226_519_852, 21785) + // Standard Error: 1 + .saturating_add(Weight::from_parts(916, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3401,10 +3374,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `779 + r * (8 ±0)` // Estimated: `21745 + r * (40 ±0)` - // Minimum execution time: 234_040_000 picoseconds. - Weight::from_parts(237_970_694, 21745) - // Standard Error: 979 - .saturating_add(Weight::from_parts(416_562, 0).saturating_mul(r.into())) + // Minimum execution time: 231_872_000 picoseconds. + Weight::from_parts(236_694_763, 21745) + // Standard Error: 870 + .saturating_add(Weight::from_parts(420_853, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3424,10 +3397,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `787` // Estimated: `21755` - // Minimum execution time: 234_840_000 picoseconds. - Weight::from_parts(227_849_778, 21755) + // Minimum execution time: 233_707_000 picoseconds. + Weight::from_parts(226_312_559, 21755) // Standard Error: 2 - .saturating_add(Weight::from_parts(923, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(924, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3446,10 +3419,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `822 + r * (76 ±0)` // Estimated: `21705 + r * (385 ±0)` - // Minimum execution time: 236_174_000 picoseconds. - Weight::from_parts(252_457_690, 21705) - // Standard Error: 20_130 - .saturating_add(Weight::from_parts(37_792_805, 0).saturating_mul(r.into())) + // Minimum execution time: 234_962_000 picoseconds. + Weight::from_parts(252_611_292, 21705) + // Standard Error: 20_134 + .saturating_add(Weight::from_parts(37_745_358, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 385).saturating_mul(r.into())) @@ -3468,11 +3441,11 @@ impl WeightInfo for () { fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `792 + r * (42 ±0)` - // Estimated: `21780 + r * (210 ±0)` - // Minimum execution time: 236_251_000 picoseconds. - Weight::from_parts(242_254_305, 21780) - // Standard Error: 9_765 - .saturating_add(Weight::from_parts(9_341_334, 0).saturating_mul(r.into())) + // Estimated: `21775 + r * (210 ±0)` + // Minimum execution time: 234_869_000 picoseconds. + Weight::from_parts(240_188_331, 21775) + // Standard Error: 9_910 + .saturating_add(Weight::from_parts(9_332_432, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 210).saturating_mul(r.into())) @@ -3493,11 +3466,11 @@ impl WeightInfo for () { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (964 ±0)` - // Estimated: `29920 + r * (11544 ±7)` - // Minimum execution time: 236_462_000 picoseconds. - Weight::from_parts(236_997_000, 29920) - // Standard Error: 46_527 - .saturating_add(Weight::from_parts(21_858_761, 0).saturating_mul(r.into())) + // Estimated: `29920 + r * (11544 ±10)` + // Minimum execution time: 235_036_000 picoseconds. + Weight::from_parts(235_538_000, 29920) + // Standard Error: 47_360 + .saturating_add(Weight::from_parts(22_113_144, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3519,10 +3492,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `773 + r * (3 ±0)` // Estimated: `21735 + r * (15 ±0)` - // Minimum execution time: 235_085_000 picoseconds. - Weight::from_parts(239_410_836, 21735) - // Standard Error: 414 - .saturating_add(Weight::from_parts(167_067, 0).saturating_mul(r.into())) + // Minimum execution time: 237_884_000 picoseconds. + Weight::from_parts(243_315_095, 21735) + // Standard Error: 560 + .saturating_add(Weight::from_parts(162_206, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(r.into())) @@ -3542,10 +3515,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1975 + r * (39 ±0)` // Estimated: `27145 + r * (200 ±0)` - // Minimum execution time: 236_690_000 picoseconds. - Weight::from_parts(268_793_030, 27145) - // Standard Error: 1_210 - .saturating_add(Weight::from_parts(263_330, 0).saturating_mul(r.into())) + // Minimum execution time: 239_402_000 picoseconds. + Weight::from_parts(267_214_783, 27145) + // Standard Error: 1_166 + .saturating_add(Weight::from_parts(261_915, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 200).saturating_mul(r.into())) @@ -3567,10 +3540,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `776 + r * (3 ±0)` // Estimated: `24004 + r * (18 ±0)` - // Minimum execution time: 236_289_000 picoseconds. - Weight::from_parts(246_581_099, 24004) - // Standard Error: 1_300 - .saturating_add(Weight::from_parts(137_499, 0).saturating_mul(r.into())) + // Minimum execution time: 233_153_000 picoseconds. + Weight::from_parts(238_999_965, 24004) + // Standard Error: 291 + .saturating_add(Weight::from_parts(143_971, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 18).saturating_mul(r.into())) @@ -3580,9 +3553,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_679_000 picoseconds. - Weight::from_parts(1_934_194, 0) - // Standard Error: 1 + // Minimum execution time: 1_706_000 picoseconds. + Weight::from_parts(1_962_558, 0) + // Standard Error: 2 .saturating_add(Weight::from_parts(3_000, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. @@ -3590,499 +3563,499 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_872_000 picoseconds. - Weight::from_parts(2_605_712, 0) - // Standard Error: 43 - .saturating_add(Weight::from_parts(6_321, 0).saturating_mul(r.into())) + // Minimum execution time: 1_870_000 picoseconds. + Weight::from_parts(2_481_243, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(6_346, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_837_000 picoseconds. - Weight::from_parts(2_035_143, 0) - // Standard Error: 65 - .saturating_add(Weight::from_parts(6_202, 0).saturating_mul(r.into())) + // Minimum execution time: 1_830_000 picoseconds. + Weight::from_parts(2_389_658, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(5_997, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_select(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_684_000 picoseconds. - Weight::from_parts(2_044_218, 0) - // Standard Error: 5 - .saturating_add(Weight::from_parts(7_929, 0).saturating_mul(r.into())) + // Minimum execution time: 1_734_000 picoseconds. + Weight::from_parts(2_170_618, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(7_919, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_if(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_635_000 picoseconds. - Weight::from_parts(2_009_851, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(10_724, 0).saturating_mul(r.into())) + // Minimum execution time: 1_661_000 picoseconds. + Weight::from_parts(1_945_771, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(10_840, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_667_000 picoseconds. - Weight::from_parts(1_869_395, 0) - // Standard Error: 12 - .saturating_add(Weight::from_parts(4_618, 0).saturating_mul(r.into())) + // Minimum execution time: 1_682_000 picoseconds. + Weight::from_parts(1_970_774, 0) + // Standard Error: 11 + .saturating_add(Weight::from_parts(4_569, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br_if(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_698_000 picoseconds. - Weight::from_parts(2_184_182, 0) - // Standard Error: 16 - .saturating_add(Weight::from_parts(6_833, 0).saturating_mul(r.into())) + // Minimum execution time: 1_668_000 picoseconds. + Weight::from_parts(1_227_080, 0) + // Standard Error: 76 + .saturating_add(Weight::from_parts(8_066, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_br_table(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_670_000 picoseconds. - Weight::from_parts(1_471_988, 0) - // Standard Error: 30 - .saturating_add(Weight::from_parts(9_550, 0).saturating_mul(r.into())) + // Minimum execution time: 1_653_000 picoseconds. + Weight::from_parts(1_394_759, 0) + // Standard Error: 39 + .saturating_add(Weight::from_parts(9_566, 0).saturating_mul(r.into())) } /// The range of component `e` is `[1, 256]`. fn instr_br_table_per_entry(e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_778_000 picoseconds. - Weight::from_parts(1_925_086, 0) - // Standard Error: 136 - .saturating_add(Weight::from_parts(502, 0).saturating_mul(e.into())) + // Minimum execution time: 1_771_000 picoseconds. + Weight::from_parts(1_905_594, 0) + // Standard Error: 147 + .saturating_add(Weight::from_parts(925, 0).saturating_mul(e.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_759_000 picoseconds. - Weight::from_parts(2_372_048, 0) - // Standard Error: 16 - .saturating_add(Weight::from_parts(17_953, 0).saturating_mul(r.into())) + // Minimum execution time: 1_863_000 picoseconds. + Weight::from_parts(2_472_635, 0) + // Standard Error: 13 + .saturating_add(Weight::from_parts(17_892, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_call_indirect(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_852_000 picoseconds. - Weight::from_parts(3_125_003, 0) - // Standard Error: 25 - .saturating_add(Weight::from_parts(24_218, 0).saturating_mul(r.into())) + // Minimum execution time: 2_013_000 picoseconds. + Weight::from_parts(3_077_100, 0) + // Standard Error: 18 + .saturating_add(Weight::from_parts(24_287, 0).saturating_mul(r.into())) } /// The range of component `l` is `[0, 1024]`. fn instr_call_per_local(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_795_000 picoseconds. - Weight::from_parts(2_121_763, 0) - // Standard Error: 45 - .saturating_add(Weight::from_parts(1_207, 0).saturating_mul(l.into())) + // Minimum execution time: 1_818_000 picoseconds. + Weight::from_parts(2_109_143, 0) + // Standard Error: 34 + .saturating_add(Weight::from_parts(1_249, 0).saturating_mul(l.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_get(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_019_000 picoseconds. - Weight::from_parts(3_267_108, 0) - // Standard Error: 55 - .saturating_add(Weight::from_parts(2_527, 0).saturating_mul(r.into())) + // Minimum execution time: 3_083_000 picoseconds. + Weight::from_parts(3_291_328, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(2_505, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_set(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_944_000 picoseconds. - Weight::from_parts(3_183_331, 0) + // Minimum execution time: 2_987_000 picoseconds. + Weight::from_parts(3_276_863, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_618, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_617, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_local_tee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_009_000 picoseconds. - Weight::from_parts(3_178_158, 0) - // Standard Error: 41 - .saturating_add(Weight::from_parts(4_075, 0).saturating_mul(r.into())) + // Minimum execution time: 2_942_000 picoseconds. + Weight::from_parts(3_350_581, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(3_976, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_global_get(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_748_000 picoseconds. - Weight::from_parts(2_371_911, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(8_378, 0).saturating_mul(r.into())) + // Minimum execution time: 1_867_000 picoseconds. + Weight::from_parts(2_920_748, 0) + // Standard Error: 44 + .saturating_add(Weight::from_parts(8_229, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_global_set(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_795_000 picoseconds. - Weight::from_parts(1_311_997, 0) - // Standard Error: 157 - .saturating_add(Weight::from_parts(9_410, 0).saturating_mul(r.into())) + // Minimum execution time: 1_757_000 picoseconds. + Weight::from_parts(2_235_198, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(8_815, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_memory_current(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_059_000 picoseconds. - Weight::from_parts(2_416_611, 0) - // Standard Error: 5 - .saturating_add(Weight::from_parts(3_775, 0).saturating_mul(r.into())) + // Minimum execution time: 1_824_000 picoseconds. + Weight::from_parts(1_941_816, 0) + // Standard Error: 86 + .saturating_add(Weight::from_parts(4_043, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 16]`. fn instr_memory_grow(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_764_000 picoseconds. - Weight::from_parts(1_414_442, 0) - // Standard Error: 142_321 - .saturating_add(Weight::from_parts(13_210_495, 0).saturating_mul(r.into())) + // Minimum execution time: 1_793_000 picoseconds. + Weight::from_parts(1_104_829, 0) + // Standard Error: 137_800 + .saturating_add(Weight::from_parts(13_336_784, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64clz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_665_000 picoseconds. - Weight::from_parts(2_047_968, 0) + // Minimum execution time: 1_693_000 picoseconds. + Weight::from_parts(2_037_305, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(4_035, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(4_044, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ctz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_696_000 picoseconds. - Weight::from_parts(2_101_548, 0) - // Standard Error: 13 - .saturating_add(Weight::from_parts(3_754, 0).saturating_mul(r.into())) + // Minimum execution time: 1_751_000 picoseconds. + Weight::from_parts(2_082_016, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(3_767, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64popcnt(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_023_482, 0) + // Minimum execution time: 1_751_000 picoseconds. + Weight::from_parts(2_110_625, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_770, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_754, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64eqz(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_700_000 picoseconds. - Weight::from_parts(2_035_759, 0) + // Minimum execution time: 1_756_000 picoseconds. + Weight::from_parts(2_100_327, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_660, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_664, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64extendsi32(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_682_000 picoseconds. - Weight::from_parts(2_015_828, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(3_977, 0).saturating_mul(r.into())) + // Minimum execution time: 1_643_000 picoseconds. + Weight::from_parts(2_169_153, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(3_961, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64extendui32(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_660_000 picoseconds. - Weight::from_parts(2_032_387, 0) + // Minimum execution time: 1_704_000 picoseconds. + Weight::from_parts(2_049_172, 0) // Standard Error: 2 - .saturating_add(Weight::from_parts(3_826, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(3_833, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i32wrapi64(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_635_000 picoseconds. - Weight::from_parts(2_013_228, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(3_752, 0).saturating_mul(r.into())) + // Minimum execution time: 1_726_000 picoseconds. + Weight::from_parts(2_064_387, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(3_745, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64eq(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_698_000 picoseconds. - Weight::from_parts(2_844_817, 0) + // Minimum execution time: 1_696_000 picoseconds. + Weight::from_parts(2_426_905, 0) // Standard Error: 56 - .saturating_add(Weight::from_parts(5_746, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_915, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ne(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_208_884, 0) - // Standard Error: 138 - .saturating_add(Weight::from_parts(6_032, 0).saturating_mul(r.into())) + // Minimum execution time: 1_617_000 picoseconds. + Weight::from_parts(2_035_161, 0) + // Standard Error: 94 + .saturating_add(Weight::from_parts(6_073, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64lts(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_695_000 picoseconds. - Weight::from_parts(2_060_880, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_966, 0).saturating_mul(r.into())) + // Minimum execution time: 1_756_000 picoseconds. + Weight::from_parts(2_098_926, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(6_002, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ltu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_700_000 picoseconds. - Weight::from_parts(2_143_484, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_932, 0).saturating_mul(r.into())) + // Minimum execution time: 1_706_000 picoseconds. + Weight::from_parts(2_257_972, 0) + // Standard Error: 23 + .saturating_add(Weight::from_parts(5_982, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64gts(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_081_646, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_813, 0).saturating_mul(r.into())) + // Minimum execution time: 1_761_000 picoseconds. + Weight::from_parts(2_114_141, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(5_815, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64gtu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_476_000 picoseconds. - Weight::from_parts(2_161_801, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(6_078, 0).saturating_mul(r.into())) + // Minimum execution time: 1_700_000 picoseconds. + Weight::from_parts(2_053_201, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(6_137, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64les(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_043_451, 0) + // Minimum execution time: 1_705_000 picoseconds. + Weight::from_parts(2_101_782, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(5_988, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(6_014, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64leu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_694_000 picoseconds. - Weight::from_parts(2_058_196, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(6_058, 0).saturating_mul(r.into())) + // Minimum execution time: 1_856_000 picoseconds. + Weight::from_parts(2_149_707, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(6_086, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64ges(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_675_000 picoseconds. - Weight::from_parts(2_036_798, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_956, 0).saturating_mul(r.into())) + // Minimum execution time: 1_739_000 picoseconds. + Weight::from_parts(2_143_216, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(5_934, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64geu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_712_000 picoseconds. - Weight::from_parts(2_121_407, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_944, 0).saturating_mul(r.into())) + // Minimum execution time: 1_716_000 picoseconds. + Weight::from_parts(2_065_762, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(6_009, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64add(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_675_000 picoseconds. - Weight::from_parts(2_061_053, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(5_823, 0).saturating_mul(r.into())) + // Minimum execution time: 1_664_000 picoseconds. + Weight::from_parts(3_062_283, 0) + // Standard Error: 94 + .saturating_add(Weight::from_parts(5_645, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64sub(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_686_000 picoseconds. - Weight::from_parts(2_023_347, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(6_126, 0).saturating_mul(r.into())) + // Minimum execution time: 1_671_000 picoseconds. + Weight::from_parts(2_011_145, 0) + // Standard Error: 44 + .saturating_add(Weight::from_parts(6_220, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64mul(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_678_000 picoseconds. - Weight::from_parts(2_390_920, 0) - // Standard Error: 55 - .saturating_add(Weight::from_parts(5_635, 0).saturating_mul(r.into())) + // Minimum execution time: 1_759_000 picoseconds. + Weight::from_parts(2_095_420, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(5_723, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64divs(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_728_000 picoseconds. - Weight::from_parts(1_944_457, 0) - // Standard Error: 7 - .saturating_add(Weight::from_parts(11_848, 0).saturating_mul(r.into())) + // Minimum execution time: 1_672_000 picoseconds. + Weight::from_parts(2_184_044, 0) + // Standard Error: 5 + .saturating_add(Weight::from_parts(11_782, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64divu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_649_000 picoseconds. - Weight::from_parts(1_881_148, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(10_618, 0).saturating_mul(r.into())) + // Minimum execution time: 1_752_000 picoseconds. + Weight::from_parts(2_276_209, 0) + // Standard Error: 5 + .saturating_add(Weight::from_parts(10_513, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rems(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_708_000 picoseconds. - Weight::from_parts(1_767_912, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(12_099, 0).saturating_mul(r.into())) + // Minimum execution time: 1_711_000 picoseconds. + Weight::from_parts(2_720_989, 0) + // Standard Error: 24 + .saturating_add(Weight::from_parts(11_884, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64remu(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_650_000 picoseconds. - Weight::from_parts(1_998_575, 0) + // Minimum execution time: 1_713_000 picoseconds. + Weight::from_parts(2_091_403, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(10_632, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(10_628, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64and(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_633_000 picoseconds. - Weight::from_parts(2_029_981, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_662, 0).saturating_mul(r.into())) + // Minimum execution time: 1_704_000 picoseconds. + Weight::from_parts(2_054_652, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(5_672, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64or(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_621_000 picoseconds. - Weight::from_parts(2_029_743, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(5_762, 0).saturating_mul(r.into())) + // Minimum execution time: 1_743_000 picoseconds. + Weight::from_parts(2_032_806, 0) + // Standard Error: 19 + .saturating_add(Weight::from_parts(5_795, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64xor(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_641_000 picoseconds. - Weight::from_parts(2_127_132, 0) + // Minimum execution time: 1_667_000 picoseconds. + Weight::from_parts(2_031_702, 0) // Standard Error: 5 - .saturating_add(Weight::from_parts(5_818, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_923, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shl(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_690_000 picoseconds. - Weight::from_parts(2_021_035, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(5_917, 0).saturating_mul(r.into())) + // Minimum execution time: 1_735_000 picoseconds. + Weight::from_parts(2_946_634, 0) + // Standard Error: 54 + .saturating_add(Weight::from_parts(5_685, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shrs(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_661_000 picoseconds. - Weight::from_parts(2_055_069, 0) - // Standard Error: 3 - .saturating_add(Weight::from_parts(6_094, 0).saturating_mul(r.into())) + // Minimum execution time: 1_652_000 picoseconds. + Weight::from_parts(2_023_049, 0) + // Standard Error: 4 + .saturating_add(Weight::from_parts(6_146, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64shru(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_677_000 picoseconds. - Weight::from_parts(2_024_748, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(5_862, 0).saturating_mul(r.into())) + // Minimum execution time: 1_654_000 picoseconds. + Weight::from_parts(2_148_951, 0) + // Standard Error: 3 + .saturating_add(Weight::from_parts(5_869, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rotl(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_651_000 picoseconds. - Weight::from_parts(2_005_814, 0) + // Minimum execution time: 1_730_000 picoseconds. + Weight::from_parts(2_130_543, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(6_007, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_999, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. fn instr_i64rotr(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_703_000 picoseconds. - Weight::from_parts(2_019_636, 0) + // Minimum execution time: 1_728_000 picoseconds. + Weight::from_parts(2_172_886, 0) // Standard Error: 3 - .saturating_add(Weight::from_parts(5_862, 0).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(5_843, 0).saturating_mul(r.into())) } } diff --git a/frame/nis/src/lib.rs b/frame/nis/src/lib.rs index 0b8d292ec5f45..539011c5149d0 100644 --- a/frame/nis/src/lib.rs +++ b/frame/nis/src/lib.rs @@ -480,9 +480,6 @@ pub mod pallet { AlreadyCommunal, /// The receipt is already private. AlreadyPrivate, - Release1, - Release2, - Tah, } pub(crate) struct WeightCounter { @@ -724,8 +721,7 @@ pub mod pallet { let dropped = receipt.proportion.is_zero(); if amount > on_hold { - T::Currency::release(&T::HoldReason::get(), &who, on_hold, Exact) - .map_err(|_| Error::::Release1)?; + T::Currency::release(&T::HoldReason::get(), &who, on_hold, Exact)?; let deficit = amount - on_hold; // Try to transfer deficit from pot to receipt owner. summary.receipts_on_hold.saturating_reduce(on_hold); @@ -756,8 +752,7 @@ pub mod pallet { )?; summary.receipts_on_hold.saturating_reduce(on_hold); } - T::Currency::release(&T::HoldReason::get(), &who, amount, Exact) - .map_err(|_| Error::::Release2)?; + T::Currency::release(&T::HoldReason::get(), &who, amount, Exact)?; } if dropped { diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index cfde05ffeeabe..78f0c730ce5dd 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -133,7 +133,7 @@ //! * Root: can change the nominator, bouncer, or itself, manage and claim commission, and can //! perform any of the actions the nominator or bouncer can. //! -//! ## Commission +//! ### Commission //! //! A pool can optionally have a commission configuration, via the `root` role, set with //! [`Call::set_commission`] and claimed with [`Call::claim_commission`]. A payee account must be @@ -2617,7 +2617,7 @@ pub mod pallet { /// commission is paid out and added to total claimed commission`. Total pending commission /// is reset to zero. the current. #[pallet::call_index(20)] - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::claim_commission())] pub fn claim_commission(origin: OriginFor, pool_id: PoolId) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_claim_commission(who, pool_id) diff --git a/frame/referenda/src/lib.rs b/frame/referenda/src/lib.rs index b96cf5a76733d..68837376c5b33 100644 --- a/frame/referenda/src/lib.rs +++ b/frame/referenda/src/lib.rs @@ -874,22 +874,21 @@ impl, I: 'static> Pallet { let when = (when.saturating_add(alarm_interval.saturating_sub(One::one())) / alarm_interval) .saturating_mul(alarm_interval); - let maybe_result = T::Scheduler::schedule( + let result = T::Scheduler::schedule( DispatchTime::At(when), None, 128u8, frame_system::RawOrigin::Root.into(), call, - ) - .ok() - .map(|x| (when, x)); + ); debug_assert!( - maybe_result.is_some(), - "Unable to schedule a new alarm at #{:?} (now: #{:?})?!", + result.is_ok(), + "Unable to schedule a new alarm at #{:?} (now: #{:?}), scheduler error: `{:?}`", when, - frame_system::Pallet::::block_number() + frame_system::Pallet::::block_number(), + result.unwrap_err(), ); - maybe_result + result.ok().map(|x| (when, x)) } /// Mutate a referendum's `status` into the correct deciding state. diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 09bb3561188f8..8194f286c8323 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -216,6 +216,10 @@ pub mod pallet { type OriginPrivilegeCmp: PrivilegeCmp; /// The maximum number of scheduled calls in the queue for a single block. + /// + /// NOTE: + /// + Dependent pallets' benchmarks might require a higher limit for the setting. Set a + /// higher limit under `runtime-benchmarks` feature. #[pallet::constant] type MaxScheduledPerBlock: Get; diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 37f23efed36c1..9250186dc38e6 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -157,7 +157,7 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use std::{collections::HashSet, str::FromStr}; -use syn::{Ident, Result}; +use syn::{spanned::Spanned, Ident, Result}; /// The fixed name of the system pallet. const SYSTEM_PALLET_NAME: &str = "System"; @@ -170,9 +170,12 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { let res = match definition { RuntimeDeclaration::Implicit(implicit_def) => - construct_runtime_intermediary_expansion(input_copy.into(), implicit_def), + check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()).and_then( + |_| construct_runtime_intermediary_expansion(input_copy.into(), implicit_def), + ), RuntimeDeclaration::Explicit(explicit_decl) => - construct_runtime_final_expansion(explicit_decl), + check_pallet_number(input_copy.into(), explicit_decl.pallets.len()) + .and_then(|_| construct_runtime_final_expansion(explicit_decl)), }; res.unwrap_or_else(|e| e.to_compile_error()).into() @@ -616,3 +619,34 @@ fn decl_static_assertions( #(#error_encoded_size_check)* } } + +fn check_pallet_number(input: TokenStream2, pallet_num: usize) -> Result<()> { + let max_pallet_num = { + if cfg!(feature = "tuples-96") { + 96 + } else if cfg!(feature = "tuples-128") { + 128 + } else { + 64 + } + }; + + if pallet_num > max_pallet_num { + let no_feature = max_pallet_num == 128; + return Err(syn::Error::new( + input.span(), + format!( + "{} To increase this limit, enable the tuples-{} feature of [frame_support]. {}", + "The number of pallets exceeds the maximum number of tuple elements.", + max_pallet_num + 32, + if no_feature { + "If the feature does not exist - it needs to be implemented." + } else { + "" + }, + ), + )) + } + + Ok(()) +} diff --git a/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs b/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs new file mode 100644 index 0000000000000..5dfc67c83836a --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs @@ -0,0 +1,169 @@ +use frame_support::construct_runtime; +use sp_core::sr25519; +use sp_runtime::{generic, traits::BlakeTwo256}; + +#[frame_support::pallet] +mod pallet { + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); +} + +pub type Signature = sr25519::Signature; +pub type BlockNumber = u32; +pub type Header = generic::Header; +pub type Block = generic::Block; +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; + +impl pallet::Config for Runtime {} + +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type BlockNumber = u32; + type RuntimeCall = RuntimeCall; + type Hash = sp_runtime::testing::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = frame_support::traits::ConstU32<250>; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +construct_runtime! { + pub struct Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Pallet1: pallet::{Pallet}, + Pallet2: pallet::{Pallet}, + Pallet3: pallet::{Pallet}, + Pallet4: pallet::{Pallet}, + Pallet5: pallet::{Pallet}, + Pallet6: pallet::{Pallet}, + Pallet7: pallet::{Pallet}, + Pallet8: pallet::{Pallet}, + Pallet9: pallet::{Pallet}, + Pallet10: pallet::{Pallet}, + Pallet11: pallet::{Pallet}, + Pallet12: pallet::{Pallet}, + Pallet13: pallet::{Pallet}, + Pallet14: pallet::{Pallet}, + Pallet15: pallet::{Pallet}, + Pallet16: pallet::{Pallet}, + Pallet17: pallet::{Pallet}, + Pallet18: pallet::{Pallet}, + Pallet19: pallet::{Pallet}, + Pallet20: pallet::{Pallet}, + Pallet21: pallet::{Pallet}, + Pallet22: pallet::{Pallet}, + Pallet23: pallet::{Pallet}, + Pallet24: pallet::{Pallet}, + Pallet25: pallet::{Pallet}, + Pallet26: pallet::{Pallet}, + Pallet27: pallet::{Pallet}, + Pallet28: pallet::{Pallet}, + Pallet29: pallet::{Pallet}, + Pallet30: pallet::{Pallet}, + Pallet31: pallet::{Pallet}, + Pallet32: pallet::{Pallet}, + Pallet33: pallet::{Pallet}, + Pallet34: pallet::{Pallet}, + Pallet35: pallet::{Pallet}, + Pallet36: pallet::{Pallet}, + Pallet37: pallet::{Pallet}, + Pallet38: pallet::{Pallet}, + Pallet39: pallet::{Pallet}, + Pallet40: pallet::{Pallet}, + Pallet41: pallet::{Pallet}, + Pallet42: pallet::{Pallet}, + Pallet43: pallet::{Pallet}, + Pallet44: pallet::{Pallet}, + Pallet45: pallet::{Pallet}, + Pallet46: pallet::{Pallet}, + Pallet47: pallet::{Pallet}, + Pallet48: pallet::{Pallet}, + Pallet49: pallet::{Pallet}, + Pallet50: pallet::{Pallet}, + Pallet51: pallet::{Pallet}, + Pallet52: pallet::{Pallet}, + Pallet53: pallet::{Pallet}, + Pallet54: pallet::{Pallet}, + Pallet55: pallet::{Pallet}, + Pallet56: pallet::{Pallet}, + Pallet57: pallet::{Pallet}, + Pallet58: pallet::{Pallet}, + Pallet59: pallet::{Pallet}, + Pallet60: pallet::{Pallet}, + Pallet61: pallet::{Pallet}, + Pallet62: pallet::{Pallet}, + Pallet63: pallet::{Pallet}, + Pallet64: pallet::{Pallet}, + Pallet65: pallet::{Pallet}, + Pallet66: pallet::{Pallet}, + Pallet67: pallet::{Pallet}, + Pallet68: pallet::{Pallet}, + Pallet69: pallet::{Pallet}, + Pallet70: pallet::{Pallet}, + Pallet71: pallet::{Pallet}, + Pallet72: pallet::{Pallet}, + Pallet73: pallet::{Pallet}, + Pallet74: pallet::{Pallet}, + Pallet75: pallet::{Pallet}, + Pallet76: pallet::{Pallet}, + Pallet77: pallet::{Pallet}, + Pallet78: pallet::{Pallet}, + Pallet79: pallet::{Pallet}, + Pallet80: pallet::{Pallet}, + Pallet81: pallet::{Pallet}, + Pallet82: pallet::{Pallet}, + Pallet83: pallet::{Pallet}, + Pallet84: pallet::{Pallet}, + Pallet85: pallet::{Pallet}, + Pallet86: pallet::{Pallet}, + Pallet87: pallet::{Pallet}, + Pallet88: pallet::{Pallet}, + Pallet89: pallet::{Pallet}, + Pallet90: pallet::{Pallet}, + Pallet91: pallet::{Pallet}, + Pallet92: pallet::{Pallet}, + Pallet93: pallet::{Pallet}, + Pallet94: pallet::{Pallet}, + Pallet95: pallet::{Pallet}, + Pallet96: pallet::{Pallet}, + Pallet97: pallet::{Pallet}, + Pallet98: pallet::{Pallet}, + Pallet99: pallet::{Pallet}, + Pallet100: pallet::{Pallet}, + Pallet101: pallet::{Pallet}, + Pallet102: pallet::{Pallet}, + Pallet103: pallet::{Pallet}, + Pallet104: pallet::{Pallet}, + Pallet105: pallet::{Pallet}, + Pallet106: pallet::{Pallet}, + Pallet107: pallet::{Pallet}, + Pallet108: pallet::{Pallet}, + Pallet109: pallet::{Pallet}, + Pallet110: pallet::{Pallet}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr b/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr new file mode 100644 index 0000000000000..dbd81ef367a9f --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr @@ -0,0 +1,61 @@ +error: The number of pallets exceeds the maximum number of tuple elements. To increase this limit, enable the tuples-96 feature of [frame_support]. + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:50:2 + | +50 | pub struct Runtime where + | ^^^ + +error[E0412]: cannot find type `RuntimeCall` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:18:64 + | +18 | pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; + | ^^^^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +18 | pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; + | +++++++++++++ + +error[E0412]: cannot find type `Runtime` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:20:25 + | +20 | impl pallet::Config for Runtime {} + | ^^^^^^^ not found in this scope + +error[E0412]: cannot find type `Runtime` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:22:31 + | +22 | impl frame_system::Config for Runtime { + | ^^^^^^^ not found in this scope + +error[E0412]: cannot find type `RuntimeOrigin` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:24:23 + | +24 | type RuntimeOrigin = RuntimeOrigin; + | ^^^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeOrigin` + +error[E0412]: cannot find type `RuntimeCall` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:27:21 + | +27 | type RuntimeCall = RuntimeCall; + | ^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeCall` + +error[E0412]: cannot find type `RuntimeEvent` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:33:22 + | +33 | type RuntimeEvent = RuntimeEvent; + | ^^^^^^^^^^^^ help: you might have meant to use the associated type: `Self::RuntimeEvent` + +error[E0412]: cannot find type `PalletInfo` in this scope + --> tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs:39:20 + | +39 | type PalletInfo = PalletInfo; + | ^^^^^^^^^^ + | +help: you might have meant to use the associated type + | +39 | type PalletInfo = Self::PalletInfo; + | ~~~~~~~~~~~~~~~~ +help: consider importing this trait + | +1 | use frame_support::traits::PalletInfo; + | diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 7e2b36bceaae4..0d265293ecf42 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -79,7 +79,14 @@ fn generate_impl_call( let pborrow = params.iter().map(|v| &v.2); let decode_params = if params.is_empty() { - quote!() + quote!( + if !#input.is_empty() { + panic!( + "Bad input data provided to {}: expected no parameters, but input buffer is not empty.", + #fn_name_str + ); + } + ) } else { let let_binding = if params.len() == 1 { quote! { diff --git a/primitives/application-crypto/src/ecdsa.rs b/primitives/application-crypto/src/ecdsa.rs index 011456df08fae..27ffe12579f55 100644 --- a/primitives/application-crypto/src/ecdsa.rs +++ b/primitives/application-crypto/src/ecdsa.rs @@ -24,13 +24,7 @@ use sp_std::vec::Vec; pub use sp_core::ecdsa::*; mod app { - use sp_core::testing::ECDSA; - - crate::app_crypto!(super, ECDSA); - - impl crate::traits::BoundToRuntimeAppPublic for Public { - type Public = Self; - } + crate::app_crypto!(super, sp_core::testing::ECDSA); } #[cfg(feature = "full_crypto")] diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index 822dd3fa5c422..bc05018370edb 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -24,13 +24,7 @@ use sp_std::vec::Vec; pub use sp_core::ed25519::*; mod app { - use sp_core::testing::ED25519; - - crate::app_crypto!(super, ED25519); - - impl crate::traits::BoundToRuntimeAppPublic for Public { - type Public = Self; - } + crate::app_crypto!(super, sp_core::testing::ED25519); } #[cfg(feature = "full_crypto")] diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index bf738813333be..3f12e06e11ec3 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -48,14 +48,15 @@ mod traits; pub use traits::*; -/// Declares Public, Pair, Signature types which are functionally equivalent to `$pair`, but are new -/// Application-specific types whose identifier is `$key_type`. +/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent +/// to the corresponding types defined by `$module` but are new application-specific +/// types whose identifier is `$key_type`. /// /// ```rust -/// # use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; -/// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId` +/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId}; +/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId` /// // of value `b"fuba"`. -/// app_crypto!(ed25519, KeyTypeId(*b"_uba")); +/// app_crypto!(ed25519, KeyTypeId(*b"fuba")); /// ``` #[cfg(feature = "full_crypto")] #[macro_export] @@ -78,14 +79,15 @@ macro_rules! app_crypto { }; } -/// Declares Public, Pair, Signature types which are functionally equivalent to `$pair`, but are new -/// Application-specific types whose identifier is `$key_type`. +/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent +/// to the corresponding types defined by `$module` but that are new application-specific +/// types whose identifier is `$key_type`. /// /// ```rust -/// # use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; -/// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId` +/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId}; +/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId` /// // of value `b"fuba"`. -/// app_crypto!(ed25519, KeyTypeId(*b"_uba")); +/// app_crypto!(ed25519, KeyTypeId(*b"fuba")); /// ``` #[cfg(not(feature = "full_crypto"))] #[macro_export] @@ -107,8 +109,8 @@ macro_rules! app_crypto { }; } -/// Declares Pair type which is functionally equivalent to `$pair`, but is new -/// Application-specific type whose identifier is `$key_type`. +/// Declares `Pair` type which is functionally equivalent to `$pair`, but is +/// new application-specific type whose identifier is `$key_type`. #[macro_export] macro_rules! app_crypto_pair { ($pair:ty, $key_type:expr, $crypto_type:expr) => { @@ -208,10 +210,10 @@ macro_rules! app_crypto_pair_functions_if_std { ($pair:ty) => {}; } -/// Declares Public type which is functionally equivalent to `$public`, but is new -/// Application-specific type whose identifier is `$key_type`. -/// can only be used together with `full_crypto` feature -/// For full functionality, app_crypto_public_common! must be called too. +/// Declares `Public` type which is functionally equivalent to `$public` but is +/// new application-specific type whose identifier is `$key_type`. +/// For full functionality, `app_crypto_public_common!` must be called too. +/// Can only be used with `full_crypto` feature. #[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_full_crypto { @@ -244,10 +246,10 @@ macro_rules! app_crypto_public_full_crypto { }; } -/// Declares Public type which is functionally equivalent to `$public`, but is new -/// Application-specific type whose identifier is `$key_type`. -/// can only be used without `full_crypto` feature -/// For full functionality, app_crypto_public_common! must be called too. +/// Declares `Public` type which is functionally equivalent to `$public` but is +/// new application-specific type whose identifier is `$key_type`. +/// For full functionality, `app_crypto_public_common!` must be called too. +/// Can only be used without `full_crypto` feature. #[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_not_full_crypto { @@ -276,9 +278,9 @@ macro_rules! app_crypto_public_not_full_crypto { }; } -/// Declares Public type which is functionally equivalent to `$public`, but is new -/// Application-specific type whose identifier is `$key_type`. -/// For full functionality, app_crypto_public_(not)_full_crypto! must be called too. +/// Declares `Public` type which is functionally equivalent to `$public` but is +/// new application-specific type whose identifier is `$key_type`. +/// For full functionality, `app_crypto_public_(not)_full_crypto!` must be called too. #[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_common { @@ -307,40 +309,6 @@ macro_rules! app_crypto_public_common { type Generic = $public; } - impl $crate::RuntimeAppPublic for Public - where - $public: $crate::RuntimePublic, - { - const ID: $crate::KeyTypeId = $key_type; - const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; - - type Signature = Signature; - - fn all() -> $crate::Vec { - <$public as $crate::RuntimePublic>::all($key_type) - .into_iter() - .map(Self) - .collect() - } - - fn generate_pair(seed: Option<$crate::Vec>) -> Self { - Self(<$public as $crate::RuntimePublic>::generate_pair($key_type, seed)) - } - - fn sign>(&self, msg: &M) -> Option { - <$public as $crate::RuntimePublic>::sign(self.as_ref(), $key_type, msg) - .map(Signature) - } - - fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - <$public as $crate::RuntimePublic>::verify(self.as_ref(), msg, &signature.as_ref()) - } - - fn to_raw_vec(&self) -> $crate::Vec { - <$public as $crate::RuntimePublic>::to_raw_vec(&self.0) - } - } - impl<'a> TryFrom<&'a [u8]> for Public { type Error = (); @@ -407,8 +375,8 @@ macro_rules! app_crypto_public_common_if_std { /// Declares Signature type which is functionally equivalent to `$sig`, but is new /// Application-specific type whose identifier is `$key_type`. -/// can only be used together with `full_crypto` feature /// For full functionality, app_crypto_public_common! must be called too. +/// Can only be used with `full_crypto` feature #[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_full_crypto { @@ -439,10 +407,10 @@ macro_rules! app_crypto_signature_full_crypto { }; } -/// Declares Signature type which is functionally equivalent to `$sig`, but is new -/// Application-specific type whose identifier is `$key_type`. -/// can only be used without `full_crypto` feature -/// For full functionality, app_crypto_public_common! must be called too. +/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new +/// application-specific type whose identifier is `$key_type`. +/// For full functionality, `app_crypto_signature_common` must be called too. +/// Can only be used without `full_crypto` feature. #[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_not_full_crypto { @@ -452,8 +420,8 @@ macro_rules! app_crypto_signature_not_full_crypto { #[derive(Clone, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode, - $crate::scale_info::TypeInfo, $crate::RuntimeDebug, + $crate::scale_info::TypeInfo, )] pub struct Signature($sig); } @@ -469,9 +437,9 @@ macro_rules! app_crypto_signature_not_full_crypto { }; } -/// Declares Signature type which is functionally equivalent to `$sig`, but is new -/// Application-specific type whose identifier is `$key_type`. -/// For full functionality, app_crypto_public_(not)_full_crypto! must be called too. +/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new +/// application-specific type whose identifier is `$key_type`. +/// For full functionality, app_crypto_signature_(not)_full_crypto! must be called too. #[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_common { diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index a961f5cf3edf0..7c91bfa7bb5ff 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -24,13 +24,7 @@ use sp_std::vec::Vec; pub use sp_core::sr25519::*; mod app { - use sp_core::testing::SR25519; - - crate::app_crypto!(super, SR25519); - - impl crate::traits::BoundToRuntimeAppPublic for Public { - type Public = Self; - } + crate::app_crypto!(super, sp_core::testing::SR25519); } #[cfg(feature = "full_crypto")] diff --git a/primitives/application-crypto/src/traits.rs b/primitives/application-crypto/src/traits.rs index b3bcd0ce2b701..88d4bf36915d0 100644 --- a/primitives/application-crypto/src/traits.rs +++ b/primitives/application-crypto/src/traits.rs @@ -15,10 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +use codec::Codec; +use scale_info::TypeInfo; + #[cfg(feature = "full_crypto")] use sp_core::crypto::Pair; - -use codec::Codec; use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Public}; use sp_std::{fmt::Debug, vec::Vec}; @@ -60,15 +61,9 @@ pub trait MaybeHash {} #[cfg(all(not(feature = "std"), not(feature = "full_crypto")))] impl MaybeHash for T {} -/// Type which implements Debug and Hash in std, not when no-std (no-std variant with crypto). -#[cfg(all(not(feature = "std"), feature = "full_crypto"))] -pub trait MaybeDebugHash: sp_std::hash::Hash {} -#[cfg(all(not(feature = "std"), feature = "full_crypto"))] -impl MaybeDebugHash for T {} - /// A application's public key. pub trait AppPublic: - AppCrypto + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec + AppCrypto + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + Codec { /// The wrapped type which is just a plain instance of `Public`. type Generic: IsWrappedBy @@ -79,7 +74,7 @@ pub trait AppPublic: + PartialEq + Debug + MaybeHash - + codec::Codec; + + Codec; } /// A application's key pair. @@ -92,15 +87,15 @@ pub trait AppPair: AppCrypto + Pair::Public> { } /// A application's signature. -pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug + MaybeHash { +pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug { /// The wrapped type which is just a plain instance of `Signature`. - type Generic: IsWrappedBy + Eq + PartialEq + Debug + MaybeHash; + type Generic: IsWrappedBy + Eq + PartialEq + Debug; } /// A runtime interface for a public key. pub trait RuntimePublic: Sized { /// The signature that will be generated when signing with the corresponding private key. - type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone; + type Signature: Debug + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; @@ -132,11 +127,9 @@ pub trait RuntimePublic: Sized { pub trait RuntimeAppPublic: Sized { /// An identifier for this application-specific key type. const ID: KeyTypeId; - /// The identifier of the crypto type of this application-specific key type. - const CRYPTO_ID: CryptoTypeId; /// The signature that will be generated when signing with the corresponding private key. - type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone + scale_info::TypeInfo; + type Signature: Debug + Eq + PartialEq + Clone + TypeInfo + Codec; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; @@ -163,8 +156,50 @@ pub trait RuntimeAppPublic: Sized { fn to_raw_vec(&self) -> Vec; } -/// Something that bound to a fixed [`RuntimeAppPublic`]. +impl RuntimeAppPublic for T +where + T: AppPublic + AsRef<::Generic>, + ::Generic: RuntimePublic, + ::Signature: TypeInfo + + Codec + + From<<::Generic as RuntimePublic>::Signature> + + AsRef<<::Generic as RuntimePublic>::Signature>, +{ + const ID: KeyTypeId = ::ID; + + type Signature = ::Signature; + + fn all() -> crate::Vec { + <::Generic as RuntimePublic>::all(Self::ID) + .into_iter() + .map(|p| p.into()) + .collect() + } + + fn generate_pair(seed: Option>) -> Self { + <::Generic as RuntimePublic>::generate_pair(Self::ID, seed).into() + } + + fn sign>(&self, msg: &M) -> Option { + <::Generic as RuntimePublic>::sign(self.as_ref(), Self::ID, msg) + .map(|s| s.into()) + } + + fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { + <::Generic as RuntimePublic>::verify(self.as_ref(), msg, signature.as_ref()) + } + + fn to_raw_vec(&self) -> Vec { + <::Generic as RuntimePublic>::to_raw_vec(self.as_ref()) + } +} + +/// Something that is bound to a fixed [`RuntimeAppPublic`]. pub trait BoundToRuntimeAppPublic { /// The [`RuntimeAppPublic`] this type is bound to. type Public: RuntimeAppPublic; } + +impl BoundToRuntimeAppPublic for T { + type Public = Self; +} diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 092baeeda95f8..9b253fd154675 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -13,10 +13,7 @@ documentation = "https://docs.rs/sp-core" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = [ - "derive", - "max-encoded-len", -] } +codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive","max-encoded-len"] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } serde = { version = "1.0.136", optional = true, features = ["derive"] } @@ -25,7 +22,7 @@ primitive-types = { version = "0.12.0", default-features = false, features = ["c impl-serde = { version = "0.4.0", optional = true } hash-db = { version = "0.16.0", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } -base58 = { version = "0.2.0", optional = true } +bs58 = { version = "0.4.0", default-features = false, optional = true } rand = { version = "0.8.5", features = ["small_rng"], optional = true } substrate-bip39 = { version = "0.4.4", optional = true } tiny-bip39 = { version = "1.0.0", optional = true } @@ -47,10 +44,7 @@ bitflags = "1.3" array-bytes = { version = "4.1", optional = true } ed25519-zebra = { version = "3.1.0", default-features = false, optional = true } blake2 = { version = "0.10.4", default-features = false, optional = true } -schnorrkel = { version = "0.9.1", features = [ - "preaudit_deprecated", - "u64_backend", -], default-features = false, optional = true } +schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } libsecp256k1 = { version = "0.7", default-features = false, features = ["static-context"], optional = true } merlin = { version = "2.0", default-features = false, optional = true } secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery", "alloc"], optional = true } @@ -96,7 +90,7 @@ std = [ "blake2/std", "array-bytes", "ed25519-zebra/std", - "base58", + "bs58/std", "substrate-bip39", "tiny-bip39", "rand", diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 2e60ac2370a16..f77e952d84546 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -21,8 +21,6 @@ use crate::{ed25519, sr25519}; #[cfg(feature = "std")] -use base58::{FromBase58, ToBase58}; -#[cfg(feature = "std")] use bip39::{Language, Mnemonic, MnemonicType}; use codec::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] @@ -276,7 +274,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + ByteArray { const CHECKSUM_LEN: usize = 2; let body_len = Self::LEN; - let data = s.from_base58().map_err(|_| PublicError::BadBase58)?; + let data = bs58::decode(s).into_vec().map_err(|_| PublicError::BadBase58)?; if data.len() < 2 { return Err(PublicError::BadLength) } @@ -345,7 +343,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + ByteArray { v.extend(self.as_ref()); let r = ss58hash(&v); v.extend(&r[0..2]); - v.to_base58() + bs58::encode(v).into_string() } /// Return the ss58-check string for this key. @@ -484,7 +482,7 @@ pub trait ByteArray: AsRef<[u8]> + AsMut<[u8]> + for<'a> TryFrom<&'a [u8], Error } } -/// Trait suitable for typical cryptographic PKI key public type. +/// Trait suitable for typical cryptographic key public type. pub trait Public: ByteArray + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync {} /// An opaque 32-byte cryptographic identifier. diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index e56bfcf56041a..c6e716396aea4 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/paritytech/substrate/" description = "I/O for Substrate runtimes" documentation = "https://docs.rs/sp-io" readme = "README.md" +build = "build.rs" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -37,6 +38,9 @@ ed25519-dalek = { version = "1.0.1", default-features = false, optional = true } # Force the usage of ed25519, this is being used in `ed25519-dalek`. ed25519 = { version = "1.5.2", optional = true } +[build-dependencies] +rustversion = "1.0.6" + [features] default = ["std"] std = [ diff --git a/primitives/io/build.rs b/primitives/io/build.rs new file mode 100644 index 0000000000000..8a9c0b6420b29 --- /dev/null +++ b/primitives/io/build.rs @@ -0,0 +1,27 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#[rustversion::before(1.68)] +fn main() { + if !cfg!(feature = "std") { + println!("cargo:rustc-cfg=enable_alloc_error_handler"); + } +} + +#[rustversion::since(1.68)] +fn main() {} diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 306ac8e60c529..72300eb102177 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -19,7 +19,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(not(feature = "std"), feature(alloc_error_handler))] +#![cfg_attr(enable_alloc_error_handler, feature(alloc_error_handler))] #![cfg_attr( feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library." @@ -1643,7 +1643,7 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { } /// A default OOM handler for WASM environment. -#[cfg(all(not(feature = "disable_oom"), not(feature = "std")))] +#[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))] #[alloc_error_handler] pub fn oom(_: core::alloc::Layout) -> ! { #[cfg(feature = "improved_panic_error_reporting")] diff --git a/primitives/keystore/src/testing.rs b/primitives/keystore/src/testing.rs index de034c65889ff..e5107cba746f2 100644 --- a/primitives/keystore/src/testing.rs +++ b/primitives/keystore/src/testing.rs @@ -42,65 +42,36 @@ impl MemoryKeystore { Self::default() } - fn sr25519_key_pair( - &self, - key_type: KeyTypeId, - public: &sr25519::Public, - ) -> Option { - self.keys.read().get(&key_type).and_then(|inner| { - inner.get(public.as_slice()).map(|s| { - sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid") - }) - }) - } - - fn ed25519_key_pair( - &self, - key_type: KeyTypeId, - public: &ed25519::Public, - ) -> Option { - self.keys.read().get(&key_type).and_then(|inner| { - inner.get(public.as_slice()).map(|s| { - ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid") - }) - }) - } - - fn ecdsa_key_pair(&self, key_type: KeyTypeId, public: &ecdsa::Public) -> Option { + fn pair(&self, key_type: KeyTypeId, public: &T::Public) -> Option { self.keys.read().get(&key_type).and_then(|inner| { inner .get(public.as_slice()) - .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) + .map(|s| T::from_string(s, None).expect("seed slice is valid")) }) } -} -impl Keystore for MemoryKeystore { - fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec { + fn public_keys(&self, key_type: KeyTypeId) -> Vec { self.keys .read() .get(&key_type) .map(|keys| { keys.values() - .map(|s| { - sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid") - }) + .map(|s| T::from_string(s, None).expect("seed slice is valid")) .map(|p| p.public()) .collect() }) .unwrap_or_default() } - fn sr25519_generate_new( + fn generate_new( &self, key_type: KeyTypeId, seed: Option<&str>, - ) -> Result { + ) -> Result { match seed { Some(seed) => { - let pair = sr25519::Pair::from_string(seed, None).map_err(|_| { - Error::ValidationError("Generates an `sr25519` pair.".to_owned()) - })?; + let pair = T::from_string(seed, None) + .map_err(|_| Error::ValidationError("Generates a pair.".to_owned()))?; self.keys .write() .entry(key_type) @@ -109,7 +80,7 @@ impl Keystore for MemoryKeystore { Ok(pair.public()) }, None => { - let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None); + let (pair, phrase, _) = T::generate_with_phrase(None); self.keys .write() .entry(key_type) @@ -120,13 +91,37 @@ impl Keystore for MemoryKeystore { } } + fn sign( + &self, + key_type: KeyTypeId, + public: &T::Public, + msg: &[u8], + ) -> Result, Error> { + let sig = self.pair::(key_type, public).map(|pair| pair.sign(msg)); + Ok(sig) + } +} + +impl Keystore for MemoryKeystore { + fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec { + self.public_keys::(key_type) + } + + fn sr25519_generate_new( + &self, + key_type: KeyTypeId, + seed: Option<&str>, + ) -> Result { + self.generate_new::(key_type, seed) + } + fn sr25519_sign( &self, key_type: KeyTypeId, public: &sr25519::Public, msg: &[u8], ) -> Result, Error> { - Ok(self.sr25519_key_pair(key_type, public).map(|pair| pair.sign(msg))) + self.sign::(key_type, public, msg) } fn sr25519_vrf_sign( @@ -135,27 +130,16 @@ impl Keystore for MemoryKeystore { public: &sr25519::Public, transcript_data: VRFTranscriptData, ) -> Result, Error> { - let transcript = make_transcript(transcript_data); - let pair = - if let Some(k) = self.sr25519_key_pair(key_type, public) { k } else { return Ok(None) }; - - let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); - Ok(Some(VRFSignature { output: inout.to_output(), proof })) + let sig = self.pair::(key_type, public).map(|pair| { + let transcript = make_transcript(transcript_data); + let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); + VRFSignature { output: inout.to_output(), proof } + }); + Ok(sig) } fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.keys - .read() - .get(&key_type) - .map(|keys| { - keys.values() - .map(|s| { - ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid") - }) - .map(|p| p.public()) - .collect() - }) - .unwrap_or_default() + self.public_keys::(key_type) } fn ed25519_generate_new( @@ -163,28 +147,7 @@ impl Keystore for MemoryKeystore { key_type: KeyTypeId, seed: Option<&str>, ) -> Result { - match seed { - Some(seed) => { - let pair = ed25519::Pair::from_string(seed, None).map_err(|_| { - Error::ValidationError("Generates an `ed25519` pair.".to_owned()) - })?; - self.keys - .write() - .entry(key_type) - .or_default() - .insert(pair.public().to_raw_vec(), seed.into()); - Ok(pair.public()) - }, - None => { - let (pair, phrase, _) = ed25519::Pair::generate_with_phrase(None); - self.keys - .write() - .entry(key_type) - .or_default() - .insert(pair.public().to_raw_vec(), phrase); - Ok(pair.public()) - }, - } + self.generate_new::(key_type, seed) } fn ed25519_sign( @@ -193,22 +156,11 @@ impl Keystore for MemoryKeystore { public: &ed25519::Public, msg: &[u8], ) -> Result, Error> { - Ok(self.ed25519_key_pair(key_type, public).map(|pair| pair.sign(msg))) + self.sign::(key_type, public, msg) } fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec { - self.keys - .read() - .get(&key_type) - .map(|keys| { - keys.values() - .map(|s| { - ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid") - }) - .map(|p| p.public()) - .collect() - }) - .unwrap_or_default() + self.public_keys::(key_type) } fn ecdsa_generate_new( @@ -216,27 +168,7 @@ impl Keystore for MemoryKeystore { key_type: KeyTypeId, seed: Option<&str>, ) -> Result { - match seed { - Some(seed) => { - let pair = ecdsa::Pair::from_string(seed, None) - .map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?; - self.keys - .write() - .entry(key_type) - .or_default() - .insert(pair.public().to_raw_vec(), seed.into()); - Ok(pair.public()) - }, - None => { - let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None); - self.keys - .write() - .entry(key_type) - .or_default() - .insert(pair.public().to_raw_vec(), phrase); - Ok(pair.public()) - }, - } + self.generate_new::(key_type, seed) } fn ecdsa_sign( @@ -245,7 +177,7 @@ impl Keystore for MemoryKeystore { public: &ecdsa::Public, msg: &[u8], ) -> Result, Error> { - Ok(self.ecdsa_key_pair(key_type, public).map(|pair| pair.sign(msg))) + self.sign::(key_type, public, msg) } fn ecdsa_sign_prehashed( @@ -254,8 +186,8 @@ impl Keystore for MemoryKeystore { public: &ecdsa::Public, msg: &[u8; 32], ) -> Result, Error> { - let pair = self.ecdsa_key_pair(key_type, public); - pair.map(|pair| pair.sign_prehashed(msg)).map(Ok).transpose() + let sig = self.pair::(key_type, public).map(|pair| pair.sign_prehashed(msg)); + Ok(sig) } fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> { diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index d691d4846c330..269b62333bd26 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -176,62 +176,85 @@ fn test_versionining_register_only() { call_wasm_method::(wasm_binary_unwrap(), "test_versionning_register_only_works"); } +fn run_test_in_another_process( + test_name: &str, + test_body: impl FnOnce(), +) -> Option { + if std::env::var("RUN_FORKED_TEST").is_ok() { + test_body(); + None + } else { + let output = std::process::Command::new(std::env::current_exe().unwrap()) + .arg(test_name) + .env("RUN_FORKED_TEST", "1") + .output() + .unwrap(); + + assert!(output.status.success()); + Some(output) + } +} + #[test] fn test_tracing() { - use std::fmt; - use tracing::span::Id as SpanId; - use tracing_core::field::{Field, Visit}; - - #[derive(Clone)] - struct TracingSubscriber(Arc>); - - struct FieldConsumer(&'static str, Option); - impl Visit for FieldConsumer { - fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { - if field.name() == self.0 { - self.1 = Some(format!("{:?}", value)) + // Run in a different process to ensure that the `Span` is registered with our local + // `TracingSubscriber`. + run_test_in_another_process("test_tracing", || { + use std::fmt; + use tracing::span::Id as SpanId; + use tracing_core::field::{Field, Visit}; + + #[derive(Clone)] + struct TracingSubscriber(Arc>); + + struct FieldConsumer(&'static str, Option); + impl Visit for FieldConsumer { + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + if field.name() == self.0 { + self.1 = Some(format!("{:?}", value)) + } } } - } - #[derive(Default)] - struct Inner { - spans: HashSet, - } - - impl tracing::subscriber::Subscriber for TracingSubscriber { - fn enabled(&self, _: &tracing::Metadata) -> bool { - true + #[derive(Default)] + struct Inner { + spans: HashSet, } - fn new_span(&self, span: &tracing::span::Attributes) -> tracing::Id { - let mut inner = self.0.lock().unwrap(); - let id = SpanId::from_u64((inner.spans.len() + 1) as _); - let mut f = FieldConsumer("name", None); - span.record(&mut f); - inner.spans.insert(f.1.unwrap_or_else(|| span.metadata().name().to_owned())); - id - } + impl tracing::subscriber::Subscriber for TracingSubscriber { + fn enabled(&self, _: &tracing::Metadata) -> bool { + true + } - fn record(&self, _: &SpanId, _: &tracing::span::Record) {} + fn new_span(&self, span: &tracing::span::Attributes) -> tracing::Id { + let mut inner = self.0.lock().unwrap(); + let id = SpanId::from_u64((inner.spans.len() + 1) as _); + let mut f = FieldConsumer("name", None); + span.record(&mut f); + inner.spans.insert(f.1.unwrap_or_else(|| span.metadata().name().to_owned())); + id + } - fn record_follows_from(&self, _: &SpanId, _: &SpanId) {} + fn record(&self, _: &SpanId, _: &tracing::span::Record) {} - fn event(&self, _: &tracing::Event) {} + fn record_follows_from(&self, _: &SpanId, _: &SpanId) {} - fn enter(&self, _: &SpanId) {} + fn event(&self, _: &tracing::Event) {} - fn exit(&self, _: &SpanId) {} - } + fn enter(&self, _: &SpanId) {} - let subscriber = TracingSubscriber(Default::default()); - let _guard = tracing::subscriber::set_default(subscriber.clone()); + fn exit(&self, _: &SpanId) {} + } - // Call some method to generate a trace - call_wasm_method::(wasm_binary_unwrap(), "test_return_data"); + let subscriber = TracingSubscriber(Default::default()); + let _guard = tracing::subscriber::set_default(subscriber.clone()); + + // Call some method to generate a trace + call_wasm_method::(wasm_binary_unwrap(), "test_return_data"); - let inner = subscriber.0.lock().unwrap(); - assert!(inner.spans.contains("return_input_version_1")); + let inner = subscriber.0.lock().unwrap(); + assert!(inner.spans.contains("return_input_version_1")); + }); } #[test] diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 7e2ee5403f3ea..6d02e23094f90 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -26,7 +26,7 @@ use crate::{ PostDispatchInfoOf, SignedExtension, ValidateUnsigned, }, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResultWithInfo, CryptoTypeId, KeyTypeId, + ApplyExtrinsicResultWithInfo, KeyTypeId, }; use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; use sp_core::{ @@ -115,7 +115,6 @@ impl UintAuthorityId { impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId { const ID: KeyTypeId = key_types::DUMMY; - const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"dumm"); type Signature = TestSignature; @@ -157,10 +156,6 @@ impl OpaqueKeys for UintAuthorityId { } } -impl crate::BoundToRuntimeAppPublic for UintAuthorityId { - type Public = Self; -} - impl traits::IdentifyAccount for UintAuthorityId { type AccountId = u64; diff --git a/utils/wasm-builder/README.md b/utils/wasm-builder/README.md index a10611cc26a00..b1ccb1b35b10e 100644 --- a/utils/wasm-builder/README.md +++ b/utils/wasm-builder/README.md @@ -77,8 +77,13 @@ Wasm builder requires the following prerequisites for building the Wasm binary: - rust nightly + `wasm32-unknown-unknown` toolchain -If a specific rust nightly is installed with `rustup`, it is important that the wasm target is installed -as well. For example if installing the rust nightly from 20.02.2020 using `rustup install nightly-2020-02-20`, -the wasm target needs to be installed as well `rustup target add wasm32-unknown-unknown --toolchain nightly-2020-02-20`. +or + +- rust stable and version at least 1.68.0 + `wasm32-unknown-unknown` toolchain + +If a specific rust is installed with `rustup`, it is important that the wasm target is +installed as well. For example if installing the rust from 20.02.2020 using `rustup +install nightly-2020-02-20`, the wasm target needs to be installed as well `rustup target add +wasm32-unknown-unknown --toolchain nightly-2020-02-20`. License: Apache-2.0 diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 659b955256af7..8405b5a0bda9e 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -100,8 +100,12 @@ //! //! - rust nightly + `wasm32-unknown-unknown` toolchain //! -//! If a specific rust nightly is installed with `rustup`, it is important that the wasm target is -//! installed as well. For example if installing the rust nightly from 20.02.2020 using `rustup +//! or +//! +//! - rust stable and version at least 1.68.0 + `wasm32-unknown-unknown` toolchain +//! +//! If a specific rust is installed with `rustup`, it is important that the wasm target is +//! installed as well. For example if installing the rust from 20.02.2020 using `rustup //! install nightly-2020-02-20`, the wasm target needs to be installed as well `rustup target add //! wasm32-unknown-unknown --toolchain nightly-2020-02-20`. @@ -111,9 +115,11 @@ use std::{ path::{Path, PathBuf}, process::Command, }; +use version::Version; mod builder; mod prerequisites; +mod version; mod wasm_project; pub use builder::{WasmBuilder, WasmBuilderSelectProject}; @@ -172,53 +178,59 @@ fn copy_file_if_changed(src: PathBuf, dst: PathBuf) { } } -/// Get a cargo command that compiles with nightly -fn get_nightly_cargo() -> CargoCommand { +/// Get a cargo command that should be used to invoke the compilation. +fn get_cargo_command() -> CargoCommand { let env_cargo = CargoCommand::new(&env::var("CARGO").expect("`CARGO` env variable is always set by cargo")); let default_cargo = CargoCommand::new("cargo"); - let rustup_run_nightly = CargoCommand::new_with_args("rustup", &["run", "nightly", "cargo"]); let wasm_toolchain = env::var(WASM_BUILD_TOOLCHAIN).ok(); // First check if the user requested a specific toolchain - if let Some(cmd) = wasm_toolchain.and_then(|t| get_rustup_nightly(Some(t))) { + if let Some(cmd) = + wasm_toolchain.map(|t| CargoCommand::new_with_args("rustup", &["run", &t, "cargo"])) + { cmd - } else if env_cargo.is_nightly() { + } else if env_cargo.supports_substrate_wasm_env() { env_cargo - } else if default_cargo.is_nightly() { + } else if default_cargo.supports_substrate_wasm_env() { default_cargo - } else if rustup_run_nightly.is_nightly() { - rustup_run_nightly } else { - // If no command before provided us with a nightly compiler, we try to search one - // with rustup. If that fails as well, we return the default cargo and let the prequisities - // check fail. - get_rustup_nightly(None).unwrap_or(default_cargo) + // If no command before provided us with a cargo that supports our Substrate wasm env, we + // try to search one with rustup. If that fails as well, we return the default cargo and let + // the prequisities check fail. + get_rustup_command().unwrap_or(default_cargo) } } -/// Get a nightly from rustup. If `selected` is `Some(_)`, a `CargoCommand` using the given -/// nightly is returned. -fn get_rustup_nightly(selected: Option) -> Option { +/// Get the newest rustup command that supports our Substrate wasm env. +/// +/// Stable versions are always favored over nightly versions even if the nightly versions are +/// newer. +fn get_rustup_command() -> Option { let host = format!("-{}", env::var("HOST").expect("`HOST` is always set by cargo")); - let version = match selected { - Some(selected) => selected, - None => { - let output = Command::new("rustup").args(&["toolchain", "list"]).output().ok()?.stdout; - let lines = output.as_slice().lines(); + let output = Command::new("rustup").args(&["toolchain", "list"]).output().ok()?.stdout; + let lines = output.as_slice().lines(); + + let mut versions = Vec::new(); + for line in lines.filter_map(|l| l.ok()) { + let rustup_version = line.trim_end_matches(&host); + + let cmd = CargoCommand::new_with_args("rustup", &["run", &rustup_version, "cargo"]); - let mut latest_nightly = None; - for line in lines.filter_map(|l| l.ok()) { - if line.starts_with("nightly-") && line.ends_with(&host) { - // Rustup prints them sorted - latest_nightly = Some(line.clone()); - } - } + if !cmd.supports_substrate_wasm_env() { + continue + } + + let Some(cargo_version) = cmd.version() else { continue; }; - latest_nightly?.trim_end_matches(&host).into() - }, - }; + versions.push((cargo_version, rustup_version.to_string())); + } + + // Sort by the parsed version to get the latest version (greatest version) at the end of the + // vec. + versions.sort_by_key(|v| v.0); + let version = &versions.last()?.1; Some(CargoCommand::new_with_args("rustup", &["run", &version, "cargo"])) } @@ -228,17 +240,23 @@ fn get_rustup_nightly(selected: Option) -> Option { struct CargoCommand { program: String, args: Vec, + version: Option, } impl CargoCommand { fn new(program: &str) -> Self { - CargoCommand { program: program.into(), args: Vec::new() } + let version = Self::extract_version(program, &[]); + + CargoCommand { program: program.into(), args: Vec::new(), version } } fn new_with_args(program: &str, args: &[&str]) -> Self { + let version = Self::extract_version(program, args); + CargoCommand { program: program.into(), args: args.iter().map(ToString::to_string).collect(), + version, } } @@ -248,20 +266,40 @@ impl CargoCommand { cmd } - /// Check if the supplied cargo command is a nightly version - fn is_nightly(&self) -> bool { + fn extract_version(program: &str, args: &[&str]) -> Option { + let version = Command::new(program) + .args(args) + .arg("--version") + .output() + .ok() + .and_then(|o| String::from_utf8(o.stdout).ok())?; + + Version::extract(&version) + } + + /// Returns the version of this cargo command or `None` if it failed to extract the version. + fn version(&self) -> Option { + self.version + } + + /// Check if the supplied cargo command supports our Substrate wasm environment. + /// + /// This means that either the cargo version is at minimum 1.68.0 or this is a nightly cargo. + /// + /// Assumes that cargo version matches the rustc version. + fn supports_substrate_wasm_env(&self) -> bool { // `RUSTC_BOOTSTRAP` tells a stable compiler to behave like a nightly. So, when this env // variable is set, we can assume that whatever rust compiler we have, it is a nightly // compiler. For "more" information, see: // https://github.com/rust-lang/rust/blob/fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f/src/libsyntax/feature_gate/check.rs#L891 - env::var("RUSTC_BOOTSTRAP").is_ok() || - self.command() - .arg("--version") - .output() - .map_err(|_| ()) - .and_then(|o| String::from_utf8(o.stdout).map_err(|_| ())) - .unwrap_or_default() - .contains("-nightly") + if env::var("RUSTC_BOOTSTRAP").is_ok() { + return true + } + + let Some(version) = self.version() else { return false }; + + // Check if major and minor are greater or equal than 1.68 or this is a nightly. + version.major > 1 || (version.major == 1 && version.minor >= 68) || version.is_nightly } } diff --git a/utils/wasm-builder/src/prerequisites.rs b/utils/wasm-builder/src/prerequisites.rs index ca07a029281a8..f5a985ab92b5d 100644 --- a/utils/wasm-builder/src/prerequisites.rs +++ b/utils/wasm-builder/src/prerequisites.rs @@ -35,10 +35,13 @@ fn print_error_message(message: &str) -> String { /// /// Returns the versioned cargo command on success. pub(crate) fn check() -> Result { - let cargo_command = crate::get_nightly_cargo(); + let cargo_command = crate::get_cargo_command(); - if !cargo_command.is_nightly() { - return Err(print_error_message("Rust nightly not installed, please install it!")) + if !cargo_command.supports_substrate_wasm_env() { + return Err(print_error_message( + "Cannot compile the WASM runtime: no compatible Rust compiler found!\n\ + Install at least Rust 1.68.0 or a recent nightly version.", + )) } check_wasm_toolchain_installed(cargo_command) diff --git a/utils/wasm-builder/src/version.rs b/utils/wasm-builder/src/version.rs new file mode 100644 index 0000000000000..77e62b394bd55 --- /dev/null +++ b/utils/wasm-builder/src/version.rs @@ -0,0 +1,198 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::cmp::Ordering; + +/// The version of rustc/cargo. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Version { + pub major: u32, + pub minor: u32, + pub patch: u32, + pub is_nightly: bool, + pub year: u32, + pub month: u32, + pub day: u32, +} + +impl Version { + /// Returns if `self` is a stable version. + pub fn is_stable(&self) -> bool { + !self.is_nightly + } + + /// Return if `self` is a nightly version. + pub fn is_nightly(&self) -> bool { + self.is_nightly + } + + /// Extract from the given `version` string. + pub fn extract(version: &str) -> Option { + let mut is_nightly = false; + let version_parts = version + .trim() + .split(" ") + .nth(1)? + .split(".") + .filter_map(|v| { + if let Some(rest) = v.strip_suffix("-nightly") { + is_nightly = true; + rest.parse().ok() + } else { + v.parse().ok() + } + }) + .collect::>(); + + if version_parts.len() != 3 { + return None + } + + let date = version.split(" ").nth(3)?; + + let date_parts = date + .split("-") + .filter_map(|v| v.trim().strip_suffix(")").unwrap_or(v).parse().ok()) + .collect::>(); + + if date_parts.len() != 3 { + return None + } + + Some(Version { + major: version_parts[0], + minor: version_parts[1], + patch: version_parts[2], + is_nightly, + year: date_parts[0], + month: date_parts[1], + day: date_parts[2], + }) + } +} + +/// Ordering is done in the following way: +/// +/// 1. `stable` > `nightly` +/// 2. Then compare major, minor and patch. +/// 3. Last compare the date. +impl Ord for Version { + fn cmp(&self, other: &Self) -> Ordering { + if self == other { + return Ordering::Equal + } + + // Ensure that `stable > nightly` + if self.is_stable() && other.is_nightly() { + return Ordering::Greater + } else if self.is_nightly() && other.is_stable() { + return Ordering::Less + } + + let to_compare = [ + (self.major, other.major), + (self.minor, other.minor), + (self.patch, other.patch), + (self.year, other.year), + (self.month, other.month), + (self.day, other.day), + ]; + + to_compare + .iter() + .find_map(|(l, r)| if l != r { l.partial_cmp(&r) } else { None }) + // We already checked this right at the beginning, so we should never return here + // `Equal`. + .unwrap_or(Ordering::Equal) + } +} + +impl PartialOrd for Version { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn version_compare_and_extract_works() { + let version_1_66_0 = Version::extract("cargo 1.66.0 (d65d197ad 2022-11-15)").unwrap(); + let version_1_66_1 = Version::extract("cargo 1.66.1 (d65d197ad 2022-11-15)").unwrap(); + let version_1_66_0_nightly = + Version::extract("cargo 1.66.0-nightly (d65d197ad 2022-10-15)").unwrap(); + let version_1_66_0_nightly_older_date = + Version::extract("cargo 1.66.0-nightly (d65d197ad 2022-10-14)").unwrap(); + let version_1_65_0 = Version::extract("cargo 1.65.0 (d65d197ad 2022-10-15)").unwrap(); + let version_1_65_0_older_date = + Version::extract("cargo 1.65.0 (d65d197ad 2022-10-14)").unwrap(); + + assert!(version_1_66_1 > version_1_66_0); + assert!(version_1_66_1 > version_1_65_0); + assert!(version_1_66_1 > version_1_66_0_nightly); + assert!(version_1_66_1 > version_1_66_0_nightly_older_date); + assert!(version_1_66_1 > version_1_65_0_older_date); + + assert!(version_1_66_0 > version_1_65_0); + assert!(version_1_66_0 > version_1_66_0_nightly); + assert!(version_1_66_0 > version_1_66_0_nightly_older_date); + assert!(version_1_66_0 > version_1_65_0_older_date); + + assert!(version_1_65_0 > version_1_66_0_nightly); + assert!(version_1_65_0 > version_1_66_0_nightly_older_date); + assert!(version_1_65_0 > version_1_65_0_older_date); + + let mut versions = vec![ + version_1_66_0, + version_1_66_0_nightly, + version_1_66_0_nightly_older_date, + version_1_65_0_older_date, + version_1_65_0, + version_1_66_1, + ]; + versions.sort_by(|a, b| b.cmp(a)); + + let expected_versions_order = vec![ + version_1_66_1, + version_1_66_0, + version_1_65_0, + version_1_65_0_older_date, + version_1_66_0_nightly, + version_1_66_0_nightly_older_date, + ]; + assert_eq!(expected_versions_order, versions); + } + + #[test] + fn parse_with_newline() { + let version_1_66_0 = Version::extract("cargo 1.66.0 (d65d197ad 2022-11-15)\n").unwrap(); + assert_eq!( + Version { + major: 1, + minor: 66, + patch: 0, + is_nightly: false, + year: 2022, + month: 11, + day: 15 + }, + version_1_66_0 + ); + } +} diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index a3038c4e934c9..c45a40a6b9202 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -632,7 +632,7 @@ fn build_project( let mut build_cmd = cargo_cmd.command(); let rustflags = format!( - "-C link-arg=--export-table {} {}", + "-C target-cpu=mvp -C target-feature=-sign-ext -C link-arg=--export-table {} {}", default_rustflags, env::var(crate::WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(), );