From 549165727c3b3c14b6f90011085aaebbeff9d7e3 Mon Sep 17 00:00:00 2001 From: Kasper Ziemianek Date: Tue, 28 Mar 2023 16:38:13 +0200 Subject: [PATCH 01/26] contracts: proper event link in docs (#13729) --- frame/contracts/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From f40ba0d09785159a31a43b16b47ddb5ae8e62e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Mar 2023 09:17:50 +0200 Subject: [PATCH 02/26] Support stable rust for compiling the runtime (#13580) * Support stable rust for compiling the runtime This pull request brings support for compiling the runtime with stable Rust. This requires at least rust 1.68.0 to work on stable. The code is written in a way that it is backwards compatible and should automatically work when someone compiles with 1.68.0+ stable. * We always support nightlies! * :facepalm: * Sort by version * Review feedback * Review feedback * Fix version parsing * Apply suggestions from code review Co-authored-by: Koute --------- Co-authored-by: Koute --- Cargo.lock | 1 + primitives/io/Cargo.toml | 4 + primitives/io/build.rs | 27 ++++ primitives/io/src/lib.rs | 4 +- utils/wasm-builder/README.md | 11 +- utils/wasm-builder/src/lib.rs | 124 ++++++++++----- utils/wasm-builder/src/prerequisites.rs | 9 +- utils/wasm-builder/src/version.rs | 198 ++++++++++++++++++++++++ 8 files changed, 327 insertions(+), 51 deletions(-) create mode 100644 primitives/io/build.rs create mode 100644 utils/wasm-builder/src/version.rs diff --git a/Cargo.lock b/Cargo.lock index 33bca4005483c..cf30a6a94ae8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10474,6 +10474,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", + "rustversion", "secp256k1", "sp-core", "sp-externalities", 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/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 + ); + } +} From 4498e271881194bd626b1ac94e7ae7aa1f2e37c4 Mon Sep 17 00:00:00 2001 From: Mira Ressel Date: Wed, 29 Mar 2023 12:27:48 +0200 Subject: [PATCH 03/26] provide a default value for RELENG_SCRIPTS_BRANCH (#13743) Currently this variable is configured exclusively via a project variable, which makes it impossible to override for specific test prs. --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 093a0bb415d09..c9b68bca1ea09 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,6 +50,7 @@ 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 From 56d8cbfcac926439aa78b684b7c77921dd2f4a7f Mon Sep 17 00:00:00 2001 From: Mira Ressel Date: Wed, 29 Mar 2023 15:27:40 +0200 Subject: [PATCH 04/26] roll out new debian 11 ci image (#13744) --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c9b68bca1ea09..3928c190113ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,9 +48,9 @@ variables: CARGO_INCREMENTAL: 0 DOCKER_OS: "debian:stretch" ARCH: "x86_64" - CI_IMAGE: "paritytech/ci-linux:production" + CI_IMAGE: "paritytech/ci-linux@sha256:a8b63e4f1ab37f90034b9edd3a936a1d4ae897560e25010e0f2fccd8274c6f27" # staging 2023-03-28 BUILDAH_IMAGE: "quay.io/buildah/stable:v1.27" - RELENG_SCRIPTS_BRANCH: "master" + RELENG_SCRIPTS_BRANCH: "mira/pg-13" # TODO: back to master when the ci image is moved back to prod RUSTY_CACHIER_SINGLE_BRANCH: master RUSTY_CACHIER_DONT_OPERATE_ON_MAIN_BRANCH: "true" RUSTY_CACHIER_COMPRESSION_METHOD: zstd From 49ba186c53c24a3ace99c55ecd75370d8e65da1f Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Wed, 29 Mar 2023 15:46:05 +0200 Subject: [PATCH 05/26] Swap 'base58' with 'bs58' (#13739) * Swap base58 with bs58 * Removed unused clone * std flag --- Cargo.lock | 8 +------- primitives/core/Cargo.toml | 14 ++++---------- primitives/core/src/crypto.rs | 6 ++---- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf30a6a94ae8f..a49f8fc4208a2 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" @@ -10357,10 +10351,10 @@ name = "sp-core" version = "7.0.0" dependencies = [ "array-bytes", - "base58", "bitflags", "blake2", "bounded-collections", + "bs58", "criterion", "dyn-clonable", "ed25519-zebra", 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..0f86abf8671ad 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. From d7b9969c96f621b9cd93f91ebc8220aa620ac0e8 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Wed, 29 Mar 2023 16:54:02 +0200 Subject: [PATCH 06/26] proc-macro: check for non-args runtime calls added (#13742) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * proc-macro: check for non-args runtime calls added * Update primitives/api/proc-macro/src/impl_runtime_apis.rs Co-authored-by: Bastian Köcher --------- Co-authored-by: Bastian Köcher Co-authored-by: parity-processbot <> --- primitives/api/proc-macro/src/impl_runtime_apis.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 5ac07975df0f7..d0725ffd2ba54 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! { From bf8e565791ca2760a52a1074168808d6858cd8cb Mon Sep 17 00:00:00 2001 From: Mira Ressel Date: Wed, 29 Mar 2023 20:25:41 +0200 Subject: [PATCH 07/26] Clean up after debian 11 rollout (#13762) This reverts commit 56d8cbfcac926439aa78b684b7c77921dd2f4a7f. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3928c190113ea..c9b68bca1ea09 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,9 +48,9 @@ variables: CARGO_INCREMENTAL: 0 DOCKER_OS: "debian:stretch" ARCH: "x86_64" - CI_IMAGE: "paritytech/ci-linux@sha256:a8b63e4f1ab37f90034b9edd3a936a1d4ae897560e25010e0f2fccd8274c6f27" # staging 2023-03-28 + CI_IMAGE: "paritytech/ci-linux:production" BUILDAH_IMAGE: "quay.io/buildah/stable:v1.27" - RELENG_SCRIPTS_BRANCH: "mira/pg-13" # TODO: back to master when the ci image is moved back to prod + RELENG_SCRIPTS_BRANCH: "master" RUSTY_CACHIER_SINGLE_BRANCH: master RUSTY_CACHIER_DONT_OPERATE_ON_MAIN_BRANCH: "true" RUSTY_CACHIER_COMPRESSION_METHOD: zstd From e2176625e4120c01fa524fca858747c7a78c1bb7 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 29 Mar 2023 22:30:15 +0200 Subject: [PATCH 08/26] [Fix] Bump tuple element number in frame-support. (#13760) That is to avoid hitting the pallet limit that emits a cryptic error. More detail could be found here: https://substrate.stackexchange.com/questions/7212 . Co-authored-by: parity-processbot <> --- bin/node/runtime/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" } From 9c92e4987160a17daa72f79186d981b6fbe5879e Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 Mar 2023 01:22:34 +0200 Subject: [PATCH 09/26] Generic keystore internals (#13749) * Generic testing keystore internals * Generic local keystore internals * Restore deleted comment --- client/keystore/src/local.rs | 121 +++++++++------------ primitives/keystore/src/testing.rs | 164 +++++++++-------------------- 2 files changed, 95 insertions(+), 190 deletions(-) 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/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<(), ()> { From 14f1a3951d5a9de4dd3ae3ff83fd5ef66c4fbbe7 Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Thu, 30 Mar 2023 10:30:35 +0200 Subject: [PATCH 10/26] Application Crypto cleanup (#13746) * Adjust application crypto docs * Blanket implementation for 'RuntimeAppPublic' trait * Blanket implementation for 'BoundToRuntimeAppPublic' for 'RuntimeAppPublic' * Relax type bounds * Docs fix * restore MaybeHash * Commit suggestion Co-authored-by: Anton --------- Co-authored-by: Anton --- primitives/application-crypto/src/ecdsa.rs | 8 +- primitives/application-crypto/src/ed25519.rs | 8 +- primitives/application-crypto/src/lib.rs | 100 +++++++------------ primitives/application-crypto/src/sr25519.rs | 8 +- primitives/application-crypto/src/traits.rs | 69 +++++++++---- primitives/core/src/crypto.rs | 2 +- primitives/runtime/src/testing.rs | 7 +- 7 files changed, 91 insertions(+), 111 deletions(-) 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/src/crypto.rs b/primitives/core/src/crypto.rs index 0f86abf8671ad..f77e952d84546 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -482,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/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; From 44998291834b3a36a11c8dede63ce60362f1a3a5 Mon Sep 17 00:00:00 2001 From: Aaro Altonen <48052676+altonen@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:59:58 +0300 Subject: [PATCH 11/26] Attempt to relieve pressure on `mpsc_network_worker` (#13725) * Attempt to relieve pressure on `mpsc_network_worker` `SyncingEngine` interacting with `NetworkWorker` can put a lot of strain on the channel if the number of inbound connections is high. This is because `SyncingEngine` is notified of each inbound substream which it then can either accept or reject and this causes a lot of message exchange on the already busy channel. Use a direct channel pair between `Protocol` and `SyncingEngine` to exchange notification events. It is a temporary change to alleviate the problems caused by syncing being an independent protocol and the fix will be removed once `NotificationService` is implemented. * Apply review comments * fixes * trigger ci * Fix tests Verify that both peers have a connection now that the validation goes through `SyncingEngine`. Depending on how the tasks are scheduled, one of them might not have the peer registered in `SyncingEngine` at which point the test won't make any progress because block announcement received from an unknown peer is discarded. Move polling of `ChainSync` at the end of the function so that if a block announcement causes a block request to be sent, that can be sent in the same call to `SyncingEngine::poll()`. --------- Co-authored-by: parity-processbot <> --- Cargo.lock | 1 + client/network/src/config.rs | 11 +- client/network/src/event.rs | 47 ++++++- client/network/src/lib.rs | 6 +- client/network/src/protocol.rs | 108 +++++++++++++--- client/network/src/service.rs | 6 +- client/network/sync/src/engine.rs | 199 +++++++++++++---------------- client/network/test/Cargo.toml | 1 + client/network/test/src/lib.rs | 12 +- client/network/test/src/service.rs | 6 +- client/network/test/src/sync.rs | 2 +- client/service/src/builder.rs | 13 +- 12 files changed, 259 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a49f8fc4208a2..7fd0122f3cc0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9128,6 +9128,7 @@ dependencies = [ "sc-network-light", "sc-network-sync", "sc-service", + "sc-utils", "sp-blockchain", "sp-consensus", "sp-consensus-babe", 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/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( From 9b8e6e780352051029b0fdc56fcac5074bd74552 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Thu, 30 Mar 2023 14:53:47 +0200 Subject: [PATCH 12/26] [Enhancement] Throw an error when there are too many pallets (#13763) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Enhancement] Throw an error when there are too many pallets * fix ui test * fix PR comments * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Bastian Köcher * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Bastian Köcher * ".git/.scripts/commands/fmt/fmt.sh" --------- Co-authored-by: Bastian Köcher Co-authored-by: command-bot <> --- .../procedural/src/construct_runtime/mod.rs | 40 ++++- .../number_of_pallets_exceeds_tuple_size.rs | 169 ++++++++++++++++++ ...umber_of_pallets_exceeds_tuple_size.stderr | 61 +++++++ 3 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.rs create mode 100644 frame/support/test/tests/construct_runtime_ui/number_of_pallets_exceeds_tuple_size.stderr 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; + | From a0468b335a4bb57ad83d6b0a19a8088ec1319eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 30 Mar 2023 16:20:12 +0200 Subject: [PATCH 13/26] Build wasm for mvp cpu (#13758) --- utils/wasm-builder/src/wasm_project.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index a3038c4e934c9..d25fb4acd2345 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 link-arg=--export-table {} {}", default_rustflags, env::var(crate::WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(), ); From 025325d0c2c478a6f27789408ecaabaf8b9e8680 Mon Sep 17 00:00:00 2001 From: Adrian Catangiu Date: Thu, 30 Mar 2023 17:23:36 +0300 Subject: [PATCH 14/26] BEEFY: gossip finality proofs (#13727) * sc-consensus-beefy: add justifications to gossip protocol * sc-consensus-beefy: voter gossips finality proofs * sc-consensus-beefy: add finality proof gossip test * sc-consensus-beefy: always gossip finality proof Gossip finality proof in _both_ cases of reaching finality threshold through votes: 1. threshold reached through self vote, 2. threshold reached through incoming vote. * address comments --- .../beefy/src/communication/gossip.rs | 516 +++++++++++++----- .../consensus/beefy/src/communication/mod.rs | 6 +- client/consensus/beefy/src/justification.rs | 16 +- client/consensus/beefy/src/lib.rs | 2 +- client/consensus/beefy/src/round.rs | 38 +- client/consensus/beefy/src/tests.rs | 176 +++++- client/consensus/beefy/src/worker.rs | 94 +++- 7 files changed, 642 insertions(+), 206 deletions(-) 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; } }, From 4c7866a0df02e1c45fb4b5f473b2265a6bdb5465 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:50:45 +0200 Subject: [PATCH 15/26] Fix nomiantion pools doc render (#13748) Co-authored-by: parity-processbot <> --- frame/nomination-pools/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index cfde05ffeeabe..e7c99e023289b 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 From ee38a52d9ea643e4eec1e954b0b603aea4461416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 30 Mar 2023 21:31:08 +0200 Subject: [PATCH 16/26] sp-runtime-interface-test: Fix flaky test (#13770) --- primitives/runtime-interface/test/src/lib.rs | 105 +++++++++++-------- 1 file changed, 64 insertions(+), 41 deletions(-) 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] From 4bf67fb3dc0f095e4210b5ebc5f1f2ea24bf36c0 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Thu, 30 Mar 2023 18:01:50 -0300 Subject: [PATCH 17/26] bump zombienet version (#13772) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c9b68bca1ea09..470ce2ce3180e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -56,7 +56,7 @@ variables: 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: From de4cca40b5da41e76c111c66229521f1052ea298 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 31 Mar 2023 13:03:56 +0200 Subject: [PATCH 18/26] [Contracts] Overflowing bounded `DeletionQueue` allows DoS against contract termination (#13702) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Contracts review] Overflowing bounded `DeletionQueue` allows DoS against contract termination * wip * wip * wip * wip * wip * fix doc * wip * PR review * unbreak tests * fixes * update budget computation * PR comment: use BlockWeights::get().max_block * PR comment: Update queue_trie_for_deletion signature * PR comment: update deletion budget docstring * PR comment: impl Default with derive(DefaultNoBound) * PR comment: Remove DeletedContract * PR comment Add ring_buffer test * remove missed comment * misc comments * contracts: add sr25519_recover * Revert "contracts: add sr25519_recover" This reverts commit d4600e00934b90e5882cf5288f36f98911b51722. * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * PR comments update print_schedule * Update frame/contracts/src/benchmarking/mod.rs * Update frame/contracts/src/storage.rs * Update frame/contracts/src/storage.rs * rm temporary fixes * fix extra ; * Update frame/contracts/src/storage.rs Co-authored-by: juangirini * Update frame/contracts/src/storage.rs Co-authored-by: Alexander Theißen * Update frame/contracts/src/lib.rs Co-authored-by: Alexander Theißen * Update frame/contracts/src/lib.rs Co-authored-by: Alexander Theißen * Support stable rust for compiling the runtime (#13580) * Support stable rust for compiling the runtime This pull request brings support for compiling the runtime with stable Rust. This requires at least rust 1.68.0 to work on stable. The code is written in a way that it is backwards compatible and should automatically work when someone compiles with 1.68.0+ stable. * We always support nightlies! * :facepalm: * Sort by version * Review feedback * Review feedback * Fix version parsing * Apply suggestions from code review Co-authored-by: Koute --------- Co-authored-by: Koute * github PR commit fixes * Revert "Support stable rust for compiling the runtime (#13580)" This reverts commit 0b985aa5ad114a42003519b712d25a6acc40b0ad. * Restore DeletionQueueMap * fix namings * PR comment * move comments * Update frame/contracts/src/storage.rs * Update frame/contracts/src/storage.rs * fixes --------- Co-authored-by: command-bot <> Co-authored-by: juangirini Co-authored-by: Alexander Theißen Co-authored-by: Bastian Köcher Co-authored-by: Koute --- bin/node/runtime/src/lib.rs | 9 - frame/contracts/src/benchmarking/mod.rs | 26 +- frame/contracts/src/exec.rs | 2 +- frame/contracts/src/lib.rs | 65 +- frame/contracts/src/storage.rs | 154 +- frame/contracts/src/tests.rs | 153 +- frame/contracts/src/weights.rs | 1885 +++++++++++------------ 7 files changed, 1118 insertions(+), 1176 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 48bea5ddc101f..5562dc263ddc8 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1198,13 +1198,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 +1220,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/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..beaec458e36f7 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; @@ -1972,25 +1970,6 @@ fn lazy_removal_works() { }); } -#[test] -fn lazy_removal_on_full_queue_works_on_initialize() { - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Fill the deletion queue with dummy values, so that on_initialize attempts - // to clear the queue - ContractInfo::::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 +2033,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 +2118,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 +2161,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 +2211,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 +2266,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())) } } From a7bc9c2a8c0a14fd6033de1f972a11a2b3dbb73a Mon Sep 17 00:00:00 2001 From: asynchronous rob Date: Fri, 31 Mar 2023 05:00:07 -0700 Subject: [PATCH 19/26] Refactor: extract most aura logic out to standalone module, make use of these (#13764) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Extract most aura logic out to standalone module, make use of these * Update client/consensus/aura/src/standalone.rs improve docs Co-authored-by: Bastian Köcher * add slot_duration_at * ".git/.scripts/commands/fmt/fmt.sh" --------- Co-authored-by: Bastian Köcher Co-authored-by: parity-processbot <> --- client/consensus/aura/src/import_queue.rs | 46 ++- client/consensus/aura/src/lib.rs | 127 +------- client/consensus/aura/src/standalone.rs | 357 ++++++++++++++++++++++ 3 files changed, 393 insertions(+), 137 deletions(-) create mode 100644 client/consensus/aura/src/standalone.rs 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() + ] + ); + } +} From 75dee3c6fc72f6399a43f498e0e42f94fb82a7bd Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 31 Mar 2023 19:44:29 +0200 Subject: [PATCH 20/26] contracts: make test work with debugger (#13776) * contracts: make test work with debugger * fix path * PR review * Add comment * space * Update frame/contracts/src/tests.rs * lint * spelling --- frame/contracts/src/tests.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index beaec458e36f7..bae6c1946e183 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -456,7 +456,14 @@ fn compile_module(fixture_name: &str) -> wat::Result<(Vec, Date: Sat, 1 Apr 2023 18:19:12 +0100 Subject: [PATCH 21/26] add claim_commission weight (#13774) --- frame/nomination-pools/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/nomination-pools/src/lib.rs b/frame/nomination-pools/src/lib.rs index e7c99e023289b..78f0c730ce5dd 100644 --- a/frame/nomination-pools/src/lib.rs +++ b/frame/nomination-pools/src/lib.rs @@ -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) From d6f278b9685ac871c79e45551b66111b77cb1b71 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 1 Apr 2023 23:59:37 +0200 Subject: [PATCH 22/26] FRAME: Minor fix for failsafe. (#13741) * max instead of min * Remove debug stuff * remove debug code * warn log on no provider ref * format string for log --------- Co-authored-by: muharem --- frame/balances/src/lib.rs | 7 ++++++- frame/nis/src/lib.rs | 9 ++------- 2 files changed, 8 insertions(+), 8 deletions(-) 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/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 { From db40c484953a17a1eefb92ee743415749892a727 Mon Sep 17 00:00:00 2001 From: Damian Straszak Date: Mon, 3 Apr 2023 10:36:28 +0200 Subject: [PATCH 23/26] Adjustments to RPC-query docstrings. (#13698) * Changes in RPC docs. * ".git/.scripts/commands/fmt/fmt.sh" --------- Co-authored-by: command-bot <> --- client/rpc-api/src/state/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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, From be9fa62238fcfd7eb49218809a6b981f71c34eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 3 Apr 2023 11:37:18 +0200 Subject: [PATCH 24/26] Force upgrade snow to 0.9.2 (#13806) This fixes the compilation on master for the node template that was not pulling the latest release as part of its build. --- Cargo.lock | 11 ++++++----- client/network/Cargo.toml | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fd0122f3cc0f..1e9a87e818641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1473,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", @@ -8955,6 +8955,7 @@ dependencies = [ "serde", "serde_json", "smallvec", + "snow", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -10034,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", 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" From b94d98bfcb167c80a96a748955671a60ce09360d Mon Sep 17 00:00:00 2001 From: Muharem Ismailov Date: Mon, 3 Apr 2023 12:59:01 +0200 Subject: [PATCH 25/26] Scheduler pre block limit note (#13231) Co-authored-by: parity-processbot <> --- bin/node/runtime/src/lib.rs | 3 +++ frame/referenda/src/lib.rs | 15 +++++++-------- frame/scheduler/src/lib.rs | 4 ++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5562dc263ddc8..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; 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; From dd45632f298db02f6946c906296bbf86a74f4f46 Mon Sep 17 00:00:00 2001 From: Koute Date: Mon, 3 Apr 2023 21:00:31 +0900 Subject: [PATCH 26/26] Disable `sign-ext` WASM feature when building runtimes (#13804) Co-authored-by: parity-processbot <> --- utils/wasm-builder/src/wasm_project.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index d25fb4acd2345..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 target-cpu=mvp -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(), );