From 3a279b9a7a14b6439d174179ed9a6d3f48e40a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 9 Nov 2020 14:33:45 +0100 Subject: [PATCH 001/163] Run polkadot companion tests with correct feature enabled (#7507) --- .maintain/gitlab/check_polkadot_companion_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 219af5001b0..73a5a36ff8a 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -91,4 +91,4 @@ cd polkadot # Test Polkadot pr or master branch with this Substrate commit. cargo update -p sp-io -time cargo test --all --release --verbose +time cargo test --all --release --verbose --features=real-overseer -- GitLab From e756e8339c3d1b532351ba893cd3ba9e763d87e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 9 Nov 2020 15:32:14 +0100 Subject: [PATCH 002/163] contracts: Add automated weights for wasm instructions (#7361) * pallet_contracts: Inline benchmark helper that is only used once * Move all max_* Schedule items into a new struct * Limit the number of globals a module can declare * The current limits are too high for wasmi to even execute * Limit the amount of parameters any wasm function is allowed to have * Limit the size the BrTable's immediate value * Add instruction benchmarks * Add new benchmarks to the schedule and make use of it * Add Benchmark Results generated by the bench bot * Add proc macro that implements `Debug` for `Schedule` * Add missing imports necessary for no_std build * Make the WeightDebug macro available for no_std In this case a dummy implementation is derived in order to not blow up the code size akin to the RuntimeDebug macro. * Rework instr_memory_grow benchmark to use only the maximum amount of pages allowed * Add maximum amount of memory when benching (seal_)call/instantiate * cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_contracts * Added utility benchmark that allows pretty printing of the real schedule * review: Add missing header to the proc-macro lib.rs * review: Clarify why #[allow(dead_code)] attribute is there * review: Fix pwasm-utils line * review: Fixup rand usage * review: Fix typo * review: Imported -> Exported * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs * contracts: Adapt to new weight structure * contracts: Fixup runtime WeightInfo * contracts: Remove unneeded fullpath of WeightInfo type * Apply suggestions from code review Co-authored-by: Andrew Jones * Fix typo in schedule.rs Co-authored-by: Andrew Jones * Fix docs in schedule.rs * Apply suggestions from code review Co-authored-by: Nikolay Volf * Don't publish proc-macro crate until 3.0.0 is ready * Optimize imports for less repetition * Break overlong line Co-authored-by: Parity Benchmarking Bot Co-authored-by: Andrew Jones Co-authored-by: Nikolay Volf --- Cargo.lock | 27 +- bin/node/runtime/src/lib.rs | 5 +- bin/node/runtime/src/weights/mod.rs | 18 - .../runtime/src/weights/pallet_contracts.rs | 294 ---- frame/contracts/Cargo.toml | 10 +- frame/contracts/proc-macro/Cargo.toml | 27 + frame/contracts/proc-macro/src/lib.rs | 142 ++ frame/contracts/src/benchmarking/code.rs | 259 +++- frame/contracts/src/benchmarking/mod.rs | 901 +++++++++++- frame/contracts/src/benchmarking/sandbox.rs | 52 + frame/contracts/src/lib.rs | 8 +- frame/contracts/src/schedule.rs | 418 +++++- frame/contracts/src/wasm/mod.rs | 17 +- frame/contracts/src/wasm/prepare.rs | 192 ++- frame/contracts/src/wasm/runtime.rs | 13 +- frame/contracts/src/weight_info.rs | 341 ----- frame/contracts/src/weights.rs | 1267 +++++++++++++++++ 17 files changed, 3150 insertions(+), 841 deletions(-) delete mode 100644 bin/node/runtime/src/weights/mod.rs delete mode 100644 bin/node/runtime/src/weights/pallet_contracts.rs create mode 100644 frame/contracts/proc-macro/Cargo.toml create mode 100644 frame/contracts/proc-macro/src/lib.rs create mode 100644 frame/contracts/src/benchmarking/sandbox.rs delete mode 100644 frame/contracts/src/weight_info.rs create mode 100644 frame/contracts/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 0da8f25b224..aff2c999176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4472,13 +4472,16 @@ dependencies = [ "hex-literal", "pallet-balances", "pallet-contracts-primitives", + "pallet-contracts-proc-macro", "pallet-randomness-collective-flip", "pallet-timestamp", "parity-scale-codec", "parity-wasm 0.41.0", "paste 1.0.0", "pretty_assertions", - "pwasm-utils", + "pwasm-utils 0.16.0", + "rand 0.7.3", + "rand_pcg 0.2.1", "serde", "sp-core", "sp-io", @@ -4499,6 +4502,15 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-contracts-proc-macro" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pallet-contracts-rpc" version = "0.8.0" @@ -5835,6 +5847,17 @@ dependencies = [ "parity-wasm 0.41.0", ] +[[package]] +name = "pwasm-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c8ac87af529432d3a4f0e2b3bbf08af49f28f09cc73ed7e551161bdaef5f78d" +dependencies = [ + "byteorder", + "log", + "parity-wasm 0.41.0", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -6960,7 +6983,7 @@ dependencies = [ "log", "parity-scale-codec", "parity-wasm 0.41.0", - "pwasm-utils", + "pwasm-utils 0.14.0", "sc-executor-common", "scoped-tls", "sp-allocator", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index dddef0b46a8..bfa412e8820 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -87,9 +87,6 @@ pub mod constants; use constants::{time::*, currency::*}; use sp_runtime::generic::Era; -/// Weights for pallets used in the runtime. -mod weights; - // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -697,7 +694,7 @@ impl pallet_contracts::Trait for Runtime { type MaxDepth = pallet_contracts::DefaultMaxDepth; type MaxValueSize = pallet_contracts::DefaultMaxValueSize; type WeightPrice = pallet_transaction_payment::Module; - type WeightInfo = weights::pallet_contracts::WeightInfo; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; } impl pallet_sudo::Trait for Runtime { diff --git a/bin/node/runtime/src/weights/mod.rs b/bin/node/runtime/src/weights/mod.rs deleted file mode 100644 index 5de6286da9b..00000000000 --- a/bin/node/runtime/src/weights/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! A list of the different weight modules for our runtime. - -pub mod pallet_contracts; diff --git a/bin/node/runtime/src/weights/pallet_contracts.rs b/bin/node/runtime/src/weights/pallet_contracts.rs deleted file mode 100644 index 8cd97b4a721..00000000000 --- a/bin/node/runtime/src/weights/pallet_contracts.rs +++ /dev/null @@ -1,294 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2020 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. - -//! Weights for pallet_contracts -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-10-06, STEPS: [50], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] - -#![allow(unused_parens)] -#![allow(unused_imports)] - -use frame_support::{traits::Get, weights::Weight}; -use sp_std::marker::PhantomData; - -pub struct WeightInfo(PhantomData); -impl pallet_contracts::WeightInfo for WeightInfo { - fn update_schedule() -> Weight { - (33_207_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn put_code(n: u32, ) -> Weight { - (0 as Weight) - .saturating_add((144_833_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn instantiate(n: u32, ) -> Weight { - (223_974_000 as Weight) - .saturating_add((1_007_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn call() -> Weight { - (210_638_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn claim_surcharge() -> Weight { - (508_079_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn seal_caller(r: u32, ) -> Weight { - (143_336_000 as Weight) - .saturating_add((397_788_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_address(r: u32, ) -> Weight { - (147_296_000 as Weight) - .saturating_add((396_962_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_gas_left(r: u32, ) -> Weight { - (141_677_000 as Weight) - .saturating_add((393_308_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_balance(r: u32, ) -> Weight { - (157_556_000 as Weight) - .saturating_add((879_861_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } - fn seal_value_transferred(r: u32, ) -> Weight { - (148_867_000 as Weight) - .saturating_add((391_678_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_minimum_balance(r: u32, ) -> Weight { - (147_252_000 as Weight) - .saturating_add((393_977_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_tombstone_deposit(r: u32, ) -> Weight { - (144_208_000 as Weight) - .saturating_add((394_625_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_rent_allowance(r: u32, ) -> Weight { - (135_320_000 as Weight) - .saturating_add((925_541_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_block_number(r: u32, ) -> Weight { - (145_849_000 as Weight) - .saturating_add((390_065_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_now(r: u32, ) -> Weight { - (146_363_000 as Weight) - .saturating_add((391_772_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_weight_to_fee(r: u32, ) -> Weight { - (129_872_000 as Weight) - .saturating_add((670_744_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } - fn seal_gas(r: u32, ) -> Weight { - (130_985_000 as Weight) - .saturating_add((198_427_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_input(r: u32, ) -> Weight { - (138_647_000 as Weight) - .saturating_add((8_363_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_input_per_kb(n: u32, ) -> Weight { - (149_418_000 as Weight) - .saturating_add((272_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_return(r: u32, ) -> Weight { - (129_116_000 as Weight) - .saturating_add((5_745_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_return_per_kb(n: u32, ) -> Weight { - (139_601_000 as Weight) - .saturating_add((680_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_terminate(r: u32, ) -> Weight { - (138_548_000 as Weight) - .saturating_add((355_473_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) - } - fn seal_restore_to(r: u32, ) -> Weight { - (239_880_000 as Weight) - .saturating_add((138_305_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) - } - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (40_572_000 as Weight) - .saturating_add((3_748_632_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) - } - fn seal_random(r: u32, ) -> Weight { - (148_156_000 as Weight) - .saturating_add((1_036_452_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } - fn seal_deposit_event(r: u32, ) -> Weight { - (176_039_000 as Weight) - .saturating_add((1_497_705_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_923_547_000 as Weight) - .saturating_add((783_354_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((240_600_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) - } - fn seal_set_rent_allowance(r: u32, ) -> Weight { - (151_095_000 as Weight) - .saturating_add((1_104_696_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - fn seal_set_storage(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((14_975_467_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (2_465_724_000 as Weight) - .saturating_add((203_125_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn seal_clear_storage(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((5_254_595_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_get_storage(r: u32, ) -> Weight { - (60_303_000 as Weight) - .saturating_add((1_135_486_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (931_900_000 as Weight) - .saturating_add((144_572_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } - fn seal_transfer(r: u32, ) -> Weight { - (50_722_000 as Weight) - .saturating_add((6_701_164_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_call(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((10_589_747_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (11_223_388_000 as Weight) - .saturating_add((4_965_182_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((50_603_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((72_972_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(T::DbWeight::get().reads(105 as Weight)) - .saturating_add(T::DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) - .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) - } - fn seal_instantiate(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((22_933_938_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - .saturating_add(T::DbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) - } - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { - (20_986_307_000 as Weight) - .saturating_add((152_611_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((73_457_000 as Weight).saturating_mul(o as Weight)) - .saturating_add(T::DbWeight::get().reads(207 as Weight)) - .saturating_add(T::DbWeight::get().writes(202 as Weight)) - } - fn seal_hash_sha2_256(r: u32, ) -> Weight { - (145_988_000 as Weight) - .saturating_add((343_540_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (719_758_000 as Weight) - .saturating_add((420_306_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_keccak_256(r: u32, ) -> Weight { - (116_261_000 as Weight) - .saturating_add((360_601_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (583_726_000 as Weight) - .saturating_add((333_091_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_256(r: u32, ) -> Weight { - (144_609_000 as Weight) - .saturating_add((332_388_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (612_987_000 as Weight) - .saturating_add((150_030_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_128(r: u32, ) -> Weight { - (142_085_000 as Weight) - .saturating_add((329_426_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (632_517_000 as Weight) - .saturating_add((149_974_000 as Weight).saturating_mul(n as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } -} diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index 3c8ac89f5d0..67d9ae8101f 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -21,8 +21,9 @@ frame-benchmarking = { version = "2.0.0", default-features = false, path = "../b frame-support = { version = "2.0.0", default-features = false, path = "../support" } frame-system = { version = "2.0.0", default-features = false, path = "../system" } pallet-contracts-primitives = { version = "2.0.0", default-features = false, path = "common" } +pallet-contracts-proc-macro = { version = "0.1.0", path = "proc-macro" } parity-wasm = { version = "0.41.0", default-features = false } -pwasm-utils = { version = "0.14.0", default-features = false } +pwasm-utils = { version = "0.16", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } @@ -31,6 +32,10 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../primitives sp-sandbox = { version = "0.8.0", default-features = false, path = "../../primitives/sandbox" } wasmi-validation = { version = "0.3.0", default-features = false } +# Only used in benchmarking to generate random contract code +rand = { version = "0.7.0", optional = true, default-features = false } +rand_pcg = { version = "0.2.1", optional = true } + [dev-dependencies] assert_matches = "1.3.0" hex-literal = "0.3.1" @@ -57,7 +62,10 @@ std = [ "pwasm-utils/std", "wasmi-validation/std", "pallet-contracts-primitives/std", + "pallet-contracts-proc-macro/full", ] runtime-benchmarks = [ "frame-benchmarking", + "rand", + "rand_pcg", ] diff --git a/frame/contracts/proc-macro/Cargo.toml b/frame/contracts/proc-macro/Cargo.toml new file mode 100644 index 00000000000..56ef8553355 --- /dev/null +++ b/frame/contracts/proc-macro/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "pallet-contracts-proc-macro" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Procedural macros used in pallet_contracts" +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = "1" + +[dev-dependencies] + +[features] +# If set the full output is generated. Do NOT set when generating for wasm runtime. +full = [] diff --git a/frame/contracts/proc-macro/src/lib.rs b/frame/contracts/proc-macro/src/lib.rs new file mode 100644 index 00000000000..4e38508297d --- /dev/null +++ b/frame/contracts/proc-macro/src/lib.rs @@ -0,0 +1,142 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Proc macros used in the contracts module. + +#![no_std] + +extern crate alloc; + +use proc_macro2::TokenStream; +use quote::{quote, quote_spanned}; +use syn::spanned::Spanned; +use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields, Ident}; +use alloc::string::ToString; + +/// This derives `Debug` for a struct where each field must be of some numeric type. +/// It interprets each field as its represents some weight and formats it as times so that +/// it is readable by humans. +#[proc_macro_derive(WeightDebug)] +pub fn derive_weight_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + derive_debug(input, format_weight) +} + +/// This is basically identical to the std libs Debug derive but without adding any +/// bounds to existing generics. +#[proc_macro_derive(ScheduleDebug)] +pub fn derive_schedule_debug(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + derive_debug(input, format_default) +} + +fn derive_debug( + input: proc_macro::TokenStream, + fmt: impl Fn(&Ident) -> TokenStream +) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let data = if let Data::Struct(data) = &input.data { + data + } else { + return quote_spanned! { + name.span() => + compile_error!("WeightDebug is only supported for structs."); + }.into(); + }; + + #[cfg(feature = "full")] + let fields = iterate_fields(data, fmt); + + #[cfg(not(feature = "full"))] + let fields = { + drop(fmt); + drop(data); + TokenStream::new() + }; + + let tokens = quote! { + impl #impl_generics core::fmt::Debug for #name #ty_generics #where_clause { + fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + use ::sp_runtime::{FixedPointNumber, FixedU128 as Fixed}; + let mut formatter = formatter.debug_struct(stringify!(#name)); + #fields + formatter.finish() + } + } + }; + + tokens.into() +} + +/// This is only used then the `full` feature is activated. +#[cfg(feature = "full")] +fn iterate_fields(data: &DataStruct, fmt: impl Fn(&Ident) -> TokenStream) -> TokenStream { + match &data.fields { + Fields::Named(fields) => { + let recurse = fields.named + .iter() + .filter_map(|f| { + let name = f.ident.as_ref()?; + if name.to_string().starts_with('_') { + return None; + } + let value = fmt(name); + let ret = quote_spanned!{ f.span() => + formatter.field(stringify!(#name), #value); + }; + Some(ret) + }); + quote!{ + #( #recurse )* + } + } + Fields::Unnamed(fields) => quote_spanned!{ + fields.span() => + compile_error!("Unnamed fields are not supported") + }, + Fields::Unit => quote!(), + } +} + +fn format_weight(field: &Ident) -> TokenStream { + quote_spanned! { field.span() => + &if self.#field > 1_000_000_000 { + format!( + "{:.1?} ms", + Fixed::saturating_from_rational(self.#field, 1_000_000_000).to_fraction() + ) + } else if self.#field > 1_000_000 { + format!( + "{:.1?} µs", + Fixed::saturating_from_rational(self.#field, 1_000_000).to_fraction() + ) + } else if self.#field > 1_000 { + format!( + "{:.1?} ns", + Fixed::saturating_from_rational(self.#field, 1_000).to_fraction() + ) + } else { + format!("{} ps", self.#field) + } + } +} + +fn format_default(field: &Ident) -> TokenStream { + quote_spanned! { field.span() => + &self.#field + } +} diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index dc3730e95ca..cb5052042aa 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -28,28 +28,50 @@ use crate::Trait; use crate::Module as Contracts; use parity_wasm::elements::{Instruction, Instructions, FuncBody, ValueType, BlockType}; +use pwasm_utils::stack_height::inject_limiter; use sp_runtime::traits::Hash; +use sp_sandbox::{EnvironmentDefinitionBuilder, Memory}; use sp_std::{prelude::*, convert::TryFrom}; /// Pass to `create_code` in order to create a compiled `WasmModule`. +/// +/// This exists to have a more declarative way to describe a wasm module than to use +/// parity-wasm directly. It is tailored to fit the structure of contracts that are +/// needed for benchmarking. +#[derive(Default)] pub struct ModuleDefinition { - pub data_segments: Vec, + /// Imported memory attached to the module. No memory is imported if `None`. pub memory: Option, + /// Initializers for the imported memory. + pub data_segments: Vec, + /// Creates the supplied amount of i64 mutable globals initialized with random values. + pub num_globals: u32, + /// List of functions that the module should import. They start with index 0. pub imported_functions: Vec, + /// Function body of the exported `deploy` function. Body is empty if `None`. + /// Its index is `imported_functions.len()`. pub deploy_body: Option, + /// Function body of the exported `call` function. Body is empty if `None`. + /// Its index is `imported_functions.len() + 1`. pub call_body: Option, + /// Function body of a non-exported function with index `imported_functions.len() + 2`. + pub aux_body: Option, + /// The amount of I64 arguments the aux function should have. + pub aux_arg_num: u32, + /// If set to true the stack height limiter is injected into the the module. This is + /// needed for instruction debugging because the cost of executing the stack height + /// instrumentation should be included in the costs for the individual instructions + /// that cause more metering code (only call). + pub inject_stack_metering: bool, + /// Create a table containing function pointers. + pub table: Option, } -impl Default for ModuleDefinition { - fn default() -> Self { - Self { - data_segments: vec![], - memory: None, - imported_functions: vec![], - deploy_body: None, - call_body: None, - } - } +pub struct TableSegment { + /// How many elements should be created inside the table. + pub num_elements: u32, + /// The function index with which all table elements should be initialized. + pub function_index: u32, } pub struct DataSegment { @@ -57,6 +79,7 @@ pub struct DataSegment { pub value: Vec, } +#[derive(Clone)] pub struct ImportedMemory { pub min_pages: u32, pub max_pages: u32, @@ -80,6 +103,7 @@ pub struct ImportedFunction { pub struct WasmModule { pub code: Vec, pub hash: ::Output, + memory: Option, } impl From for WasmModule { @@ -91,14 +115,14 @@ impl From for WasmModule { let mut contract = parity_wasm::builder::module() // deploy function (first internal function) .function() - .signature().with_params(vec![]).with_return_type(None).build() + .signature().with_return_type(None).build() .with_body(def.deploy_body.unwrap_or_else(|| FuncBody::new(Vec::new(), Instructions::empty()) )) .build() // call function (second internal function) .function() - .signature().with_params(vec![]).with_return_type(None).build() + .signature().with_return_type(None).build() .with_body(def.call_body.unwrap_or_else(|| FuncBody::new(Vec::new(), Instructions::empty()) )) @@ -106,8 +130,19 @@ impl From for WasmModule { .export().field("deploy").internal().func(func_offset).build() .export().field("call").internal().func(func_offset + 1).build(); + // If specified we add an additional internal function + if let Some(body) = def.aux_body { + let mut signature = contract + .function() + .signature().with_return_type(None); + for _ in 0 .. def.aux_arg_num { + signature = signature.with_param(ValueType::I64); + } + contract = signature.build().with_body(body).build(); + } + // Grant access to linear memory. - if let Some(memory) = def.memory { + if let Some(memory) = &def.memory { contract = contract.import() .module("env").field("memory") .external().memory(memory.min_pages, Some(memory.max_pages)) @@ -136,20 +171,69 @@ impl From for WasmModule { .build() } - let code = contract.build().to_bytes().unwrap(); + // Add global variables + if def.num_globals > 0 { + use rand::{prelude::*, distributions::Standard}; + let rng = rand_pcg::Pcg32::seed_from_u64(3112244599778833558); + for val in rng.sample_iter(Standard).take(def.num_globals as usize) { + contract = contract + .global() + .value_type().i64() + .mutable() + .init_expr(Instruction::I64Const(val)) + .build() + } + } + + // Add function pointer table + if let Some(table) = def.table { + contract = contract + .table() + .with_min(table.num_elements) + .with_max(Some(table.num_elements)) + .with_element(0, vec![table.function_index; table.num_elements as usize]) + .build(); + } + + let mut code = contract.build(); + + // Inject stack height metering + if def.inject_stack_metering { + code = inject_limiter( + code, + Contracts::::current_schedule().limits.stack_height + ) + .unwrap(); + } + + let code = code.to_bytes().unwrap(); let hash = T::Hashing::hash(&code); Self { code, - hash + hash, + memory: def.memory, } } } impl WasmModule { + /// Creates a wasm module with an empty `call` and `deploy` function and nothing else. pub fn dummy() -> Self { ModuleDefinition::default().into() } + /// Same as `dummy` but with maximum sized linear memory. + pub fn dummy_with_mem() -> Self { + ModuleDefinition { + memory: Some(ImportedMemory::max::()), + .. Default::default() + } + .into() + } + + /// Creates a wasm module of `target_bytes` size. Used to benchmark the performance of + /// `put_code` for different sizes of wasm modules. The generated module maximizes + /// instrumentation runtime by nesting blocks as deeply as possible given the byte budget. pub fn sized(target_bytes: u32) -> Self { use parity_wasm::elements::Instruction::{If, I32Const, Return, End}; // Base size of a contract is 47 bytes and each expansion adds 6 bytes. @@ -171,6 +255,9 @@ impl WasmModule { .into() } + /// Creates a wasm module that calls the imported function named `getter_name` `repeat` + /// times. The imported function is expected to have the "getter signature" of + /// (out_ptr: u32, len_ptr: u32) -> (). pub fn getter(getter_name: &'static str, repeat: u32) -> Self { let pages = max_pages::(); ModuleDefinition { @@ -198,11 +285,14 @@ impl WasmModule { .into() } + /// Creates a wasm module that calls the imported hash function named `name` `repeat` times + /// with an input of size `data_size`. Hash functions have the signature + /// (input_ptr: u32, input_len: u32, output_ptr: u32) -> () pub fn hasher(name: &'static str, repeat: u32, data_size: u32) -> Self { ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { - name: name, + name, params: vec![ValueType::I32, ValueType::I32, ValueType::I32], return_type: None, }], @@ -216,16 +306,84 @@ impl WasmModule { } .into() } + + /// Creates a memory instance for use in a sandbox with dimensions declared in this module + /// and adds it to `env`. A reference to that memory is returned so that it can be used to + /// access the memory contents from the supervisor. + pub fn add_memory(&self, env: &mut EnvironmentDefinitionBuilder) -> Option { + let memory = if let Some(memory) = &self.memory { + memory + } else { + return None; + }; + let memory = Memory::new(memory.min_pages, Some(memory.max_pages)).unwrap(); + env.add_memory("env", "memory", memory.clone()); + Some(memory) + } + + pub fn unary_instr(instr: Instruction, repeat: u32) -> Self { + use body::DynInstr::{RandomI64Repeated, Regular}; + ModuleDefinition { + call_body: Some(body::repeated_dyn(repeat, vec![ + RandomI64Repeated(1), + Regular(instr), + Regular(Instruction::Drop), + ])), + .. Default::default() + }.into() + } + + pub fn binary_instr(instr: Instruction, repeat: u32) -> Self { + use body::DynInstr::{RandomI64Repeated, Regular}; + ModuleDefinition { + call_body: Some(body::repeated_dyn(repeat, vec![ + RandomI64Repeated(2), + Regular(instr), + Regular(Instruction::Drop), + ])), + .. Default::default() + }.into() + } } -/// Mechanisms to create a function body that can be used inside a `ModuleDefinition`. +/// Mechanisms to generate a function body that can be used inside a `ModuleDefinition`. pub mod body { use super::*; - pub enum CountedInstruction { - // (offset, increment_by) - Counter(u32, u32), + /// When generating contract code by repeating a wasm sequence, it's sometimes necessary + /// to change those instructions on each repetition. The variants of this enum describe + /// various ways in which this can happen. + pub enum DynInstr { + /// Insert the associated instruction. Regular(Instruction), + /// Insert a I32Const with incrementing value for each insertion. + /// (start_at, increment_by) + Counter(u32, u32), + /// Insert a I32Const with a random value in [low, high) not divisible by two. + /// (low, high) + RandomUnaligned(u32, u32), + /// Insert a I32Const with a random value in [low, high). + /// (low, high) + RandomI32(i32, i32), + /// Insert the specified amount of I32Const with a random value. + RandomI32Repeated(usize), + /// Insert the specified amount of I64Const with a random value. + RandomI64Repeated(usize), + /// Insert a GetLocal with a random offset in [low, high). + /// (low, high) + RandomGetLocal(u32, u32), + /// Insert a SetLocal with a random offset in [low, high). + /// (low, high) + RandomSetLocal(u32, u32), + /// Insert a TeeLocal with a random offset in [low, high). + /// (low, high) + RandomTeeLocal(u32, u32), + /// Insert a GetGlobal with a random offset in [low, high). + /// (low, high) + RandomGetGlobal(u32, u32), + /// Insert a SetGlobal with a random offset in [low, high). + /// (low, high) + RandomSetGlobal(u32, u32) } pub fn plain(instructions: Vec) -> FuncBody { @@ -245,28 +403,73 @@ pub mod body { FuncBody::new(Vec::new(), instructions) } - pub fn counted(repetitions: u32, mut instructions: Vec) -> FuncBody { + pub fn repeated_dyn(repetitions: u32, mut instructions: Vec) -> FuncBody { + use rand::{prelude::*, distributions::Standard}; + + // We do not need to be secure here. + let mut rng = rand_pcg::Pcg32::seed_from_u64(8446744073709551615); + // We need to iterate over indices because we cannot cycle over mutable references let body = (0..instructions.len()) .cycle() .take(instructions.len() * usize::try_from(repetitions).unwrap()) - .map(|idx| { + .flat_map(|idx| match &mut instructions[idx] { - CountedInstruction::Counter(offset, increment_by) => { + DynInstr::Regular(instruction) => vec![instruction.clone()], + DynInstr::Counter(offset, increment_by) => { let current = *offset; *offset += *increment_by; - Instruction::I32Const(current as i32) + vec![Instruction::I32Const(current as i32)] + }, + DynInstr::RandomUnaligned(low, high) => { + let unaligned = rng.gen_range(*low, *high) | 1; + vec![Instruction::I32Const(unaligned as i32)] + }, + DynInstr::RandomI32(low, high) => { + vec![Instruction::I32Const(rng.gen_range(*low, *high))] + }, + DynInstr::RandomI32Repeated(num) => { + (&mut rng).sample_iter(Standard).take(*num).map(|val| + Instruction::I32Const(val) + ) + .collect() + }, + DynInstr::RandomI64Repeated(num) => { + (&mut rng).sample_iter(Standard).take(*num).map(|val| + Instruction::I64Const(val) + ) + .collect() + }, + DynInstr::RandomGetLocal(low, high) => { + vec![Instruction::GetLocal(rng.gen_range(*low, *high))] + }, + DynInstr::RandomSetLocal(low, high) => { + vec![Instruction::SetLocal(rng.gen_range(*low, *high))] + }, + DynInstr::RandomTeeLocal(low, high) => { + vec![Instruction::TeeLocal(rng.gen_range(*low, *high))] + }, + DynInstr::RandomGetGlobal(low, high) => { + vec![Instruction::GetGlobal(rng.gen_range(*low, *high))] + }, + DynInstr::RandomSetGlobal(low, high) => { + vec![Instruction::SetGlobal(rng.gen_range(*low, *high))] }, - CountedInstruction::Regular(instruction) => instruction.clone(), } - }) + ) .chain(sp_std::iter::once(Instruction::End)) .collect(); FuncBody::new(Vec::new(), Instructions::new(body)) } + + /// Replace the locals of the supplied `body` with `num` i64 locals. + pub fn inject_locals(body: &mut FuncBody, num: u32) { + use parity_wasm::elements::Local; + *body.locals_mut() = (0..num).map(|i| Local::new(i, ValueType::I64)).collect() + } } /// The maximum amount of pages any contract is allowed to have according to the current `Schedule`. pub fn max_pages() -> u32 { - Contracts::::current_schedule().max_memory_pages + Contracts::::current_schedule().limits.memory_pages } diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index 79863afc441..dd9e89d6f35 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -20,25 +20,33 @@ #![cfg(feature = "runtime-benchmarks")] mod code; +mod sandbox; -use crate::*; -use crate::Module as Contracts; -use crate::exec::StorageKey; -use crate::schedule::API_BENCHMARK_BATCH_SIZE; -use self::code::{ - body, ModuleDefinition, DataSegment, ImportedMemory, ImportedFunction, WasmModule, +use crate::{ + *, Module as Contracts, + exec::StorageKey, + schedule::{API_BENCHMARK_BATCH_SIZE, INSTR_BENCHMARK_BATCH_SIZE}, +}; +use self::{ + code::{ + body::{self, DynInstr::*}, + ModuleDefinition, DataSegment, ImportedMemory, ImportedFunction, WasmModule, + }, + sandbox::Sandbox, }; - use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use frame_system::{Module as System, RawOrigin}; use parity_wasm::elements::{Instruction, ValueType, BlockType}; use sp_runtime::traits::{Hash, Bounded}; -use sp_std::{default::Default, convert::{TryInto}}; +use sp_std::{default::Default, convert::{TryInto}, vec::Vec, vec}; use pallet_contracts_primitives::RentProjection; /// How many batches we do per API benchmark. const API_BENCHMARK_BATCHES: u32 = 20; +/// How many batches we do per Instruction benchmark. +const INSTR_BENCHMARK_BATCHES: u32 = 1; + /// An instantiated and deployed contract. struct Contract { caller: T::AccountId, @@ -116,7 +124,14 @@ impl Contract { }; T::Currency::make_free_balance_be(&caller, caller_funding::()); let addr = T::DetermineContractAddress::contract_address_for(&module.hash, &data, &caller); - init_block_number::(); + + // The default block number is zero. The benchmarking system bumps the block number + // to one for the benchmarking closure when it is set to zero. In order to prevent this + // undesired implicit bump (which messes with rent collection), we do the bump ourselves + // in the setup closure so that both the instantiate and subsequent call are run with the + // same block number. + System::::set_block_number(1u32.into()); + Contracts::::put_code_raw(module.code)?; Contracts::::instantiate( RawOrigin::Signed(caller.clone()).into(), @@ -234,17 +249,6 @@ fn caller_funding() -> BalanceOf { BalanceOf::::max_value() / 2u32.into() } -/// Set the block number to one. -/// -/// The default block number is zero. The benchmarking system bumps the block number -/// to one for the benchmarking closure when it is set to zero. In order to prevent this -/// undesired implicit bump (which messes with rent collection), wo do the bump ourselfs -/// in the setup closure so that both the instantiate and subsequent call are run with the -/// same block number. -fn init_block_number() { - System::::set_block_number(1u32.into()); -} - benchmarks! { _ { } @@ -261,7 +265,7 @@ benchmarks! { // It creates a maximum number of metering blocks per byte. // `n`: Size of the code in kilobytes. put_code { - let n in 0 .. Contracts::::current_schedule().max_code_size / 1024; + let n in 0 .. Contracts::::current_schedule().limits.code_size / 1024; let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let module = WasmModule::::sized(n * 1024); @@ -278,7 +282,7 @@ benchmarks! { let endowment = Config::::subsistence_threshold_uncached(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); - let WasmModule { code, hash } = WasmModule::::dummy(); + let WasmModule { code, hash, .. } = WasmModule::::dummy_with_mem(); let origin = RawOrigin::Signed(caller.clone()); let addr = T::DetermineContractAddress::contract_address_for(&hash, &data, &caller); Contracts::::put_code_raw(code)?; @@ -300,7 +304,7 @@ benchmarks! { call { let data = vec![42u8; 1024]; let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::dummy(), vec![], Endow::CollectRent + whitelisted_caller(), WasmModule::dummy_with_mem(), vec![], Endow::CollectRent )?; let value = T::Currency::minimum_balance() * 100u32.into(); let origin = RawOrigin::Signed(instance.caller.clone()); @@ -783,7 +787,7 @@ benchmarks! { seal_random { let r in 0 .. API_BENCHMARK_BATCHES; let pages = code::max_pages::(); - let subject_len = Contracts::::current_schedule().max_subject_len; + let subject_len = Contracts::::current_schedule().limits.subject_len; assert!(subject_len < 1024); let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), @@ -839,14 +843,13 @@ benchmarks! { // `t`: Number of topics // `n`: Size of event payload in kb seal_deposit_event_per_topic_and_kb { - let t in 0 .. Contracts::::current_schedule().max_event_topics; + let t in 0 .. Contracts::::current_schedule().limits.event_topics; let n in 0 .. T::MaxValueSize::get() / 1024; let mut topics = (0..API_BENCHMARK_BATCH_SIZE) .map(|n| (n * t..n * t + t).map(|i| T::Hashing::hash_of(&i)).collect::>().encode()) .peekable(); let topics_len = topics.peek().map(|i| i.len()).unwrap_or(0); let topics = topics.flatten().collect(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -860,7 +863,7 @@ benchmarks! { value: topics, }, ], - call_body: Some(body::counted(API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(API_BENCHMARK_BATCH_SIZE, vec![ Counter(0, topics_len as u32), // topics_ptr Regular(Instruction::I32Const(topics_len as i32)), // topics_len Regular(Instruction::I32Const(0)), // data_ptr @@ -911,7 +914,6 @@ benchmarks! { .flat_map(|n| T::Hashing::hash_of(&n).as_ref().to_vec()) .collect::>(); let key_len = sp_std::mem::size_of::<::Output>(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -925,7 +927,7 @@ benchmarks! { value: keys, }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(0, key_len as u32), // key_ptr Regular(Instruction::I32Const(0)), // value_ptr Regular(Instruction::I32Const(0)), // value_len @@ -976,7 +978,6 @@ benchmarks! { .collect::>(); let key_bytes = keys.iter().flatten().cloned().collect::>(); let key_len = sp_std::mem::size_of::<::Output>(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -990,7 +991,7 @@ benchmarks! { value: key_bytes, }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(0, key_len as u32), Regular(Instruction::Call(0)), ])), @@ -1019,7 +1020,6 @@ benchmarks! { let key_len = sp_std::mem::size_of::<::Output>(); let key_bytes = keys.iter().flatten().cloned().collect::>(); let key_bytes_len = key_bytes.len(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1033,7 +1033,7 @@ benchmarks! { value: key_bytes, }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(0, key_len as u32), // key_ptr Regular(Instruction::I32Const((key_bytes_len + 4) as i32)), // out_ptr Regular(Instruction::I32Const(key_bytes_len as i32)), // out_len_ptr @@ -1111,7 +1111,6 @@ benchmarks! { assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1129,7 +1128,7 @@ benchmarks! { value: account_bytes, }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(value_len as u32, account_len as u32), // account_ptr Regular(Instruction::I32Const(account_len as i32)), // account_len Regular(Instruction::I32Const(0)), // value_ptr @@ -1154,7 +1153,7 @@ benchmarks! { // We call unique accounts. seal_call { let r in 0 .. API_BENCHMARK_BATCHES; - let dummy_code = WasmModule::::dummy(); + let dummy_code = WasmModule::::dummy_with_mem(); let callees = (0..r * API_BENCHMARK_BATCH_SIZE) .map(|i| Contract::with_index(i + 1, dummy_code.clone(), vec![], Endow::Max)) .collect::, _>>()?; @@ -1163,7 +1162,6 @@ benchmarks! { let value: BalanceOf = 0u32.into(); let value_bytes = value.encode(); let value_len = value_bytes.len(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1191,7 +1189,7 @@ benchmarks! { value: callee_bytes, }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(value_len as u32, callee_len as u32), // callee_ptr Regular(Instruction::I32Const(callee_len as i32)), // callee_len Regular(Instruction::I64Const(0)), // gas @@ -1243,7 +1241,6 @@ benchmarks! { let value: BalanceOf = t.into(); let value_bytes = value.encode(); let value_len = value_bytes.len(); - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1275,7 +1272,7 @@ benchmarks! { value: (o * 1024).to_le_bytes().into(), }, ], - call_body: Some(body::counted(API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(API_BENCHMARK_BATCH_SIZE, vec![ Counter(value_len as u32, callee_len as u32), // callee_ptr Regular(Instruction::I32Const(callee_len as i32)), // callee_len Regular(Instruction::I64Const(0)), // gas @@ -1300,7 +1297,10 @@ benchmarks! { let hashes = (0..r * API_BENCHMARK_BATCH_SIZE) .map(|i| { let code = WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory::max::()), call_body: Some(body::plain(vec![ + // we need to add this in order to make contracts unique + // so that they can be deployed from the same sender Instruction::I32Const(i as i32), Instruction::Drop, Instruction::End, @@ -1326,7 +1326,6 @@ benchmarks! { let addr_len_offset = hashes_offset + hashes_len; let addr_offset = addr_len_offset + addr_len; - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1360,7 +1359,7 @@ benchmarks! { value: addr_len.to_le_bytes().into(), }, ], - call_body: Some(body::counted(r * API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(r * API_BENCHMARK_BATCH_SIZE, vec![ Counter(hashes_offset as u32, hash_len as u32), // code_hash_ptr Regular(Instruction::I32Const(hash_len as i32)), // code_hash_len Regular(Instruction::I64Const(0)), // gas @@ -1444,7 +1443,6 @@ benchmarks! { let output_len_offset = addr_len_offset + 4; let output_offset = output_len_offset + 4; - use body::CountedInstruction::{Counter, Regular}; let code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1486,7 +1484,7 @@ benchmarks! { value: (o * 1024).to_le_bytes().into(), }, ], - call_body: Some(body::counted(API_BENCHMARK_BATCH_SIZE, vec![ + call_body: Some(body::repeated_dyn(API_BENCHMARK_BATCH_SIZE, vec![ Regular(Instruction::I32Const(hash_offset as i32)), // code_hash_ptr Regular(Instruction::I32Const(hash_len as i32)), // code_hash_len Regular(Instruction::I64Const(0)), // gas @@ -1583,6 +1581,768 @@ benchmarks! { ), vec![], Endow::Max)?; let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![]) + + // We make the assumption that pushing a constant and dropping a value takes roughly + // the same amount of time. We follow that `t.load` and `drop` both have the weight + // of this benchmark / 2. We need to make this assumption because there is no way + // to measure them on their own using a valid wasm module. We need their individual + // values to derive the weight of individual instructions (by substraction) from + // benchmarks that include those for parameter pushing and return type dropping. + // We call the weight of `t.load` and `drop`: `w_param`. + // The weight that would result from the respective benchmark we call: `w_bench`. + // + // w_i{32,64}const = w_drop = w_bench / 2 + instr_i64const { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(1), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_i{32,64}load = w_bench - 2 * w_param + instr_i64load { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory::max::()), + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomUnaligned(0, code::max_pages::() * 64 * 1024 - 8), + Regular(Instruction::I64Load(3, 0)), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_i{32,64}store{...} = w_bench - 2 * w_param + instr_i64store { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory::max::()), + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomUnaligned(0, code::max_pages::() * 64 * 1024 - 8), + RandomI64Repeated(1), + Regular(Instruction::I64Store(3, 0)), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_select = w_bench - 4 * w_param + instr_select { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(1), + RandomI64Repeated(1), + RandomI32(0, 2), + Regular(Instruction::Select), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_if = w_bench - 3 * w_param + instr_if { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI32(0, 2), + Regular(Instruction::If(BlockType::Value(ValueType::I64))), + RandomI64Repeated(1), + Regular(Instruction::Else), + RandomI64Repeated(1), + Regular(Instruction::End), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_br = w_bench - 2 * w_param + instr_br { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Br(1)), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_br_if = w_bench - 5 * w_param + // The two additional pushes + drop are only executed 50% of the time. + // Making it: 3 * w_param + (50% * 4 * w_param) + instr_br_if { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + RandomI32(0, 2), + Regular(Instruction::BrIf(1)), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_br_table = w_bench - 3 * w_param + // 1 * w_param + 0.5 * 2 * w_param + 0.25 * 4 * w_param + instr_br_table { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let table = Box::new(parity_wasm::elements::BrTableData { + table: Box::new([0, 1, 2]), + default: 1, + }); + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + RandomI32(0, 4), + Regular(Instruction::BrTable(table)), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_br_table_per_entry = w_bench + instr_br_table_per_entry { + let e in 1 .. Contracts::::current_schedule().limits.br_table_size; + let entry: Vec = [0, 1].iter() + .cloned() + .cycle() + .take((e / 2) as usize).collect(); + let table = Box::new(parity_wasm::elements::BrTableData { + table: entry.into_boxed_slice(), + default: 0, + }); + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(INSTR_BENCHMARK_BATCH_SIZE, vec![ + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + Regular(Instruction::Block(BlockType::NoResult)), + RandomI32(0, (e + 1) as i32), // Make sure the default entry is also used + Regular(Instruction::BrTable(table)), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + RandomI64Repeated(1), + Regular(Instruction::Drop), + Regular(Instruction::End), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_call = w_bench - 2 * w_param + instr_call { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + // We need to make use of the stack here in order to trigger stack height + // instrumentation. + aux_body: Some(body::plain(vec![ + Instruction::I64Const(42), + Instruction::Drop, + Instruction::End, + ])), + call_body: Some(body::repeated(r * INSTR_BENCHMARK_BATCH_SIZE, &[ + Instruction::Call(2), // call aux + ])), + inject_stack_metering: true, + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_call_indrect = w_bench - 3 * w_param + instr_call_indirect { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let num_elements = Contracts::::current_schedule().limits.table_size; + use self::code::TableSegment; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + // We need to make use of the stack here in order to trigger stack height + // instrumentation. + aux_body: Some(body::plain(vec![ + Instruction::I64Const(42), + Instruction::Drop, + Instruction::End, + ])), + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI32(0, num_elements as i32), + Regular(Instruction::CallIndirect(0, 0)), // we only have one sig: 0 + ])), + inject_stack_metering: true, + table: Some(TableSegment { + num_elements, + function_index: 2, // aux + }), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_instr_call_indirect_per_param = w_bench - 1 * w_param + // Calling a function indirectly causes it to go through a thunk function whose runtime + // linearly depend on the amount of parameters to this function. + // Please note that this is not necessary with a direct call. + instr_call_indirect_per_param { + let p in 0 .. Contracts::::current_schedule().limits.parameters; + let num_elements = Contracts::::current_schedule().limits.table_size; + use self::code::TableSegment; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + // We need to make use of the stack here in order to trigger stack height + // instrumentation. + aux_body: Some(body::plain(vec![ + Instruction::I64Const(42), + Instruction::Drop, + Instruction::End, + ])), + aux_arg_num: p, + call_body: Some(body::repeated_dyn(INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(p as usize), + RandomI32(0, num_elements as i32), + Regular(Instruction::CallIndirect(p.min(1), 0)), // aux signature: 1 or 0 + ])), + inject_stack_metering: true, + table: Some(TableSegment { + num_elements, + function_index: 2, // aux + }), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_local_get = w_bench - 1 * w_param + instr_local_get { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let max_locals = Contracts::::current_schedule().limits.stack_height; + let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomGetLocal(0, max_locals), + Regular(Instruction::Drop), + ]); + body::inject_locals(&mut call_body, max_locals); + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(call_body), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_local_set = w_bench - 1 * w_param + instr_local_set { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let max_locals = Contracts::::current_schedule().limits.stack_height; + let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(1), + RandomSetLocal(0, max_locals), + ]); + body::inject_locals(&mut call_body, max_locals); + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(call_body), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_local_tee = w_bench - 2 * w_param + instr_local_tee { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let max_locals = Contracts::::current_schedule().limits.stack_height; + let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(1), + RandomTeeLocal(0, max_locals), + Regular(Instruction::Drop), + ]); + body::inject_locals(&mut call_body, max_locals); + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(call_body), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_global_get = w_bench - 1 * w_param + instr_global_get { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let max_globals = Contracts::::current_schedule().limits.globals; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomGetGlobal(0, max_globals), + Regular(Instruction::Drop), + ])), + num_globals: max_globals, + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_global_set = w_bench - 1 * w_param + instr_global_set { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let max_globals = Contracts::::current_schedule().limits.globals; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI64Repeated(1), + RandomSetGlobal(0, max_globals), + ])), + num_globals: max_globals, + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_memory_get = w_bench - 1 * w_param + instr_memory_current { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory::max::()), + call_body: Some(body::repeated(r * INSTR_BENCHMARK_BATCH_SIZE, &[ + Instruction::CurrentMemory(0), + Instruction::Drop + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // w_memory_grow = w_bench - 2 * w_param + // We can only allow allocate as much memory as it is allowed in a a contract. + // Therefore the repeat count is limited by the maximum memory any contract can have. + // Using a contract with more memory will skew the benchmark because the runtime of grow + // depends on how much memory is already allocated. + instr_memory_grow { + let r in 0 .. 1; + let max_pages = ImportedMemory::max::().max_pages; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + memory: Some(ImportedMemory { + min_pages: 0, + max_pages, + }), + call_body: Some(body::repeated(r * max_pages, &[ + Instruction::I32Const(1), + Instruction::GrowMemory(0), + Instruction::Drop, + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + // Unary numeric instructions. + // All use w = w_bench - 2 * w_param. + + instr_i64clz { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::unary_instr( + Instruction::I64Clz, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64ctz { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::unary_instr( + Instruction::I64Ctz, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64popcnt { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::unary_instr( + Instruction::I64Popcnt, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64eqz { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::unary_instr( + Instruction::I64Eqz, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64extendsi32 { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI32Repeated(1), + Regular(Instruction::I64ExtendSI32), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + instr_i64extendui32 { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { + call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![ + RandomI32Repeated(1), + Regular(Instruction::I64ExtendUI32), + Regular(Instruction::Drop), + ])), + .. Default::default() + })); + }: { + sbox.invoke(); + } + + instr_i32wrapi64 { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::unary_instr( + Instruction::I32WrapI64, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + // Binary numeric instructions. + // All use w = w_bench - 3 * w_param. + + instr_i64eq { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Eq, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64ne { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Ne, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64lts { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64LtS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64ltu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64LtU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64gts { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64GtS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64gtu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64GtU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64les { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64LeS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64leu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64LeU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64ges { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64GeS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64geu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64GeU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64add { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Add, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64sub { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Sub, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64mul { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Mul, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64divs { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64DivS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64divu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64DivU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64rems { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64RemS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64remu { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64RemU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64and { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64And, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64or { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Or, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64xor { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Xor, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64shl { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Shl, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64shrs { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64ShrS, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64shru { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64ShrU, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64rotl { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Rotl, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + instr_i64rotr { + let r in 0 .. INSTR_BENCHMARK_BATCHES; + let mut sbox = Sandbox::from(&WasmModule::::binary_instr( + Instruction::I64Rotr, + r * INSTR_BENCHMARK_BATCH_SIZE, + )); + }: { + sbox.invoke(); + } + + // This is no benchmark. It merely exist to have an easy way to pretty print the curently + // configured `Schedule` during benchmark development. + // It can be outputed using the following command: + // cargo run --manifest-path=bin/node/cli/Cargo.toml --release \ + // --features runtime-benchmarks -- benchmark --dev --execution=native \ + // -p pallet_contracts -e print_schedule --no-median-slopes --no-min-squares + #[extra] + print_schedule { + #[cfg(feature = "std")] + println!("{:#?}", Schedule::::default()); + #[cfg(not(feature = "std"))] + return Err("Run this bench with a native runtime in order to see the schedule."); + }: {} } #[cfg(test)] @@ -1610,6 +2370,7 @@ mod tests { create_test!(instantiate); create_test!(call); create_test!(claim_surcharge); + create_test!(seal_caller); create_test!(seal_address); create_test!(seal_gas_left); @@ -1649,4 +2410,56 @@ mod tests { create_test!(seal_hash_blake2_256_per_kb); create_test!(seal_hash_blake2_128); create_test!(seal_hash_blake2_128_per_kb); + + create_test!(instr_i64const); + create_test!(instr_i64load); + create_test!(instr_i64store); + create_test!(instr_select); + create_test!(instr_if); + create_test!(instr_br); + create_test!(instr_br_if); + create_test!(instr_br_table); + create_test!(instr_br_table_per_entry); + create_test!(instr_call); + create_test!(instr_call_indirect); + create_test!(instr_call_indirect_per_param); + create_test!(instr_local_get); + create_test!(instr_local_set); + create_test!(instr_local_tee); + create_test!(instr_global_get); + create_test!(instr_global_set); + create_test!(instr_memory_current); + create_test!(instr_memory_grow); + create_test!(instr_i64clz); + create_test!(instr_i64ctz); + create_test!(instr_i64popcnt); + create_test!(instr_i64eqz); + create_test!(instr_i64extendsi32); + create_test!(instr_i64extendui32); + create_test!(instr_i32wrapi64); + create_test!(instr_i64eq); + create_test!(instr_i64ne); + create_test!(instr_i64lts); + create_test!(instr_i64ltu); + create_test!(instr_i64gts); + create_test!(instr_i64gtu); + create_test!(instr_i64les); + create_test!(instr_i64leu); + create_test!(instr_i64ges); + create_test!(instr_i64geu); + create_test!(instr_i64add); + create_test!(instr_i64sub); + create_test!(instr_i64mul); + create_test!(instr_i64divs); + create_test!(instr_i64divu); + create_test!(instr_i64rems); + create_test!(instr_i64remu); + create_test!(instr_i64and); + create_test!(instr_i64or); + create_test!(instr_i64xor); + create_test!(instr_i64shl); + create_test!(instr_i64shrs); + create_test!(instr_i64shru); + create_test!(instr_i64rotl); + create_test!(instr_i64rotr); } diff --git a/frame/contracts/src/benchmarking/sandbox.rs b/frame/contracts/src/benchmarking/sandbox.rs new file mode 100644 index 00000000000..1d93db19ee5 --- /dev/null +++ b/frame/contracts/src/benchmarking/sandbox.rs @@ -0,0 +1,52 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +///! For instruction benchmarking we do no instantiate a full contract but merely the +///! sandbox to execute the wasm code. This is because we do not need the full +///! environment that provides the seal interface as imported functions. + +use super::code::WasmModule; +use super::Trait; +use sp_sandbox::{EnvironmentDefinitionBuilder, Instance, Memory}; + +/// Minimal execution environment without any exported functions. +pub struct Sandbox { + instance: Instance<()>, + _memory: Option, +} + +impl Sandbox { + /// Invoke the `call` function of a contract code and panic on any execution error. + pub fn invoke(&mut self) { + self.instance.invoke("call", &[], &mut ()).unwrap(); + } +} + +impl From<&WasmModule> for Sandbox { + /// Creates an instance from the supplied module and supplies as much memory + /// to the instance as the module declares as imported. + fn from(module: &WasmModule) -> Self { + let mut env_builder = EnvironmentDefinitionBuilder::new(); + let memory = module.add_memory(&mut env_builder); + let instance = Instance::new(&module.code, &env_builder, &mut ()) + .expect("Failed to create benchmarking Sandbox instance"); + Self { + instance, + _memory: memory, + } + } +} diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 9f1656f35f6..f43bfd0ebdb 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -88,18 +88,18 @@ mod wasm; mod rent; mod benchmarking; mod schedule; -mod weight_info; +pub mod weights; #[cfg(test)] mod tests; use crate::exec::ExecutionContext; use crate::wasm::{WasmLoader, WasmVm}; +use crate::weights::WeightInfo; pub use crate::gas::{Gas, GasMeter}; pub use crate::wasm::ReturnCode as RuntimeReturnCode; -pub use crate::weight_info::WeightInfo; -pub use crate::schedule::{Schedule, HostFnWeights, InstructionWeights}; +pub use crate::schedule::{Schedule, HostFnWeights, InstructionWeights, Limits}; use sp_core::crypto::UncheckedFrom; use sp_std::{prelude::*, marker::PhantomData, fmt::Debug}; @@ -530,7 +530,7 @@ decl_module! { ) -> DispatchResult { ensure_signed(origin)?; let schedule = >::current_schedule(); - ensure!(code.len() as u32 <= schedule.max_code_size, Error::::CodeTooLarge); + ensure!(code.len() as u32 <= schedule.limits.code_size, Error::::CodeTooLarge); let result = wasm::save_code::(code, &schedule); if let Ok(code_hash) = result { Self::deposit_event(RawEvent::CodeStored(code_hash)); diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index fb38b1b895d..24f8bb0a02c 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -17,77 +17,180 @@ //! This module contains the cost schedule and supporting code that constructs a //! sane default schedule from a `WeightInfo` implementation. -use crate::{Trait, WeightInfo}; +use crate::{Trait, weights::WeightInfo}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; +use pallet_contracts_proc_macro::{ScheduleDebug, WeightDebug}; use frame_support::weights::Weight; -use sp_std::{marker::PhantomData, fmt}; +use sp_std::{marker::PhantomData, vec::Vec}; use codec::{Encode, Decode}; +use parity_wasm::elements; +use pwasm_utils::rules; +use sp_runtime::RuntimeDebug; /// How many API calls are executed in a single batch. The reason for increasing the amount /// of API calls in batches (per benchmark component increase) is so that the linear regression /// has an easier time determining the contribution of that component. pub const API_BENCHMARK_BATCH_SIZE: u32 = 100; +/// How many instructions are executed in a single batch. The reasoning is the same +/// as for `API_BENCHMARK_BATCH_SIZE`. +pub const INSTR_BENCHMARK_BATCH_SIZE: u32 = 1_000; + /// Definition of the cost schedule and other parameterizations for wasm vm. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[cfg_attr(feature = "std", serde(bound(serialize = "", deserialize = "")))] +#[derive(Clone, Encode, Decode, PartialEq, Eq, ScheduleDebug)] pub struct Schedule { /// Version of the schedule. pub version: u32, - /// The weights for individual wasm instructions. - pub instruction_weights: InstructionWeights, - - /// The weights for each imported function a contract is allowed to call. - pub host_fn_weights: HostFnWeights, - /// Whether the `seal_println` function is allowed to be used contracts. /// MUST only be enabled for `dev` chains, NOT for production chains pub enable_println: bool, + /// Describes the upper limits on various metrics. + pub limits: Limits, + + /// The weights for individual wasm instructions. + pub instruction_weights: InstructionWeights, + + /// The weights for each imported function a contract is allowed to call. + pub host_fn_weights: HostFnWeights, +} + +/// Describes the upper limits on various metrics. +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] +pub struct Limits { /// The maximum number of topics supported by an event. - pub max_event_topics: u32, + pub event_topics: u32, - /// Maximum allowed stack height. + /// Maximum allowed stack height in number of elements. /// /// See https://wiki.parity.io/WebAssembly-StackHeight to find out - /// how the stack frame cost is calculated. - pub max_stack_height: u32, + /// how the stack frame cost is calculated. Each element can be of one of the + /// wasm value types. This means the maximum size per element is 64bit. + pub stack_height: u32, + + /// Maximum number of globals a module is allowed to declare. + /// + /// Globals are not limited through the `stack_height` as locals are. Neither does + /// the linear memory limit `memory_pages` applies to them. + pub globals: u32, + + /// Maximum numbers of parameters a function can have. + /// + /// Those need to be limited to prevent a potentially exploitable interaction with + /// the stack height instrumentation: The costs of executing the stack height + /// instrumentation for an indirectly called function scales linearly with the amount + /// of parameters of this function. Because the stack height instrumentation itself is + /// is not weight metered its costs must be static (via this limit) and included in + /// the costs of the instructions that cause them (call, call_indirect). + pub parameters: u32, /// Maximum number of memory pages allowed for a contract. - pub max_memory_pages: u32, + pub memory_pages: u32, + + /// Maximum number of elements allowed in a table. + /// + /// Currently, the only type of element that is allowed in a table is funcref. + pub table_size: u32, - /// Maximum allowed size of a declared table. - pub max_table_size: u32, + /// Maximum number of elements that can appear as immediate value to the br_table instruction. + pub br_table_size: u32, - /// The maximum length of a subject used for PRNG generation. - pub max_subject_len: u32, + /// The maximum length of a subject in bytes used for PRNG generation. + pub subject_len: u32, /// The maximum length of a contract code in bytes. This limit applies to the uninstrumented /// and pristine form of the code as supplied to `put_code`. - pub max_code_size: u32, - - /// The type parameter is used in the default implementation. - pub _phantom: PhantomData, + pub code_size: u32, } /// Describes the weight for all categories of supported wasm instructions. +/// +/// There there is one field for each wasm instruction that describes the weight to +/// execute one instruction of that name. There are a few execptions: +/// +/// 1. If there is a i64 and a i32 variant of an instruction we use the weight +/// of the former for both. +/// 2. The following instructions are free of charge because they merely structure the +/// wasm module and cannot be spammed without making the module invalid (and rejected): +/// End, Unreachable, Return, Else +/// 3. The following instructions cannot be benchmarked because they are removed by any +/// real world execution engine as a preprocessing step and therefore don't yield a +/// meaningful benchmark result. However, in contrast to the instructions mentioned +/// in 2. they can be spammed. We price them with the same weight as the "default" +/// instruction (i64.const): Block, Loop, Nop +/// 4. We price both i64.const and drop as InstructionWeights.i64const / 2. The reason +/// for that is that we cannot benchmark either of them on its own but we need their +/// individual values to derive (by subtraction) the weight of all other instructions +/// that use them as supporting instructions. Supporting means mainly pushing arguments +/// and dropping return values in order to maintain a valid module. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] -pub struct InstructionWeights { - /// Weight of a growing memory by single page. - pub grow_mem: Weight, - - /// Weight of a regular operation. - pub regular: Weight, +#[derive(Clone, Encode, Decode, PartialEq, Eq, WeightDebug)] +pub struct InstructionWeights { + pub i64const: u32, + pub i64load: u32, + pub i64store: u32, + pub select: u32, + pub r#if: u32, + pub br: u32, + pub br_if: u32, + pub br_table: u32, + pub br_table_per_entry: u32, + pub call: u32, + pub call_indirect: u32, + pub call_indirect_per_param: u32, + pub local_get: u32, + pub local_set: u32, + pub local_tee: u32, + pub global_get: u32, + pub global_set: u32, + pub memory_current: u32, + pub memory_grow: u32, + pub i64clz: u32, + pub i64ctz: u32, + pub i64popcnt: u32, + pub i64eqz: u32, + pub i64extendsi32: u32, + pub i64extendui32: u32, + pub i32wrapi64: u32, + pub i64eq: u32, + pub i64ne: u32, + pub i64lts: u32, + pub i64ltu: u32, + pub i64gts: u32, + pub i64gtu: u32, + pub i64les: u32, + pub i64leu: u32, + pub i64ges: u32, + pub i64geu: u32, + pub i64add: u32, + pub i64sub: u32, + pub i64mul: u32, + pub i64divs: u32, + pub i64divu: u32, + pub i64rems: u32, + pub i64remu: u32, + pub i64and: u32, + pub i64or: u32, + pub i64xor: u32, + pub i64shl: u32, + pub i64shrs: u32, + pub i64shru: u32, + pub i64rotl: u32, + pub i64rotr: u32, + /// The type parameter is used in the default implementation. + pub _phantom: PhantomData, } /// Describes the weight for each imported function that a contract is allowed to call. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Clone, Encode, Decode, PartialEq, Eq)] -pub struct HostFnWeights { +#[derive(Clone, Encode, Decode, PartialEq, Eq, WeightDebug)] +pub struct HostFnWeights { /// Weight of calling `seal_caller`. pub caller: Weight, @@ -222,21 +325,11 @@ pub struct HostFnWeights { /// Weight per byte hashed by `seal_hash_blake2_128`. pub hash_blake2_128_per_byte: Weight, -} -/// We need to implement Debug manually because the automatic derive enforces T -/// to also implement Debug. -impl fmt::Debug for Schedule { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Schedule").finish() - } + /// The type parameter is used in the default implementation. + pub _phantom: PhantomData } -/// 500 (2 instructions per nano second on 2GHZ) * 1000x slowdown through wasmi -/// This is a wild guess and should be viewed as a rough estimation. -/// Proper benchmarks are needed before this value and its derivatives can be used in production. -const WASM_INSTRUCTION_COST: Weight = 500_000; - macro_rules! replace_token { ($_in:tt $replacement:tt) => { $replacement }; } @@ -259,6 +352,25 @@ macro_rules! cost_batched_args { } } +macro_rules! cost_instr_no_params_with_batch_size { + ($name:ident, $batch_size:expr) => { + (cost_args!($name, 1) / Weight::from($batch_size)) as u32 + } +} + +macro_rules! cost_instr_with_batch_size { + ($name:ident, $num_params:expr, $batch_size:expr) => { + cost_instr_no_params_with_batch_size!($name, $batch_size) + .saturating_sub((cost_instr_no_params_with_batch_size!(instr_i64const, $batch_size) / 2).saturating_mul($num_params)) + } +} + +macro_rules! cost_instr { + ($name:ident, $num_params:expr) => { + cost_instr_with_batch_size!($name, $num_params, INSTR_BENCHMARK_BATCH_SIZE) + } +} + macro_rules! cost_byte_args { ($name:ident, $( $arg: expr ),+) => { cost_args!($name, $( $arg ),+) / 1024 @@ -297,12 +409,97 @@ macro_rules! cost_byte_batched { impl Default for Schedule { fn default() -> Self { - let instruction_weights = InstructionWeights { - grow_mem: WASM_INSTRUCTION_COST, - regular: WASM_INSTRUCTION_COST, - }; + Self { + version: 0, + enable_println: false, + limits: Default::default(), + instruction_weights: Default::default(), + host_fn_weights: Default::default(), + } + } +} + +impl Default for Limits { + fn default() -> Self { + Self { + event_topics: 4, + // 512 * sizeof(i64) will give us a 4k stack. + stack_height: 512, + globals: 256, + parameters: 128, + memory_pages: 16, + // 4k function pointers (This is in count not bytes). + table_size: 4096, + br_table_size: 256, + subject_len: 32, + code_size: 512 * 1024, + } + } +} - let host_fn_weights = HostFnWeights { +impl Default for InstructionWeights { + fn default() -> Self { + let max_pages = Limits::default().memory_pages; + Self { + i64const: cost_instr!(instr_i64const, 1), + i64load: cost_instr!(instr_i64load, 2), + i64store: cost_instr!(instr_i64store, 2), + select: cost_instr!(instr_select, 4), + r#if: cost_instr!(instr_if, 3), + br: cost_instr!(instr_br, 2), + br_if: cost_instr!(instr_br_if, 5), + br_table: cost_instr!(instr_br_table, 3), + br_table_per_entry: cost_instr!(instr_br_table_per_entry, 0), + call: cost_instr!(instr_call, 2), + call_indirect: cost_instr!(instr_call_indirect, 3), + call_indirect_per_param: cost_instr!(instr_call_indirect_per_param, 1), + local_get: cost_instr!(instr_local_get, 1), + local_set: cost_instr!(instr_local_set, 1), + local_tee: cost_instr!(instr_local_tee, 2), + global_get: cost_instr!(instr_global_get, 1), + global_set: cost_instr!(instr_global_set, 1), + memory_current: cost_instr!(instr_memory_current, 1), + memory_grow: cost_instr_with_batch_size!(instr_memory_grow, 1, max_pages), + i64clz: cost_instr!(instr_i64clz, 2), + i64ctz: cost_instr!(instr_i64ctz, 2), + i64popcnt: cost_instr!(instr_i64popcnt, 2), + i64eqz: cost_instr!(instr_i64eqz, 2), + i64extendsi32: cost_instr!(instr_i64extendsi32, 2), + i64extendui32: cost_instr!(instr_i64extendui32, 2), + i32wrapi64: cost_instr!(instr_i32wrapi64, 2), + i64eq: cost_instr!(instr_i64eq, 3), + i64ne: cost_instr!(instr_i64ne, 3), + i64lts: cost_instr!(instr_i64lts, 3), + i64ltu: cost_instr!(instr_i64ltu, 3), + i64gts: cost_instr!(instr_i64gts, 3), + i64gtu: cost_instr!(instr_i64gtu, 3), + i64les: cost_instr!(instr_i64les, 3), + i64leu: cost_instr!(instr_i64leu, 3), + i64ges: cost_instr!(instr_i64ges, 3), + i64geu: cost_instr!(instr_i64geu, 3), + i64add: cost_instr!(instr_i64add, 3), + i64sub: cost_instr!(instr_i64sub, 3), + i64mul: cost_instr!(instr_i64mul, 3), + i64divs: cost_instr!(instr_i64divs, 3), + i64divu: cost_instr!(instr_i64divu, 3), + i64rems: cost_instr!(instr_i64rems, 3), + i64remu: cost_instr!(instr_i64remu, 3), + i64and: cost_instr!(instr_i64and, 3), + i64or: cost_instr!(instr_i64or, 3), + i64xor: cost_instr!(instr_i64xor, 3), + i64shl: cost_instr!(instr_i64shl, 3), + i64shrs: cost_instr!(instr_i64shrs, 3), + i64shru: cost_instr!(instr_i64shru, 3), + i64rotl: cost_instr!(instr_i64rotl, 3), + i64rotr: cost_instr!(instr_i64rotr, 3), + _phantom: PhantomData, + } + } +} + +impl Default for HostFnWeights { + fn default() -> Self { + Self { caller: cost_batched!(seal_caller), address: cost_batched!(seal_address), gas_left: cost_batched!(seal_gas_left), @@ -348,20 +545,119 @@ impl Default for Schedule { hash_blake2_256_per_byte: cost_byte_batched!(seal_hash_blake2_256_per_kb), hash_blake2_128: cost_batched!(seal_hash_blake2_128), hash_blake2_128_per_byte: cost_byte_batched!(seal_hash_blake2_128_per_kb), - }; - - Self { - version: 0, - instruction_weights, - host_fn_weights, - enable_println: false, - max_event_topics: 4, - max_stack_height: 64 * 1024, - max_memory_pages: 16, - max_table_size: 16 * 1024, - max_subject_len: 32, - max_code_size: 512 * 1024, _phantom: PhantomData, } } } + +struct ScheduleRules<'a, T: Trait> { + schedule: &'a Schedule, + params: Vec, +} + +impl Schedule { + pub fn rules(&self, module: &elements::Module) -> impl rules::Rules + '_ { + ScheduleRules { + schedule: &self, + params: module + .type_section() + .iter() + .flat_map(|section| section.types()) + .map(|func| { + let elements::Type::Function(func) = func; + func.params().len() as u32 + }) + .collect() + } + } +} + +impl<'a, T: Trait> rules::Rules for ScheduleRules<'a, T> { + fn instruction_cost(&self, instruction: &elements::Instruction) -> Option { + use parity_wasm::elements::Instruction::*; + let w = &self.schedule.instruction_weights; + let max_params = self.schedule.limits.parameters; + + let weight = match *instruction { + End | Unreachable | Return | Else => 0, + I32Const(_) | I64Const(_) | Block(_) | Loop(_) | Nop | Drop => w.i64const, + I32Load(_, _) | I32Load8S(_, _) | I32Load8U(_, _) | I32Load16S(_, _) | + I32Load16U(_, _) | I64Load(_, _) | I64Load8S(_, _) | I64Load8U(_, _) | + I64Load16S(_, _) | I64Load16U(_, _) | I64Load32S(_, _) | I64Load32U(_, _) + => w.i64load, + I32Store(_, _) | I32Store8(_, _) | I32Store16(_, _) | I64Store(_, _) | + I64Store8(_, _) | I64Store16(_, _) | I64Store32(_, _) => w.i64store, + Select => w.select, + If(_) => w.r#if, + Br(_) => w.br, + BrIf(_) => w.br_if, + Call(_) => w.call, + GetLocal(_) => w.local_get, + SetLocal(_) => w.local_set, + TeeLocal(_) => w.local_tee, + GetGlobal(_) => w.global_get, + SetGlobal(_) => w.global_set, + CurrentMemory(_) => w.memory_current, + GrowMemory(_) => w.memory_grow, + CallIndirect(idx, _) => *self.params.get(idx as usize).unwrap_or(&max_params), + BrTable(ref data) => + w.br_table.saturating_add( + w.br_table_per_entry.saturating_mul(data.table.len() as u32) + ), + I32Clz | I64Clz => w.i64clz, + I32Ctz | I64Ctz => w.i64ctz, + I32Popcnt | I64Popcnt => w.i64popcnt, + I64ExtendSI32 => w.i64extendsi32, + I64ExtendUI32 => w.i64extendui32, + I32WrapI64 => w.i32wrapi64, + I32Eq | I64Eq => w.i64eq, + I32Ne | I64Ne => w.i64ne, + I32LtS | I64LtS => w.i64lts, + I32LtU | I64LtU => w.i64ltu, + I32GtS | I64GtS => w.i64gts, + I32GtU | I64GtU => w.i64gtu, + I32LeS | I64LeS => w.i64les, + I32LeU | I64LeU => w.i64leu, + I32GeS | I64GeS => w.i64ges, + I32GeU | I64GeU => w.i64geu, + I32Add | I64Add => w.i64add, + I32Sub | I64Sub => w.i64sub, + I32Mul | I64Mul => w.i64mul, + I32DivS | I64DivS => w.i64divs, + I32DivU | I64DivU => w.i64divu, + I32RemS | I64RemS => w.i64rems, + I32RemU | I64RemU => w.i64remu, + I32And | I64And => w.i64and, + I32Or | I64Or => w.i64or, + I32Xor | I64Xor => w.i64xor, + I32Shl | I64Shl => w.i64shl, + I32ShrS | I64ShrS => w.i64shrs, + I32ShrU | I64ShrU => w.i64shru, + I32Rotl | I64Rotl => w.i64rotl, + I32Rotr | I64Rotr => w.i64rotr, + + // Returning None makes the gas instrumentation fail which we intend for + // unsupported or unknown instructions. + _ => return None, + }; + Some(weight) + } + + fn memory_grow_cost(&self) -> Option { + // We benchmarked the memory.grow instruction with the maximum allowed pages. + // The cost for growing is therefore already included in the instruction cost. + None + } +} + +#[cfg(test)] +mod test { + use crate::tests::Test; + use super::*; + + #[test] + fn print_test_schedule() { + let schedule = Schedule::::default(); + println!("{:#?}", schedule); + } +} diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 2440abed8ec..f90f3af688d 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -164,6 +164,7 @@ mod tests { use hex_literal::hex; use sp_runtime::DispatchError; use frame_support::weights::Weight; + use assert_matches::assert_matches; use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin}; const GAS_LIMIT: Gas = 10_000_000_000; @@ -645,14 +646,14 @@ mod tests { &mut GasMeter::new(GAS_LIMIT), ).unwrap(); - assert_eq!( - &mock_ext.instantiates, - &[InstantiateEntry { - code_hash: [0x11; 32].into(), + assert_matches!( + &mock_ext.instantiates[..], + [InstantiateEntry { + code_hash, endowment: 3, - data: vec![1, 2, 3, 4], - gas_left: 9392302058, - }] + data, + gas_left: _, + }] if code_hash == &[0x11; 32].into() && data == &vec![1, 2, 3, 4] ); } @@ -1461,7 +1462,7 @@ mod tests { vec![0x00, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00]) ]); - assert_eq!(gas_meter.gas_left(), 9834099446); + assert!(gas_meter.gas_left() > 0); } const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#" diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 171fca6339f..73c149d025d 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -24,9 +24,7 @@ use crate::{Schedule, Trait}; use parity_wasm::elements::{self, Internal, External, MemoryType, Type, ValueType}; use pwasm_utils; -use pwasm_utils::rules; use sp_std::prelude::*; -use sp_runtime::traits::{SaturatedConversion}; /// Currently, all imported functions must be located inside this module. We might support /// additional modules for versioning later. @@ -101,6 +99,33 @@ impl<'a, T: Trait> ContractModule<'a, T> { Ok(()) } + /// Ensure that any `br_table` instruction adheres to its immediate value limit. + fn ensure_br_table_size_limit(&self, limit: u32) -> Result<(), &'static str> { + let code_section = if let Some(type_section) = self.module.code_section() { + type_section + } else { + return Ok(()); + }; + for instr in code_section.bodies().iter().flat_map(|body| body.code().elements()) { + use parity_wasm::elements::Instruction::BrTable; + if let BrTable(table) = instr { + if table.table.len() > limit as usize { + return Err("BrTable's immediate value is too big.") + } + } + } + Ok(()) + } + + fn ensure_global_variable_limit(&self, limit: u32) -> Result<(), &'static str> { + if let Some(global_section) = self.module.global_section() { + if global_section.entries().len() > limit as usize { + return Err("module declares too many globals") + } + } + Ok(()) + } + /// Ensures that no floating point types are in use. fn ensure_no_floating_types(&self) -> Result<(), &'static str> { if let Some(global_section) = self.module.global_section() { @@ -145,15 +170,25 @@ impl<'a, T: Trait> ContractModule<'a, T> { Ok(()) } - fn inject_gas_metering(self) -> Result { - let gas_rules = - rules::Set::new( - self.schedule.instruction_weights.regular.clone().saturated_into(), - Default::default(), - ) - .with_grow_cost(self.schedule.instruction_weights.grow_mem.clone().saturated_into()) - .with_forbidden_floats(); + /// Ensure that no function exists that has more parameters than allowed. + fn ensure_parameter_limit(&self, limit: u32) -> Result<(), &'static str> { + let type_section = if let Some(type_section) = self.module.type_section() { + type_section + } else { + return Ok(()); + }; + + for Type::Function(func) in type_section.types() { + if func.params().len() > limit as usize { + return Err("Use of a function type with too many parameters."); + } + } + Ok(()) + } + + fn inject_gas_metering(self) -> Result { + let gas_rules = self.schedule.rules(&self.module); let contract_module = pwasm_utils::inject_gas_counter( self.module, &gas_rules, @@ -167,7 +202,8 @@ impl<'a, T: Trait> ContractModule<'a, T> { fn inject_stack_height_metering(self) -> Result { let contract_module = - pwasm_utils::stack_height::inject_limiter(self.module, self.schedule.max_stack_height) + pwasm_utils::stack_height + ::inject_limiter(self.module, self.schedule.limits.stack_height) .map_err(|_| "stack height instrumentation failed")?; Ok(ContractModule { module: contract_module, @@ -345,7 +381,7 @@ fn get_memory_limits(module: Option<&MemoryType>, schedule: &Schedule< "Requested initial number of pages should not exceed the requested maximum", ); } - (_, Some(maximum)) if maximum > schedule.max_memory_pages => { + (_, Some(maximum)) if maximum > schedule.limits.memory_pages => { return Err("Maximum number of pages should not exceed the configured maximum."); } (initial, Some(maximum)) => Ok((initial, maximum)), @@ -381,8 +417,11 @@ pub fn prepare_contract( let mut contract_module = ContractModule::new(original_code, schedule)?; contract_module.scan_exports()?; contract_module.ensure_no_internal_memory()?; - contract_module.ensure_table_size_limit(schedule.max_table_size)?; + contract_module.ensure_table_size_limit(schedule.limits.table_size)?; + contract_module.ensure_global_variable_limit(schedule.limits.globals)?; contract_module.ensure_no_floating_types()?; + contract_module.ensure_parameter_limit(schedule.limits.parameters)?; + contract_module.ensure_br_table_size_limit(schedule.limits.br_table_size)?; // We disallow importing `gas` function here since it is treated as implementation detail. let disallowed_imports = [b"gas".as_ref()]; @@ -442,7 +481,7 @@ pub mod benchmarking { #[cfg(test)] mod tests { use super::*; - use crate::exec::Ext; + use crate::{exec::Ext, Limits}; use std::fmt; use assert_matches::assert_matches; @@ -470,7 +509,17 @@ mod tests { #[test] fn $name() { let wasm = wat::parse_str($wat).unwrap(); - let schedule = Schedule::default(); + let schedule = Schedule { + limits: Limits { + globals: 3, + parameters: 3, + memory_pages: 16, + table_size: 3, + br_table_size: 3, + .. Default::default() + }, + .. Default::default() + }; let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, $($expected)*); } @@ -493,14 +542,66 @@ mod tests { Err("gas instrumentation failed") ); - mod memories { + mod functions { use super::*; - // Tests below assumes that maximum page number is configured to a certain number. - #[test] - fn assume_memory_size() { - assert_eq!(>::default().max_memory_pages, 16); - } + prepare_test!(param_number_valid, + r#" + (module + (func (export "call")) + (func (export "deploy")) + (func (param i32 i32 i32)) + ) + "#, + Ok(_) + ); + + prepare_test!(param_number_invalid, + r#" + (module + (func (export "call")) + (func (export "deploy")) + (func (param i32 i32 i32 i32)) + (func (param i32)) + ) + "#, + Err("Use of a function type with too many parameters.") + ); + } + + mod globals { + use super::*; + + prepare_test!(global_number_valid, + r#" + (module + (global i64 (i64.const 0)) + (global i64 (i64.const 0)) + (global i64 (i64.const 0)) + (func (export "call")) + (func (export "deploy")) + ) + "#, + Ok(_) + ); + + prepare_test!(global_number_too_high, + r#" + (module + (global i64 (i64.const 0)) + (global i64 (i64.const 0)) + (global i64 (i64.const 0)) + (global i64 (i64.const 0)) + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module declares too many globals") + ); + } + + mod memories { + use super::*; prepare_test!(memory_with_one_page, r#" @@ -561,6 +662,18 @@ mod tests { Err("Maximum number of pages should be always declared.") ); + prepare_test!(requested_maximum_valid, + r#" + (module + (import "env" "memory" (memory 1 16)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Ok(_) + ); + prepare_test!(requested_maximum_exceeds_configured_maximum, r#" (module @@ -625,12 +738,6 @@ mod tests { mod tables { use super::*; - // Tests below assumes that maximum table size is configured to a certain number. - #[test] - fn assume_table_size() { - assert_eq!(>::default().max_table_size, 16384); - } - prepare_test!(no_tables, r#" (module @@ -644,7 +751,7 @@ mod tests { prepare_test!(table_valid_size, r#" (module - (table 10000 funcref) + (table 3 funcref) (func (export "call")) (func (export "deploy")) @@ -656,13 +763,40 @@ mod tests { prepare_test!(table_too_big, r#" (module - (table 20000 funcref) + (table 4 funcref) (func (export "call")) (func (export "deploy")) )"#, Err("table exceeds maximum size allowed") ); + + prepare_test!(br_table_valid_size, + r#" + (module + (func (export "call")) + (func (export "deploy")) + (func + i32.const 0 + br_table 0 0 0 0 + ) + ) + "#, + Ok(_) + ); + + prepare_test!(br_table_too_big, + r#" + (module + (func (export "call")) + (func (export "deploy")) + (func + i32.const 0 + br_table 0 0 0 0 0 + ) + )"#, + Err("BrTable's immediate value is too big.") + ); } mod imports { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index ffc816aa4c8..c7de93ece70 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -279,7 +279,7 @@ pub enum RuntimeToken { } impl Token for RuntimeToken { - type Metadata = HostFnWeights; + type Metadata = HostFnWeights; fn calculate_amount(&self, s: &Self::Metadata) -> Gas { use self::RuntimeToken::*; @@ -340,7 +340,7 @@ impl Token for RuntimeToken { fn charge_gas(ctx: &mut Runtime, token: Tok) -> Result<(), sp_sandbox::HostError> where E: Ext, - Tok: Token, + Tok: Token>, { match ctx.gas_meter.charge(&ctx.schedule.host_fn_weights, token) { GasMeterResult::Proceed => Ok(()), @@ -1024,8 +1024,7 @@ define_env!(Env, , // The data is encoded as T::Hash. seal_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => { charge_gas(ctx, RuntimeToken::Random)?; - // The length of a subject can't exceed `max_subject_len`. - if subject_len > ctx.schedule.max_subject_len { + if subject_len > ctx.schedule.limits.subject_len { return Err(sp_sandbox::HostError); } let subject_buf = read_sandbox_memory(ctx, subject_ptr, subject_len)?; @@ -1157,7 +1156,7 @@ define_env!(Env, , }, // Deposit a contract event with the data buffer and optional list of topics. There is a limit - // on the maximum number of topics specified by `max_event_topics`. + // on the maximum number of topics specified by `event_topics`. // // - topics_ptr - a pointer to the buffer of topics encoded as `Vec`. The value of this // is ignored if `topics_len` is set to 0. The topics list can't contain duplicates. @@ -1181,8 +1180,8 @@ define_env!(Env, , _ => read_sandbox_memory_as(ctx, topics_ptr, topics_len)?, }; - // If there are more than `max_event_topics`, then trap. - if topics.len() > ctx.schedule.max_event_topics as usize { + // If there are more than `event_topics`, then trap. + if topics.len() > ctx.schedule.limits.event_topics as usize { return Err(sp_sandbox::HostError); } diff --git a/frame/contracts/src/weight_info.rs b/frame/contracts/src/weight_info.rs deleted file mode 100644 index 3a0881ed78d..00000000000 --- a/frame/contracts/src/weight_info.rs +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! This module contains the `WeightInfo` trait and its unsafe implementation on `()`. - -use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; - -/// Should be implemented by automatically generated code of the benchmarking system for -/// every runtime that makes use of this pallet. -/// This trait is also implemented on `()`. The implemention on `()` is **unsafe** and must -/// only be used during development. Proper weights can be generated by running the -/// pallet_contracts benchmark suite for the runtime in question. -pub trait WeightInfo { - fn update_schedule() -> Weight; - fn put_code(n: u32, ) -> Weight; - fn instantiate(n: u32, ) -> Weight; - fn call() -> Weight; - fn claim_surcharge() -> Weight; - fn seal_caller(r: u32, ) -> Weight; - fn seal_address(r: u32, ) -> Weight; - fn seal_gas_left(r: u32, ) -> Weight; - fn seal_balance(r: u32, ) -> Weight; - fn seal_value_transferred(r: u32, ) -> Weight; - fn seal_minimum_balance(r: u32, ) -> Weight; - fn seal_tombstone_deposit(r: u32, ) -> Weight; - fn seal_rent_allowance(r: u32, ) -> Weight; - fn seal_block_number(r: u32, ) -> Weight; - fn seal_now(r: u32, ) -> Weight; - fn seal_weight_to_fee(r: u32, ) -> Weight; - fn seal_gas(r: u32, ) -> Weight; - fn seal_input(r: u32, ) -> Weight; - fn seal_input_per_kb(n: u32, ) -> Weight; - fn seal_return(r: u32, ) -> Weight; - fn seal_return_per_kb(n: u32, ) -> Weight; - fn seal_terminate(r: u32, ) -> Weight; - fn seal_restore_to(r: u32, ) -> Weight; - fn seal_restore_to_per_delta(d: u32, ) -> Weight; - fn seal_random(r: u32, ) -> Weight; - fn seal_deposit_event(r: u32, ) -> Weight; - fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight; - fn seal_set_rent_allowance(r: u32, ) -> Weight; - fn seal_set_storage(r: u32, ) -> Weight; - fn seal_set_storage_per_kb(n: u32, ) -> Weight; - fn seal_clear_storage(r: u32, ) -> Weight; - fn seal_get_storage(r: u32, ) -> Weight; - fn seal_get_storage_per_kb(n: u32, ) -> Weight; - fn seal_transfer(r: u32, ) -> Weight; - fn seal_call(r: u32, ) -> Weight; - fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight; - fn seal_instantiate(r: u32, ) -> Weight; - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight; - fn seal_hash_sha2_256(r: u32, ) -> Weight; - fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight; - fn seal_hash_keccak_256(r: u32, ) -> Weight; - fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight; - fn seal_hash_blake2_256(r: u32, ) -> Weight; - fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight; - fn seal_hash_blake2_128(r: u32, ) -> Weight; - fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight; -} - -/// Unsafe implementation that must only be used for development. -impl WeightInfo for () { - fn update_schedule() -> Weight { - (45000000 as Weight) - .saturating_add(DbWeight::get().reads(1 as Weight)) - .saturating_add(DbWeight::get().writes(1 as Weight)) - } - fn put_code(n: u32, ) -> Weight { - (263409000 as Weight) - .saturating_add((169269000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(1 as Weight)) - .saturating_add(DbWeight::get().writes(2 as Weight)) - } - fn instantiate(n: u32, ) -> Weight { - (309311000 as Weight) - .saturating_add((1018000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(7 as Weight)) - .saturating_add(DbWeight::get().writes(4 as Weight)) - } - fn call() -> Weight { - (291000000 as Weight) - .saturating_add(DbWeight::get().reads(6 as Weight)) - .saturating_add(DbWeight::get().writes(3 as Weight)) - } - fn claim_surcharge() -> Weight { - (766000000 as Weight) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().writes(3 as Weight)) - } - fn seal_caller(r: u32, ) -> Weight { - (182241000 as Weight) - .saturating_add((697428000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_address(r: u32, ) -> Weight { - (193846000 as Weight) - .saturating_add((695989000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_gas_left(r: u32, ) -> Weight { - (166031000 as Weight) - .saturating_add((702533000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_balance(r: u32, ) -> Weight { - (251892000 as Weight) - .saturating_add((1392900000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - } - fn seal_value_transferred(r: u32, ) -> Weight { - (178472000 as Weight) - .saturating_add((694921000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_minimum_balance(r: u32, ) -> Weight { - (191301000 as Weight) - .saturating_add((697871000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_tombstone_deposit(r: u32, ) -> Weight { - (241315000 as Weight) - .saturating_add((686403000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_rent_allowance(r: u32, ) -> Weight { - (104958000 as Weight) - .saturating_add((1459573000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_block_number(r: u32, ) -> Weight { - (174140000 as Weight) - .saturating_add((698152000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_now(r: u32, ) -> Weight { - (203157000 as Weight) - .saturating_add((713595000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_weight_to_fee(r: u32, ) -> Weight { - (178413000 as Weight) - .saturating_add((1071275000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - } - fn seal_gas(r: u32, ) -> Weight { - (171395000 as Weight) - .saturating_add((371653000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_input(r: u32, ) -> Weight { - (184462000 as Weight) - .saturating_add((10538000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_input_per_kb(n: u32, ) -> Weight { - (194668000 as Weight) - .saturating_add((301000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_return(r: u32, ) -> Weight { - (175538000 as Weight) - .saturating_add((7462000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_return_per_kb(n: u32, ) -> Weight { - (189759000 as Weight) - .saturating_add((754000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_terminate(r: u32, ) -> Weight { - (184385000 as Weight) - .saturating_add((542615000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) - } - fn seal_restore_to(r: u32, ) -> Weight { - (380385000 as Weight) - .saturating_add((160308000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) - } - fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (0 as Weight) - .saturating_add((4786197000 as Weight).saturating_mul(d as Weight)) - .saturating_add(DbWeight::get().reads(7 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) - .saturating_add(DbWeight::get().writes(5 as Weight)) - .saturating_add(DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) - } - fn seal_random(r: u32, ) -> Weight { - (187944000 as Weight) - .saturating_add((1592530000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - } - fn seal_deposit_event(r: u32, ) -> Weight { - (126517000 as Weight) - .saturating_add((2346945000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (2953428000 as Weight) - .saturating_add((1117651000 as Weight).saturating_mul(t as Weight)) - .saturating_add((299890000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) - .saturating_add(DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) - } - fn seal_set_rent_allowance(r: u32, ) -> Weight { - (142094000 as Weight) - .saturating_add((1726665000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().writes(1 as Weight)) - } - fn seal_set_storage(r: u32, ) -> Weight { - (4091409000 as Weight) - .saturating_add((26440116000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes(1 as Weight)) - .saturating_add(DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (3683270000 as Weight) - .saturating_add((233826000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().writes(2 as Weight)) - } - fn seal_clear_storage(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((7152747000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes(1 as Weight)) - .saturating_add(DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_get_storage(r: u32, ) -> Weight { - (19007000 as Weight) - .saturating_add((1774675000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (1477332000 as Weight) - .saturating_add((176601000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - } - fn seal_transfer(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((10274385000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes(1 as Weight)) - .saturating_add(DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_call(r: u32, ) -> Weight { - (241916000 as Weight) - .saturating_add((14633108000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } - fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (15664107000 as Weight) - .saturating_add((8529984000 as Weight).saturating_mul(t as Weight)) - .saturating_add((52860000 as Weight).saturating_mul(i as Weight)) - .saturating_add((81175000 as Weight).saturating_mul(o as Weight)) - .saturating_add(DbWeight::get().reads(105 as Weight)) - .saturating_add(DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) - .saturating_add(DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) - } - fn seal_instantiate(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((32247550000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(5 as Weight)) - .saturating_add(DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) - .saturating_add(DbWeight::get().writes(1 as Weight)) - .saturating_add(DbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) - } - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { - (34376003000 as Weight) - .saturating_add((151350000 as Weight).saturating_mul(i as Weight)) - .saturating_add((82364000 as Weight).saturating_mul(o as Weight)) - .saturating_add(DbWeight::get().reads(207 as Weight)) - .saturating_add(DbWeight::get().writes(202 as Weight)) - } - fn seal_hash_sha2_256(r: u32, ) -> Weight { - (164203000 as Weight) - .saturating_add((565206000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (0 as Weight) - .saturating_add((330063000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_keccak_256(r: u32, ) -> Weight { - (219038000 as Weight) - .saturating_add((567992000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (434654000 as Weight) - .saturating_add((271134000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_256(r: u32, ) -> Weight { - (116374000 as Weight) - .saturating_add((566612000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (756028000 as Weight) - .saturating_add((150363000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_128(r: u32, ) -> Weight { - (150126000 as Weight) - .saturating_add((564827000 as Weight).saturating_mul(r as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } - fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (1021689000 as Weight) - .saturating_add((149452000 as Weight).saturating_mul(n as Weight)) - .saturating_add(DbWeight::get().reads(4 as Weight)) - } -} diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs new file mode 100644 index 00000000000..a84acbfd79a --- /dev/null +++ b/frame/contracts/src/weights.rs @@ -0,0 +1,1267 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Weights for pallet_contracts +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 +//! DATE: 2020-10-27, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_contracts +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/contracts/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_contracts. +pub trait WeightInfo { + fn update_schedule() -> Weight; + fn put_code(n: u32, ) -> Weight; + fn instantiate(n: u32, ) -> Weight; + fn call() -> Weight; + fn claim_surcharge() -> Weight; + fn seal_caller(r: u32, ) -> Weight; + fn seal_address(r: u32, ) -> Weight; + fn seal_gas_left(r: u32, ) -> Weight; + fn seal_balance(r: u32, ) -> Weight; + fn seal_value_transferred(r: u32, ) -> Weight; + fn seal_minimum_balance(r: u32, ) -> Weight; + fn seal_tombstone_deposit(r: u32, ) -> Weight; + fn seal_rent_allowance(r: u32, ) -> Weight; + fn seal_block_number(r: u32, ) -> Weight; + fn seal_now(r: u32, ) -> Weight; + fn seal_weight_to_fee(r: u32, ) -> Weight; + fn seal_gas(r: u32, ) -> Weight; + fn seal_input(r: u32, ) -> Weight; + fn seal_input_per_kb(n: u32, ) -> Weight; + fn seal_return(r: u32, ) -> Weight; + fn seal_return_per_kb(n: u32, ) -> Weight; + fn seal_terminate(r: u32, ) -> Weight; + fn seal_restore_to(r: u32, ) -> Weight; + fn seal_restore_to_per_delta(d: u32, ) -> Weight; + fn seal_random(r: u32, ) -> Weight; + fn seal_deposit_event(r: u32, ) -> Weight; + fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight; + fn seal_set_rent_allowance(r: u32, ) -> Weight; + fn seal_set_storage(r: u32, ) -> Weight; + fn seal_set_storage_per_kb(n: u32, ) -> Weight; + fn seal_clear_storage(r: u32, ) -> Weight; + fn seal_get_storage(r: u32, ) -> Weight; + fn seal_get_storage_per_kb(n: u32, ) -> Weight; + fn seal_transfer(r: u32, ) -> Weight; + fn seal_call(r: u32, ) -> Weight; + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight; + fn seal_instantiate(r: u32, ) -> Weight; + fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight; + fn seal_hash_sha2_256(r: u32, ) -> Weight; + fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight; + fn seal_hash_keccak_256(r: u32, ) -> Weight; + fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight; + fn seal_hash_blake2_256(r: u32, ) -> Weight; + fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight; + fn seal_hash_blake2_128(r: u32, ) -> Weight; + fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight; + fn instr_i64const(r: u32, ) -> Weight; + fn instr_i64load(r: u32, ) -> Weight; + fn instr_i64store(r: u32, ) -> Weight; + fn instr_select(r: u32, ) -> Weight; + fn instr_if(r: u32, ) -> Weight; + fn instr_br(r: u32, ) -> Weight; + fn instr_br_if(r: u32, ) -> Weight; + fn instr_br_table(r: u32, ) -> Weight; + fn instr_br_table_per_entry(e: u32, ) -> Weight; + fn instr_call(r: u32, ) -> Weight; + fn instr_call_indirect(r: u32, ) -> Weight; + fn instr_call_indirect_per_param(p: u32, ) -> Weight; + fn instr_local_get(r: u32, ) -> Weight; + fn instr_local_set(r: u32, ) -> Weight; + fn instr_local_tee(r: u32, ) -> Weight; + fn instr_global_get(r: u32, ) -> Weight; + fn instr_global_set(r: u32, ) -> Weight; + fn instr_memory_current(r: u32, ) -> Weight; + fn instr_memory_grow(r: u32, ) -> Weight; + fn instr_i64clz(r: u32, ) -> Weight; + fn instr_i64ctz(r: u32, ) -> Weight; + fn instr_i64popcnt(r: u32, ) -> Weight; + fn instr_i64eqz(r: u32, ) -> Weight; + fn instr_i64extendsi32(r: u32, ) -> Weight; + fn instr_i64extendui32(r: u32, ) -> Weight; + fn instr_i32wrapi64(r: u32, ) -> Weight; + fn instr_i64eq(r: u32, ) -> Weight; + fn instr_i64ne(r: u32, ) -> Weight; + fn instr_i64lts(r: u32, ) -> Weight; + fn instr_i64ltu(r: u32, ) -> Weight; + fn instr_i64gts(r: u32, ) -> Weight; + fn instr_i64gtu(r: u32, ) -> Weight; + fn instr_i64les(r: u32, ) -> Weight; + fn instr_i64leu(r: u32, ) -> Weight; + fn instr_i64ges(r: u32, ) -> Weight; + fn instr_i64geu(r: u32, ) -> Weight; + fn instr_i64add(r: u32, ) -> Weight; + fn instr_i64sub(r: u32, ) -> Weight; + fn instr_i64mul(r: u32, ) -> Weight; + fn instr_i64divs(r: u32, ) -> Weight; + fn instr_i64divu(r: u32, ) -> Weight; + fn instr_i64rems(r: u32, ) -> Weight; + fn instr_i64remu(r: u32, ) -> Weight; + fn instr_i64and(r: u32, ) -> Weight; + fn instr_i64or(r: u32, ) -> Weight; + fn instr_i64xor(r: u32, ) -> Weight; + fn instr_i64shl(r: u32, ) -> Weight; + fn instr_i64shrs(r: u32, ) -> Weight; + fn instr_i64shru(r: u32, ) -> Weight; + fn instr_i64rotl(r: u32, ) -> Weight; + fn instr_i64rotr(r: u32, ) -> Weight; + +} + +/// Weights for pallet_contracts using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn update_schedule() -> Weight { + (33_160_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + + } + fn put_code(n: u32, ) -> Weight { + (5_975_000 as Weight) + .saturating_add((108_953_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + + } + fn instantiate(n: u32, ) -> Weight { + (218_223_000 as Weight) + .saturating_add((1_007_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + + } + fn call() -> Weight { + (201_492_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + + } + fn claim_surcharge() -> Weight { + (449_203_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + + } + fn seal_caller(r: u32, ) -> Weight { + (136_650_000 as Weight) + .saturating_add((364_640_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_address(r: u32, ) -> Weight { + (144_167_000 as Weight) + .saturating_add((365_328_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_gas_left(r: u32, ) -> Weight { + (138_458_000 as Weight) + .saturating_add((361_076_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_balance(r: u32, ) -> Weight { + (147_909_000 as Weight) + .saturating_add((792_169_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + + } + fn seal_value_transferred(r: u32, ) -> Weight { + (148_524_000 as Weight) + .saturating_add((361_842_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_minimum_balance(r: u32, ) -> Weight { + (139_795_000 as Weight) + .saturating_add((366_013_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_tombstone_deposit(r: u32, ) -> Weight { + (140_557_000 as Weight) + .saturating_add((362_687_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_rent_allowance(r: u32, ) -> Weight { + (152_989_000 as Weight) + .saturating_add((836_876_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_block_number(r: u32, ) -> Weight { + (140_228_000 as Weight) + .saturating_add((360_561_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_now(r: u32, ) -> Weight { + (148_776_000 as Weight) + .saturating_add((361_712_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_weight_to_fee(r: u32, ) -> Weight { + (126_903_000 as Weight) + .saturating_add((603_100_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + + } + fn seal_gas(r: u32, ) -> Weight { + (125_712_000 as Weight) + .saturating_add((184_450_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_input(r: u32, ) -> Weight { + (136_175_000 as Weight) + .saturating_add((7_489_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_input_per_kb(n: u32, ) -> Weight { + (145_434_000 as Weight) + .saturating_add((276_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_return(r: u32, ) -> Weight { + (124_788_000 as Weight) + .saturating_add((5_696_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_return_per_kb(n: u32, ) -> Weight { + (133_483_000 as Weight) + .saturating_add((675_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_terminate(r: u32, ) -> Weight { + (135_387_000 as Weight) + .saturating_add((338_395_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) + } + fn seal_restore_to(r: u32, ) -> Weight { + (227_617_000 as Weight) + .saturating_add((132_493_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) + } + fn seal_restore_to_per_delta(d: u32, ) -> Weight { + (15_263_000 as Weight) + .saturating_add((3_732_219_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) + } + fn seal_random(r: u32, ) -> Weight { + (236_391_000 as Weight) + .saturating_add((913_452_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + + } + fn seal_deposit_event(r: u32, ) -> Weight { + (140_845_000 as Weight) + .saturating_add((1_322_796_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { + (1_651_556_000 as Weight) + .saturating_add((737_421_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((244_183_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) + .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) + } + fn seal_set_rent_allowance(r: u32, ) -> Weight { + (151_091_000 as Weight) + .saturating_add((983_375_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + + } + fn seal_set_storage(r: u32, ) -> Weight { + (460_478_000 as Weight) + .saturating_add((14_824_033_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_set_storage_per_kb(n: u32, ) -> Weight { + (2_255_458_000 as Weight) + .saturating_add((204_470_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + + } + fn seal_clear_storage(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((5_052_125_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_get_storage(r: u32, ) -> Weight { + (95_473_000 as Weight) + .saturating_add((1_044_784_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + + } + fn seal_get_storage_per_kb(n: u32, ) -> Weight { + (860_080_000 as Weight) + .saturating_add((146_913_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + + } + fn seal_transfer(r: u32, ) -> Weight { + (107_119_000 as Weight) + .saturating_add((5_993_434_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_call(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((10_533_320_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + + } + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { + (9_839_633_000 as Weight) + .saturating_add((5_580_035_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((53_716_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((73_668_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(T::DbWeight::get().reads(105 as Weight)) + .saturating_add(T::DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) + .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) + } + fn seal_instantiate(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((21_856_497_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + .saturating_add(T::DbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) + } + fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { + (18_796_671_000 as Weight) + .saturating_add((156_269_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((74_645_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(T::DbWeight::get().reads(207 as Weight)) + .saturating_add(T::DbWeight::get().writes(202 as Weight)) + + } + fn seal_hash_sha2_256(r: u32, ) -> Weight { + (132_190_000 as Weight) + .saturating_add((319_943_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { + (747_208_000 as Weight) + .saturating_add((421_808_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_keccak_256(r: u32, ) -> Weight { + (139_235_000 as Weight) + .saturating_add((333_792_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { + (543_256_000 as Weight) + .saturating_add((334_383_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_256(r: u32, ) -> Weight { + (142_704_000 as Weight) + .saturating_add((305_513_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { + (592_813_000 as Weight) + .saturating_add((151_270_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_128(r: u32, ) -> Weight { + (139_921_000 as Weight) + .saturating_add((304_746_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { + (544_524_000 as Weight) + .saturating_add((151_549_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + + } + fn instr_i64const(r: u32, ) -> Weight { + (24_652_000 as Weight) + .saturating_add((3_306_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64load(r: u32, ) -> Weight { + (27_131_000 as Weight) + .saturating_add((162_220_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64store(r: u32, ) -> Weight { + (27_086_000 as Weight) + .saturating_add((230_977_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_select(r: u32, ) -> Weight { + (24_656_000 as Weight) + .saturating_add((12_570_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_if(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((12_442_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br(r: u32, ) -> Weight { + (24_589_000 as Weight) + .saturating_add((6_237_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_if(r: u32, ) -> Weight { + (24_650_000 as Weight) + .saturating_add((14_393_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_table(r: u32, ) -> Weight { + (24_689_000 as Weight) + .saturating_add((15_706_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_table_per_entry(e: u32, ) -> Weight { + (40_129_000 as Weight) + .saturating_add((83_000 as Weight).saturating_mul(e as Weight)) + + } + fn instr_call(r: u32, ) -> Weight { + (24_904_000 as Weight) + .saturating_add((96_429_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_call_indirect(r: u32, ) -> Weight { + (32_540_000 as Weight) + .saturating_add((201_773_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_call_indirect_per_param(p: u32, ) -> Weight { + (248_700_000 as Weight) + .saturating_add((3_705_000 as Weight).saturating_mul(p as Weight)) + + } + fn instr_local_get(r: u32, ) -> Weight { + (42_081_000 as Weight) + .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_local_set(r: u32, ) -> Weight { + (42_128_000 as Weight) + .saturating_add((3_678_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_local_tee(r: u32, ) -> Weight { + (42_073_000 as Weight) + .saturating_add((5_212_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_global_get(r: u32, ) -> Weight { + (28_182_000 as Weight) + .saturating_add((8_180_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_global_set(r: u32, ) -> Weight { + (28_060_000 as Weight) + .saturating_add((12_081_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_memory_current(r: u32, ) -> Weight { + (27_113_000 as Weight) + .saturating_add((3_802_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_memory_grow(r: u32, ) -> Weight { + (25_521_000 as Weight) + .saturating_add((2_288_295_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64clz(r: u32, ) -> Weight { + (24_662_000 as Weight) + .saturating_add((5_497_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ctz(r: u32, ) -> Weight { + (24_647_000 as Weight) + .saturating_add((5_556_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64popcnt(r: u32, ) -> Weight { + (24_646_000 as Weight) + .saturating_add((6_138_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64eqz(r: u32, ) -> Weight { + (24_649_000 as Weight) + .saturating_add((5_477_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64extendsi32(r: u32, ) -> Weight { + (24_655_000 as Weight) + .saturating_add((5_414_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64extendui32(r: u32, ) -> Weight { + (24_619_000 as Weight) + .saturating_add((5_434_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i32wrapi64(r: u32, ) -> Weight { + (24_654_000 as Weight) + .saturating_add((5_483_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64eq(r: u32, ) -> Weight { + (24_690_000 as Weight) + .saturating_add((7_485_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ne(r: u32, ) -> Weight { + (24_652_000 as Weight) + .saturating_add((7_468_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64lts(r: u32, ) -> Weight { + (24_667_000 as Weight) + .saturating_add((7_426_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ltu(r: u32, ) -> Weight { + (24_693_000 as Weight) + .saturating_add((7_393_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64gts(r: u32, ) -> Weight { + (24_675_000 as Weight) + .saturating_add((7_407_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64gtu(r: u32, ) -> Weight { + (24_697_000 as Weight) + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64les(r: u32, ) -> Weight { + (24_646_000 as Weight) + .saturating_add((7_420_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64leu(r: u32, ) -> Weight { + (24_683_000 as Weight) + .saturating_add((7_404_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ges(r: u32, ) -> Weight { + (24_685_000 as Weight) + .saturating_add((7_461_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64geu(r: u32, ) -> Weight { + (25_147_000 as Weight) + .saturating_add((7_003_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64add(r: u32, ) -> Weight { + (24_705_000 as Weight) + .saturating_add((7_483_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64sub(r: u32, ) -> Weight { + (24_675_000 as Weight) + .saturating_add((7_377_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64mul(r: u32, ) -> Weight { + (24_680_000 as Weight) + .saturating_add((7_376_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64divs(r: u32, ) -> Weight { + (24_660_000 as Weight) + .saturating_add((13_091_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64divu(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((12_109_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rems(r: u32, ) -> Weight { + (24_615_000 as Weight) + .saturating_add((13_049_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64remu(r: u32, ) -> Weight { + (24_696_000 as Weight) + .saturating_add((12_039_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64and(r: u32, ) -> Weight { + (24_683_000 as Weight) + .saturating_add((7_314_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64or(r: u32, ) -> Weight { + (24_657_000 as Weight) + .saturating_add((7_401_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64xor(r: u32, ) -> Weight { + (24_661_000 as Weight) + .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shl(r: u32, ) -> Weight { + (24_644_000 as Weight) + .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shrs(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shru(r: u32, ) -> Weight { + (24_634_000 as Weight) + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rotl(r: u32, ) -> Weight { + (24_618_000 as Weight) + .saturating_add((7_452_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rotr(r: u32, ) -> Weight { + (24_618_000 as Weight) + .saturating_add((7_447_000 as Weight).saturating_mul(r as Weight)) + + } + +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn update_schedule() -> Weight { + (33_160_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + + } + fn put_code(n: u32, ) -> Weight { + (5_975_000 as Weight) + .saturating_add((108_953_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + + } + fn instantiate(n: u32, ) -> Weight { + (218_223_000 as Weight) + .saturating_add((1_007_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + + } + fn call() -> Weight { + (201_492_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + + } + fn claim_surcharge() -> Weight { + (449_203_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + + } + fn seal_caller(r: u32, ) -> Weight { + (136_650_000 as Weight) + .saturating_add((364_640_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_address(r: u32, ) -> Weight { + (144_167_000 as Weight) + .saturating_add((365_328_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_gas_left(r: u32, ) -> Weight { + (138_458_000 as Weight) + .saturating_add((361_076_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_balance(r: u32, ) -> Weight { + (147_909_000 as Weight) + .saturating_add((792_169_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + + } + fn seal_value_transferred(r: u32, ) -> Weight { + (148_524_000 as Weight) + .saturating_add((361_842_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_minimum_balance(r: u32, ) -> Weight { + (139_795_000 as Weight) + .saturating_add((366_013_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_tombstone_deposit(r: u32, ) -> Weight { + (140_557_000 as Weight) + .saturating_add((362_687_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_rent_allowance(r: u32, ) -> Weight { + (152_989_000 as Weight) + .saturating_add((836_876_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_block_number(r: u32, ) -> Weight { + (140_228_000 as Weight) + .saturating_add((360_561_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_now(r: u32, ) -> Weight { + (148_776_000 as Weight) + .saturating_add((361_712_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_weight_to_fee(r: u32, ) -> Weight { + (126_903_000 as Weight) + .saturating_add((603_100_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + + } + fn seal_gas(r: u32, ) -> Weight { + (125_712_000 as Weight) + .saturating_add((184_450_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_input(r: u32, ) -> Weight { + (136_175_000 as Weight) + .saturating_add((7_489_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_input_per_kb(n: u32, ) -> Weight { + (145_434_000 as Weight) + .saturating_add((276_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_return(r: u32, ) -> Weight { + (124_788_000 as Weight) + .saturating_add((5_696_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_return_per_kb(n: u32, ) -> Weight { + (133_483_000 as Weight) + .saturating_add((675_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_terminate(r: u32, ) -> Weight { + (135_387_000 as Weight) + .saturating_add((338_395_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) + } + fn seal_restore_to(r: u32, ) -> Weight { + (227_617_000 as Weight) + .saturating_add((132_493_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) + } + fn seal_restore_to_per_delta(d: u32, ) -> Weight { + (15_263_000 as Weight) + .saturating_add((3_732_219_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) + } + fn seal_random(r: u32, ) -> Weight { + (236_391_000 as Weight) + .saturating_add((913_452_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + + } + fn seal_deposit_event(r: u32, ) -> Weight { + (140_845_000 as Weight) + .saturating_add((1_322_796_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { + (1_651_556_000 as Weight) + .saturating_add((737_421_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((244_183_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) + .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) + } + fn seal_set_rent_allowance(r: u32, ) -> Weight { + (151_091_000 as Weight) + .saturating_add((983_375_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + + } + fn seal_set_storage(r: u32, ) -> Weight { + (460_478_000 as Weight) + .saturating_add((14_824_033_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_set_storage_per_kb(n: u32, ) -> Weight { + (2_255_458_000 as Weight) + .saturating_add((204_470_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + + } + fn seal_clear_storage(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((5_052_125_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_get_storage(r: u32, ) -> Weight { + (95_473_000 as Weight) + .saturating_add((1_044_784_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + + } + fn seal_get_storage_per_kb(n: u32, ) -> Weight { + (860_080_000 as Weight) + .saturating_add((146_913_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + + } + fn seal_transfer(r: u32, ) -> Weight { + (107_119_000 as Weight) + .saturating_add((5_993_434_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) + } + fn seal_call(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((10_533_320_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) + + } + fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { + (9_839_633_000 as Weight) + .saturating_add((5_580_035_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((53_716_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((73_668_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(RocksDbWeight::get().reads(105 as Weight)) + .saturating_add(RocksDbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) + .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) + } + fn seal_instantiate(r: u32, ) -> Weight { + (0 as Weight) + .saturating_add((21_856_497_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) + } + fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { + (18_796_671_000 as Weight) + .saturating_add((156_269_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((74_645_000 as Weight).saturating_mul(o as Weight)) + .saturating_add(RocksDbWeight::get().reads(207 as Weight)) + .saturating_add(RocksDbWeight::get().writes(202 as Weight)) + + } + fn seal_hash_sha2_256(r: u32, ) -> Weight { + (132_190_000 as Weight) + .saturating_add((319_943_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { + (747_208_000 as Weight) + .saturating_add((421_808_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_keccak_256(r: u32, ) -> Weight { + (139_235_000 as Weight) + .saturating_add((333_792_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { + (543_256_000 as Weight) + .saturating_add((334_383_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_256(r: u32, ) -> Weight { + (142_704_000 as Weight) + .saturating_add((305_513_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { + (592_813_000 as Weight) + .saturating_add((151_270_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_128(r: u32, ) -> Weight { + (139_921_000 as Weight) + .saturating_add((304_746_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { + (544_524_000 as Weight) + .saturating_add((151_549_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + + } + fn instr_i64const(r: u32, ) -> Weight { + (24_652_000 as Weight) + .saturating_add((3_306_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64load(r: u32, ) -> Weight { + (27_131_000 as Weight) + .saturating_add((162_220_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64store(r: u32, ) -> Weight { + (27_086_000 as Weight) + .saturating_add((230_977_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_select(r: u32, ) -> Weight { + (24_656_000 as Weight) + .saturating_add((12_570_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_if(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((12_442_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br(r: u32, ) -> Weight { + (24_589_000 as Weight) + .saturating_add((6_237_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_if(r: u32, ) -> Weight { + (24_650_000 as Weight) + .saturating_add((14_393_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_table(r: u32, ) -> Weight { + (24_689_000 as Weight) + .saturating_add((15_706_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_br_table_per_entry(e: u32, ) -> Weight { + (40_129_000 as Weight) + .saturating_add((83_000 as Weight).saturating_mul(e as Weight)) + + } + fn instr_call(r: u32, ) -> Weight { + (24_904_000 as Weight) + .saturating_add((96_429_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_call_indirect(r: u32, ) -> Weight { + (32_540_000 as Weight) + .saturating_add((201_773_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_call_indirect_per_param(p: u32, ) -> Weight { + (248_700_000 as Weight) + .saturating_add((3_705_000 as Weight).saturating_mul(p as Weight)) + + } + fn instr_local_get(r: u32, ) -> Weight { + (42_081_000 as Weight) + .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_local_set(r: u32, ) -> Weight { + (42_128_000 as Weight) + .saturating_add((3_678_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_local_tee(r: u32, ) -> Weight { + (42_073_000 as Weight) + .saturating_add((5_212_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_global_get(r: u32, ) -> Weight { + (28_182_000 as Weight) + .saturating_add((8_180_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_global_set(r: u32, ) -> Weight { + (28_060_000 as Weight) + .saturating_add((12_081_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_memory_current(r: u32, ) -> Weight { + (27_113_000 as Weight) + .saturating_add((3_802_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_memory_grow(r: u32, ) -> Weight { + (25_521_000 as Weight) + .saturating_add((2_288_295_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64clz(r: u32, ) -> Weight { + (24_662_000 as Weight) + .saturating_add((5_497_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ctz(r: u32, ) -> Weight { + (24_647_000 as Weight) + .saturating_add((5_556_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64popcnt(r: u32, ) -> Weight { + (24_646_000 as Weight) + .saturating_add((6_138_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64eqz(r: u32, ) -> Weight { + (24_649_000 as Weight) + .saturating_add((5_477_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64extendsi32(r: u32, ) -> Weight { + (24_655_000 as Weight) + .saturating_add((5_414_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64extendui32(r: u32, ) -> Weight { + (24_619_000 as Weight) + .saturating_add((5_434_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i32wrapi64(r: u32, ) -> Weight { + (24_654_000 as Weight) + .saturating_add((5_483_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64eq(r: u32, ) -> Weight { + (24_690_000 as Weight) + .saturating_add((7_485_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ne(r: u32, ) -> Weight { + (24_652_000 as Weight) + .saturating_add((7_468_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64lts(r: u32, ) -> Weight { + (24_667_000 as Weight) + .saturating_add((7_426_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ltu(r: u32, ) -> Weight { + (24_693_000 as Weight) + .saturating_add((7_393_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64gts(r: u32, ) -> Weight { + (24_675_000 as Weight) + .saturating_add((7_407_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64gtu(r: u32, ) -> Weight { + (24_697_000 as Weight) + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64les(r: u32, ) -> Weight { + (24_646_000 as Weight) + .saturating_add((7_420_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64leu(r: u32, ) -> Weight { + (24_683_000 as Weight) + .saturating_add((7_404_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64ges(r: u32, ) -> Weight { + (24_685_000 as Weight) + .saturating_add((7_461_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64geu(r: u32, ) -> Weight { + (25_147_000 as Weight) + .saturating_add((7_003_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64add(r: u32, ) -> Weight { + (24_705_000 as Weight) + .saturating_add((7_483_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64sub(r: u32, ) -> Weight { + (24_675_000 as Weight) + .saturating_add((7_377_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64mul(r: u32, ) -> Weight { + (24_680_000 as Weight) + .saturating_add((7_376_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64divs(r: u32, ) -> Weight { + (24_660_000 as Weight) + .saturating_add((13_091_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64divu(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((12_109_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rems(r: u32, ) -> Weight { + (24_615_000 as Weight) + .saturating_add((13_049_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64remu(r: u32, ) -> Weight { + (24_696_000 as Weight) + .saturating_add((12_039_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64and(r: u32, ) -> Weight { + (24_683_000 as Weight) + .saturating_add((7_314_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64or(r: u32, ) -> Weight { + (24_657_000 as Weight) + .saturating_add((7_401_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64xor(r: u32, ) -> Weight { + (24_661_000 as Weight) + .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shl(r: u32, ) -> Weight { + (24_644_000 as Weight) + .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shrs(r: u32, ) -> Weight { + (24_643_000 as Weight) + .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64shru(r: u32, ) -> Weight { + (24_634_000 as Weight) + .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rotl(r: u32, ) -> Weight { + (24_618_000 as Weight) + .saturating_add((7_452_000 as Weight).saturating_mul(r as Weight)) + + } + fn instr_i64rotr(r: u32, ) -> Weight { + (24_618_000 as Weight) + .saturating_add((7_447_000 as Weight).saturating_mul(r as Weight)) + + } + +} -- GitLab From dde09ab71c7c6c0c71a3b653e26c9df7ba377925 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 9 Nov 2020 14:00:33 -0300 Subject: [PATCH 003/163] Remove development TODO from public doc comment (#7500) --- frame/system/src/offchain.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index edb4e577572..25d18ac6bf2 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -445,8 +445,8 @@ pub trait AppCrypto { /// This trait adds extra bounds to `Public` and `Signature` types of the runtime /// that are necessary to use these types for signing. /// -/// TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`? -/// Seems that this may cause issues with bounds resolution. +// TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`? +// Seems that this may cause issues with bounds resolution. pub trait SigningTypes: crate::Trait { /// A public key that is capable of identifing `AccountId`s. /// -- GitLab From bf78c1655b7e49503a11cb070235089ea1e2455e Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Mon, 9 Nov 2020 20:26:24 +0100 Subject: [PATCH 004/163] refactor subtrait/elevated trait as not needed (#7497) --- frame/balances/src/lib.rs | 74 +++++---------------------------------- 1 file changed, 9 insertions(+), 65 deletions(-) diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 7ca6fd1e780..141a360f7e1 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -704,7 +704,7 @@ impl, I: Instance> Module { // of the inner member. mod imbalances { use super::{ - result, Subtrait, DefaultInstance, Imbalance, Trait, Zero, Instance, Saturating, + result, DefaultInstance, Imbalance, Trait, Zero, Instance, Saturating, StorageValue, TryDrop, }; use sp_std::mem; @@ -712,9 +712,9 @@ mod imbalances { /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been created without any equal and opposite accounting. #[must_use] - pub struct PositiveImbalance, I: Instance=DefaultInstance>(T::Balance); + pub struct PositiveImbalance, I: Instance=DefaultInstance>(T::Balance); - impl, I: Instance> PositiveImbalance { + impl, I: Instance> PositiveImbalance { /// Create a new positive imbalance from a balance. pub fn new(amount: T::Balance) -> Self { PositiveImbalance(amount) @@ -724,9 +724,9 @@ mod imbalances { /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been destroyed without any equal and opposite accounting. #[must_use] - pub struct NegativeImbalance, I: Instance=DefaultInstance>(T::Balance); + pub struct NegativeImbalance, I: Instance=DefaultInstance>(T::Balance); - impl, I: Instance> NegativeImbalance { + impl, I: Instance> NegativeImbalance { /// Create a new negative imbalance from a balance. pub fn new(amount: T::Balance) -> Self { NegativeImbalance(amount) @@ -835,81 +835,25 @@ mod imbalances { } } - impl, I: Instance> Drop for PositiveImbalance { + impl, I: Instance> Drop for PositiveImbalance { /// Basic drop handler will just square up the total issuance. fn drop(&mut self) { - , I>>::mutate( + >::mutate( |v| *v = v.saturating_add(self.0) ); } } - impl, I: Instance> Drop for NegativeImbalance { + impl, I: Instance> Drop for NegativeImbalance { /// Basic drop handler will just square up the total issuance. fn drop(&mut self) { - , I>>::mutate( + >::mutate( |v| *v = v.saturating_sub(self.0) ); } } } -// TODO: #2052 -// Somewhat ugly hack in order to gain access to module's `increase_total_issuance_by` -// using only the Subtrait (which defines only the types that are not dependent -// on Positive/NegativeImbalance). Subtrait must be used otherwise we end up with a -// circular dependency with Trait having some types be dependent on PositiveImbalance -// and PositiveImbalance itself depending back on Trait for its Drop impl (and thus -// its type declaration). -// This works as long as `increase_total_issuance_by` doesn't use the Imbalance -// types (basically for charging fees). -// This should eventually be refactored so that the type item that -// depends on the Imbalance type (DustRemoval) is placed in its own pallet. -struct ElevatedTrait, I: Instance>(T, I); -impl, I: Instance> Clone for ElevatedTrait { - fn clone(&self) -> Self { unimplemented!() } -} -impl, I: Instance> PartialEq for ElevatedTrait { - fn eq(&self, _: &Self) -> bool { unimplemented!() } -} -impl, I: Instance> Eq for ElevatedTrait {} -impl, I: Instance> frame_system::Trait for ElevatedTrait { - type BaseCallFilter = T::BaseCallFilter; - type Origin = T::Origin; - type Call = T::Call; - type Index = T::Index; - type BlockNumber = T::BlockNumber; - type Hash = T::Hash; - type Hashing = T::Hashing; - type AccountId = T::AccountId; - type Lookup = T::Lookup; - type Header = T::Header; - type Event = (); - type BlockHashCount = T::BlockHashCount; - type MaximumBlockWeight = T::MaximumBlockWeight; - type DbWeight = T::DbWeight; - type BlockExecutionWeight = T::BlockExecutionWeight; - type ExtrinsicBaseWeight = T::ExtrinsicBaseWeight; - type MaximumExtrinsicWeight = T::MaximumBlockWeight; - type MaximumBlockLength = T::MaximumBlockLength; - type AvailableBlockRatio = T::AvailableBlockRatio; - type Version = T::Version; - type PalletInfo = T::PalletInfo; - type OnNewAccount = T::OnNewAccount; - type OnKilledAccount = T::OnKilledAccount; - type AccountData = T::AccountData; - type SystemWeightInfo = T::SystemWeightInfo; -} -impl, I: Instance> Trait for ElevatedTrait { - type Balance = T::Balance; - type Event = (); - type DustRemoval = (); - type ExistentialDeposit = T::ExistentialDeposit; - type AccountStore = T::AccountStore; - type WeightInfo = >::WeightInfo; - type MaxLocks = T::MaxLocks; -} - impl, I: Instance> Currency for Module where T::Balance: MaybeSerializeDeserialize + Debug { -- GitLab From c9bde3d908a1995c99d7c241c72223bf6fe56ad7 Mon Sep 17 00:00:00 2001 From: Antoine Le Calvez Date: Tue, 10 Nov 2020 14:17:30 +0100 Subject: [PATCH 005/163] Fix comments of indices pallet events (#7511) Arguments for IndexAssigned and IndexFrozen were inverted in comments. --- frame/indices/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index aa645d0cb9e..fd2eb956f92 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -80,11 +80,11 @@ decl_event!( ::AccountId, ::AccountIndex { - /// A account index was assigned. \[who, index\] + /// A account index was assigned. \[index, who\] IndexAssigned(AccountId, AccountIndex), /// A account index has been freed up (unassigned). \[index\] IndexFreed(AccountIndex), - /// A account index has been frozen to its current account ID. \[who, index\] + /// A account index has been frozen to its current account ID. \[index, who\] IndexFrozen(AccountIndex, AccountId), } ); -- GitLab From f8bfe224b0a0143455f706bd96da3104141d0c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 11 Nov 2020 09:57:14 +0100 Subject: [PATCH 006/163] Skip slot lenience on first block in BABE (#7515) The genesis header doesn't have the BABE pre-digest and we insert `0` as slot number. The slot lenience calculation will return the maximum in this situation. Besides returning the maximum which is not bad at all, it also prints some a debug message that can be confusing in the first moment. To prevent printing this debug message, we now just return early when we see that the parent block is the genesis block. --- client/consensus/babe/src/lib.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 948959e9649..dce25292014 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -669,12 +669,17 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeSlot fn proposing_remaining_duration( &self, - head: &B::Header, + parent_head: &B::Header, slot_info: &SlotInfo, ) -> Option { let slot_remaining = self.slot_remaining_duration(slot_info); - let parent_slot = match find_pre_digest::(head) { + // If parent is genesis block, we don't require any lenience factor. + if parent_head.number().is_zero() { + return Some(slot_remaining) + } + + let parent_slot = match find_pre_digest::(parent_head) { Err(_) => return Some(slot_remaining), Ok(d) => d.slot_number(), }; @@ -682,7 +687,8 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeSlot if let Some(slot_lenience) = sc_consensus_slots::slot_lenience_exponential(parent_slot, slot_info) { - debug!(target: "babe", + debug!( + target: "babe", "No block for {} slots. Applying exponential lenience of {}s", slot_info.number.saturating_sub(parent_slot + 1), slot_lenience.as_secs(), @@ -697,8 +703,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeSlot /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. -pub fn find_pre_digest(header: &B::Header) -> Result> -{ +pub fn find_pre_digest(header: &B::Header) -> Result> { // genesis block doesn't contain a pre digest so let's generate a // dummy one to not break any invariants in the rest of the code if header.number().is_zero() { -- GitLab From 095d0f06a42b66a92f28d097499a69e3f170d59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Wed, 11 Nov 2020 14:29:19 +0100 Subject: [PATCH 007/163] slots: incrementally backoff claiming slots if finality lags behind (#7186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * babe: backoff authoring blocks when finality lags * babe: move backoff authoring params to default constructor * babe: deduplicate the test a bit * babe: set backoff constants in service * babe: use better names for backoff authoring block parameters * babe: remove last unwrap * babe: slight style tweak * babe: fix comment * slots: move backoff block authorship logic to SimpleSlotWorker * aura: append SlotInfo in on_slot * slots: use the correct types for parameters * slots: fix review comments * aura: add missing backoff authoring blocks parameters * slots: add comments for default values * slots: add additional checks in test * slots: update implementation for new master * slots: revert the change to SlotInfo * Fix review comments * slots: rework unit tests for backing off claiming slots * slots: add test for asymptotic behaviour for slot claims * slots: address review comments * slots: add test for max_interval * slots: add assertion for intervals between between claimed slots * slots: remove rustfmt directive * slots: another attempt at explaining authoring_rate * slots: up unfinalized_slack to 50 by default * slots: add tests for time to reach max_interval * slots: fix typo in comments * Apply suggestions from code review Co-authored-by: Bastian Köcher * slots: additional tweaks to comments and info calls * slots: rename to BackoffAuthoringOnFinalizedHeadLagging * slots: make the backing off strategy generic * Apply suggestions from code review Co-authored-by: Bastian Köcher * slots: implement backoff trait for () for simplicity * slots: move logging inside backing off function to make it more specific * aura: add missing function parameter Co-authored-by: Bastian Köcher --- Cargo.lock | 2 + bin/node-template/node/src/service.rs | 4 +- bin/node/cli/Cargo.toml | 1 + bin/node/cli/src/service.rs | 3 + client/consensus/aura/src/lib.rs | 40 ++- client/consensus/babe/src/lib.rs | 38 ++- client/consensus/babe/src/tests.rs | 2 + client/consensus/slots/Cargo.toml | 1 + client/consensus/slots/src/lib.rs | 469 +++++++++++++++++++++++++- 9 files changed, 540 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aff2c999176..62cb03dedaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3827,6 +3827,7 @@ dependencies = [ "sc-consensus", "sc-consensus-babe", "sc-consensus-epochs", + "sc-consensus-slots", "sc-finality-grandpa", "sc-keystore", "sc-network", @@ -6881,6 +6882,7 @@ dependencies = [ "sc-telemetry", "sp-api", "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-slots", diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 90187061c9c..d85de7c840d 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -111,6 +111,7 @@ pub fn new_full(config: Configuration) -> Result { let role = config.role.clone(); let force_authoring = config.force_authoring; + let backoff_authoring_blocks: Option<()> = None; let name = config.network.node_name.clone(); let enable_grandpa = !config.disable_grandpa; let prometheus_registry = config.prometheus_registry().cloned(); @@ -155,7 +156,7 @@ pub fn new_full(config: Configuration) -> Result { let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>( + let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _,_>( sc_consensus_aura::slot_duration(&*client)?, client.clone(), select_chain, @@ -164,6 +165,7 @@ pub fn new_full(config: Configuration) -> Result { network.clone(), inherent_data_providers.clone(), force_authoring, + backoff_authoring_blocks, keystore_container.sync_keystore(), can_author_with, )?; diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index e396b2dceff..26a23ce36ec 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -64,6 +64,7 @@ sc-chain-spec = { version = "2.0.0", path = "../../../client/chain-spec" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-transaction-pool = { version = "2.0.0", path = "../../../client/transaction-pool" } sc-network = { version = "0.8.0", path = "../../../client/network" } +sc-consensus-slots = { version = "0.8.0", path = "../../../client/consensus/slots" } sc-consensus-babe = { version = "0.8.0", path = "../../../client/consensus/babe" } grandpa = { version = "0.8.0", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } sc-client-db = { version = "0.8.0", default-features = false, path = "../../../client/db" } diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index ecf50dc1463..3bc406b84fc 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -204,6 +204,8 @@ pub fn new_full_base( let role = config.role.clone(); let force_authoring = config.force_authoring; + let backoff_authoring_blocks = + Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default()); let name = config.network.node_name.clone(); let enable_grandpa = !config.disable_grandpa; let prometheus_registry = config.prometheus_registry().cloned(); @@ -249,6 +251,7 @@ pub fn new_full_base( sync_oracle: network.clone(), inherent_data_providers: inherent_data_providers.clone(), force_authoring, + backoff_authoring_blocks, babe_link, can_author_with, }; diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 5013c1813b6..97bfb217b93 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -59,7 +59,7 @@ use sp_core::crypto::Public; use sp_application_crypto::{AppKey, AppPublic}; use sp_runtime::{ generic::{BlockId, OpaqueDigestItemId}, - Justification, + traits::NumberFor, Justification, }; use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero, Member}; use sp_api::ProvideRuntimeApi; @@ -73,6 +73,7 @@ use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO}; use sc_consensus_slots::{ CheckedHeader, SlotInfo, SlotCompatible, StorageChanges, check_equivocation, + BackoffAuthoringBlocksStrategy, }; use sp_api::ApiExt; @@ -138,7 +139,7 @@ impl SlotCompatible for AuraSlotCompatible { } /// Start the aura worker. The returned future should be run in a futures executor. -pub fn start_aura( +pub fn start_aura( slot_duration: SlotDuration, client: Arc, select_chain: SC, @@ -147,11 +148,12 @@ pub fn start_aura( sync_oracle: SO, inherent_data_providers: InherentDataProviders, force_authoring: bool, + backoff_authoring_blocks: Option, keystore: SyncCryptoStorePtr, can_author_with: CAW, ) -> Result, sp_consensus::Error> where B: BlockT, - C: ProvideRuntimeApi + BlockOf + ProvideCache + AuxStore + Send + Sync, + C: ProvideRuntimeApi + BlockOf + ProvideCache + AuxStore + HeaderBackend + Send + Sync, C::Api: AuraApi>, SC: SelectChain, E: Environment + Send + Sync + 'static, @@ -163,6 +165,7 @@ pub fn start_aura( Error: std::error::Error + Send + From + 'static, SO: SyncOracle + Send + Sync + Clone, CAW: CanAuthorWith + Send, + BS: BackoffAuthoringBlocksStrategy> + Send + 'static, { let worker = AuraWorker { client, @@ -171,6 +174,7 @@ pub fn start_aura( keystore, sync_oracle: sync_oracle.clone(), force_authoring, + backoff_authoring_blocks, _key_type: PhantomData::

, }; register_aura_inherent_data_provider( @@ -188,20 +192,22 @@ pub fn start_aura( )) } -struct AuraWorker { +struct AuraWorker { client: Arc, block_import: Arc>, env: E, keystore: SyncCryptoStorePtr, sync_oracle: SO, force_authoring: bool, + backoff_authoring_blocks: Option, _key_type: PhantomData

, } -impl sc_consensus_slots::SimpleSlotWorker for AuraWorker +impl sc_consensus_slots::SimpleSlotWorker + for AuraWorker where B: BlockT, - C: ProvideRuntimeApi + BlockOf + ProvideCache + Sync, + C: ProvideRuntimeApi + BlockOf + ProvideCache + HeaderBackend + Sync, C::Api: AuraApi>, E: Environment, E::Proposer: Proposer>, @@ -210,6 +216,7 @@ where P::Public: AppPublic + Public + Member + Encode + Decode + Hash, P::Signature: TryFrom> + Member + Encode + Decode + Hash + Debug, SO: SyncOracle + Send + Clone, + BS: BackoffAuthoringBlocksStrategy> + Send + 'static, Error: std::error::Error + Send + From + 'static, { type BlockImport = I; @@ -316,6 +323,21 @@ where self.force_authoring } + fn should_backoff(&self, slot_number: u64, chain_head: &B::Header) -> bool { + if let Some(ref strategy) = self.backoff_authoring_blocks { + if let Ok(chain_head_slot) = find_pre_digest::(chain_head) { + return strategy.should_backoff( + *chain_head.number(), + chain_head_slot, + self.client.info().finalized_number, + slot_number, + self.logging_target(), + ); + } + } + false + } + fn sync_oracle(&mut self) -> &mut Self::SyncOracle { &mut self.sync_oracle } @@ -863,7 +885,7 @@ mod tests { use sp_keyring::sr25519::Keyring; use sc_client_api::BlockchainEvents; use sp_consensus_aura::sr25519::AuthorityPair; - use sc_consensus_slots::SimpleSlotWorker; + use sc_consensus_slots::{SimpleSlotWorker, BackoffAuthoringOnFinalizedHeadLagging}; use std::task::Poll; use sc_block_builder::BlockBuilderProvider; use sp_runtime::traits::Header as _; @@ -1012,7 +1034,7 @@ mod tests { &inherent_data_providers, slot_duration.get() ).expect("Registers aura inherent data provider"); - aura_futures.push(start_aura::<_, _, _, _, _, AuthorityPair, _, _, _>( + aura_futures.push(start_aura::<_, _, _, _, _, AuthorityPair, _, _, _, _>( slot_duration, client.clone(), select_chain, @@ -1021,6 +1043,7 @@ mod tests { DummyOracle, inherent_data_providers, false, + Some(BackoffAuthoringOnFinalizedHeadLagging::default()), keystore, sp_consensus::AlwaysCanAuthor, ).expect("Starts aura")); @@ -1081,6 +1104,7 @@ mod tests { keystore: keystore.into(), sync_oracle: DummyOracle.clone(), force_authoring: false, + backoff_authoring_blocks: Some(BackoffAuthoringOnFinalizedHeadLagging::default()), _key_type: PhantomData::, }; diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index dce25292014..c672440d114 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -114,6 +114,7 @@ use log::{debug, info, log, trace, warn}; use prometheus_endpoint::Registry; use sc_consensus_slots::{ SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation, + BackoffAuthoringBlocksStrategy, }; use sc_consensus_epochs::{ descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT, ViableEpochDescriptor, @@ -354,7 +355,7 @@ impl std::ops::Deref for Config { } /// Parameters for BABE. -pub struct BabeParams { +pub struct BabeParams { /// The keystore that manages the keys of the node. pub keystore: SyncCryptoStorePtr, @@ -381,6 +382,9 @@ pub struct BabeParams { /// Force authoring of blocks even if we are offline pub force_authoring: bool, + /// Strategy and parameters for backing off block production. + pub backoff_authoring_blocks: Option, + /// The source of timestamps for relative slots pub babe_link: BabeLink, @@ -389,7 +393,7 @@ pub struct BabeParams { } /// Start the babe worker. -pub fn start_babe(BabeParams { +pub fn start_babe(BabeParams { keystore, client, select_chain, @@ -398,9 +402,10 @@ pub fn start_babe(BabeParams { sync_oracle, inherent_data_providers, force_authoring, + backoff_authoring_blocks, babe_link, can_author_with, -}: BabeParams) -> Result< +}: BabeParams) -> Result< BabeWorker, sp_consensus::Error, > where @@ -416,6 +421,7 @@ pub fn start_babe(BabeParams { Error: std::error::Error + Send + From + From + 'static, SO: SyncOracle + Send + Sync + Clone + 'static, CAW: CanAuthorWith + Send + 'static, + BS: BackoffAuthoringBlocksStrategy> + Send + 'static, { let config = babe_link.config; let slot_notification_sinks = Arc::new(Mutex::new(Vec::new())); @@ -426,6 +432,7 @@ pub fn start_babe(BabeParams { env, sync_oracle: sync_oracle.clone(), force_authoring, + backoff_authoring_blocks, keystore, epoch_changes: babe_link.epoch_changes.clone(), slot_notification_sinks: slot_notification_sinks.clone(), @@ -490,19 +497,22 @@ impl futures::Future for BabeWorker { /// Slot notification sinks. type SlotNotificationSinks = Arc::Hash, NumberFor, Epoch>)>>>>; -struct BabeSlotWorker { +struct BabeSlotWorker { client: Arc, block_import: Arc>, env: E, sync_oracle: SO, force_authoring: bool, + backoff_authoring_blocks: Option, keystore: SyncCryptoStorePtr, epoch_changes: SharedEpochChanges, slot_notification_sinks: SlotNotificationSinks, config: Config, } -impl sc_consensus_slots::SimpleSlotWorker for BabeSlotWorker where +impl sc_consensus_slots::SimpleSlotWorker + for BabeSlotWorker +where B: BlockT, C: ProvideRuntimeApi + ProvideCache + @@ -513,6 +523,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeSlot E::Proposer: Proposer>, I: BlockImport> + Send + Sync + 'static, SO: SyncOracle + Send + Clone, + BS: BackoffAuthoringBlocksStrategy>, Error: std::error::Error + Send + From + From + 'static, { type EpochData = ViableEpochDescriptor, Epoch>; @@ -657,6 +668,23 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeSlot self.force_authoring } + fn should_backoff(&self, slot_number: u64, chain_head: &B::Header) -> bool { + if let Some(ref strategy) = self.backoff_authoring_blocks { + if let Ok(chain_head_slot) = find_pre_digest::(chain_head) + .map(|digest| digest.slot_number()) + { + return strategy.should_backoff( + *chain_head.number(), + chain_head_slot, + self.client.info().finalized_number, + slot_number, + self.logging_target(), + ); + } + } + false + } + fn sync_oracle(&mut self) -> &mut Self::SyncOracle { &mut self.sync_oracle } diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 6b0f5870ba5..b31699d13e0 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -33,6 +33,7 @@ use sp_consensus_babe::{ make_transcript, make_transcript_data, }; +use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sp_consensus::{ NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor, @@ -434,6 +435,7 @@ fn run_one_test( sync_oracle: DummyOracle, inherent_data_providers: data.inherent_data_providers.clone(), force_authoring: false, + backoff_authoring_blocks: Some(BackoffAuthoringOnFinalizedHeadLagging::default()), babe_link: data.link.clone(), keystore, can_author_with: sp_consensus::AlwaysCanAuthor, diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index a13a712fe76..d07ef49835b 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -19,6 +19,7 @@ sc-client-api = { version = "2.0.0", path = "../../api" } sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-trie = { version = "2.0.0", path = "../../../primitives/trie" } sp-application-crypto = { version = "2.0.0", path = "../../../primitives/application-crypto" } +sp-arithmetic = { version = "2.0.0", path = "../../../primitives/arithmetic" } sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } sp-consensus-slots = { version = "0.8.0", path = "../../../primitives/consensus/slots" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 681d4a6273e..d8601a7c12c 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -29,18 +29,21 @@ pub use slots::SlotInfo; use slots::Slots; pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND}; +use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc, time::{Instant, Duration}}; use codec::{Decode, Encode}; -use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData, RecordProof}; use futures::{prelude::*, future::{self, Either}}; use futures_timer::Delay; -use sp_inherents::{InherentData, InherentDataProviders}; use log::{debug, error, info, warn}; -use sp_runtime::generic::BlockId; -use sp_runtime::traits::{Block as BlockT, Header, HashFor, NumberFor}; +use parking_lot::Mutex; use sp_api::{ProvideRuntimeApi, ApiRef}; -use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc, time::{Instant, Duration}}; +use sp_arithmetic::traits::BaseArithmetic; +use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData, RecordProof}; +use sp_inherents::{InherentData, InherentDataProviders}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Header, HashFor, NumberFor} +}; use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO}; -use parking_lot::Mutex; /// The changes that need to applied to the storage to create the state for a block. /// @@ -158,6 +161,16 @@ pub trait SimpleSlotWorker { /// Whether to force authoring if offline. fn force_authoring(&self) -> bool; + /// Returns whether the block production should back off. + /// + /// By default this function always returns `false`. + /// + /// An example strategy that back offs if the finalized head is lagging too much behind the tip + /// is implemented by [`BackoffAuthoringOnFinalizedHeadLagging`]. + fn should_backoff(&self, _slot_number: u64, _chain_head: &B::Header) -> bool { + false + } + /// Returns a handle to a `SyncOracle`. fn sync_oracle(&mut self) -> &mut Self::SyncOracle; @@ -249,6 +262,10 @@ pub trait SimpleSlotWorker { Some(claim) => claim, }; + if self.should_backoff(slot_number, &chain_head) { + return Box::pin(future::ready(None)); + } + debug!( target: self.logging_target(), "Starting authorship at slot {}; timestamp = {}", @@ -583,9 +600,110 @@ pub fn slot_lenience_linear(parent_slot: u64, slot_info: &SlotInfo) -> Option { + /// Returns true if we should backoff authoring new blocks. + fn should_backoff( + &self, + chain_head_number: N, + chain_head_slot: u64, + finalized_number: N, + slow_now: u64, + logging_target: &str, + ) -> bool; +} + +/// A simple default strategy for how to decide backing off authoring blocks if the number of +/// unfinalized blocks grows too large. +#[derive(Clone)] +pub struct BackoffAuthoringOnFinalizedHeadLagging { + /// The max interval to backoff when authoring blocks, regardless of delay in finality. + pub max_interval: N, + /// The number of unfinalized blocks allowed before starting to consider to backoff authoring + /// blocks. Note that depending on the value for `authoring_bias`, there might still be an + /// additional wait until block authorship starts getting declined. + pub unfinalized_slack: N, + /// Scales the backoff rate. A higher value effectively means we backoff slower, taking longer + /// time to reach the maximum backoff as the unfinalized head of chain grows. + pub authoring_bias: N, +} + +/// These parameters is supposed to be some form of sensible defaults. +impl Default for BackoffAuthoringOnFinalizedHeadLagging { + fn default() -> Self { + Self { + // Never wait more than 100 slots before authoring blocks, regardless of delay in + // finality. + max_interval: 100.into(), + // Start to consider backing off block authorship once we have 50 or more unfinalized + // blocks at the head of the chain. + unfinalized_slack: 50.into(), + // A reasonable default for the authoring bias, or reciprocal interval scaling, is 2. + // Effectively meaning that consider the unfinalized head suffix length to grow half as + // fast as in actuality. + authoring_bias: 2.into(), + } + } +} + +impl BackoffAuthoringBlocksStrategy for BackoffAuthoringOnFinalizedHeadLagging +where + N: BaseArithmetic + Copy +{ + fn should_backoff( + &self, + chain_head_number: N, + chain_head_slot: u64, + finalized_number: N, + slot_now: u64, + logging_target: &str, + ) -> bool { + // This should not happen, but we want to keep the previous behaviour if it does. + if slot_now <= chain_head_slot { + return false; + } + + let unfinalized_block_length = chain_head_number - finalized_number; + let interval = unfinalized_block_length.saturating_sub(self.unfinalized_slack) + / self.authoring_bias; + let interval = interval.min(self.max_interval); + + // We're doing arithmetic between block and slot numbers. + let interval: u64 = interval.unique_saturated_into(); + + // If interval is nonzero we backoff if the current slot isn't far enough ahead of the chain + // head. + if slot_now <= chain_head_slot + interval { + info!( + target: logging_target, + "Backing off claiming new slot for block authorship: finality is lagging.", + ); + true + } else { + false + } + } +} + +impl BackoffAuthoringBlocksStrategy for () { + fn should_backoff( + &self, + _chain_head_number: N, + _chain_head_slot: u64, + _finalized_number: N, + _slot_now: u64, + _logging_target: &str, + ) -> bool { + false + } +} + #[cfg(test)] mod test { use std::time::{Duration, Instant}; + use crate::{BackoffAuthoringOnFinalizedHeadLagging, BackoffAuthoringBlocksStrategy}; + use substrate_test_runtime_client::runtime::Block; + use sp_api::NumberFor; const SLOT_DURATION: Duration = Duration::from_millis(6000); @@ -644,4 +762,343 @@ mod test { Some(SLOT_DURATION * 2u32.pow(7)), ); } + + #[derive(PartialEq, Debug)] + struct HeadState { + head_number: NumberFor, + head_slot: u64, + slot_now: NumberFor, + } + + impl HeadState { + fn author_block(&mut self) { + // Add a block to the head, and set latest slot to the current + self.head_number += 1; + self.head_slot = self.slot_now; + // Advance slot to next + self.slot_now += 1; + } + + fn dont_author_block(&mut self) { + self.slot_now += 1; + } + } + + #[test] + fn should_never_backoff_when_head_not_advancing() { + let strategy = BackoffAuthoringOnFinalizedHeadLagging::> { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + + let head_number = 1; + let head_slot = 1; + let finalized_number = 1; + let slot_now = 2; + + let should_backoff: Vec = (slot_now..1000) + .map(|s| strategy.should_backoff(head_number, head_slot, finalized_number, s, "slots")) + .collect(); + + // Should always be false, since the head isn't advancing + let expected: Vec = (slot_now..1000).map(|_| false).collect(); + assert_eq!(should_backoff, expected); + } + + #[test] + fn should_stop_authoring_if_blocks_are_still_produced_when_finality_stalled() { + let strategy = BackoffAuthoringOnFinalizedHeadLagging::> { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + + let mut head_number = 1; + let mut head_slot = 1; + let finalized_number = 1; + let slot_now = 2; + + let should_backoff: Vec = (slot_now..300) + .map(move |s| { + let b = strategy.should_backoff( + head_number, + head_slot, + finalized_number, + s, + "slots", + ); + // Chain is still advancing (by someone else) + head_number += 1; + head_slot = s; + b + }) + .collect(); + + // Should always be true after a short while, since the chain is advancing but finality is stalled + let expected: Vec = (slot_now..300).map(|s| s > 8).collect(); + assert_eq!(should_backoff, expected); + } + + #[test] + fn should_never_backoff_if_max_interval_is_reached() { + let strategy = BackoffAuthoringOnFinalizedHeadLagging::> { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + + // The limit `max_interval` is used when the unfinalized chain grows to + // `max_interval * authoring_bias + unfinalized_slack`, + // which for the above parameters becomes + // 100 * 2 + 5 = 205. + // Hence we trigger this with head_number > finalized_number + 205. + let head_number = 207; + let finalized_number = 1; + + // The limit is then used once the current slot is `max_interval` ahead of slot of the head. + let head_slot = 1; + let slot_now = 2; + let max_interval = strategy.max_interval; + + let should_backoff: Vec = (slot_now..200) + .map(|s| strategy.should_backoff(head_number, head_slot, finalized_number, s, "slots")) + .collect(); + + // Should backoff (true) until we are `max_interval` number of slots ahead of the chain + // head slot, then we never backoff (false). + let expected: Vec = (slot_now..200).map(|s| s <= max_interval + head_slot).collect(); + assert_eq!(should_backoff, expected); + } + + #[test] + fn should_backoff_authoring_when_finality_stalled() { + let param = BackoffAuthoringOnFinalizedHeadLagging { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + + let finalized_number = 2; + let mut head_state = HeadState { + head_number: 4, + head_slot: 10, + slot_now: 11, + }; + + let should_backoff = |head_state: &HeadState| -> bool { + >>::should_backoff( + ¶m, + head_state.head_number, + head_state.head_slot, + finalized_number, + head_state.slot_now, + "slots", + ) + }; + + let backoff: Vec = (head_state.slot_now..200) + .map(|_| { + if should_backoff(&head_state) { + head_state.dont_author_block(); + true + } else { + head_state.author_block(); + false + } + }) + .collect(); + + // Gradually start to backoff more and more frequently + let expected = [ + false, false, false, false, false, // no effect + true, false, + true, false, // 1:1 + true, true, false, + true, true, false, // 2:1 + true, true, true, false, + true, true, true, false, // 3:1 + true, true, true, true, false, + true, true, true, true, false, // 4:1 + true, true, true, true, true, false, + true, true, true, true, true, false, // 5:1 + true, true, true, true, true, true, false, + true, true, true, true, true, true, false, // 6:1 + true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, false, // 7:1 + true, true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, true, false, // 8:1 + true, true, true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, true, true, false, // 9:1 + true, true, true, true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, true, true, true, false, // 10:1 + true, true, true, true, true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, true, true, true, true, false, // 11:1 + true, true, true, true, true, true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, true, true, true, true, true, false, // 12:1 + true, true, true, true, + ]; + + assert_eq!(backoff, expected); + } + + #[test] + fn should_never_wait_more_than_max_interval() { + let param = BackoffAuthoringOnFinalizedHeadLagging { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + + let finalized_number = 2; + let starting_slot = 11; + let mut head_state = HeadState { + head_number: 4, + head_slot: 10, + slot_now: starting_slot, + }; + + let should_backoff = |head_state: &HeadState| -> bool { + >>::should_backoff( + ¶m, + head_state.head_number, + head_state.head_slot, + finalized_number, + head_state.slot_now, + "slots", + ) + }; + + let backoff: Vec = (head_state.slot_now..40000) + .map(|_| { + if should_backoff(&head_state) { + head_state.dont_author_block(); + true + } else { + head_state.author_block(); + false + } + }) + .collect(); + + let slots_claimed: Vec = backoff + .iter() + .enumerate() + .filter(|&(_i, x)| x == &false) + .map(|(i, _x)| i + starting_slot as usize) + .collect(); + + let last_slot = backoff.len() + starting_slot as usize; + let mut last_two_claimed = slots_claimed.iter().rev().take(2); + + // Check that we claimed all the way to the end. Check two slots for when we have an uneven + // number of slots_claimed. + let expected_distance = param.max_interval as usize + 1; + assert_eq!(last_slot - last_two_claimed.next().unwrap(), 92); + assert_eq!(last_slot - last_two_claimed.next().unwrap(), 92 + expected_distance); + + let intervals: Vec<_> = slots_claimed + .windows(2) + .map(|x| x[1] - x[0]) + .collect(); + + // The key thing is that the distance between claimed slots is capped to `max_interval + 1` + // assert_eq!(max_observed_interval, Some(&expected_distance)); + assert_eq!(intervals.iter().max(), Some(&expected_distance)); + + // But lets assert all distances, which we expect to grow linearly until `max_interval + 1` + let expected_intervals: Vec<_> = (0..497) + .map(|i| (i/2).max(1).min(expected_distance) ) + .collect(); + + assert_eq!(intervals, expected_intervals); + } + + fn run_until_max_interval(param: BackoffAuthoringOnFinalizedHeadLagging) -> (u64, u64) { + let finalized_number = 0; + let mut head_state = HeadState { + head_number: 0, + head_slot: 0, + slot_now: 1, + }; + + let should_backoff = |head_state: &HeadState| -> bool { + >>::should_backoff( + ¶m, + head_state.head_number, + head_state.head_slot, + finalized_number, + head_state.slot_now, + "slots", + ) + }; + + // Number of blocks until we reach the max interval + let block_for_max_interval + = param.max_interval * param.authoring_bias + param.unfinalized_slack; + + while head_state.head_number < block_for_max_interval { + if should_backoff(&head_state) { + head_state.dont_author_block(); + } else { + head_state.author_block(); + } + } + + let slot_time = 6; + let time_to_reach_limit = slot_time * head_state.slot_now; + (block_for_max_interval, time_to_reach_limit) + } + + // Denoting + // C: unfinalized_slack + // M: authoring_bias + // X: max_interval + // then the number of slots to reach the max interval can be computed from + // (start_slot + C) + M * sum(n, 1, X) + // or + // (start_slot + C) + M * X*(X+1)/2 + fn expected_time_to_reach_max_interval( + param: &BackoffAuthoringOnFinalizedHeadLagging + ) -> (u64, u64) { + let c = param.unfinalized_slack; + let m = param.authoring_bias; + let x = param.max_interval; + let slot_time = 6; + + let block_for_max_interval = x * m + c; + + // The 1 is because we start at slot_now = 1. + let expected_number_of_slots = (1 + c) + m * x * (x + 1) / 2; + let time_to_reach = expected_number_of_slots * slot_time; + + (block_for_max_interval, time_to_reach) + } + + #[test] + fn time_to_reach_upper_bound_for_smaller_slack() { + let param = BackoffAuthoringOnFinalizedHeadLagging { + max_interval: 100, + unfinalized_slack: 5, + authoring_bias: 2, + }; + let expected = expected_time_to_reach_max_interval(¶m); + let (block_for_max_interval, time_to_reach_limit) = run_until_max_interval(param); + assert_eq!((block_for_max_interval, time_to_reach_limit), expected); + // Note: 16 hours is 57600 sec + assert_eq!((block_for_max_interval, time_to_reach_limit), (205, 60636)); + } + + #[test] + fn time_to_reach_upper_bound_for_larger_slack() { + let param = BackoffAuthoringOnFinalizedHeadLagging { + max_interval: 100, + unfinalized_slack: 50, + authoring_bias: 2, + }; + let expected = expected_time_to_reach_max_interval(¶m); + let (block_for_max_interval, time_to_reach_limit) = run_until_max_interval(param); + assert_eq!((block_for_max_interval, time_to_reach_limit), expected); + assert_eq!((block_for_max_interval, time_to_reach_limit), (250, 60906)); + } } -- GitLab From 71d027841a57a6bfa0549218923e78477cf96a0a Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 11 Nov 2020 18:19:27 +0100 Subject: [PATCH 008/163] Export app-crypto specific keystore functions (#7489) * Export app-crypto specific keystore functions * Also add back the insert function * Switch KeystoreContainer to an enum * Only export the bare minimal for LocalKeystore and fix service compile * fix: should return Arc * Add docs stating that functions only available in local keystore * Remove insert and generate functions * fix: generate function should be available in test * Add keypair function to trait * Revert "Add keypair function to trait" This reverts commit ad921b09ca73d3c09298e3a51b562ef8e0067781. * Add note for local_keystore function in service --- client/keystore/src/local.rs | 94 +++++++++++++++++------------------ client/service/src/builder.rs | 37 ++++++++++---- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 856327d46f6..e0b95a08d5c 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -38,7 +38,7 @@ use sp_keystore::{ SyncCryptoStore, vrf::{VRFTranscriptData, VRFSignature, make_transcript}, }; -use sp_application_crypto::{ed25519, sr25519, ecdsa}; +use sp_application_crypto::{ed25519, sr25519, ecdsa, AppPair, AppKey, IsWrappedBy}; use crate::{Result, Error}; @@ -57,6 +57,14 @@ impl LocalKeystore { let inner = KeystoreInner::new_in_memory(); Self(RwLock::new(inner)) } + + /// Get a key pair for the given public key. + /// + /// This function is only available for a local keystore. If your application plans to work with + /// remote keystores, you do not want to depend on it. + pub fn key_pair(&self, public: &::Public) -> Result { + self.0.read().key_pair::(public) + } } #[async_trait] @@ -470,6 +478,11 @@ impl KeystoreInner { Ok(public_keys) } + + /// Get a key pair for the given public key. + pub fn key_pair(&self, public: &::Public) -> Result { + self.key_pair_by_type::(IsWrappedBy::from_ref(public), Pair::ID).map(Into::into) + } } @@ -479,47 +492,32 @@ mod tests { use tempfile::TempDir; use sp_core::{ Pair, - crypto::{IsWrappedBy, Ss58Codec}, + crypto::Ss58Codec, testing::SR25519, }; - use sp_application_crypto::{ed25519, sr25519, AppPublic, AppKey, AppPair}; + use sp_application_crypto::{ed25519, sr25519, AppPublic}; use std::{ fs, str::FromStr, }; - /// Generate a new key. - /// - /// Places it into the file system store. - fn generate(store: &KeystoreInner) -> Result { - store.generate_by_type::(Pair::ID).map(Into::into) - } - - /// Create a new key from seed. - /// - /// Does not place it into the file system store. - fn insert_ephemeral_from_seed(store: &mut KeystoreInner, seed: &str) -> Result { - store.insert_ephemeral_from_seed_by_type::(seed, Pair::ID).map(Into::into) - } + impl KeystoreInner { + fn insert_ephemeral_from_seed(&mut self, seed: &str) -> Result { + self.insert_ephemeral_from_seed_by_type::(seed, Pair::ID).map(Into::into) + } - /// Get public keys of all stored keys that match the key type. - /// - /// This will just use the type of the public key (a list of which to be returned) in order - /// to determine the key type. Unless you use a specialized application-type public key, then - /// this only give you keys registered under generic cryptography, and will not return keys - /// registered under the application type. - fn public_keys(store: &KeystoreInner) -> Result> { - store.raw_public_keys(Public::ID) - .map(|v| { - v.into_iter() - .map(|k| Public::from_slice(k.as_slice())) - .collect() - }) - } + fn public_keys(&self) -> Result> { + self.raw_public_keys(Public::ID) + .map(|v| { + v.into_iter() + .map(|k| Public::from_slice(k.as_slice())) + .collect() + }) + } - /// Get a key pair for the given public key. - fn key_pair(store: &KeystoreInner, public: &::Public) -> Result { - store.key_pair_by_type::(IsWrappedBy::from_ref(public), Pair::ID).map(Into::into) + fn generate(&self) -> Result { + self.generate_by_type::(Pair::ID).map(Into::into) + } } #[test] @@ -527,14 +525,14 @@ mod tests { let temp_dir = TempDir::new().unwrap(); let store = KeystoreInner::open(temp_dir.path(), None).unwrap(); - assert!(public_keys::(&store).unwrap().is_empty()); + assert!(store.public_keys::().unwrap().is_empty()); - let key: ed25519::AppPair = generate(&store).unwrap(); - let key2: ed25519::AppPair = key_pair(&store, &key.public()).unwrap(); + let key: ed25519::AppPair = store.generate().unwrap(); + let key2: ed25519::AppPair = store.key_pair(&key.public()).unwrap(); assert_eq!(key.public(), key2.public()); - assert_eq!(public_keys::(&store).unwrap()[0], key.public()); + assert_eq!(store.public_keys::().unwrap()[0], key.public()); } #[test] @@ -542,8 +540,7 @@ mod tests { let temp_dir = TempDir::new().unwrap(); let mut store = KeystoreInner::open(temp_dir.path(), None).unwrap(); - let pair: ed25519::AppPair = insert_ephemeral_from_seed( - &mut store, + let pair: ed25519::AppPair = store.insert_ephemeral_from_seed( "0x3d97c819d68f9bafa7d6e79cb991eebcd77d966c5334c0b94d9e1fa7ad0869dc" ).unwrap(); assert_eq!( @@ -554,7 +551,7 @@ mod tests { drop(store); let store = KeystoreInner::open(temp_dir.path(), None).unwrap(); // Keys generated from seed should not be persisted! - assert!(key_pair::(&store, &pair.public()).is_err()); + assert!(store.key_pair::(&pair.public()).is_err()); } #[test] @@ -566,15 +563,15 @@ mod tests { Some(FromStr::from_str(password.as_str()).unwrap()), ).unwrap(); - let pair: ed25519::AppPair = generate(&store).unwrap(); + let pair: ed25519::AppPair = store.generate().unwrap(); assert_eq!( pair.public(), - key_pair::(&store, &pair.public()).unwrap().public(), + store.key_pair::(&pair.public()).unwrap().public(), ); // Without the password the key should not be retrievable let store = KeystoreInner::open(temp_dir.path(), None).unwrap(); - assert!(key_pair::(&store, &pair.public()).is_err()); + assert!(store.key_pair::(&pair.public()).is_err()); let store = KeystoreInner::open( temp_dir.path(), @@ -582,7 +579,7 @@ mod tests { ).unwrap(); assert_eq!( pair.public(), - key_pair::(&store, &pair.public()).unwrap().public(), + store.key_pair::(&pair.public()).unwrap().public(), ); } @@ -593,18 +590,17 @@ mod tests { let mut keys = Vec::new(); for i in 0..10 { - keys.push(generate::(&store).unwrap().public()); - keys.push(insert_ephemeral_from_seed::( - &mut store, + keys.push(store.generate::().unwrap().public()); + keys.push(store.insert_ephemeral_from_seed::( &format!("0x3d97c819d68f9bafa7d6e79cb991eebcd7{}d966c5334c0b94d9e1fa7ad0869dc", i), ).unwrap().public()); } // Generate a key of a different type - generate::(&store).unwrap(); + store.generate::().unwrap(); keys.sort(); - let mut store_pubs = public_keys::(&store).unwrap(); + let mut store_pubs = store.public_keys::().unwrap(); store_pubs.sort(); assert_eq!(keys, store_pubs); diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 2a4dda477ab..7d613f2bc62 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -205,12 +205,13 @@ pub type TLightClientWithBackend = Client< TRtApi, >; -/// Construct and hold different layers of Keystore wrappers -pub struct KeystoreContainer { - keystore: Arc, - sync_keystore: SyncCryptoStorePtr, +enum KeystoreContainerInner { + Local(Arc) } +/// Construct and hold different layers of Keystore wrappers +pub struct KeystoreContainer(KeystoreContainerInner); + impl KeystoreContainer { /// Construct KeystoreContainer pub fn new(config: &KeystoreConfig) -> Result { @@ -221,22 +222,36 @@ impl KeystoreContainer { )?, KeystoreConfig::InMemory => LocalKeystore::in_memory(), }); - let sync_keystore = keystore.clone() as SyncCryptoStorePtr; - Ok(Self { - keystore, - sync_keystore, - }) + Ok(Self(KeystoreContainerInner::Local(keystore))) } /// Returns an adapter to the asynchronous keystore that implements `CryptoStore` pub fn keystore(&self) -> Arc { - self.keystore.clone() + match self.0 { + KeystoreContainerInner::Local(ref keystore) => keystore.clone(), + } } /// Returns the synchrnous keystore wrapper pub fn sync_keystore(&self) -> SyncCryptoStorePtr { - self.sync_keystore.clone() + match self.0 { + KeystoreContainerInner::Local(ref keystore) => keystore.clone() as SyncCryptoStorePtr, + } + } + + /// Returns the local keystore if available + /// + /// The function will return None if the available keystore is not a local keystore. + /// + /// # Note + /// + /// Using the [`LocalKeystore`] will result in loosing the ability to use any other keystore implementation, like + /// a remote keystore for example. Only use this if you a certain that you require it! + pub fn local_keystore(&self) -> Option> { + match self.0 { + KeystoreContainerInner::Local(ref keystore) => Some(keystore.clone()), + } } } -- GitLab From 210300dc38713461a5537cb1752c87736670d3ee Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 12 Nov 2020 02:08:22 +0100 Subject: [PATCH 009/163] Update doc for the --chain flag (#7520) --- client/cli/src/params/shared_params.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index ad9ab040705..3276e5b7c4b 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -23,7 +23,10 @@ use structopt::StructOpt; /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt)] pub struct SharedParams { - /// Specify the chain specification (one of dev, local, or staging). + /// Specify the chain specification. + /// + /// It can be one of the predefined ones (dev, local, or staging) or it can be a path to a file with + /// the chainspec (such as one exported by the `build-spec` subcommand). #[structopt(long, value_name = "CHAIN_SPEC")] pub chain: Option, -- GitLab From e26a46a805d68ce55457d67552ba71b76421f708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 12 Nov 2020 16:45:51 +0100 Subject: [PATCH 010/163] contracts: Add missing instruction to the `Schedule` (#7527) --- frame/contracts/src/schedule.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index 24f8bb0a02c..ff2cde22971 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -607,6 +607,7 @@ impl<'a, T: Trait> rules::Rules for ScheduleRules<'a, T> { I32Clz | I64Clz => w.i64clz, I32Ctz | I64Ctz => w.i64ctz, I32Popcnt | I64Popcnt => w.i64popcnt, + I32Eqz | I64Eqz => w.i64eqz, I64ExtendSI32 => w.i64extendsi32, I64ExtendUI32 => w.i64extendui32, I32WrapI64 => w.i32wrapi64, -- GitLab From 02771e146f126a9759a62948ec8a2edd6ad47ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 12 Nov 2020 20:01:58 +0100 Subject: [PATCH 011/163] Don't log with colors when we are writing to a tty (#7525) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don't log with colors when we are writing to a tty This fixes a regression that was introduced by the switch to tracing. Before we killed all colors before writing to a tty, this pr brings the behaviour back. * Remove accidentally added crate * Review feedback * More feedback * Update client/cli/src/logging.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/cli/src/logging.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- Cargo.lock | 9 +++--- client/cli/Cargo.toml | 3 +- client/cli/src/lib.rs | 46 ++++++++++++++++++++++++----- client/cli/src/logging.rs | 59 +++++++++++++++++++++++++++++++++---- client/informant/src/lib.rs | 4 ++- 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62cb03dedaf..7c9bdc4305d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6204,9 +6204,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.9" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" dependencies = [ "aho-corasick", "memchr", @@ -6226,9 +6226,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.18" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" [[package]] name = "region" @@ -6549,6 +6549,7 @@ dependencies = [ "fdlimit", "futures 0.3.5", "hex", + "lazy_static", "libp2p", "log", "names", diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index b7e798a3ba1..51c499828ac 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -15,7 +15,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.11" atty = "0.2.13" -regex = "1.3.4" +regex = "1.4.2" +lazy_static = "1.4.0" ansi_term = "0.12.1" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index c25693dc418..b543f80a9d3 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -47,13 +47,13 @@ use structopt::{ clap::{self, AppSettings}, StructOpt, }; -#[doc(hidden)] -pub use tracing; use tracing_subscriber::{ filter::Directive, fmt::time::ChronoLocal, layer::SubscriberExt, FmtSubscriber, Layer, }; pub use logging::PREFIX_LOG_SPAN; +#[doc(hidden)] +pub use tracing; /// Substrate client CLI /// @@ -308,8 +308,7 @@ pub fn init_logger( } } - let isatty = atty::is(atty::Stream::Stderr); - let enable_color = isatty; + let enable_color = atty::is(atty::Stream::Stderr); let timer = ChronoLocal::with_format(if simple { "%Y-%m-%d %H:%M:%S".to_string() } else { @@ -321,12 +320,13 @@ pub fn init_logger( .with_writer(std::io::stderr) .event_format(logging::EventFormat { timer, - ansi: enable_color, display_target: !simple, display_level: !simple, display_thread_name: !simple, + enable_color, }) - .finish().with(logging::NodeNameLayer); + .finish() + .with(logging::NodeNameLayer); if let Some(profiling_targets) = profiling_targets { let profiling = sc_tracing::ProfilingLayer::new(tracing_receiver, &profiling_targets); @@ -450,8 +450,7 @@ mod tests { #[test] fn prefix_in_log_lines_entrypoint() { if env::var("ENABLE_LOGGING").is_ok() { - let test_pattern = "test-target=info"; - init_logger(&test_pattern, Default::default(), Default::default()).unwrap(); + init_logger("", Default::default(), Default::default()).unwrap(); prefix_in_log_lines_process(); } } @@ -460,4 +459,35 @@ mod tests { fn prefix_in_log_lines_process() { log::info!("{}", EXPECTED_LOG_MESSAGE); } + + /// This is no actual test, it will be used by the `do_not_write_with_colors_on_tty` test. + /// The given test will call the test executable to only execute this test that + /// will only print a log line with some colors in it. + #[test] + fn do_not_write_with_colors_on_tty_entrypoint() { + if env::var("ENABLE_LOGGING").is_ok() { + init_logger("", Default::default(), Default::default()).unwrap(); + log::info!("{}", ansi_term::Colour::Yellow.paint(EXPECTED_LOG_MESSAGE)); + } + } + + #[test] + fn do_not_write_with_colors_on_tty() { + let re = regex::Regex::new(&format!( + r"^\d{{4}}-\d{{2}}-\d{{2}} \d{{2}}:\d{{2}}:\d{{2}} {}$", + EXPECTED_LOG_MESSAGE, + )).unwrap(); + let executable = env::current_exe().unwrap(); + let output = Command::new(executable) + .env("ENABLE_LOGGING", "1") + .args(&["--nocapture", "do_not_write_with_colors_on_tty_entrypoint"]) + .output() + .unwrap(); + + let output = String::from_utf8(output.stderr).unwrap(); + assert!( + re.is_match(output.trim()), + format!("Expected:\n{}\nGot:\n{}", re, output), + ); + } } diff --git a/client/cli/src/logging.rs b/client/cli/src/logging.rs index e1fc90505b4..ffb4c3dfaaf 100644 --- a/client/cli/src/logging.rs +++ b/client/cli/src/logging.rs @@ -16,8 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use std::fmt::{self, Write}; use ansi_term::Colour; -use std::fmt; use tracing::{span::Attributes, Event, Id, Level, Subscriber}; use tracing_log::NormalizeEvent; use tracing_subscriber::{ @@ -29,16 +29,62 @@ use tracing_subscriber::{ registry::LookupSpan, Layer, }; +use regex::Regex; /// Span name used for the logging prefix. See macro `sc_cli::prefix_logs_with!` pub const PREFIX_LOG_SPAN: &str = "substrate-log-prefix"; +/// A writer that may write to `inner_writer` with colors. +/// +/// This is used by [`EventFormat`] to kill colors when `enable_color` is `false`. +/// +/// It is required to call [`MaybeColorWriter::write`] after all writes are done, +/// because the content of these writes is buffered and will only be written to the +/// `inner_writer` at that point. +struct MaybeColorWriter<'a> { + enable_color: bool, + buffer: String, + inner_writer: &'a mut dyn fmt::Write, +} + +impl<'a> fmt::Write for MaybeColorWriter<'a> { + fn write_str(&mut self, buf: &str) -> fmt::Result { + self.buffer.push_str(buf); + Ok(()) + } +} + +impl<'a> MaybeColorWriter<'a> { + /// Creates a new instance. + fn new(enable_color: bool, inner_writer: &'a mut dyn fmt::Write) -> Self { + Self { + enable_color, + inner_writer, + buffer: String::new(), + } + } + + /// Write the buffered content to the `inner_writer`. + fn write(&mut self) -> fmt::Result { + lazy_static::lazy_static! { + static ref RE: Regex = Regex::new("\x1b\\[[^m]+m").expect("Error initializing color regex"); + } + + if !self.enable_color { + let replaced = RE.replace_all(&self.buffer, ""); + self.inner_writer.write_str(&replaced) + } else { + self.inner_writer.write_str(&self.buffer) + } + } +} + pub(crate) struct EventFormat { pub(crate) timer: T, - pub(crate) ansi: bool, pub(crate) display_target: bool, pub(crate) display_level: bool, pub(crate) display_thread_name: bool, + pub(crate) enable_color: bool, } // NOTE: the following code took inspiration from tracing-subscriber @@ -56,12 +102,13 @@ where writer: &mut dyn fmt::Write, event: &Event, ) -> fmt::Result { + let writer = &mut MaybeColorWriter::new(self.enable_color, writer); let normalized_meta = event.normalized_metadata(); let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - time::write(&self.timer, writer, self.ansi)?; + time::write(&self.timer, writer, self.enable_color)?; if self.display_level { - let fmt_level = { FmtLevel::new(meta.level(), self.ansi) }; + let fmt_level = { FmtLevel::new(meta.level(), self.enable_color) }; write!(writer, "{} ", fmt_level)?; } @@ -94,7 +141,9 @@ where write!(writer, "{}:", meta.target())?; } ctx.format_fields(writer, event)?; - writeln!(writer) + writeln!(writer)?; + + writer.write() } } diff --git a/client/informant/src/lib.rs b/client/informant/src/lib.rs index c60eda76f63..d4f34cb488a 100644 --- a/client/informant/src/lib.rs +++ b/client/informant/src/lib.rs @@ -35,7 +35,9 @@ mod display; /// The format to print telemetry output in. #[derive(Clone, Debug)] pub struct OutputFormat { - /// Enable color output in logs. True by default. + /// Enable color output in logs. + /// + /// Is enabled by default. pub enable_color: bool, } -- GitLab From 1c0f76b168345d1a42bb6a106d74d22d10ae2310 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Fri, 13 Nov 2020 14:48:23 +0100 Subject: [PATCH 012/163] MemoryId -> u32 (#7534) --- client/executor/wasmtime/src/host.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/executor/wasmtime/src/host.rs b/client/executor/wasmtime/src/host.rs index eeb7cb92716..8d20c9a566d 100644 --- a/client/executor/wasmtime/src/host.rs +++ b/client/executor/wasmtime/src/host.rs @@ -232,7 +232,7 @@ impl<'a> Sandbox for HostContext<'a> { .map_err(|e| e.to_string()) } - fn memory_new(&mut self, initial: u32, maximum: MemoryId) -> sp_wasm_interface::Result { + fn memory_new(&mut self, initial: u32, maximum: u32) -> sp_wasm_interface::Result { self.sandbox_store .borrow_mut() .new_memory(initial, maximum) -- GitLab From 5222a8f4a71134e3a95f268d1bcd9c8c5715b048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 13 Nov 2020 22:38:55 +0100 Subject: [PATCH 013/163] Enable local addresses in DHT when chain type == `Local` | `Development` (#7538) * Enable local addresses in DHT when chain type == `Local` | `Development` This pr changes when to add local addresses to DHT. Instead of only checking if `--discover-local` and `--dev` are present, we now also check if the chain type is `Local` or `Development`. * Update the docs! --- client/cli/src/params/network_params.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 209742f54e9..a973d61272c 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -21,7 +21,7 @@ use sc_network::{ config::{NetworkConfiguration, NodeKeyConfig, NonReservedPeerMode, TransportConfig}, multiaddr::Protocol, }; -use sc_service::{ChainSpec, config::{Multiaddr, MultiaddrWithPeerId}}; +use sc_service::{ChainSpec, ChainType, config::{Multiaddr, MultiaddrWithPeerId}}; use std::path::PathBuf; use structopt::StructOpt; @@ -94,7 +94,8 @@ pub struct NetworkParams { /// Enable peer discovery on local networks. /// - /// By default this option is true for `--dev` and false otherwise. + /// By default this option is `true` for `--dev` or when the chain type is `Local`/`Development` + /// and false otherwise. #[structopt(long)] pub discover_local: bool, @@ -139,6 +140,13 @@ impl NetworkParams { let mut boot_nodes = chain_spec.boot_nodes().to_vec(); boot_nodes.extend(self.bootnodes.clone()); + let chain_type = chain_spec.chain_type(); + // Activate if the user explicitly requested local discovery, `--dev` is given or the + // chain type is `Local`/`Development` + let allow_non_globals_in_dht = self.discover_local + || is_dev + || matches!(chain_type, ChainType::Local | ChainType::Development); + NetworkConfiguration { boot_nodes, net_config_path, @@ -163,7 +171,7 @@ impl NetworkParams { wasm_external_transport: None, }, max_parallel_downloads: self.max_parallel_downloads, - allow_non_globals_in_dht: self.discover_local || is_dev, + allow_non_globals_in_dht, kademlia_disjoint_query_paths: self.kademlia_disjoint_query_paths, } } -- GitLab From 77007ed87727a761169d4c57cbeae0151d9efb81 Mon Sep 17 00:00:00 2001 From: Kirill Pimenov Date: Sat, 14 Nov 2020 07:19:26 +0100 Subject: [PATCH 014/163] Update tiny-bip39 to v0.8 (#7539) It would improve secret zeroization due to https://github.com/maciejhirsz/tiny-bip39/pull/22, and would also remove one of the points where we depend on `failure` crate, which is deprecated (see https://github.com/rust-lang-nursery/failure/pull/347) --- Cargo.lock | 63 +++++++++++++++++++++++++------------- primitives/core/Cargo.toml | 2 +- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c9bdc4305d..fca7a32c96d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.31" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" +checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" [[package]] name = "approx" @@ -462,9 +462,9 @@ checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4" dependencies = [ "failure", "hashbrown 0.1.8", - "hmac", + "hmac 0.7.1", "once_cell 0.1.8", - "pbkdf2", + "pbkdf2 0.3.0", "rand 0.6.5", "sha2 0.8.2", ] @@ -2288,6 +2288,16 @@ dependencies = [ "digest 0.8.1", ] +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + [[package]] name = "hmac-drbg" version = "0.2.0" @@ -2296,7 +2306,7 @@ checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ "digest 0.8.1", "generic-array 0.12.3", - "hmac", + "hmac 0.7.1", ] [[package]] @@ -5474,6 +5484,15 @@ dependencies = [ "rayon", ] +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac 0.8.0", +] + [[package]] name = "pdqselect" version = "0.1.0" @@ -8896,8 +8915,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bed6646a0159b9935b5d045611560eeef842b78d7adc3ba36f5ca325a13a0236" dependencies = [ - "hmac", - "pbkdf2", + "hmac 0.7.1", + "pbkdf2 0.3.0", "schnorrkel", "sha2 0.8.2", "zeroize", @@ -9168,9 +9187,9 @@ checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03e57e4fcbfe7749842d53e24ccb9aa12b7252dbe5e91d2acad31834c8b8fdd" +checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" dependencies = [ "proc-macro2", "quote", @@ -9259,18 +9278,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42" +checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab" +checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56" dependencies = [ "proc-macro2", "quote", @@ -9307,18 +9326,20 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" +checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" dependencies = [ - "failure", - "hmac", + "anyhow", + "hmac 0.8.1", "once_cell 1.4.1", - "pbkdf2", + "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", - "sha2 0.8.2", + "sha2 0.9.1", + "thiserror", "unicode-normalization", + "zeroize", ] [[package]] @@ -10514,9 +10535,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" dependencies = [ "zeroize_derive", ] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 1757bb4e0d5..f6989a0df4f 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -26,7 +26,7 @@ hash256-std-hasher = { version = "0.15.2", default-features = false } base58 = { version = "0.1.0", optional = true } rand = { version = "0.7.3", optional = true, features = ["small_rng"] } substrate-bip39 = { version = "0.4.2", optional = true } -tiny-bip39 = { version = "0.7", optional = true } +tiny-bip39 = { version = "0.8", optional = true } regex = { version = "1.3.1", optional = true } num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } -- GitLab From f31e7784e8b7c1c14535274c7b6c0be7b8310b4b Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 16 Nov 2020 12:40:35 +0100 Subject: [PATCH 015/163] make LocalCallExecutor public (#7528) --- client/service/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index cb741c2920b..8e6b0037bdf 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -80,6 +80,7 @@ pub use sc_tracing::TracingReceiver; pub use task_manager::SpawnTaskHandle; pub use task_manager::TaskManager; pub use sp_consensus::import_queue::ImportQueue; +pub use self::client::LocalCallExecutor; use sc_client_api::{blockchain::HeaderBackend, BlockchainEvents}; const DEFAULT_PROTOCOL_ID: &str = "sup"; -- GitLab From 74e01c84ca73b22cb9053e6e641a61ed87c31f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 16 Nov 2020 14:15:05 +0100 Subject: [PATCH 016/163] Fix some weirdness in `offchain_worker` (#7541) We call `offchain_worker` with the state of the imported block and pass the header of this block. However in the runtime we call all `offchain_worker` functions with the number of the parent block. Besides that we also pass all digests and not only the pre runtime digests. In the context where the offchain worker is executed we have all digests, so there is no real reason to only pass pre runtime digests. Another fix is that we also insert the hash of the current header into the block hash map. --- frame/executive/src/lib.rs | 44 +++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 961dbc4376a..ccb5c2d2628 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -117,7 +117,7 @@ use sp_std::{prelude::*, marker::PhantomData}; use frame_support::{ - storage::StorageValue, weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, + StorageValue, StorageMap, weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker}, dispatch::PostDispatchInfo, }; @@ -453,7 +453,7 @@ where // We need to keep events available for offchain workers, // hence we initialize the block manually. // OffchainWorker RuntimeApi should skip initialization. - let digests = Self::extract_pre_digest(header); + let digests = header.digest().clone(); >::initialize( header.number(), @@ -463,15 +463,16 @@ where frame_system::InitKind::Inspection, ); + // Frame system only inserts the parent hash into the block hashes as normally we don't know + // the hash for the header before. However, here we are aware of the hash and we can add it + // as well. + frame_system::BlockHash::::insert(header.number(), header.hash()); + // Initialize logger, so the log messages are visible // also when running WASM. frame_support::debug::RuntimeLogger::init(); - >::offchain_worker( - // to maintain backward compatibility we call module offchain workers - // with parent block number. - header.number().saturating_sub(1u32.into()) - ) + >::offchain_worker(*header.number()) } } @@ -481,7 +482,7 @@ mod tests { use super::*; use sp_core::H256; use sp_runtime::{ - generic::Era, Perbill, DispatchError, testing::{Digest, Header, Block}, + generic::{Era, DigestItem}, Perbill, DispatchError, testing::{Digest, Header, Block}, traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}, transaction_validity::{ InvalidTransaction, ValidTransaction, TransactionValidityError, UnknownTransaction @@ -547,6 +548,10 @@ mod tests { sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); 200 } + + fn offchain_worker(n: T::BlockNumber) { + assert_eq!(T::BlockNumber::from(1u32), n); + } } } @@ -1115,4 +1120,27 @@ mod tests { ); }); } + + #[test] + fn offchain_worker_works_as_expected() { + new_test_ext(1).execute_with(|| { + let parent_hash = sp_core::H256::from([69u8; 32]); + let mut digest = Digest::default(); + digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); + + let header = Header::new( + 1, + H256::default(), + H256::default(), + parent_hash, + digest.clone(), + ); + + Executive::offchain_worker(&header); + + assert_eq!(digest, System::digest()); + assert_eq!(parent_hash, System::block_hash(0)); + assert_eq!(header.hash(), System::block_hash(1)); + }); + } } -- GitLab From 99602cda4e1c06d66a40aa933789308d4ca9a7ce Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 16 Nov 2020 16:46:36 +0100 Subject: [PATCH 017/163] Use inbound peerslot slots when a substream is received, rather than a connection (#7464) * Use inbound peerslot slots when a substream is received, rather than a connection * Refactor PeerState * Some bugfixes * Fix warnings so that CI runs, gmlrlblbl * Bugfixes * Update docs * Apply suggestions from code review Co-authored-by: Roman Borschel * Clean up Banned state * Refactor connections state * Fix possibility of Enabled with no Opening or Open connection * Line width * Add some debug_asserts! and fix TODO * Refactor legacy handler * Rewrite group.rs entirely [part 1] * Rewrite group.rs entirely [part 2] * Remove faulty assertion Because of the asynchronous nature of the behaviour <-> handler communications, it is possible to receive notifications while in the Closing state * Don't poll the legacy substream is not Open * Tolerate when not all substreams are accepted * Remove TODOs * Dummy commit to make CI log interesting things * Try race condition fix * Revert "Try race condition fix" This reverts commit 0675c659d06195c30f8c5bc13e2d88141d57a3ba. * Correctly rebuild pending_opening * Minor tweaks * Printlns for CI debugging * Revert "Printlns for CI debugging" This reverts commit e7852a231f4fc418898767aaa27c9a4358e12e8b. * Revert "Dummy commit to make CI log interesting things" This reverts commit 259ddd74088e53e7c6a9b0a62a8d1573a0063ce3. * mv group.rs ../handler.rs * Apply suggestions from code review Co-authored-by: Max Inden * Banned => Backoff * Mention the actual PeerStates * OpenDesired -> OpenDesiredByRemote * OpeningThenClosing * Add doc links to PeerState * Simplify increment logic * One more debug_assert * debug_assert! * OpenDesiredByRemote * Update client/network/src/protocol/generic_proto/behaviour.rs Co-authored-by: Max Inden Co-authored-by: Roman Borschel Co-authored-by: Max Inden --- client/network/src/protocol.rs | 4 +- client/network/src/protocol/generic_proto.rs | 2 +- .../src/protocol/generic_proto/behaviour.rs | 1672 +++++++++++------ .../src/protocol/generic_proto/handler.rs | 1055 ++++++++++- .../protocol/generic_proto/handler/group.rs | 737 -------- .../protocol/generic_proto/handler/legacy.rs | 559 ------ .../generic_proto/handler/notif_in.rs | 293 --- .../generic_proto/handler/notif_out.rs | 444 ----- .../protocol/generic_proto/upgrade/legacy.rs | 26 +- client/network/src/service.rs | 5 +- 10 files changed, 2197 insertions(+), 2600 deletions(-) delete mode 100644 client/network/src/protocol/generic_proto/handler/group.rs delete mode 100644 client/network/src/protocol/generic_proto/handler/legacy.rs delete mode 100644 client/network/src/protocol/generic_proto/handler/notif_in.rs delete mode 100644 client/network/src/protocol/generic_proto/handler/notif_out.rs diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index ac74af0f5ca..9403e471b0f 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -63,7 +63,7 @@ pub mod message; pub mod event; pub mod sync; -pub use generic_proto::{NotificationsSink, Ready, NotifsHandlerError, LegacyConnectionKillError}; +pub use generic_proto::{NotificationsSink, Ready, NotifsHandlerError}; const REQUEST_TIMEOUT_SEC: u64 = 40; /// Interval at which we perform time based maintenance @@ -1668,7 +1668,7 @@ impl NetworkBehaviour for Protocol { notifications_sink, } }, - GenericProtoOut::CustomProtocolClosed { peer_id, .. } => { + GenericProtoOut::CustomProtocolClosed { peer_id } => { self.on_peer_disconnected(peer_id) }, GenericProtoOut::LegacyMessage { peer_id, message } => diff --git a/client/network/src/protocol/generic_proto.rs b/client/network/src/protocol/generic_proto.rs index 3133471b0d2..4d6e607a146 100644 --- a/client/network/src/protocol/generic_proto.rs +++ b/client/network/src/protocol/generic_proto.rs @@ -21,7 +21,7 @@ //! network, then performs the Substrate protocol handling on top. pub use self::behaviour::{GenericProto, GenericProtoOut}; -pub use self::handler::{NotifsHandlerError, NotificationsSink, Ready, LegacyConnectionKillError}; +pub use self::handler::{NotifsHandlerError, NotificationsSink, Ready}; mod behaviour; mod handler; diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 7b62b154016..f84aead4728 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -42,45 +42,35 @@ use wasm_timer::Instant; /// Network behaviour that handles opening substreams for custom protocols with other peers. /// -/// ## Legacy vs new protocol -/// -/// The `GenericProto` behaves as following: -/// -/// - Whenever a connection is established, we open a single substream (called "legacy protocol" in -/// the source code) on that connection. This substream name depends on the `protocol_id` and -/// `versions` passed at initialization. If the remote refuses this substream, we close the -/// connection. -/// -/// - For each registered protocol, we also open an additional substream for this protocol. If the -/// remote refuses this substream, then it's fine. -/// -/// - Whenever we want to send a message, we can call either `send_packet` to force the legacy -/// substream, or `write_notification` to indicate a registered protocol. If the registered -/// protocol was refused or isn't supported by the remote, we always use the legacy instead. -/// -/// ## How it works +/// # How it works /// /// The role of the `GenericProto` is to synchronize the following components: /// /// - The libp2p swarm that opens new connections and reports disconnects. -/// - The connection handler (see `handler.rs`) that handles individual connections. +/// - The connection handler (see `group.rs`) that handles individual connections. /// - The peerset manager (PSM) that requests links to peers to be established or broken. /// - The external API, that requires knowledge of the links that have been established. /// -/// Each connection handler can be in four different states: Enabled+Open, Enabled+Closed, -/// Disabled+Open, or Disabled+Closed. The Enabled/Disabled component must be in sync with the -/// peerset manager. For example, if the peerset manager requires a disconnection, we disable the -/// connection handlers of that peer. The Open/Closed component must be in sync with the external -/// API. +/// In the state machine below, each `PeerId` is attributed one of these states: +/// +/// - [`PeerState::Requested`]: No open connection, but requested by the peerset. Currently dialing. +/// - [`PeerState::Disabled`]: Has open TCP connection(s) unbeknownst to the peerset. No substream +/// is open. +/// - [`PeerState::Enabled`]: Has open TCP connection(s), acknowledged by the peerset. +/// - Notifications substreams are open on at least one connection, and external +/// API has been notified. +/// - Notifications substreams aren't open. +/// - [`PeerState::Incoming`]: Has open TCP connection(s) and remote would like to open substreams. +/// Peerset has been asked to attribute an inbound slot. /// -/// However, a connection handler for a peer only exists if we are actually connected to that peer. -/// What this means is that there are six possible states for each peer: Disconnected, Dialing -/// (trying to connect), Enabled+Open, Enabled+Closed, Disabled+Open, Disabled+Closed. -/// Most notably, the Dialing state must correspond to a "link established" state in the peerset -/// manager. In other words, the peerset manager doesn't differentiate whether we are dialing a -/// peer or connected to it. +/// In addition to these states, there also exists a "banning" system. If we fail to dial a peer, +/// we back-off for a few seconds. If the PSM requests connecting to a peer that is currently +/// backed-off, the next dialing attempt is delayed until after the ban expires. However, the PSM +/// will still consider the peer to be connected. This "ban" is thus not a ban in a strict sense: +/// if a backed-off peer tries to connect, the connection is accepted. A ban only delays dialing +/// attempts. /// -/// There may be multiple connections to a peer. However, the status of a peer on +/// There may be multiple connections to a peer. The status of a peer on /// the API of this behaviour and towards the peerset manager is aggregated in /// the following way: /// @@ -94,9 +84,9 @@ use wasm_timer::Instant; /// in terms of potential reordering and dropped messages. Messages can /// be received on any connection. /// 3. The behaviour reports `GenericProtoOut::CustomProtocolOpen` when the -/// first connection reports `NotifsHandlerOut::Open`. +/// first connection reports `NotifsHandlerOut::OpenResultOk`. /// 4. The behaviour reports `GenericProtoOut::CustomProtocolClosed` when the -/// last connection reports `NotifsHandlerOut::Closed`. +/// last connection reports `NotifsHandlerOut::ClosedResult`. /// /// In this way, the number of actual established connections to the peer is /// an implementation detail of this behaviour. Note that, in practice and at @@ -104,12 +94,6 @@ use wasm_timer::Instant; /// and only as a result of simultaneous dialing. However, the implementation /// accommodates for any number of connections. /// -/// Additionally, there also exists a "banning" system. If we fail to dial a peer, we "ban" it for -/// a few seconds. If the PSM requests connecting to a peer that is currently "banned", the next -/// dialing attempt is delayed until after the ban expires. However, the PSM will still consider -/// the peer to be connected. This "ban" is thus not a ban in a strict sense: If a "banned" peer -/// tries to connect, the connection is accepted. A ban only delays dialing attempts. -/// pub struct GenericProto { /// `PeerId` of the local node. local_peer_id: PeerId, @@ -157,6 +141,8 @@ pub struct GenericProto { struct DelayId(u64); /// State of a peer we're connected to. +/// +/// The variants correspond to the state of the peer w.r.t. the peerset. #[derive(Debug)] enum PeerState { /// State is poisoned. This is a temporary state for a peer and we should always switch back @@ -166,9 +152,11 @@ enum PeerState { /// The peer misbehaved. If the PSM wants us to connect to this peer, we will add an artificial /// delay to the connection. - Banned { - /// Until when the peer is banned. - until: Instant, + Backoff { + /// When the ban expires. For clean-up purposes. References an entry in `delays`. + timer: DelayId, + /// Until when the peer is backed-off. + timer_deadline: Instant, }, /// The peerset requested that we connect to this peer. We are currently not connected. @@ -182,40 +170,54 @@ enum PeerState { /// The peerset requested that we connect to this peer. We are currently dialing this peer. Requested, - /// We are connected to this peer but the peerset refused it. + /// We are connected to this peer but the peerset hasn't requested it or has denied it. /// - /// We may still have ongoing traffic with that peer, but it should cease shortly. + /// The handler is either in the closed state, or a `Close` message has been sent to it and + /// hasn't been answered yet. Disabled { - /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, - /// If `Some`, any dial attempts to this peer are delayed until the given `Instant`. - banned_until: Option, + /// If `Some`, any connection request from the peerset to this peer is delayed until the + /// given `Instant`. + backoff_until: Option, + + /// List of connections with this peer, and their state. + connections: SmallVec<[(ConnectionId, ConnectionState); crate::MAX_CONNECTIONS_PER_PEER]>, }, - /// We are connected to this peer but we are not opening any Substrate substream. The handler - /// will be enabled when `timer` fires. This peer can still perform Kademlia queries and such, - /// but should get disconnected in a few seconds. + /// We are connected to this peer. The peerset has requested a connection to this peer, but + /// it is currently in a "backed-off" phase. The state will switch to `Enabled` once the timer + /// expires. + /// + /// The handler is either in the closed state, or a `Close` message has been sent to it and + /// hasn't been answered yet. + /// + /// The handler will be opened when `timer` fires. DisabledPendingEnable { - /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, /// When to enable this remote. References an entry in `delays`. timer: DelayId, /// When the `timer` will trigger. timer_deadline: Instant, + + /// List of connections with this peer, and their state. + connections: SmallVec<[(ConnectionId, ConnectionState); crate::MAX_CONNECTIONS_PER_PEER]>, }, - /// We are connected to this peer and the peerset has accepted it. The handler is in the - /// enabled state. + /// We are connected to this peer and the peerset has accepted it. Enabled { - /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, + /// List of connections with this peer, and their state. + connections: SmallVec<[(ConnectionId, ConnectionState); crate::MAX_CONNECTIONS_PER_PEER]>, }, - /// We received an incoming connection from this peer and forwarded that - /// connection request to the peerset. The connection handlers are waiting - /// for initialisation, i.e. to be enabled or disabled based on whether - /// the peerset accepts or rejects the peer. - Incoming, + /// We are connected to this peer. We have received an `OpenDesiredByRemote` from one of the + /// handlers and forwarded that request to the peerset. The connection handlers are waiting for + /// a response, i.e. to be opened or closed based on whether the peerset accepts or rejects + /// the peer. + Incoming { + /// If `Some`, any dial attempts to this peer are delayed until the given `Instant`. + backoff_until: Option, + + /// List of connections with this peer, and their state. + connections: SmallVec<[(ConnectionId, ConnectionState); crate::MAX_CONNECTIONS_PER_PEER]>, + }, } impl PeerState { @@ -229,18 +231,19 @@ impl PeerState { /// that is open for custom protocol traffic. fn get_open(&self) -> Option<&NotificationsSink> { match self { - PeerState::Disabled { open, .. } | - PeerState::DisabledPendingEnable { open, .. } | - PeerState::Enabled { open, .. } => - if !open.is_empty() { - Some(&open[0].1) - } else { - None - } + PeerState::Enabled { connections, .. } => connections + .iter() + .filter_map(|(_, s)| match s { + ConnectionState::Open(s) => Some(s), + _ => None, + }) + .next(), PeerState::Poisoned => None, - PeerState::Banned { .. } => None, + PeerState::Backoff { .. } => None, PeerState::PendingRequest { .. } => None, PeerState::Requested => None, + PeerState::Disabled { .. } => None, + PeerState::DisabledPendingEnable { .. } => None, PeerState::Incoming { .. } => None, } } @@ -249,7 +252,7 @@ impl PeerState { fn is_requested(&self) -> bool { match self { PeerState::Poisoned => false, - PeerState::Banned { .. } => false, + PeerState::Backoff { .. } => false, PeerState::PendingRequest { .. } => true, PeerState::Requested => true, PeerState::Disabled { .. } => false, @@ -260,6 +263,37 @@ impl PeerState { } } +/// State of the handler of a single connection visible from this state machine. +#[derive(Debug)] +enum ConnectionState { + /// Connection is in the `Closed` state, meaning that the remote hasn't requested anything. + Closed, + + /// Connection is either in the `Open` or the `Closed` state, but a + /// [`NotifsHandlerIn::Close`] message has been sent. Waiting for this message to be + /// acknowledged through a [`NotifsHandlerOut::CloseResult`]. + Closing, + + /// Connection is in the `Closed` state but a [`NotifsHandlerIn::Open`] message has been sent. + /// An `OpenResultOk`/`OpenResultErr` message is expected. + Opening, + + /// Connection is in the `Closed` state but a [`NotifsHandlerIn::Open`] message then a + /// [`NotifsHandlerIn::Close`] message has been sent. An `OpenResultOk`/`OpenResultErr` message + /// followed with a `CloseResult` message are expected. + OpeningThenClosing, + + /// Connection is in the `Closed` state, but a [`NotifsHandlerOut::OpenDesiredByRemote`] + /// message has been received, meaning that the remote wants to open a substream. + OpenDesiredByRemote, + + /// Connection is in the `Open` state. + /// + /// The external API is notified of a channel with this peer if any of its connection is in + /// this state. + Open(NotificationsSink), +} + /// State of an "incoming" message sent to the peer set manager. #[derive(Debug)] struct IncomingPeer { @@ -303,8 +337,6 @@ pub enum GenericProtoOut { CustomProtocolClosed { /// Id of the peer we were connected to. peer_id: PeerId, - /// Reason why the substream closed, for debugging purposes. - reason: Cow<'static, str>, }, /// Receives a message on the legacy substream. @@ -438,46 +470,79 @@ impl GenericProto { st @ PeerState::Disabled { .. } => *entry.into_mut() = st, st @ PeerState::Requested => *entry.into_mut() = st, st @ PeerState::PendingRequest { .. } => *entry.into_mut() = st, - st @ PeerState::Banned { .. } => *entry.into_mut() = st, + st @ PeerState::Backoff { .. } => *entry.into_mut() = st, // DisabledPendingEnable => Disabled. PeerState::DisabledPendingEnable { - open, + connections, timer_deadline, timer: _ } => { debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); self.peerset.dropped(peer_id.clone()); - let banned_until = Some(if let Some(ban) = ban { + let backoff_until = Some(if let Some(ban) = ban { cmp::max(timer_deadline, Instant::now() + ban) } else { timer_deadline }); *entry.into_mut() = PeerState::Disabled { - open, - banned_until + connections, + backoff_until } }, // Enabled => Disabled. - PeerState::Enabled { open } => { + // All open or opening connections are sent a `Close` message. + // If relevant, the external API is instantly notified. + PeerState::Enabled { mut connections } => { debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); self.peerset.dropped(peer_id.clone()); - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Disable, - }); - let banned_until = ban.map(|dur| Instant::now() + dur); + + if connections.iter().any(|(_, s)| matches!(s, ConnectionState::Open(_))) { + debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); + let event = GenericProtoOut::CustomProtocolClosed { + peer_id: peer_id.clone(), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::Open(_))) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::Closing; + } + + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::Opening)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::OpeningThenClosing; + } + + debug_assert!(!connections.iter().any(|(_, s)| matches!(s, ConnectionState::Open(_)))); + debug_assert!(!connections.iter().any(|(_, s)| matches!(s, ConnectionState::Opening))); + + let backoff_until = ban.map(|dur| Instant::now() + dur); *entry.into_mut() = PeerState::Disabled { - open, - banned_until + connections, + backoff_until } }, // Incoming => Disabled. - PeerState::Incoming => { + // Ongoing opening requests from the remote are rejected. + PeerState::Incoming { mut connections, backoff_until } => { let inc = if let Some(inc) = self.incoming.iter_mut() .find(|i| i.peer_id == *entry.key() && i.alive) { inc @@ -488,16 +553,30 @@ impl GenericProto { }; inc.alive = false; - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Disable, - }); - let banned_until = ban.map(|dur| Instant::now() + dur); + + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::Closing; + } + + let backoff_until = match (backoff_until, ban) { + (Some(a), Some(b)) => Some(cmp::max(a, Instant::now() + b)), + (Some(a), None) => Some(a), + (None, Some(b)) => Some(Instant::now() + b), + (None, None) => None, + }; + + debug_assert!(!connections.iter().any(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote))); *entry.into_mut() = PeerState::Disabled { - open: SmallVec::new(), - banned_until + connections, + backoff_until } }, @@ -521,7 +600,7 @@ impl GenericProto { Some(PeerState::Incoming { .. }) => false, Some(PeerState::Requested) => false, Some(PeerState::PendingRequest { .. }) => false, - Some(PeerState::Banned { .. }) => false, + Some(PeerState::Backoff { .. }) => false, Some(PeerState::Poisoned) => false, } } @@ -591,7 +670,8 @@ impl GenericProto { /// Function that is called when the peerset wants us to connect to a peer. fn peerset_report_connect(&mut self, peer_id: PeerId) { - let mut occ_entry = match self.peers.entry(peer_id) { + // If `PeerId` is unknown to us, insert an entry, start dialing, and return early. + let mut occ_entry = match self.peers.entry(peer_id.clone()) { Entry::Occupied(entry) => entry, Entry::Vacant(entry) => { // If there's no entry in `self.peers`, start dialing. @@ -609,26 +689,19 @@ impl GenericProto { let now = Instant::now(); match mem::replace(occ_entry.get_mut(), PeerState::Poisoned) { - PeerState::Banned { ref until } if *until > now => { + // Backoff (not expired) => PendingRequest + PeerState::Backoff { ref timer, ref timer_deadline } if *timer_deadline > now => { let peer_id = occ_entry.key().clone(); debug!(target: "sub-libp2p", "PSM => Connect({:?}): Will start to connect at \ - until {:?}", peer_id, until); - - let delay_id = self.next_delay_id; - self.next_delay_id.0 += 1; - let delay = futures_timer::Delay::new(*until - now); - self.delays.push(async move { - delay.await; - (delay_id, peer_id) - }.boxed()); - + until {:?}", peer_id, timer_deadline); *occ_entry.into_mut() = PeerState::PendingRequest { - timer: delay_id, - timer_deadline: *until, + timer: *timer, + timer_deadline: *timer_deadline, }; }, - PeerState::Banned { .. } => { + // Backoff (expired) => Requested + PeerState::Backoff { .. } => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Starting to connect", occ_entry.key()); debug!(target: "sub-libp2p", "Libp2p <= Dial {:?}", occ_entry.key()); self.events.push_back(NetworkBehaviourAction::DialPeer { @@ -638,42 +711,90 @@ impl GenericProto { *occ_entry.into_mut() = PeerState::Requested; }, + // Disabled (with non-expired ban) => DisabledPendingEnable PeerState::Disabled { - open, - banned_until: Some(ref banned) - } if *banned > now => { + connections, + backoff_until: Some(ref backoff) + } if *backoff > now => { let peer_id = occ_entry.key().clone(); - debug!(target: "sub-libp2p", "PSM => Connect({:?}): But peer is banned until {:?}", - peer_id, banned); + debug!(target: "sub-libp2p", "PSM => Connect({:?}): But peer is backed-off until {:?}", + peer_id, backoff); let delay_id = self.next_delay_id; self.next_delay_id.0 += 1; - let delay = futures_timer::Delay::new(*banned - now); + let delay = futures_timer::Delay::new(*backoff - now); self.delays.push(async move { delay.await; (delay_id, peer_id) }.boxed()); *occ_entry.into_mut() = PeerState::DisabledPendingEnable { - open, + connections, timer: delay_id, - timer_deadline: *banned, + timer_deadline: *backoff, }; }, - PeerState::Disabled { open, banned_until: _ } => { - debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", - occ_entry.key()); - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: occ_entry.key().clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Enable, - }); - *occ_entry.into_mut() = PeerState::Enabled { open }; + // Disabled => Enabled + PeerState::Disabled { mut connections, backoff_until } => { + debug_assert!(!connections.iter().any(|(_, s)| { + matches!(s, ConnectionState::Open(_)) + })); + + // The first element of `closed` is chosen to open the notifications substream. + if let Some((connec_id, connec_state)) = connections.iter_mut() + .find(|(_, s)| matches!(s, ConnectionState::Closed)) + { + debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", + occ_entry.key()); + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Open, + }); + *connec_state = ConnectionState::Opening; + *occ_entry.into_mut() = PeerState::Enabled { connections }; + } else { + // If no connection is available, switch to `DisabledPendingEnable` in order + // to try again later. + debug_assert!(connections.iter().any(|(_, s)| { + matches!(s, ConnectionState::OpeningThenClosing | ConnectionState::Closing) + })); + debug!( + target: "sub-libp2p", + "PSM => Connect({:?}): No connection in proper state. Delaying.", + occ_entry.key() + ); + + let timer_deadline = { + let base = now + Duration::from_secs(5); + if let Some(backoff_until) = backoff_until { + cmp::max(base, backoff_until) + } else { + base + } + }; + + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + debug_assert!(timer_deadline > now); + let delay = futures_timer::Delay::new(timer_deadline - now); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + + *occ_entry.into_mut() = PeerState::DisabledPendingEnable { + connections, + timer: delay_id, + timer_deadline, + }; + } }, - PeerState::Incoming => { + // Incoming => Enabled + PeerState::Incoming { mut connections, .. } => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", occ_entry.key()); if let Some(inc) = self.incoming.iter_mut() @@ -683,36 +804,50 @@ impl GenericProto { error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in \ incoming for incoming peer") } - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: occ_entry.key().clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Enable, - }); - *occ_entry.into_mut() = PeerState::Enabled { open: SmallVec::new() }; + + debug_assert!(connections.iter().any(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote))); + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", occ_entry.key(), *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: occ_entry.key().clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Open, + }); + *connec_state = ConnectionState::Opening; + } + + *occ_entry.into_mut() = PeerState::Enabled { connections }; }, + // Other states are kept as-is. st @ PeerState::Enabled { .. } => { warn!(target: "sub-libp2p", "PSM => Connect({:?}): Already connected.", occ_entry.key()); *occ_entry.into_mut() = st; + debug_assert!(false); }, st @ PeerState::DisabledPendingEnable { .. } => { warn!(target: "sub-libp2p", "PSM => Connect({:?}): Already pending enabling.", occ_entry.key()); *occ_entry.into_mut() = st; + debug_assert!(false); }, st @ PeerState::Requested { .. } | st @ PeerState::PendingRequest { .. } => { warn!(target: "sub-libp2p", "PSM => Connect({:?}): Duplicate request.", occ_entry.key()); *occ_entry.into_mut() = st; + debug_assert!(false); }, - PeerState::Poisoned => - error!(target: "sub-libp2p", "State of {:?} is poisoned", occ_entry.key()), + PeerState::Poisoned => { + error!(target: "sub-libp2p", "State of {:?} is poisoned", occ_entry.key()); + debug_assert!(false); + }, } } @@ -727,43 +862,66 @@ impl GenericProto { }; match mem::replace(entry.get_mut(), PeerState::Poisoned) { - st @ PeerState::Disabled { .. } | st @ PeerState::Banned { .. } => { + st @ PeerState::Disabled { .. } | st @ PeerState::Backoff { .. } => { debug!(target: "sub-libp2p", "PSM => Drop({:?}): Already disabled.", entry.key()); *entry.into_mut() = st; }, - PeerState::DisabledPendingEnable { - open, - timer_deadline, - timer: _ - } => { + // DisabledPendingEnable => Disabled + PeerState::DisabledPendingEnable { connections, timer_deadline, timer: _ } => { + debug_assert!(!connections.is_empty()); debug!(target: "sub-libp2p", "PSM => Drop({:?}): Interrupting pending enabling.", entry.key()); *entry.into_mut() = PeerState::Disabled { - open, - banned_until: Some(timer_deadline), + connections, + backoff_until: Some(timer_deadline), }; }, - PeerState::Enabled { open } => { + // Enabled => Disabled + PeerState::Enabled { mut connections } => { debug!(target: "sub-libp2p", "PSM => Drop({:?}): Disabling connections.", entry.key()); - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", entry.key()); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: entry.key().clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Disable, - }); - *entry.into_mut() = PeerState::Disabled { - open, - banned_until: None + + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + + if connections.iter().any(|(_, s)| matches!(s, ConnectionState::Open(_))) { + debug!(target: "sub-libp2p", "External API <= Closed({})", entry.key()); + let event = GenericProtoOut::CustomProtocolClosed { + peer_id: entry.key().clone(), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); } + + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::Opening)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", entry.key(), *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: entry.key().clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::OpeningThenClosing; + } + + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::Open(_))) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", entry.key(), *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: entry.key().clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::Closing; + } + + *entry.into_mut() = PeerState::Disabled { connections, backoff_until: None } }, - st @ PeerState::Incoming => { - error!(target: "sub-libp2p", "PSM => Drop({:?}): Not enabled (Incoming).", - entry.key()); - *entry.into_mut() = st; - }, + + // Requested => Ø PeerState::Requested => { // We don't cancel dialing. Libp2p doesn't expose that on purpose, as other // sub-systems (such as the discovery mechanism) may require dialing this peer as @@ -771,13 +929,24 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM => Drop({:?}): Not yet connected.", entry.key()); entry.remove(); }, - PeerState::PendingRequest { timer_deadline, .. } => { + + // PendingRequest => Backoff + PeerState::PendingRequest { timer, timer_deadline } => { debug!(target: "sub-libp2p", "PSM => Drop({:?}): Not yet connected", entry.key()); - *entry.into_mut() = PeerState::Banned { until: timer_deadline } + *entry.into_mut() = PeerState::Backoff { timer, timer_deadline } }, - PeerState::Poisoned => - error!(target: "sub-libp2p", "State of {:?} is poisoned", entry.key()), + // Invalid state transitions. + st @ PeerState::Incoming { .. } => { + error!(target: "sub-libp2p", "PSM => Drop({:?}): Not enabled (Incoming).", + entry.key()); + *entry.into_mut() = st; + debug_assert!(!false); + }, + PeerState::Poisoned => { + error!(target: "sub-libp2p", "State of {:?} is poisoned", entry.key()); + debug_assert!(!false); + }, } } @@ -792,28 +961,56 @@ impl GenericProto { }; if !incoming.alive { - debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Obsolete incoming, - sending back dropped", index, incoming.peer_id); - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", incoming.peer_id); - self.peerset.dropped(incoming.peer_id); + debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Obsolete incoming", + index, incoming.peer_id); + match self.peers.get_mut(&incoming.peer_id) { + Some(PeerState::DisabledPendingEnable { .. }) | + Some(PeerState::Enabled { .. }) => {} + _ => { + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", incoming.peer_id); + self.peerset.dropped(incoming.peer_id); + }, + } return } - match self.peers.get_mut(&incoming.peer_id) { - Some(state @ PeerState::Incoming) => { + let state = match self.peers.get_mut(&incoming.peer_id) { + Some(s) => s, + None => { + debug_assert!(false); + return; + } + }; + + match mem::replace(state, PeerState::Poisoned) { + // Incoming => Enabled + PeerState::Incoming { mut connections, .. } => { debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Enabling connections.", index, incoming.peer_id); - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", incoming.peer_id); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: incoming.peer_id, - handler: NotifyHandler::All, - event: NotifsHandlerIn::Enable, - }); - *state = PeerState::Enabled { open: SmallVec::new() }; + + debug_assert!(connections.iter().any(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote))); + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", incoming.peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: incoming.peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Open, + }); + *connec_state = ConnectionState::Opening; + } + + *state = PeerState::Enabled { connections }; + } + + // Any state other than `Incoming` is invalid. + peer => { + error!(target: "sub-libp2p", + "State mismatch in libp2p: Expected alive incoming. Got {:?}.", + peer); + debug_assert!(false); } - peer => error!(target: "sub-libp2p", - "State mismatch in libp2p: Expected alive incoming. Got {:?}.", - peer) } } @@ -832,20 +1029,34 @@ impl GenericProto { return } - match self.peers.get_mut(&incoming.peer_id) { - Some(state @ PeerState::Incoming) => { + let state = match self.peers.get_mut(&incoming.peer_id) { + Some(s) => s, + None => { + debug_assert!(false); + return; + } + }; + + match mem::replace(state, PeerState::Poisoned) { + // Incoming => Disabled + PeerState::Incoming { mut connections, backoff_until } => { debug!(target: "sub-libp2p", "PSM => Reject({:?}, {:?}): Rejecting connections.", index, incoming.peer_id); - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", incoming.peer_id); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: incoming.peer_id, - handler: NotifyHandler::All, - event: NotifsHandlerIn::Disable, - }); - *state = PeerState::Disabled { - open: SmallVec::new(), - banned_until: None - }; + + debug_assert!(connections.iter().any(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote))); + for (connec_id, connec_state) in connections.iter_mut() + .filter(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Close", incoming.peer_id, connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: incoming.peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Close, + }); + *connec_state = ConnectionState::Closing; + } + + *state = PeerState::Disabled { connections, backoff_until }; } peer => error!(target: "sub-libp2p", "State mismatch in libp2p: Expected alive incoming. Got {:?}.", @@ -873,212 +1084,309 @@ impl NetworkBehaviour for GenericProto { } fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { - debug!(target: "sub-libp2p", "Libp2p => Connection ({:?},{:?}) to {} established.", - conn, endpoint, peer_id); - match (self.peers.entry(peer_id.clone()).or_insert(PeerState::Poisoned), endpoint) { - (st @ &mut PeerState::Requested, endpoint) | - (st @ &mut PeerState::PendingRequest { .. }, endpoint) => { + match self.peers.entry(peer_id.clone()).or_insert(PeerState::Poisoned) { + // Requested | PendingRequest => Enabled + st @ &mut PeerState::Requested | + st @ &mut PeerState::PendingRequest { .. } => { debug!(target: "sub-libp2p", "Libp2p => Connected({}, {:?}): Connection was requested by PSM.", peer_id, endpoint ); - *st = PeerState::Enabled { open: SmallVec::new() }; + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", peer_id, *conn); self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::One(*conn), - event: NotifsHandlerIn::Enable + event: NotifsHandlerIn::Open }); - } - // Note: it may seem weird that "Banned" peers get treated as if they were absent. - // This is because the word "Banned" means "temporarily prevent outgoing connections to - // this peer", and not "banned" in the sense that we would refuse the peer altogether. - (st @ &mut PeerState::Poisoned, endpoint @ ConnectedPoint::Listener { .. }) | - (st @ &mut PeerState::Banned { .. }, endpoint @ ConnectedPoint::Listener { .. }) => { - let incoming_id = self.next_incoming_index; - self.next_incoming_index.0 = match self.next_incoming_index.0.checked_add(1) { - Some(v) => v, - None => { - error!(target: "sub-libp2p", "Overflow in next_incoming_index"); - return - } - }; - debug!(target: "sub-libp2p", "Libp2p => Connected({}, {:?}): Incoming connection", - peer_id, endpoint); - debug!(target: "sub-libp2p", "PSM <= Incoming({}, {:?}).", - peer_id, incoming_id); - self.peerset.incoming(peer_id.clone(), incoming_id); - self.incoming.push(IncomingPeer { - peer_id: peer_id.clone(), - alive: true, - incoming_id, - }); - *st = PeerState::Incoming { }; + let mut connections = SmallVec::new(); + connections.push((*conn, ConnectionState::Opening)); + *st = PeerState::Enabled { connections }; } - (st @ &mut PeerState::Poisoned, endpoint) | - (st @ &mut PeerState::Banned { .. }, endpoint) => { - let banned_until = if let PeerState::Banned { until } = st { - Some(*until) + // Poisoned gets inserted above if the entry was missing. + // Ø | Backoff => Disabled + st @ &mut PeerState::Poisoned | + st @ &mut PeerState::Backoff { .. } => { + let backoff_until = if let PeerState::Backoff { timer_deadline, .. } = st { + Some(*timer_deadline) } else { None }; debug!(target: "sub-libp2p", - "Libp2p => Connected({},{:?}): Not requested by PSM, disabling.", - peer_id, endpoint); - *st = PeerState::Disabled { open: SmallVec::new(), banned_until }; - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::One(*conn), - event: NotifsHandlerIn::Disable - }); - } + "Libp2p => Connected({}, {:?}, {:?}): Not requested by PSM, disabling.", + peer_id, endpoint, *conn); - (PeerState::Incoming { .. }, _) => { - debug!(target: "sub-libp2p", - "Secondary connection {:?} to {} waiting for PSM decision.", - conn, peer_id); - }, - - (PeerState::Enabled { .. }, _) => { - debug!(target: "sub-libp2p", "Handler({},{:?}) <= Enable secondary connection", - peer_id, conn); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::One(*conn), - event: NotifsHandlerIn::Enable - }); + let mut connections = SmallVec::new(); + connections.push((*conn, ConnectionState::Closed)); + *st = PeerState::Disabled { connections, backoff_until }; } - (PeerState::Disabled { .. }, _) | (PeerState::DisabledPendingEnable { .. }, _) => { - debug!(target: "sub-libp2p", "Handler({},{:?}) <= Disable secondary connection", - peer_id, conn); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::One(*conn), - event: NotifsHandlerIn::Disable - }); + // In all other states, add this new connection to the list of closed inactive + // connections. + PeerState::Incoming { connections, .. } | + PeerState::Disabled { connections, .. } | + PeerState::DisabledPendingEnable { connections, .. } | + PeerState::Enabled { connections, .. } => { + debug!(target: "sub-libp2p", + "Libp2p => Connected({}, {:?}, {:?}): Secondary connection. Leaving closed.", + peer_id, endpoint, *conn); + connections.push((*conn, ConnectionState::Closed)); } } } - fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) { - debug!(target: "sub-libp2p", "Libp2p => Connection ({:?},{:?}) to {} closed.", - conn, endpoint, peer_id); - match self.peers.get_mut(peer_id) { - Some(PeerState::Disabled { open, .. }) | - Some(PeerState::DisabledPendingEnable { open, .. }) | - Some(PeerState::Enabled { open, .. }) => { - // Check if the "link" to the peer is already considered closed, - // i.e. there is no connection that is open for custom protocols, - // in which case `CustomProtocolClosed` was already emitted. - let closed = open.is_empty(); - let sink_closed = open.get(0).map_or(false, |(c, _)| c == conn); - open.retain(|(c, _)| c != conn); - if !closed { - if let Some((_, sink)) = open.get(0) { - if sink_closed { - let event = GenericProtoOut::CustomProtocolReplaced { - peer_id: peer_id.clone(), - notifications_sink: sink.clone(), + fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, _endpoint: &ConnectedPoint) { + let mut entry = if let Entry::Occupied(entry) = self.peers.entry(peer_id.clone()) { + entry + } else { + error!(target: "sub-libp2p", "inject_connection_closed: State mismatch in the custom protos handler"); + debug_assert!(false); + return + }; + + match mem::replace(entry.get_mut(), PeerState::Poisoned) { + // Disabled => Disabled | Backoff | Ø + PeerState::Disabled { mut connections, backoff_until } => { + debug!(target: "sub-libp2p", "Libp2p => Disconnected({}, {:?}): Disabled.", peer_id, *conn); + + if let Some(pos) = connections.iter().position(|(c, _)| *c == *conn) { + connections.remove(pos); + } else { + debug_assert!(false); + error!(target: "sub-libp2p", + "inject_connection_closed: State mismatch in the custom protos handler"); + } + + if connections.is_empty() { + if let Some(until) = backoff_until { + let now = Instant::now(); + if until > now { + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(until - now); + let peer_id = peer_id.clone(); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + + *entry.get_mut() = PeerState::Backoff { + timer: delay_id, + timer_deadline: until, }; - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } else { + entry.remove(); } } else { - debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); - let event = GenericProtoOut::CustomProtocolClosed { - peer_id: peer_id.clone(), - reason: "Disconnected by libp2p".into(), - }; - - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + entry.remove(); } + } else { + *entry.get_mut() = PeerState::Disabled { connections, backoff_until }; } - } - _ => {} - } - } + }, - fn inject_disconnected(&mut self, peer_id: &PeerId) { - match self.peers.remove(peer_id) { - None | Some(PeerState::Requested) | Some(PeerState::PendingRequest { .. }) | - Some(PeerState::Banned { .. }) => - // This is a serious bug either in this state machine or in libp2p. - error!(target: "sub-libp2p", - "`inject_disconnected` called for unknown peer {}", - peer_id), + // DisabledPendingEnable => DisabledPendingEnable | Backoff + PeerState::DisabledPendingEnable { mut connections, timer_deadline, timer } => { + debug!( + target: "sub-libp2p", + "Libp2p => Disconnected({}, {:?}): Disabled but pending enable.", + peer_id, *conn + ); - Some(PeerState::Disabled { open, banned_until, .. }) => { - if !open.is_empty() { + if let Some(pos) = connections.iter().position(|(c, _)| *c == *conn) { + connections.remove(pos); + } else { debug_assert!(false); - error!( - target: "sub-libp2p", - "State mismatch: disconnected from {} with non-empty list of connections", - peer_id - ); + error!(target: "sub-libp2p", + "inject_connection_closed: State mismatch in the custom protos handler"); } - debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was disabled.", peer_id); - if let Some(until) = banned_until { - self.peers.insert(peer_id.clone(), PeerState::Banned { until }); + + if connections.is_empty() { + debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); + self.peerset.dropped(peer_id.clone()); + *entry.get_mut() = PeerState::Backoff { timer, timer_deadline }; + + } else { + *entry.get_mut() = PeerState::DisabledPendingEnable { + connections, timer_deadline, timer + }; } - } + }, - Some(PeerState::DisabledPendingEnable { open, timer_deadline, .. }) => { - if !open.is_empty() { + // Incoming => Incoming | Disabled | Backoff | Ø + PeerState::Incoming { mut connections, backoff_until } => { + debug!( + target: "sub-libp2p", + "Libp2p => Disconnected({}, {:?}): OpenDesiredByRemote.", + peer_id, *conn + ); + + debug_assert!(connections.iter().any(|(_, s)| matches!(s, ConnectionState::OpenDesiredByRemote))); + + if let Some(pos) = connections.iter().position(|(c, _)| *c == *conn) { + connections.remove(pos); + } else { debug_assert!(false); - error!( - target: "sub-libp2p", - "State mismatch: disconnected from {} with non-empty list of connections", - peer_id - ); + error!(target: "sub-libp2p", + "inject_connection_closed: State mismatch in the custom protos handler"); + } + + let no_desired_left = !connections.iter().any(|(_, s)| { + matches!(s, ConnectionState::OpenDesiredByRemote) + }); + + // If no connection is `OpenDesiredByRemote` anymore, clean up the peerset incoming + // request. + if no_desired_left { + // In the incoming state, we don't report "Dropped". Instead we will just + // ignore the corresponding Accept/Reject. + if let Some(state) = self.incoming.iter_mut() + .find(|i| i.alive && i.peer_id == *peer_id) + { + state.alive = false; + } else { + error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in \ + incoming corresponding to an incoming state in peers"); + debug_assert!(false); + } + } + + if connections.is_empty() { + if let Some(until) = backoff_until { + let now = Instant::now(); + if until > now { + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(until - now); + let peer_id = peer_id.clone(); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + + *entry.get_mut() = PeerState::Backoff { + timer: delay_id, + timer_deadline: until, + }; + } else { + entry.remove(); + } + } else { + entry.remove(); + } + + } else if no_desired_left { + // If no connection is `OpenDesiredByRemote` anymore, switch to `Disabled`. + *entry.get_mut() = PeerState::Disabled { connections, backoff_until }; + } else { + *entry.get_mut() = PeerState::Incoming { connections, backoff_until }; } - debug!(target: "sub-libp2p", - "Libp2p => Disconnected({}): Was disabled but pending enable.", - peer_id); - debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); - self.peerset.dropped(peer_id.clone()); - self.peers.insert(peer_id.clone(), PeerState::Banned { until: timer_deadline }); } - Some(PeerState::Enabled { open, .. }) => { - if !open.is_empty() { + // Enabled => Enabled | Backoff + // Peers are always backed-off when disconnecting while Enabled. + PeerState::Enabled { mut connections } => { + debug!( + target: "sub-libp2p", + "Libp2p => Disconnected({}, {:?}): Enabled.", + peer_id, *conn + ); + + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + + if let Some(pos) = connections.iter().position(|(c, _)| *c == *conn) { + let (_, state) = connections.remove(pos); + if let ConnectionState::Open(_) = state { + if let Some((replacement_pos, replacement_sink)) = connections + .iter() + .enumerate() + .filter_map(|(num, (_, s))| { + match s { + ConnectionState::Open(s) => Some((num, s.clone())), + _ => None + } + }) + .next() + { + if pos <= replacement_pos { + debug!(target: "sub-libp2p", "External API <= Sink replaced({})", peer_id); + let event = GenericProtoOut::CustomProtocolReplaced { + peer_id: peer_id.clone(), + notifications_sink: replacement_sink, + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + } else { + debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); + let event = GenericProtoOut::CustomProtocolClosed { + peer_id: peer_id.clone(), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + } + + } else { + error!(target: "sub-libp2p", + "inject_connection_closed: State mismatch in the custom protos handler"); debug_assert!(false); - error!( - target: "sub-libp2p", - "State mismatch: disconnected from {} with non-empty list of connections", - peer_id - ); } - debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was enabled.", peer_id); - debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); - self.peerset.dropped(peer_id.clone()); - let ban_dur = Uniform::new(5, 10).sample(&mut rand::thread_rng()); - self.peers.insert(peer_id.clone(), PeerState::Banned { - until: Instant::now() + Duration::from_secs(ban_dur) - }); - } - // In the incoming state, we don't report "Dropped". Instead we will just ignore the - // corresponding Accept/Reject. - Some(PeerState::Incoming { }) => { - if let Some(state) = self.incoming.iter_mut() - .find(|i| i.alive && i.peer_id == *peer_id) + if connections.is_empty() { + debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); + self.peerset.dropped(peer_id.clone()); + let ban_dur = Uniform::new(5, 10).sample(&mut rand::thread_rng()); + + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(Duration::from_secs(ban_dur)); + let peer_id = peer_id.clone(); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + + *entry.get_mut() = PeerState::Backoff { + timer: delay_id, + timer_deadline: Instant::now() + Duration::from_secs(ban_dur), + }; + + } else if !connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_))) { - debug!(target: "sub-libp2p", - "Libp2p => Disconnected({}): Was in incoming mode with id {:?}.", - peer_id, state.incoming_id); - state.alive = false; + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); + self.peerset.dropped(peer_id.clone()); + + *entry.get_mut() = PeerState::Disabled { + connections, + backoff_until: None + }; + } else { - error!(target: "sub-libp2p", "State mismatch in libp2p: no entry in incoming \ - corresponding to an incoming state in peers") + *entry.get_mut() = PeerState::Enabled { connections }; } } - Some(PeerState::Poisoned) => - error!(target: "sub-libp2p", "State of peer {} is poisoned", peer_id), + PeerState::Requested | + PeerState::PendingRequest { .. } | + PeerState::Backoff { .. } => { + // This is a serious bug either in this state machine or in libp2p. + error!(target: "sub-libp2p", + "`inject_connection_closed` called for unknown peer {}", + peer_id); + debug_assert!(false); + }, + PeerState::Poisoned => { + error!(target: "sub-libp2p", "State of peer {} is poisoned", peer_id); + debug_assert!(false); + }, } } + fn inject_disconnected(&mut self, _peer_id: &PeerId) { + } + fn inject_addr_reach_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, error: &dyn error::Error) { trace!(target: "sub-libp2p", "Libp2p => Reach failure for {:?} through {:?}: {:?}", peer_id, addr, error); } @@ -1087,19 +1395,39 @@ impl NetworkBehaviour for GenericProto { if let Entry::Occupied(mut entry) = self.peers.entry(peer_id.clone()) { match mem::replace(entry.get_mut(), PeerState::Poisoned) { // The peer is not in our list. - st @ PeerState::Banned { .. } => { + st @ PeerState::Backoff { .. } => { trace!(target: "sub-libp2p", "Libp2p => Dial failure for {:?}", peer_id); *entry.into_mut() = st; }, // "Basic" situation: we failed to reach a peer that the peerset requested. - PeerState::Requested | PeerState::PendingRequest { .. } => { + st @ PeerState::Requested | + st @ PeerState::PendingRequest { .. } => { debug!(target: "sub-libp2p", "Libp2p => Dial failure for {:?}", peer_id); - *entry.into_mut() = PeerState::Banned { - until: Instant::now() + Duration::from_secs(5) - }; + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); - self.peerset.dropped(peer_id.clone()) + self.peerset.dropped(peer_id.clone()); + + let now = Instant::now(); + let ban_duration = match st { + PeerState::PendingRequest { timer_deadline, .. } if timer_deadline > now => + cmp::max(timer_deadline - now, Duration::from_secs(5)), + _ => Duration::from_secs(5) + }; + + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(ban_duration); + let peer_id = peer_id.clone(); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + + *entry.into_mut() = PeerState::Backoff { + timer: delay_id, + timer_deadline: now + ban_duration, + }; }, // We can still get dial failures even if we are already connected to the peer, @@ -1110,8 +1438,10 @@ impl NetworkBehaviour for GenericProto { *entry.into_mut() = st; }, - PeerState::Poisoned => - error!(target: "sub-libp2p", "State of {:?} is poisoned", peer_id), + PeerState::Poisoned => { + error!(target: "sub-libp2p", "State of {:?} is poisoned", peer_id); + debug_assert!(false); + }, } } else { @@ -1127,123 +1457,271 @@ impl NetworkBehaviour for GenericProto { event: NotifsHandlerOut, ) { match event { - NotifsHandlerOut::Closed { endpoint, reason } => { + NotifsHandlerOut::OpenDesiredByRemote => { debug!(target: "sub-libp2p", - "Handler({:?}) => Endpoint {:?} closed for custom protocols: {}", - source, endpoint, reason); + "Handler({:?}, {:?}]) => OpenDesiredByRemote", + source, connection); let mut entry = if let Entry::Occupied(entry) = self.peers.entry(source.clone()) { entry } else { - error!(target: "sub-libp2p", "Closed: State mismatch in the custom protos handler"); + error!(target: "sub-libp2p", "OpenDesiredByRemote: State mismatch in the custom protos handler"); + debug_assert!(false); return }; - let (last, new_notifications_sink) = match mem::replace(entry.get_mut(), PeerState::Poisoned) { - PeerState::Enabled { mut open } => { - let pos = open.iter().position(|(c, _)| c == &connection); - let sink_closed = pos == Some(0); - if let Some(pos) = pos { - open.remove(pos); + match mem::replace(entry.get_mut(), PeerState::Poisoned) { + // Incoming => Incoming + PeerState::Incoming { mut connections, backoff_until } => { + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::OpenDesiredByRemote))); + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, _)| *c == connection) { + if let ConnectionState::Closed = *connec_state { + *connec_state = ConnectionState::OpenDesiredByRemote; + } else { + // Connections in `OpeningThenClosing` state are in a Closed phase, + // and as such can emit `OpenDesiredByRemote` messages. + // Since an `Open` and a `Close` messages have already been sent, + // there is nothing much that can be done about this anyway. + debug_assert!(matches!( + connec_state, + ConnectionState::OpeningThenClosing + )); + } } else { - debug_assert!(false); error!( target: "sub-libp2p", - "State mismatch with {}: unknown closed connection", - source + "OpenDesiredByRemote: State mismatch in the custom protos handler" ); + debug_assert!(false); } - // TODO: We switch the entire peer state to "disabled" because of possible - // race conditions involving the legacy substream. - // Once https://github.com/paritytech/substrate/issues/5670 is done, this - // should be changed to stay in the `Enabled` state. - debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", source); - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); - self.peerset.dropped(source.clone()); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: source.clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::Disable, - }); + *entry.into_mut() = PeerState::Incoming { connections, backoff_until }; + }, - let last = open.is_empty(); - let new_notifications_sink = open.iter().next().and_then(|(_, sink)| - if sink_closed { - Some(sink.clone()) + PeerState::Enabled { mut connections } => { + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, _)| *c == connection) { + if let ConnectionState::Closed = *connec_state { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", source, connection); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: source, + handler: NotifyHandler::One(connection), + event: NotifsHandlerIn::Open, + }); + *connec_state = ConnectionState::Opening; } else { - None - }); - - *entry.into_mut() = PeerState::Disabled { - open, - banned_until: None - }; - - (last, new_notifications_sink) - }, - PeerState::Disabled { mut open, banned_until } => { - let pos = open.iter().position(|(c, _)| c == &connection); - let sink_closed = pos == Some(0); - if let Some(pos) = pos { - open.remove(pos); + // Connections in `OpeningThenClosing` and `Opening` are in a Closed + // phase, and as such can emit `OpenDesiredByRemote` messages. + // Since an `Open` message haS already been sent, there is nothing + // more to do. + debug_assert!(matches!( + connec_state, + ConnectionState::OpenDesiredByRemote | ConnectionState::Opening + )); + } } else { - debug_assert!(false); error!( target: "sub-libp2p", - "State mismatch with {}: unknown closed connection", - source + "OpenDesiredByRemote: State mismatch in the custom protos handler" ); + debug_assert!(false); } - let last = open.is_empty(); - let new_notifications_sink = open.iter().next().and_then(|(_, sink)| - if sink_closed { - Some(sink.clone()) - } else { - None - }); + *entry.into_mut() = PeerState::Enabled { connections }; + }, - *entry.into_mut() = PeerState::Disabled { - open, - banned_until - }; + // Disabled => Disabled | Incoming + PeerState::Disabled { mut connections, backoff_until } => { + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, _)| *c == connection) { + if let ConnectionState::Closed = *connec_state { + *connec_state = ConnectionState::OpenDesiredByRemote; - (last, new_notifications_sink) - }, - PeerState::DisabledPendingEnable { - mut open, - timer, - timer_deadline - } => { - let pos = open.iter().position(|(c, _)| c == &connection); - let sink_closed = pos == Some(0); - if let Some(pos) = pos { - open.remove(pos); + let incoming_id = self.next_incoming_index; + self.next_incoming_index.0 += 1; + + debug!(target: "sub-libp2p", "PSM <= Incoming({}, {:?}).", + source, incoming_id); + self.peerset.incoming(source.clone(), incoming_id); + self.incoming.push(IncomingPeer { + peer_id: source.clone(), + alive: true, + incoming_id, + }); + + *entry.into_mut() = PeerState::Incoming { connections, backoff_until }; + + } else { + // Connections in `OpeningThenClosing` are in a Closed phase, and + // as such can emit `OpenDesiredByRemote` messages. + // We ignore them. + debug_assert!(matches!( + connec_state, + ConnectionState::OpeningThenClosing + )); + } } else { - debug_assert!(false); error!( target: "sub-libp2p", - "State mismatch with {}: unknown closed connection", - source + "OpenDesiredByRemote: State mismatch in the custom protos handler" ); + debug_assert!(false); } + } + + // DisabledPendingEnable => DisabledPendingEnable | Incoming + PeerState::DisabledPendingEnable { mut connections, timer, timer_deadline } => { + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, _)| *c == connection) { + if let ConnectionState::Closed = *connec_state { + *connec_state = ConnectionState::OpenDesiredByRemote; + + let incoming_id = self.next_incoming_index; + self.next_incoming_index.0 = match self.next_incoming_index.0.checked_add(1) { + Some(v) => v, + None => { + error!(target: "sub-libp2p", "Overflow in next_incoming_index"); + return + } + }; + + debug!(target: "sub-libp2p", "PSM <= Incoming({}, {:?}).", + source, incoming_id); + self.peerset.incoming(source.clone(), incoming_id); + self.incoming.push(IncomingPeer { + peer_id: source.clone(), + alive: true, + incoming_id, + }); + + *entry.into_mut() = PeerState::Incoming { + connections, + backoff_until: Some(timer_deadline), + }; - let last = open.is_empty(); - let new_notifications_sink = open.iter().next().and_then(|(_, sink)| - if sink_closed { - Some(sink.clone()) } else { - None - }); + // Connections in `OpeningThenClosing` are in a Closed phase, and + // as such can emit `OpenDesiredByRemote` messages. + // We ignore them. + debug_assert!(matches!( + connec_state, + ConnectionState::OpeningThenClosing + )); + *entry.into_mut() = PeerState::DisabledPendingEnable { + connections, + timer, + timer_deadline, + }; + } + } else { + error!( + target: "sub-libp2p", + "OpenDesiredByRemote: State mismatch in the custom protos handler" + ); + debug_assert!(false); + } + } - *entry.into_mut() = PeerState::DisabledPendingEnable { - open, - timer, - timer_deadline + state => { + error!(target: "sub-libp2p", + "OpenDesiredByRemote: Unexpected state in the custom protos handler: {:?}", + state); + debug_assert!(false); + return + } + }; + } + + NotifsHandlerOut::CloseDesired => { + debug!(target: "sub-libp2p", + "Handler({}, {:?}) => CloseDesired", + source, connection); + + let mut entry = if let Entry::Occupied(entry) = self.peers.entry(source.clone()) { + entry + } else { + error!(target: "sub-libp2p", "CloseDesired: State mismatch in the custom protos handler"); + debug_assert!(false); + return + }; + + match mem::replace(entry.get_mut(), PeerState::Poisoned) { + // Enabled => Enabled | Disabled + PeerState::Enabled { mut connections } => { + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + + let pos = if let Some(pos) = connections.iter().position(|(c, _)| *c == connection) { + pos + } else { + error!(target: "sub-libp2p", + "CloseDesired: State mismatch in the custom protos handler"); + debug_assert!(false); + return; }; - (last, new_notifications_sink) + if matches!(connections[pos].1, ConnectionState::Closing) { + return; + } + + debug_assert!(matches!(connections[pos].1, ConnectionState::Open(_))); + connections[pos].1 = ConnectionState::Closing; + + debug!(target: "sub-libp2p", "Handler({}, {:?}) <= Close", source, connection); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: source.clone(), + handler: NotifyHandler::One(connection), + event: NotifsHandlerIn::Close, + }); + + if let Some((replacement_pos, replacement_sink)) = connections + .iter() + .enumerate() + .filter_map(|(num, (_, s))| { + match s { + ConnectionState::Open(s) => Some((num, s.clone())), + _ => None + } + }) + .next() + { + if pos <= replacement_pos { + debug!(target: "sub-libp2p", "External API <= Sink replaced({:?})", source); + let event = GenericProtoOut::CustomProtocolReplaced { + peer_id: source, + notifications_sink: replacement_sink, + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + *entry.into_mut() = PeerState::Enabled { connections, }; + } + + } else { + // List of open connections wasn't empty before but now it is. + if !connections.iter().any(|(_, s)| matches!(s, ConnectionState::Opening)) { + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); + self.peerset.dropped(source.clone()); + *entry.into_mut() = PeerState::Disabled { + connections, backoff_until: None + }; + } else { + *entry.into_mut() = PeerState::Enabled { connections }; + } + + debug!(target: "sub-libp2p", "External API <= Closed({:?})", source); + let event = GenericProtoOut::CustomProtocolClosed { + peer_id: source, + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + }, + + // All connections in `Disabled` and `DisabledPendingEnable` have been sent a + // `Close` message already, and as such ignore any `CloseDesired` message. + state @ PeerState::Disabled { .. } | + state @ PeerState::DisabledPendingEnable { .. } => { + *entry.into_mut() = state; + return; }, state => { error!(target: "sub-libp2p", @@ -1251,103 +1729,227 @@ impl NetworkBehaviour for GenericProto { state); return } - }; + } + } - if last { - debug!(target: "sub-libp2p", "External API <= Closed({:?})", source); - let event = GenericProtoOut::CustomProtocolClosed { - reason, - peer_id: source, - }; - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + NotifsHandlerOut::CloseResult => { + debug!(target: "sub-libp2p", + "Handler({}, {:?}) => CloseResult", + source, connection); + + match self.peers.get_mut(&source) { + // Move the connection from `Closing` to `Closed`. + Some(PeerState::DisabledPendingEnable { connections, .. }) | + Some(PeerState::Disabled { connections, .. }) | + Some(PeerState::Enabled { connections, .. }) => { + if let Some((_, connec_state)) = connections + .iter_mut() + .find(|(c, s)| *c == connection && matches!(s, ConnectionState::Closing)) + { + *connec_state = ConnectionState::Closed; + } else { + error!(target: "sub-libp2p", + "CloseResult: State mismatch in the custom protos handler"); + debug_assert!(false); + } + }, - } else { - if let Some(new_notifications_sink) = new_notifications_sink { - let event = GenericProtoOut::CustomProtocolReplaced { - peer_id: source, - notifications_sink: new_notifications_sink, - }; - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + state => { + error!(target: "sub-libp2p", + "CloseResult: Unexpected state in the custom protos handler: {:?}", + state); + debug_assert!(false); } - debug!(target: "sub-libp2p", "Secondary connection closed custom protocol."); } } - NotifsHandlerOut::Open { endpoint, received_handshake, notifications_sink } => { + NotifsHandlerOut::OpenResultOk { received_handshake, notifications_sink, .. } => { debug!(target: "sub-libp2p", - "Handler({:?}) => Endpoint {:?} open for custom protocols.", - source, endpoint); - - let first = match self.peers.get_mut(&source) { - Some(PeerState::Enabled { ref mut open, .. }) | - Some(PeerState::DisabledPendingEnable { ref mut open, .. }) | - Some(PeerState::Disabled { ref mut open, .. }) => { - let first = open.is_empty(); - if !open.iter().any(|(c, _)| *c == connection) { - open.push((connection, notifications_sink.clone())); + "Handler({}, {:?}) => OpenResultOk", + source, connection); + + match self.peers.get_mut(&source) { + Some(PeerState::Enabled { connections, .. }) => { + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + let any_open = connections.iter().any(|(_, s)| matches!(s, ConnectionState::Open(_))); + + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::Opening)) + { + if !any_open { + debug!(target: "sub-libp2p", "External API <= Open({:?})", source); + let event = GenericProtoOut::CustomProtocolOpen { + peer_id: source, + received_handshake, + notifications_sink: notifications_sink.clone(), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + *connec_state = ConnectionState::Open(notifications_sink); + } else if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::OpeningThenClosing)) + { + *connec_state = ConnectionState::Closing; } else { - error!( - target: "sub-libp2p", - "State mismatch: connection with {} opened a second time", - source - ); + debug_assert!(false); + error!(target: "sub-libp2p", + "OpenResultOk State mismatch in the custom protos handler"); + } + }, + + Some(PeerState::DisabledPendingEnable { connections, .. }) | + Some(PeerState::Disabled { connections, .. }) => { + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::OpeningThenClosing)) + { + *connec_state = ConnectionState::Closing; + } else { + error!(target: "sub-libp2p", + "OpenResultOk State mismatch in the custom protos handler"); + debug_assert!(false); } - first } + state => { error!(target: "sub-libp2p", - "Open: Unexpected state in the custom protos handler: {:?}", + "OpenResultOk: Unexpected state in the custom protos handler: {:?}", state); + debug_assert!(false); return } + } + } + + NotifsHandlerOut::OpenResultErr => { + debug!(target: "sub-libp2p", + "Handler({:?}, {:?}) => OpenResultErr", + source, connection); + + let mut entry = if let Entry::Occupied(entry) = self.peers.entry(source.clone()) { + entry + } else { + error!(target: "sub-libp2p", "OpenResultErr: State mismatch in the custom protos handler"); + debug_assert!(false); + debug_assert!(false); + return + }; + + match mem::replace(entry.get_mut(), PeerState::Poisoned) { + PeerState::Enabled { mut connections } => { + debug_assert!(connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_)))); + + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::Opening)) + { + *connec_state = ConnectionState::Closed; + } else if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::OpeningThenClosing)) + { + *connec_state = ConnectionState::Closing; + } else { + error!(target: "sub-libp2p", + "OpenResultErr: State mismatch in the custom protos handler"); + debug_assert!(false); + } + + if !connections.iter().any(|(_, s)| + matches!(s, ConnectionState::Opening | ConnectionState::Open(_))) + { + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); + self.peerset.dropped(source.clone()); + + *entry.into_mut() = PeerState::Disabled { + connections, + backoff_until: None + }; + } else { + *entry.into_mut() = PeerState::Enabled { connections }; + } + }, + PeerState::Disabled { mut connections, backoff_until } => { + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::OpeningThenClosing)) + { + *connec_state = ConnectionState::Closing; + } else { + error!(target: "sub-libp2p", + "OpenResultErr: State mismatch in the custom protos handler"); + debug_assert!(false); + } + + *entry.into_mut() = PeerState::Disabled { connections, backoff_until }; + }, + PeerState::DisabledPendingEnable { mut connections, timer, timer_deadline } => { + if let Some((_, connec_state)) = connections.iter_mut().find(|(c, s)| + *c == connection && matches!(s, ConnectionState::OpeningThenClosing)) + { + *connec_state = ConnectionState::Closing; + } else { + error!(target: "sub-libp2p", + "OpenResultErr: State mismatch in the custom protos handler"); + debug_assert!(false); + } + + *entry.into_mut() = PeerState::DisabledPendingEnable { + connections, + timer, + timer_deadline, + }; + }, + state => { + error!(target: "sub-libp2p", + "Unexpected state in the custom protos handler: {:?}", + state); + debug_assert!(false); + } }; + } - if first { - debug!(target: "sub-libp2p", "External API <= Open({:?})", source); - let event = GenericProtoOut::CustomProtocolOpen { + NotifsHandlerOut::CustomMessage { message } => { + if self.is_open(&source) { + trace!(target: "sub-libp2p", "Handler({:?}) => Message", source); + trace!(target: "sub-libp2p", "External API <= Message({:?})", source); + let event = GenericProtoOut::LegacyMessage { peer_id: source, - received_handshake, - notifications_sink + message, }; - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); } else { - debug!( + trace!( target: "sub-libp2p", - "Handler({:?}) => Secondary connection opened custom protocol", - source + "Handler({:?}) => Post-close message. Dropping message.", + source, ); } } - NotifsHandlerOut::CustomMessage { message } => { - debug_assert!(self.is_open(&source)); - trace!(target: "sub-libp2p", "Handler({:?}) => Message", source); - trace!(target: "sub-libp2p", "External API <= Message({:?})", source); - let event = GenericProtoOut::LegacyMessage { - peer_id: source, - message, - }; - - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); - } - NotifsHandlerOut::Notification { protocol_name, message } => { - debug_assert!(self.is_open(&source)); - trace!( - target: "sub-libp2p", - "Handler({:?}) => Notification({:?})", - source, - protocol_name, - ); - trace!(target: "sub-libp2p", "External API <= Message({:?}, {:?})", protocol_name, source); - let event = GenericProtoOut::Notification { - peer_id: source, - protocol_name, - message, - }; + if self.is_open(&source) { + trace!( + target: "sub-libp2p", + "Handler({:?}) => Notification({:?})", + source, + protocol_name, + ); + trace!(target: "sub-libp2p", "External API <= Message({:?}, {:?})", protocol_name, source); + let event = GenericProtoOut::Notification { + peer_id: source, + protocol_name, + message, + }; - self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } else { + trace!( + target: "sub-libp2p", + "Handler({:?}) => Post-close notification({:?})", + source, + protocol_name, + ); + } } } } @@ -1400,6 +2002,11 @@ impl NetworkBehaviour for GenericProto { }; match peer_state { + PeerState::Backoff { timer, .. } if *timer == delay_id => { + debug!(target: "sub-libp2p", "Libp2p <= Clean up ban of {:?} from the state", peer_id); + self.peers.remove(&peer_id); + } + PeerState::PendingRequest { timer, .. } if *timer == delay_id => { debug!(target: "sub-libp2p", "Libp2p <= Dial {:?} now that ban has expired", peer_id); self.events.push_back(NetworkBehaviourAction::DialPeer { @@ -1409,14 +2016,33 @@ impl NetworkBehaviour for GenericProto { *peer_state = PeerState::Requested; } - PeerState::DisabledPendingEnable { timer, open, .. } if *timer == delay_id => { - debug!(target: "sub-libp2p", "Handler({:?}) <= Enable (ban expired)", peer_id); - self.events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id, - handler: NotifyHandler::All, - event: NotifsHandlerIn::Enable, - }); - *peer_state = PeerState::Enabled { open: mem::replace(open, Default::default()) }; + PeerState::DisabledPendingEnable { connections, timer, timer_deadline } + if *timer == delay_id => + { + // The first element of `closed` is chosen to open the notifications substream. + if let Some((connec_id, connec_state)) = connections.iter_mut() + .find(|(_, s)| matches!(s, ConnectionState::Closed)) + { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open (ban expired)", + peer_id, *connec_id); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: peer_id.clone(), + handler: NotifyHandler::One(*connec_id), + event: NotifsHandlerIn::Open, + }); + *connec_state = ConnectionState::Opening; + *peer_state = PeerState::Enabled { + connections: mem::replace(connections, Default::default()), + }; + } else { + *timer_deadline = Instant::now() + Duration::from_secs(5); + let delay = futures_timer::Delay::new(Duration::from_secs(5)); + let timer = *timer; + self.delays.push(async move { + delay.await; + (timer, peer_id) + }.boxed()); + } } // We intentionally never remove elements from `delays`, and it may diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index 5845130a7db..0272261f67d 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -1,27 +1,1054 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Copyright (C) 2020 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 +// Substrate 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, +// Substrate 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 +// 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 . +// along with Substrate. If not, see . + +//! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for both incoming +//! and outgoing substreams for all gossiping protocols together. +//! +//! This is the main implementation of `ProtocolsHandler` in this crate, that handles all the +//! protocols that are Substrate-related and outside of the scope of libp2p. +//! +//! # Usage +//! +//! From an API perspective, the [`NotifsHandler`] is always in one of the following state (see [`State`]): +//! +//! - Closed substreams. This is the initial state. +//! - Closed substreams, but remote desires them to be open. +//! - Open substreams. +//! - Open substreams, but remote desires them to be closed. +//! +//! The [`NotifsHandler`] can spontaneously switch between these states: +//! +//! - "Closed substreams" to "Closed substreams but open desired". When that happens, a +//! [`NotifsHandlerOut::OpenDesiredByRemote`] is emitted. +//! - "Closed substreams but open desired" to "Closed substreams" (i.e. the remote has cancelled +//! their request). When that happens, a [`NotifsHandlerOut::CloseDesired`] is emitted. +//! - "Open substreams" to "Open substreams but close desired". When that happens, a +//! [`NotifsHandlerOut::CloseDesired`] is emitted. +//! +//! The user can instruct the `NotifsHandler` to switch from "closed" to "open" or vice-versa by +//! sending either a [`NotifsHandlerIn::Open`] or a [`NotifsHandlerIn::Close`]. The `NotifsHandler` +//! must answer with [`NotifsHandlerOut::OpenResultOk`] or [`NotifsHandlerOut::OpenResultErr`], or +//! with [`NotifsHandlerOut::CloseResult`]. +//! +//! When a [`NotifsHandlerOut::OpenResultOk`] is emitted, the `NotifsHandler` is now in the open +//! state. When a [`NotifsHandlerOut::OpenResultErr`] or [`NotifsHandlerOut::CloseResult`] is +//! emitted, the `NotifsHandler` is now (or remains) in the closed state. +//! +//! When a [`NotifsHandlerOut::OpenDesiredByRemote`] is emitted, the user should always send back either a +//! [`NotifsHandlerIn::Open`] or a [`NotifsHandlerIn::Close`].If this isn't done, the remote will +//! be left in a pending state. +//! +//! It is illegal to send a [`NotifsHandlerIn::Open`] before a previously-emitted +//! [`NotifsHandlerIn::Open`] has gotten an answer. + +use crate::protocol::generic_proto::{ + upgrade::{ + NotificationsIn, NotificationsOut, NotificationsInSubstream, NotificationsOutSubstream, + NotificationsHandshakeError, RegisteredProtocol, RegisteredProtocolSubstream, + RegisteredProtocolEvent, UpgradeCollec + }, +}; -pub use self::group::{ - NotificationsSink, NotifsHandlerError, Ready, NotifsHandlerProto, NotifsHandler, NotifsHandlerIn, NotifsHandlerOut +use bytes::BytesMut; +use libp2p::core::{either::EitherOutput, ConnectedPoint, PeerId}; +use libp2p::core::upgrade::{SelectUpgrade, InboundUpgrade, OutboundUpgrade}; +use libp2p::swarm::{ + ProtocolsHandler, ProtocolsHandlerEvent, + IntoProtocolsHandler, + KeepAlive, + ProtocolsHandlerUpgrErr, + SubstreamProtocol, + NegotiatedSubstream, }; -pub use self::legacy::ConnectionKillError as LegacyConnectionKillError; +use futures::{ + channel::mpsc, + lock::{Mutex as FuturesMutex, MutexGuard as FuturesMutexGuard}, + prelude::* +}; +use log::error; +use parking_lot::{Mutex, RwLock}; +use smallvec::SmallVec; +use std::{borrow::Cow, collections::VecDeque, mem, pin::Pin, str, sync::Arc, task::{Context, Poll}, time::Duration}; +use wasm_timer::Instant; + +/// Number of pending notifications in asynchronous contexts. +/// See [`NotificationsSink::reserve_notification`] for context. +const ASYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 8; + +/// Number of pending notifications in synchronous contexts. +const SYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 2048; + +/// Maximum duration to open a substream and receive the handshake message. After that, we +/// consider that we failed to open the substream. +const OPEN_TIMEOUT: Duration = Duration::from_secs(10); + +/// After successfully establishing a connection with the remote, we keep the connection open for +/// at least this amount of time in order to give the rest of the code the chance to notify us to +/// open substreams. +const INITIAL_KEEPALIVE_TIME: Duration = Duration::from_secs(5); + +/// Implements the `IntoProtocolsHandler` trait of libp2p. +/// +/// Every time a connection with a remote starts, an instance of this struct is created and +/// sent to a background task dedicated to this connection. Once the connection is established, +/// it is turned into a [`NotifsHandler`]. +/// +/// See the documentation at the module level for more information. +pub struct NotifsHandlerProto { + /// Prototypes for upgrades for inbound substreams, and the message we respond with in the + /// handshake. + in_protocols: Vec<(NotificationsIn, Arc>>)>, + + /// Name of protocols available for outbound substreams, and the initial handshake message we + /// send. + out_protocols: Vec<(Cow<'static, str>, Arc>>)>, + + /// Configuration for the legacy protocol upgrade. + legacy_protocol: RegisteredProtocol, +} + +/// The actual handler once the connection has been established. +/// +/// See the documentation at the module level for more information. +pub struct NotifsHandler { + /// Prototypes for upgrades for inbound substreams, and the message we respond with in the + /// handshake. + in_protocols: Vec<(NotificationsIn, Arc>>)>, + + /// Name of protocols available for outbound substreams, and the initial handshake message we + /// send. + out_protocols: Vec<(Cow<'static, str>, Arc>>)>, + + /// When the connection with the remote has been successfully established. + when_connection_open: Instant, + + /// Whether we are the connection dialer or listener. + endpoint: ConnectedPoint, + + /// State of this handler. + state: State, + + /// Configuration for the legacy protocol upgrade. + legacy_protocol: RegisteredProtocol, + + /// The substreams where bidirectional communications happen. + legacy_substreams: SmallVec<[RegisteredProtocolSubstream; 4]>, + + /// Contains substreams which are being shut down. + legacy_shutdown: SmallVec<[RegisteredProtocolSubstream; 4]>, + + /// Events to return in priority from `poll`. + events_queue: VecDeque< + ProtocolsHandlerEvent + >, +} + +/// See the module-level documentation to learn about the meaning of these variants. +enum State { + /// Handler is in the "Closed" state. + Closed { + /// Vec of the same length as [`NotifsHandler::out_protocols`]. For each protocol, contains + /// a boolean indicating whether an outgoing substream is still in the process of being + /// opened. + pending_opening: Vec, + }, + + /// Handler is in the "Closed" state. A [`NotifsHandlerOut::OpenDesiredByRemote`] has been emitted. + OpenDesiredByRemote { + /// Vec of the same length as [`NotifsHandler::in_protocols`]. For each protocol, contains + /// a substream opened by the remote and that hasn't been accepted/rejected yet. + /// + /// Must always contain at least one `Some`. + in_substreams: Vec>>, + + /// See [`State::Closed::pending_opening`]. + pending_opening: Vec, + }, + + /// Handler is in the "Closed" state, but has received a [`NotifsHandlerIn::Open`] and is + /// consequently trying to open the various notifications substreams. + /// + /// A [`NotifsHandlerOut::OpenResultOk`] or a [`NotifsHandlerOut::OpenResultErr`] event must + /// be emitted when transitionning to respectively [`State::Open`] or [`State::Closed`]. + Opening { + /// In the situation where either the legacy substream has been opened or the + /// handshake-bearing notifications protocol is open, but we haven't sent out any + /// [`NotifsHandlerOut::Open`] event yet, this contains the received handshake waiting to + /// be reported through the external API. + pending_handshake: Option>, + + /// Vec of the same length as [`NotifsHandler::in_protocols`]. For each protocol, contains + /// a substream opened by the remote and that has been accepted. + /// + /// Contrary to [`State::OpenDesiredByRemote::in_substreams`], it is possible for this to + /// contain only `None`s. + in_substreams: Vec>>, + + /// Vec of the same length as [`NotifsHandler::out_protocols`]. For each protocol, contains + /// an outbound substream that has been accepted by the remote. + /// + /// Items that contain `None` mean that a substream is still being opened or has been + /// rejected by the remote. In other words, this `Vec` is kind of a mirror version of + /// [`State::Closed::pending_opening`]. + /// + /// Items that contain `Some(None)` have been rejected by the remote, most likely because + /// they don't support this protocol. At the time of writing, the external API doesn't + /// distinguish between the different protocols. From the external API's point of view, + /// either all protocols are open or none are open. In reality, light clients in particular + /// don't support for example the GrandPa protocol, and as such will refuse our outgoing + /// attempts. This is problematic in theory, but in practice this is handled properly at a + /// higher level. This flaw will fixed once the outer layers know to differentiate the + /// multiple protocols. + out_substreams: Vec>>>, + }, + + /// Handler is in the "Open" state. + Open { + /// Contains the two `Receiver`s connected to the [`NotificationsSink`] that has been + /// sent out. The notifications to send out can be pulled from this receivers. + /// We use two different channels in order to have two different channel sizes, but from + /// the receiving point of view, the two channels are the same. + /// The receivers are fused in case the user drops the [`NotificationsSink`] entirely. + notifications_sink_rx: stream::Select< + stream::Fuse>, + stream::Fuse> + >, + + /// Vec of the same length as [`NotifsHandler::out_protocols`]. For each protocol, contains + /// an outbound substream that has been accepted by the remote. + /// + /// On transition to [`State::Open`], all the elements must be `Some`. Elements are + /// switched to `None` only if the remote closes substreams, in which case `want_closed` + /// must be true. + out_substreams: Vec>>, + + /// Vec of the same length as [`NotifsHandler::in_protocols`]. For each protocol, contains + /// a substream opened by the remote and that has been accepted. + /// + /// Contrary to [`State::OpenDesiredByRemote::in_substreams`], it is possible for this to + /// contain only `None`s. + in_substreams: Vec>>, + + /// If true, at least one substream in [`State::Open::out_substreams`] has been closed or + /// reset by the remote and a [`NotifsHandlerOut::CloseDesired`] message has been sent + /// out. + want_closed: bool, + }, +} + +impl IntoProtocolsHandler for NotifsHandlerProto { + type Handler = NotifsHandler; + + fn inbound_protocol(&self) -> SelectUpgrade, RegisteredProtocol> { + let in_protocols = self.in_protocols.iter() + .map(|(h, _)| h.clone()) + .collect::>(); + + SelectUpgrade::new(in_protocols, self.legacy_protocol.clone()) + } + + fn into_handler(self, _: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler { + let num_out_proto = self.out_protocols.len(); + + NotifsHandler { + in_protocols: self.in_protocols, + out_protocols: self.out_protocols, + endpoint: connected_point.clone(), + when_connection_open: Instant::now(), + state: State::Closed { + pending_opening: (0..num_out_proto).map(|_| false).collect(), + }, + legacy_protocol: self.legacy_protocol, + legacy_substreams: SmallVec::new(), + legacy_shutdown: SmallVec::new(), + events_queue: VecDeque::with_capacity(16), + } + } +} + +/// Event that can be received by a `NotifsHandler`. +#[derive(Debug, Clone)] +pub enum NotifsHandlerIn { + /// Instruct the handler to open the notification substreams. + /// + /// Must always be answered by a [`NotifsHandlerOut::OpenResultOk`] or a + /// [`NotifsHandlerOut::OpenResultErr`] event. + /// + /// Importantly, it is forbidden to send a [`NotifsHandlerIn::Open`] while a previous one is + /// already in the fly. It is however possible if a `Close` is still in the fly. + Open, + + /// Instruct the handler to close the notification substreams, or reject any pending incoming + /// substream request. + /// + /// Must always be answered by a [`NotifsHandlerOut::CloseResult`] event. + Close, +} + +/// Event that can be emitted by a `NotifsHandler`. +#[derive(Debug)] +pub enum NotifsHandlerOut { + /// Acknowledges a [`NotifsHandlerIn::Open`]. + OpenResultOk { + /// The endpoint of the connection that is open for custom protocols. + endpoint: ConnectedPoint, + /// Handshake that was sent to us. + /// This is normally a "Status" message, but this out of the concern of this code. + received_handshake: Vec, + /// How notifications can be sent to this node. + notifications_sink: NotificationsSink, + }, + + /// Acknowledges a [`NotifsHandlerIn::Open`]. The remote has refused the attempt to open + /// notification substreams. + OpenResultErr, + + /// Acknowledges a [`NotifsHandlerIn::Close`]. + CloseResult, + + /// The remote would like the substreams to be open. Send a [`NotifsHandlerIn::Open`] or a + /// [`NotifsHandlerIn::Close`] in order to either accept or deny this request. If a + /// [`NotifsHandlerIn::Open`] or [`NotifsHandlerIn::Close`] has been sent before and has not + /// yet been acknowledged by a matching [`NotifsHandlerOut`], then you don't need to a send + /// another [`NotifsHandlerIn`]. + OpenDesiredByRemote, + + /// The remote would like the substreams to be closed. Send a [`NotifsHandlerIn::Close`] in + /// order to close them. If a [`NotifsHandlerIn::Close`] has been sent before and has not yet + /// been acknowledged by a [`NotifsHandlerOut::CloseResult`], then you don't need to a send + /// another one. + CloseDesired, + + /// Received a non-gossiping message on the legacy substream. + /// + /// Can only happen when the handler is in the open state. + CustomMessage { + /// Message that has been received. + /// + /// Keep in mind that this can be a `ConsensusMessage` message, which then contains a + /// notification. + message: BytesMut, + }, + + /// Received a message on a custom protocol substream. + /// + /// Can only happen when the handler is in the open state. + Notification { + /// Name of the protocol of the message. + protocol_name: Cow<'static, str>, + + /// Message that has been received. + message: BytesMut, + }, +} + +/// Sink connected directly to the node background task. Allows sending notifications to the peer. +/// +/// Can be cloned in order to obtain multiple references to the same peer. +#[derive(Debug, Clone)] +pub struct NotificationsSink { + inner: Arc, +} + +#[derive(Debug)] +struct NotificationsSinkInner { + /// Sender to use in asynchronous contexts. Uses an asynchronous mutex. + async_channel: FuturesMutex>, + /// Sender to use in synchronous contexts. Uses a synchronous mutex. + /// This channel has a large capacity and is meant to be used in contexts where + /// back-pressure cannot be properly exerted. + /// It will be removed in a future version. + sync_channel: Mutex>, +} + +/// Message emitted through the [`NotificationsSink`] and processed by the background task +/// dedicated to the peer. +#[derive(Debug)] +enum NotificationsSinkMessage { + /// Message emitted by [`NotificationsSink::reserve_notification`] and + /// [`NotificationsSink::write_notification_now`]. + Notification { + protocol_name: Cow<'static, str>, + message: Vec, + }, + + /// Must close the connection. + ForceClose, +} + +impl NotificationsSink { + /// Sends a notification to the peer. + /// + /// If too many messages are already buffered, the notification is silently discarded and the + /// connection to the peer will be closed shortly after. + /// + /// The protocol name is expected to be checked ahead of calling this method. It is a logic + /// error to send a notification using an unknown protocol. + /// + /// This method will be removed in a future version. + pub fn send_sync_notification<'a>( + &'a self, + protocol_name: Cow<'static, str>, + message: impl Into> + ) { + let mut lock = self.inner.sync_channel.lock(); + let result = lock.try_send(NotificationsSinkMessage::Notification { + protocol_name, + message: message.into() + }); + + if result.is_err() { + // Cloning the `mpsc::Sender` guarantees the allocation of an extra spot in the + // buffer, and therefore `try_send` will succeed. + let _result2 = lock.clone().try_send(NotificationsSinkMessage::ForceClose); + debug_assert!(_result2.map(|()| true).unwrap_or_else(|err| err.is_disconnected())); + } + } + + /// Wait until the remote is ready to accept a notification. + /// + /// Returns an error in the case where the connection is closed. + /// + /// The protocol name is expected to be checked ahead of calling this method. It is a logic + /// error to send a notification using an unknown protocol. + pub async fn reserve_notification<'a>(&'a self, protocol_name: Cow<'static, str>) -> Result, ()> { + let mut lock = self.inner.async_channel.lock().await; + + let poll_ready = future::poll_fn(|cx| lock.poll_ready(cx)).await; + if poll_ready.is_ok() { + Ok(Ready { protocol_name: protocol_name, lock }) + } else { + Err(()) + } + } +} + +/// Notification slot is reserved and the notification can actually be sent. +#[must_use] +#[derive(Debug)] +pub struct Ready<'a> { + /// Guarded channel. The channel inside is guaranteed to not be full. + lock: FuturesMutexGuard<'a, mpsc::Sender>, + /// Name of the protocol. Should match one of the protocols passed at initialization. + protocol_name: Cow<'static, str>, +} + +impl<'a> Ready<'a> { + /// Consumes this slots reservation and actually queues the notification. + /// + /// Returns an error if the substream has been closed. + pub fn send( + mut self, + notification: impl Into> + ) -> Result<(), ()> { + self.lock.start_send(NotificationsSinkMessage::Notification { + protocol_name: self.protocol_name, + message: notification.into(), + }).map_err(|_| ()) + } +} + +/// Error specific to the collection of protocols. +#[derive(Debug, derive_more::Display, derive_more::Error)] +pub enum NotifsHandlerError { + /// Channel of synchronous notifications is full. + SyncNotificationsClogged, +} + +impl NotifsHandlerProto { + /// Builds a new handler. + /// + /// `list` is a list of notification protocols names, and the message to send as part of the + /// handshake. At the moment, the message is always the same whether we open a substream + /// ourselves or respond to handshake from the remote. + /// + /// The first protocol in `list` is special-cased as the protocol that contains the handshake + /// to report through the [`NotifsHandlerOut::Open`] event. + /// + /// # Panic + /// + /// - Panics if `list` is empty. + /// + pub fn new( + legacy_protocol: RegisteredProtocol, + list: impl Into, Arc>>)>>, + ) -> Self { + let list = list.into(); + assert!(!list.is_empty()); + + let out_protocols = list + .clone() + .into_iter() + .collect(); + + let in_protocols = list.clone() + .into_iter() + .map(|(proto_name, msg)| (NotificationsIn::new(proto_name), msg)) + .collect(); + + NotifsHandlerProto { + in_protocols, + out_protocols, + legacy_protocol, + } + } +} + +impl ProtocolsHandler for NotifsHandler { + type InEvent = NotifsHandlerIn; + type OutEvent = NotifsHandlerOut; + type Error = NotifsHandlerError; + type InboundProtocol = SelectUpgrade, RegisteredProtocol>; + type OutboundProtocol = NotificationsOut; + // Index within the `out_protocols`. + type OutboundOpenInfo = usize; + type InboundOpenInfo = (); + + fn listen_protocol(&self) -> SubstreamProtocol { + let in_protocols = self.in_protocols.iter() + .map(|(h, _)| h.clone()) + .collect::>(); + + let proto = SelectUpgrade::new(in_protocols, self.legacy_protocol.clone()); + SubstreamProtocol::new(proto, ()) + } + + fn inject_fully_negotiated_inbound( + &mut self, + out: >::Output, + (): () + ) { + match out { + // Received notifications substream. + EitherOutput::First(((_remote_handshake, mut proto), num)) => { + match &mut self.state { + State::Closed { pending_opening } => { + self.events_queue.push_back(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::OpenDesiredByRemote + )); + + let mut in_substreams = (0..self.in_protocols.len()) + .map(|_| None) + .collect::>(); + in_substreams[num] = Some(proto); + self.state = State::OpenDesiredByRemote { + in_substreams, + pending_opening: mem::replace(pending_opening, Vec::new()), + }; + }, + State::OpenDesiredByRemote { in_substreams, .. } => { + if in_substreams[num].is_some() { + // If a substream already exists, silently drop the new one. + // Note that we drop the substream, which will send an equivalent to a + // TCP "RST" to the remote and force-close the substream. It might + // seem like an unclean way to get rid of a substream. However, keep + // in mind that it is invalid for the remote to open multiple such + // substreams, and therefore sending a "RST" is the most correct thing + // to do. + return; + } + in_substreams[num] = Some(proto); + }, + State::Opening { in_substreams, .. } | + State::Open { in_substreams, .. } => { + if in_substreams[num].is_some() { + // Same remark as above. + return; + } + + // We create `handshake_message` on a separate line to be sure + // that the lock is released as soon as possible. + let handshake_message = self.in_protocols[num].1.read().clone(); + proto.send_handshake(handshake_message); + in_substreams[num] = Some(proto); + }, + }; + } + + // Received legacy substream. + EitherOutput::Second((substream, _handshake)) => { + // Note: while we awknowledge legacy substreams and handle incoming messages, + // it doesn't trigger any `OpenDesiredByRemote` event as a way to simplify the + // logic of this code. + // Since mid-2019, legacy substreams are supposed to be used at the same time as + // notifications substreams, and not in isolation. Nodes that open legacy + // substreams in isolation are considered deprecated. + if self.legacy_substreams.len() <= 4 { + self.legacy_substreams.push(substream); + } + }, + } + } + + fn inject_fully_negotiated_outbound( + &mut self, + (handshake, substream): >::Output, + num: Self::OutboundOpenInfo + ) { + match &mut self.state { + State::Closed { pending_opening } | + State::OpenDesiredByRemote { pending_opening, .. } => { + debug_assert!(pending_opening[num]); + pending_opening[num] = false; + } + State::Open { .. } => { + error!(target: "sub-libp2p", "☎️ State mismatch in notifications handler"); + debug_assert!(false); + } + State::Opening { pending_handshake, in_substreams, out_substreams } => { + debug_assert!(out_substreams[num].is_none()); + out_substreams[num] = Some(Some(substream)); + + if num == 0 { + debug_assert!(pending_handshake.is_none()); + *pending_handshake = Some(handshake); + } + + if !out_substreams.iter().any(|s| s.is_none()) { + let (async_tx, async_rx) = mpsc::channel(ASYNC_NOTIFICATIONS_BUFFER_SIZE); + let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); + let notifications_sink = NotificationsSink { + inner: Arc::new(NotificationsSinkInner { + async_channel: FuturesMutex::new(async_tx), + sync_channel: Mutex::new(sync_tx), + }), + }; + + debug_assert!(pending_handshake.is_some()); + let pending_handshake = pending_handshake.take().unwrap_or_default(); + + let out_substreams = out_substreams + .drain(..) + .map(|s| s.expect("checked by the if above; qed")) + .collect(); + + self.state = State::Open { + notifications_sink_rx: stream::select(async_rx.fuse(), sync_rx.fuse()), + out_substreams, + in_substreams: mem::replace(in_substreams, Vec::new()), + want_closed: false, + }; + + self.events_queue.push_back(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::OpenResultOk { + endpoint: self.endpoint.clone(), + received_handshake: pending_handshake, + notifications_sink + } + )); + } + } + } + } + + fn inject_event(&mut self, message: NotifsHandlerIn) { + match message { + NotifsHandlerIn::Open => { + match &mut self.state { + State::Closed { .. } | State::OpenDesiredByRemote { .. } => { + let (pending_opening, mut in_substreams) = match &mut self.state { + State::Closed { pending_opening } => (pending_opening, None), + State::OpenDesiredByRemote { pending_opening, in_substreams } => + (pending_opening, Some(mem::replace(in_substreams, Vec::new()))), + _ => unreachable!() + }; + + for (n, is_pending) in pending_opening.iter().enumerate() { + if *is_pending { + continue; + } + + let proto = NotificationsOut::new( + self.out_protocols[n].0.clone(), + self.out_protocols[n].1.read().clone() + ); + + self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { + protocol: SubstreamProtocol::new(proto, n) + .with_timeout(OPEN_TIMEOUT), + }); + } + + if let Some(in_substreams) = in_substreams.as_mut() { + for (num, substream) in in_substreams.iter_mut().enumerate() { + let substream = match substream.as_mut() { + Some(s) => s, + None => continue, + }; + + let handshake_message = self.in_protocols[num].1.read().clone(); + substream.send_handshake(handshake_message); + } + } + + self.state = State::Opening { + pending_handshake: None, + in_substreams: if let Some(in_substreams) = in_substreams { + in_substreams + } else { + (0..self.in_protocols.len()).map(|_| None).collect() + }, + out_substreams: (0..self.out_protocols.len()).map(|_| None).collect(), + }; + }, + State::Opening { .. } | + State::Open { .. } => { + // As documented, it is forbidden to send an `Open` while there is already + // one in the fly. + error!(target: "sub-libp2p", "opening already-opened handler"); + debug_assert!(false); + }, + } + }, + + NotifsHandlerIn::Close => { + for mut substream in self.legacy_substreams.drain() { + substream.shutdown(); + self.legacy_shutdown.push(substream); + } + + match &mut self.state { + State::Open { .. } => { + self.state = State::Closed { + pending_opening: Vec::new(), + }; + }, + State::Opening { out_substreams, .. } => { + let pending_opening = out_substreams.iter().map(|s| s.is_none()).collect(); + self.state = State::Closed { + pending_opening, + }; + + self.events_queue.push_back(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::OpenResultErr + )); + }, + State::OpenDesiredByRemote { pending_opening, .. } => { + self.state = State::Closed { + pending_opening: mem::replace(pending_opening, Vec::new()), + }; + } + State::Closed { .. } => {}, + } + + self.events_queue.push_back( + ProtocolsHandlerEvent::Custom(NotifsHandlerOut::CloseResult) + ); + }, + } + } + + fn inject_dial_upgrade_error( + &mut self, + num: usize, + _: ProtocolsHandlerUpgrErr + ) { + match &mut self.state { + State::Closed { pending_opening } | State::OpenDesiredByRemote { pending_opening, .. } => { + debug_assert!(pending_opening[num]); + pending_opening[num] = false; + } + + State::Opening { in_substreams, pending_handshake, out_substreams } => { + // Failing to open a substream isn't considered a failure. Instead, it is marked + // as `Some(None)` and the opening continues. + + out_substreams[num] = Some(None); + + // Some substreams are still being opened. Nothing more to do. + if out_substreams.iter().any(|s| s.is_none()) { + return; + } + + // All substreams have finished being open. + // If the handshake has been received, proceed and report the opening. + + if let Some(pending_handshake) = pending_handshake.take() { + // Open! + let (async_tx, async_rx) = mpsc::channel(ASYNC_NOTIFICATIONS_BUFFER_SIZE); + let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); + let notifications_sink = NotificationsSink { + inner: Arc::new(NotificationsSinkInner { + async_channel: FuturesMutex::new(async_tx), + sync_channel: Mutex::new(sync_tx), + }), + }; + + let out_substreams = out_substreams + .drain(..) + .map(|s| s.expect("checked by the if above; qed")) + .collect(); + + self.state = State::Open { + notifications_sink_rx: stream::select(async_rx.fuse(), sync_rx.fuse()), + out_substreams, + in_substreams: mem::replace(in_substreams, Vec::new()), + want_closed: false, + }; + + self.events_queue.push_back(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::OpenResultOk { + endpoint: self.endpoint.clone(), + received_handshake: pending_handshake, + notifications_sink + } + )); + + } else { + // Open failure! + self.state = State::Closed { + pending_opening: (0..self.out_protocols.len()).map(|_| false).collect(), + }; + + self.events_queue.push_back(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::OpenResultErr + )); + } + } + + // No substream is being open when already `Open`. + State::Open { .. } => debug_assert!(false), + } + } + + fn connection_keep_alive(&self) -> KeepAlive { + if !self.legacy_substreams.is_empty() { + return KeepAlive::Yes; + } + + match self.state { + State::Closed { .. } => KeepAlive::Until(self.when_connection_open + INITIAL_KEEPALIVE_TIME), + State::OpenDesiredByRemote { .. } | State::Opening { .. } | State::Open { .. } => + KeepAlive::Yes, + } + } + + fn poll( + &mut self, + cx: &mut Context, + ) -> Poll< + ProtocolsHandlerEvent + > { + if let Some(ev) = self.events_queue.pop_front() { + return Poll::Ready(ev); + } + + // Poll inbound substreams. + // Inbound substreams being closed is always tolerated, except for the + // `OpenDesiredByRemote` state which might need to be switched back to `Closed`. + match &mut self.state { + State::Closed { .. } => {} + State::Open { in_substreams, .. } => { + for (num, substream) in in_substreams.iter_mut().enumerate() { + match substream.as_mut().map(|s| Stream::poll_next(Pin::new(s), cx)) { + None | Some(Poll::Pending) => continue, + Some(Poll::Ready(Some(Ok(message)))) => { + let event = NotifsHandlerOut::Notification { + message, + protocol_name: self.in_protocols[num].0.protocol_name().clone(), + }; + return Poll::Ready(ProtocolsHandlerEvent::Custom(event)) + }, + Some(Poll::Ready(None)) | Some(Poll::Ready(Some(Err(_)))) => + *substream = None, + } + } + } + + State::OpenDesiredByRemote { in_substreams, .. } | + State::Opening { in_substreams, .. } => { + for substream in in_substreams { + match substream.as_mut().map(|s| NotificationsInSubstream::poll_process(Pin::new(s), cx)) { + None | Some(Poll::Pending) => continue, + Some(Poll::Ready(Ok(void))) => match void {}, + Some(Poll::Ready(Err(_))) => *substream = None, + } + } + } + } + + // Since the previous block might have closed inbound substreams, make sure that we can + // stay in `OpenDesiredByRemote` state. + if let State::OpenDesiredByRemote { in_substreams, pending_opening } = &mut self.state { + if !in_substreams.iter().any(|s| s.is_some()) { + self.state = State::Closed { + pending_opening: mem::replace(pending_opening, Vec::new()), + }; + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::CloseDesired + )) + } + } + + // Poll outbound substreams. + match &mut self.state { + State::Open { out_substreams, want_closed, .. } => { + let mut any_closed = false; + + for substream in out_substreams.iter_mut() { + match substream.as_mut().map(|s| Sink::poll_flush(Pin::new(s), cx)) { + None | Some(Poll::Pending) | Some(Poll::Ready(Ok(()))) => continue, + Some(Poll::Ready(Err(_))) => {} + }; + + // Reached if the substream has been closed. + *substream = None; + any_closed = true; + } + + if any_closed { + if !*want_closed { + *want_closed = true; + return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsHandlerOut::CloseDesired)); + } + } + } + + State::Opening { out_substreams, pending_handshake, .. } => { + debug_assert!(out_substreams.iter().any(|s| s.is_none())); + + for (num, substream) in out_substreams.iter_mut().enumerate() { + match substream { + None | Some(None) => continue, + Some(Some(substream)) => match Sink::poll_flush(Pin::new(substream), cx) { + Poll::Pending | Poll::Ready(Ok(())) => continue, + Poll::Ready(Err(_)) => {} + } + } + + // Reached if the substream has been closed. + *substream = Some(None); + if num == 0 { + // Cancel the handshake. + *pending_handshake = None; + } + } + } + + State::Closed { .. } | + State::OpenDesiredByRemote { .. } => {} + } + + if let State::Open { notifications_sink_rx, out_substreams, .. } = &mut self.state { + 'poll_notifs_sink: loop { + // Before we poll the notifications sink receiver, check that all the notification + // channels are ready to send a message. + // TODO: it is planned that in the future we switch to one `NotificationsSink` per + // protocol, in which case each sink should wait only for its corresponding handler + // to be ready, and not all handlers + // see https://github.com/paritytech/substrate/issues/5670 + for substream in out_substreams.iter_mut() { + match substream.as_mut().map(|s| s.poll_ready_unpin(cx)) { + None | Some(Poll::Ready(_)) => {}, + Some(Poll::Pending) => break 'poll_notifs_sink + } + } + + // Now that all substreams are ready for a message, grab what to send. + let message = match notifications_sink_rx.poll_next_unpin(cx) { + Poll::Ready(Some(msg)) => msg, + Poll::Ready(None) | Poll::Pending => break, + }; + + match message { + NotificationsSinkMessage::Notification { + protocol_name, + message + } => { + if let Some(pos) = self.out_protocols.iter().position(|(n, _)| *n == protocol_name) { + if let Some(substream) = out_substreams[pos].as_mut() { + let _ = substream.start_send_unpin(message); + continue 'poll_notifs_sink; + } + + } else { + log::warn!( + target: "sub-libp2p", + "Tried to send a notification on non-registered protocol: {:?}", + protocol_name + ); + } + } + NotificationsSinkMessage::ForceClose => { + return Poll::Ready( + ProtocolsHandlerEvent::Close(NotifsHandlerError::SyncNotificationsClogged) + ); + } + } + } + } + + // The legacy substreams are polled only if the state is `Open`. Otherwise, it would be + // possible to receive notifications that would need to get silently discarded. + if matches!(self.state, State::Open { .. }) { + for n in (0..self.legacy_substreams.len()).rev() { + let mut substream = self.legacy_substreams.swap_remove(n); + let poll_outcome = Pin::new(&mut substream).poll_next(cx); + match poll_outcome { + Poll::Pending => self.legacy_substreams.push(substream), + Poll::Ready(Some(Ok(RegisteredProtocolEvent::Message(message)))) => { + self.legacy_substreams.push(substream); + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::CustomMessage { message } + )) + }, + Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged))) => { + return Poll::Ready(ProtocolsHandlerEvent::Close( + NotifsHandlerError::SyncNotificationsClogged + )) + } + Poll::Ready(None) | Poll::Ready(Some(Err(_))) => { + if matches!(poll_outcome, Poll::Ready(None)) { + self.legacy_shutdown.push(substream); + } + + if let State::Open { want_closed, .. } = &mut self.state { + if !*want_closed { + *want_closed = true; + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::CloseDesired + )) + } + } + } + } + } + } + + shutdown_list(&mut self.legacy_shutdown, cx); + + Poll::Pending + } +} -mod group; -mod legacy; -mod notif_in; -mod notif_out; +/// Given a list of substreams, tries to shut them down. The substreams that have been successfully +/// shut down are removed from the list. +fn shutdown_list + (list: &mut SmallVec>>, + cx: &mut Context) +{ + 'outer: for n in (0..list.len()).rev() { + let mut substream = list.swap_remove(n); + loop { + match substream.poll_next_unpin(cx) { + Poll::Ready(Some(Ok(_))) => {} + Poll::Pending => break, + Poll::Ready(Some(Err(_))) | Poll::Ready(None) => continue 'outer, + } + } + list.push(substream); + } +} diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs deleted file mode 100644 index fbfdb1cb6ab..00000000000 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ /dev/null @@ -1,737 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for both incoming -//! and outgoing substreams for all gossiping protocols together. -//! -//! This is the main implementation of `ProtocolsHandler` in this crate, that handles all the -//! protocols that are Substrate-related and outside of the scope of libp2p. -//! -//! # Usage -//! -//! The handler can be in one of the following states: `Initial`, `Enabled`, `Disabled`. -//! -//! The `Initial` state is the state that the handler initially is in. It is a temporary state -//! during which the user must either enable or disable the handler. After that, the handler stays -//! either enabled or disabled. -//! -//! On the wire, we try to open the following substreams: -//! -//! - One substream for each notification protocol passed as parameter to the -//! `NotifsHandlerProto::new` function. -//! - One "legacy" substream used for anything non-related to gossiping, and used as a fallback -//! in case the notification protocol can't be opened. -//! -//! When the handler is in the `Enabled` state, we immediately open and try to maintain all the -//! aforementioned substreams. When the handler is in the `Disabled` state, we immediately close -//! (or abort opening) all these substreams. It is intended that in the future we allow states in -//! which some protocols are open and not others. Symmetrically, we allow incoming -//! Substrate-related substreams if and only if we are in the `Enabled` state. -//! -//! The user has the choice between sending a message with `SendNotification`, to send a -//! notification, and `SendLegacy`, to send any other kind of message. -//! - -use crate::protocol::generic_proto::{ - handler::legacy::{LegacyProtoHandler, LegacyProtoHandlerProto, LegacyProtoHandlerIn, LegacyProtoHandlerOut}, - handler::notif_in::{NotifsInHandlerProto, NotifsInHandler, NotifsInHandlerIn, NotifsInHandlerOut}, - handler::notif_out::{NotifsOutHandlerProto, NotifsOutHandler, NotifsOutHandlerIn, NotifsOutHandlerOut}, - upgrade::{NotificationsIn, NotificationsOut, NotificationsHandshakeError, RegisteredProtocol, UpgradeCollec}, -}; - -use bytes::BytesMut; -use libp2p::core::{either::EitherOutput, ConnectedPoint, PeerId}; -use libp2p::core::upgrade::{UpgradeError, SelectUpgrade, InboundUpgrade, OutboundUpgrade}; -use libp2p::swarm::{ - ProtocolsHandler, ProtocolsHandlerEvent, - IntoProtocolsHandler, - KeepAlive, - ProtocolsHandlerUpgrErr, - SubstreamProtocol, - NegotiatedSubstream, -}; -use futures::{ - channel::mpsc, - lock::{Mutex as FuturesMutex, MutexGuard as FuturesMutexGuard}, - prelude::* -}; -use log::{debug, error}; -use parking_lot::{Mutex, RwLock}; -use std::{borrow::Cow, str, sync::Arc, task::{Context, Poll}}; - -/// Number of pending notifications in asynchronous contexts. -/// See [`NotificationsSink::reserve_notification`] for context. -const ASYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 8; -/// Number of pending notifications in synchronous contexts. -const SYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 2048; - -/// Implements the `IntoProtocolsHandler` trait of libp2p. -/// -/// Every time a connection with a remote starts, an instance of this struct is created and -/// sent to a background task dedicated to this connection. Once the connection is established, -/// it is turned into a [`NotifsHandler`]. -/// -/// See the documentation at the module level for more information. -pub struct NotifsHandlerProto { - /// Prototypes for handlers for inbound substreams, and the message we respond with in the - /// handshake. - in_handlers: Vec<(NotifsInHandlerProto, Arc>>)>, - - /// Prototypes for handlers for outbound substreams, and the initial handshake message we send. - out_handlers: Vec<(NotifsOutHandlerProto, Arc>>)>, - - /// Prototype for handler for backwards-compatibility. - legacy: LegacyProtoHandlerProto, -} - -/// The actual handler once the connection has been established. -/// -/// See the documentation at the module level for more information. -pub struct NotifsHandler { - /// Handlers for inbound substreams, and the message we respond with in the handshake. - in_handlers: Vec<(NotifsInHandler, Arc>>)>, - - /// Handlers for outbound substreams, and the initial handshake message we send. - out_handlers: Vec<(NotifsOutHandler, Arc>>)>, - - /// Whether we are the connection dialer or listener. - endpoint: ConnectedPoint, - - /// Handler for backwards-compatibility. - legacy: LegacyProtoHandler, - - /// In the situation where either the legacy substream has been opened or the handshake-bearing - /// notifications protocol is open, but we haven't sent out any [`NotifsHandlerOut::Open`] - /// event yet, this contains the received handshake waiting to be reported through the - /// external API. - pending_handshake: Option>, - - /// State of this handler. - enabled: EnabledState, - - /// If we receive inbound substream requests while in initialization mode, - /// we push the corresponding index here and process them when the handler - /// gets enabled/disabled. - pending_in: Vec, - - /// If `Some`, contains the two `Receiver`s connected to the [`NotificationsSink`] that has - /// been sent out. The notifications to send out can be pulled from this receivers. - /// We use two different channels in order to have two different channel sizes, but from the - /// receiving point of view, the two channels are the same. - /// The receivers are fused in case the user drops the [`NotificationsSink`] entirely. - /// - /// Contains `Some` if and only if it has been reported to the user that the substreams are - /// open. - notifications_sink_rx: Option< - stream::Select< - stream::Fuse>, - stream::Fuse> - > - >, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -enum EnabledState { - Initial, - Enabled, - Disabled, -} - -impl IntoProtocolsHandler for NotifsHandlerProto { - type Handler = NotifsHandler; - - fn inbound_protocol(&self) -> SelectUpgrade, RegisteredProtocol> { - let in_handlers = self.in_handlers.iter() - .map(|(h, _)| h.inbound_protocol()) - .collect::>(); - - SelectUpgrade::new(in_handlers, self.legacy.inbound_protocol()) - } - - fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler { - NotifsHandler { - in_handlers: self.in_handlers - .into_iter() - .map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg)) - .collect(), - out_handlers: self.out_handlers - .into_iter() - .map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg)) - .collect(), - endpoint: connected_point.clone(), - legacy: self.legacy.into_handler(remote_peer_id, connected_point), - pending_handshake: None, - enabled: EnabledState::Initial, - pending_in: Vec::new(), - notifications_sink_rx: None, - } - } -} - -/// Event that can be received by a `NotifsHandler`. -#[derive(Debug, Clone)] -pub enum NotifsHandlerIn { - /// The node should start using custom protocols. - Enable, - - /// The node should stop using custom protocols. - Disable, -} - -/// Event that can be emitted by a `NotifsHandler`. -#[derive(Debug)] -pub enum NotifsHandlerOut { - /// The connection is open for custom protocols. - Open { - /// The endpoint of the connection that is open for custom protocols. - endpoint: ConnectedPoint, - /// Handshake that was sent to us. - /// This is normally a "Status" message, but this out of the concern of this code. - received_handshake: Vec, - /// How notifications can be sent to this node. - notifications_sink: NotificationsSink, - }, - - /// The connection is closed for custom protocols. - Closed { - /// The reason for closing, for diagnostic purposes. - reason: Cow<'static, str>, - /// The endpoint of the connection that closed for custom protocols. - endpoint: ConnectedPoint, - }, - - /// Received a non-gossiping message on the legacy substream. - CustomMessage { - /// Message that has been received. - /// - /// Keep in mind that this can be a `ConsensusMessage` message, which then contains a - /// notification. - message: BytesMut, - }, - - /// Received a message on a custom protocol substream. - Notification { - /// Name of the protocol of the message. - protocol_name: Cow<'static, str>, - - /// Message that has been received. - message: BytesMut, - }, -} - -/// Sink connected directly to the node background task. Allows sending notifications to the peer. -/// -/// Can be cloned in order to obtain multiple references to the same peer. -#[derive(Debug, Clone)] -pub struct NotificationsSink { - inner: Arc, -} - -#[derive(Debug)] -struct NotificationsSinkInner { - /// Sender to use in asynchronous contexts. Uses an asynchronous mutex. - async_channel: FuturesMutex>, - /// Sender to use in synchronous contexts. Uses a synchronous mutex. - /// This channel has a large capacity and is meant to be used in contexts where - /// back-pressure cannot be properly exerted. - /// It will be removed in a future version. - sync_channel: Mutex>, -} - -/// Message emitted through the [`NotificationsSink`] and processed by the background task -/// dedicated to the peer. -#[derive(Debug)] -enum NotificationsSinkMessage { - /// Message emitted by [`NotificationsSink::reserve_notification`] and - /// [`NotificationsSink::write_notification_now`]. - Notification { - protocol_name: Cow<'static, str>, - message: Vec, - }, - - /// Must close the connection. - ForceClose, -} - -impl NotificationsSink { - /// Sends a notification to the peer. - /// - /// If too many messages are already buffered, the notification is silently discarded and the - /// connection to the peer will be closed shortly after. - /// - /// The protocol name is expected to be checked ahead of calling this method. It is a logic - /// error to send a notification using an unknown protocol. - /// - /// This method will be removed in a future version. - pub fn send_sync_notification<'a>( - &'a self, - protocol_name: Cow<'static, str>, - message: impl Into> - ) { - let mut lock = self.inner.sync_channel.lock(); - let result = lock.try_send(NotificationsSinkMessage::Notification { - protocol_name, - message: message.into() - }); - - if result.is_err() { - // Cloning the `mpsc::Sender` guarantees the allocation of an extra spot in the - // buffer, and therefore that `try_send` will succeed. - let _result2 = lock.clone().try_send(NotificationsSinkMessage::ForceClose); - debug_assert!(_result2.map(|()| true).unwrap_or_else(|err| err.is_disconnected())); - } - } - - /// Wait until the remote is ready to accept a notification. - /// - /// Returns an error in the case where the connection is closed. - /// - /// The protocol name is expected to be checked ahead of calling this method. It is a logic - /// error to send a notification using an unknown protocol. - pub async fn reserve_notification<'a>(&'a self, protocol_name: Cow<'static, str>) -> Result, ()> { - let mut lock = self.inner.async_channel.lock().await; - - let poll_ready = future::poll_fn(|cx| lock.poll_ready(cx)).await; - if poll_ready.is_ok() { - Ok(Ready { protocol_name: protocol_name, lock }) - } else { - Err(()) - } - } -} - -/// Notification slot is reserved and the notification can actually be sent. -#[must_use] -#[derive(Debug)] -pub struct Ready<'a> { - /// Guarded channel. The channel inside is guaranteed to not be full. - lock: FuturesMutexGuard<'a, mpsc::Sender>, - /// Name of the protocol. Should match one of the protocols passed at initialization. - protocol_name: Cow<'static, str>, -} - -impl<'a> Ready<'a> { - /// Consumes this slots reservation and actually queues the notification. - /// - /// Returns an error if the substream has been closed. - pub fn send( - mut self, - notification: impl Into> - ) -> Result<(), ()> { - self.lock.start_send(NotificationsSinkMessage::Notification { - protocol_name: self.protocol_name, - message: notification.into(), - }).map_err(|_| ()) - } -} - -/// Error specific to the collection of protocols. -#[derive(Debug, derive_more::Display, derive_more::Error)] -pub enum NotifsHandlerError { - /// Channel of synchronous notifications is full. - SyncNotificationsClogged, - /// Error in legacy protocol. - Legacy(::Error), -} - -impl NotifsHandlerProto { - /// Builds a new handler. - /// - /// `list` is a list of notification protocols names, and the message to send as part of the - /// handshake. At the moment, the message is always the same whether we open a substream - /// ourselves or respond to handshake from the remote. - /// - /// The first protocol in `list` is special-cased as the protocol that contains the handshake - /// to report through the [`NotifsHandlerOut::Open`] event. - /// - /// # Panic - /// - /// - Panics if `list` is empty. - /// - pub fn new( - legacy: RegisteredProtocol, - list: impl Into, Arc>>)>>, - ) -> Self { - let list = list.into(); - assert!(!list.is_empty()); - - let out_handlers = list - .clone() - .into_iter() - .map(|(proto_name, initial_message)| { - (NotifsOutHandlerProto::new(proto_name), initial_message) - }).collect(); - - let in_handlers = list.clone() - .into_iter() - .map(|(proto_name, msg)| (NotifsInHandlerProto::new(proto_name), msg)) - .collect(); - - NotifsHandlerProto { - in_handlers, - out_handlers, - legacy: LegacyProtoHandlerProto::new(legacy), - } - } -} - -impl ProtocolsHandler for NotifsHandler { - type InEvent = NotifsHandlerIn; - type OutEvent = NotifsHandlerOut; - type Error = NotifsHandlerError; - type InboundProtocol = SelectUpgrade, RegisteredProtocol>; - type OutboundProtocol = NotificationsOut; - // Index within the `out_handlers` - type OutboundOpenInfo = usize; - type InboundOpenInfo = (); - - fn listen_protocol(&self) -> SubstreamProtocol { - let in_handlers = self.in_handlers.iter() - .map(|(h, _)| h.listen_protocol().into_upgrade().1) - .collect::>(); - - let proto = SelectUpgrade::new(in_handlers, self.legacy.listen_protocol().into_upgrade().1); - SubstreamProtocol::new(proto, ()) - } - - fn inject_fully_negotiated_inbound( - &mut self, - out: >::Output, - (): () - ) { - match out { - EitherOutput::First((out, num)) => - self.in_handlers[num].0.inject_fully_negotiated_inbound(out, ()), - EitherOutput::Second(out) => - self.legacy.inject_fully_negotiated_inbound(out, ()), - } - } - - fn inject_fully_negotiated_outbound( - &mut self, - out: >::Output, - num: Self::OutboundOpenInfo - ) { - self.out_handlers[num].0.inject_fully_negotiated_outbound(out, ()) - } - - fn inject_event(&mut self, message: NotifsHandlerIn) { - match message { - NotifsHandlerIn::Enable => { - if let EnabledState::Enabled = self.enabled { - debug!("enabling already-enabled handler"); - } - self.enabled = EnabledState::Enabled; - self.legacy.inject_event(LegacyProtoHandlerIn::Enable); - for (handler, initial_message) in &mut self.out_handlers { - // We create `initial_message` on a separate line to be sure that the lock - // is released as soon as possible. - let initial_message = initial_message.read().clone(); - handler.inject_event(NotifsOutHandlerIn::Enable { - initial_message, - }); - } - for num in self.pending_in.drain(..) { - // We create `handshake_message` on a separate line to be sure - // that the lock is released as soon as possible. - let handshake_message = self.in_handlers[num].1.read().clone(); - self.in_handlers[num].0 - .inject_event(NotifsInHandlerIn::Accept(handshake_message)); - } - }, - NotifsHandlerIn::Disable => { - if let EnabledState::Disabled = self.enabled { - debug!("disabling already-disabled handler"); - } - self.legacy.inject_event(LegacyProtoHandlerIn::Disable); - // The notifications protocols start in the disabled state. If we were in the - // "Initial" state, then we shouldn't disable the notifications protocols again. - if self.enabled != EnabledState::Initial { - for (handler, _) in &mut self.out_handlers { - handler.inject_event(NotifsOutHandlerIn::Disable); - } - } - self.enabled = EnabledState::Disabled; - for num in self.pending_in.drain(..) { - self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Refuse); - } - }, - } - } - - fn inject_dial_upgrade_error( - &mut self, - num: usize, - err: ProtocolsHandlerUpgrErr - ) { - match err { - ProtocolsHandlerUpgrErr::Timeout => - self.out_handlers[num].0.inject_dial_upgrade_error( - (), - ProtocolsHandlerUpgrErr::Timeout - ), - ProtocolsHandlerUpgrErr::Timer => - self.out_handlers[num].0.inject_dial_upgrade_error( - (), - ProtocolsHandlerUpgrErr::Timer - ), - ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) => - self.out_handlers[num].0.inject_dial_upgrade_error( - (), - ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)) - ), - ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)) => - self.out_handlers[num].0.inject_dial_upgrade_error( - (), - ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)) - ), - } - } - - fn connection_keep_alive(&self) -> KeepAlive { - // Iterate over each handler and return the maximum value. - - let mut ret = self.legacy.connection_keep_alive(); - if ret.is_yes() { - return KeepAlive::Yes; - } - - for (handler, _) in &self.in_handlers { - let val = handler.connection_keep_alive(); - if val.is_yes() { - return KeepAlive::Yes; - } - if ret < val { ret = val; } - } - - for (handler, _) in &self.out_handlers { - let val = handler.connection_keep_alive(); - if val.is_yes() { - return KeepAlive::Yes; - } - if ret < val { ret = val; } - } - - ret - } - - fn poll( - &mut self, - cx: &mut Context, - ) -> Poll< - ProtocolsHandlerEvent - > { - if let Some(notifications_sink_rx) = &mut self.notifications_sink_rx { - 'poll_notifs_sink: loop { - // Before we poll the notifications sink receiver, check that all the notification - // channels are ready to send a message. - // TODO: it is planned that in the future we switch to one `NotificationsSink` per - // protocol, in which case each sink should wait only for its corresponding handler - // to be ready, and not all handlers - // see https://github.com/paritytech/substrate/issues/5670 - for (out_handler, _) in &mut self.out_handlers { - match out_handler.poll_ready(cx) { - Poll::Ready(_) => {}, - Poll::Pending => break 'poll_notifs_sink, - } - } - - let message = match notifications_sink_rx.poll_next_unpin(cx) { - Poll::Ready(Some(msg)) => msg, - Poll::Ready(None) | Poll::Pending => break, - }; - - match message { - NotificationsSinkMessage::Notification { - protocol_name, - message - } => { - let mut found_any_with_name = false; - - for (handler, _) in &mut self.out_handlers { - if *handler.protocol_name() == protocol_name { - found_any_with_name = true; - if handler.is_open() { - handler.send_or_discard(message); - continue 'poll_notifs_sink; - } - } - } - - // This code can be reached via the following scenarios: - // - // - User tried to send a notification on a non-existing protocol. This - // most likely relates to https://github.com/paritytech/substrate/issues/6827 - // - User tried to send a notification to a peer we're not or no longer - // connected to. This happens in a normal scenario due to the racy nature - // of connections and disconnections, and is benign. - // - // We print a warning in the former condition. - if !found_any_with_name { - log::warn!( - target: "sub-libp2p", - "Tried to send a notification on non-registered protocol: {:?}", - protocol_name - ); - } - } - NotificationsSinkMessage::ForceClose => { - return Poll::Ready(ProtocolsHandlerEvent::Close(NotifsHandlerError::SyncNotificationsClogged)); - } - } - } - } - - // If `self.pending_handshake` is `Some`, we are in a state where the handshake-bearing - // substream (either the legacy substream or the one special-cased as providing the - // handshake) is open but the user isn't aware yet of the substreams being open. - // When that is the case, neither the legacy substream nor the incoming notifications - // substreams should be polled, otherwise there is a risk of receiving messages from them. - if self.pending_handshake.is_none() { - while let Poll::Ready(ev) = self.legacy.poll(cx) { - match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, .. } => - match *protocol.info() {}, - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { - received_handshake, - .. - }) => { - if self.notifications_sink_rx.is_none() { - debug_assert!(self.pending_handshake.is_none()); - self.pending_handshake = Some(received_handshake); - } - cx.waker().wake_by_ref(); - return Poll::Pending; - }, - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { reason, .. }) => { - // We consciously drop the receivers despite notifications being potentially - // still buffered up. - self.notifications_sink_rx = None; - - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Closed { endpoint: self.endpoint.clone(), reason } - )) - }, - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => { - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::CustomMessage { message } - )) - }, - ProtocolsHandlerEvent::Close(err) => - return Poll::Ready(ProtocolsHandlerEvent::Close(NotifsHandlerError::Legacy(err))), - } - } - } - - for (handler_num, (handler, handshake_message)) in self.in_handlers.iter_mut().enumerate() { - loop { - let poll = if self.notifications_sink_rx.is_some() { - handler.poll(cx) - } else { - handler.poll_process(cx) - }; - - let ev = match poll { - Poll::Ready(e) => e, - Poll::Pending => break, - }; - - match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } => - error!("Incoming substream handler tried to open a substream"), - ProtocolsHandlerEvent::Close(err) => void::unreachable(err), - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(_)) => - match self.enabled { - EnabledState::Initial => self.pending_in.push(handler_num), - EnabledState::Enabled => { - // We create `handshake_message` on a separate line to be sure - // that the lock is released as soon as possible. - let handshake_message = handshake_message.read().clone(); - handler.inject_event(NotifsInHandlerIn::Accept(handshake_message)) - }, - EnabledState::Disabled => - handler.inject_event(NotifsInHandlerIn::Refuse), - }, - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed) => {}, - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(message)) => { - debug_assert!(self.pending_handshake.is_none()); - if self.notifications_sink_rx.is_some() { - let msg = NotifsHandlerOut::Notification { - message, - protocol_name: handler.protocol_name().clone(), - }; - return Poll::Ready(ProtocolsHandlerEvent::Custom(msg)); - } - }, - } - } - } - - for (handler_num, (handler, _)) in self.out_handlers.iter_mut().enumerate() { - while let Poll::Ready(ev) = handler.poll(cx) { - match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol } => - return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: protocol - .map_info(|()| handler_num), - }), - ProtocolsHandlerEvent::Close(err) => void::unreachable(err), - - // Opened substream on the handshake-bearing notification protocol. - ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Open { handshake }) - if handler_num == 0 => - { - if self.notifications_sink_rx.is_none() && self.pending_handshake.is_none() { - self.pending_handshake = Some(handshake); - } - }, - - // Nothing to do in response to other notification substreams being opened - // or closed. - ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Open { .. }) => {}, - ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Closed) => {}, - ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Refused) => {}, - } - } - } - - if self.out_handlers.iter().all(|(h, _)| h.is_open() || h.is_refused()) { - if let Some(handshake) = self.pending_handshake.take() { - let (async_tx, async_rx) = mpsc::channel(ASYNC_NOTIFICATIONS_BUFFER_SIZE); - let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); - let notifications_sink = NotificationsSink { - inner: Arc::new(NotificationsSinkInner { - async_channel: FuturesMutex::new(async_tx), - sync_channel: Mutex::new(sync_tx), - }), - }; - - debug_assert!(self.notifications_sink_rx.is_none()); - self.notifications_sink_rx = Some(stream::select(async_rx.fuse(), sync_rx.fuse())); - - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Open { - endpoint: self.endpoint.clone(), - received_handshake: handshake, - notifications_sink - } - )) - } - } - - Poll::Pending - } -} diff --git a/client/network/src/protocol/generic_proto/handler/legacy.rs b/client/network/src/protocol/generic_proto/handler/legacy.rs deleted file mode 100644 index 40409355378..00000000000 --- a/client/network/src/protocol/generic_proto/handler/legacy.rs +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use crate::protocol::generic_proto::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProtocolSubstream}; -use bytes::BytesMut; -use futures::prelude::*; -use futures_timer::Delay; -use libp2p::core::{ConnectedPoint, PeerId, Endpoint}; -use libp2p::core::upgrade::{InboundUpgrade, OutboundUpgrade}; -use libp2p::swarm::{ - ProtocolsHandler, ProtocolsHandlerEvent, - IntoProtocolsHandler, - KeepAlive, - ProtocolsHandlerUpgrErr, - SubstreamProtocol, - NegotiatedSubstream, -}; -use log::{debug, error}; -use smallvec::{smallvec, SmallVec}; -use std::{borrow::Cow, collections::VecDeque, convert::Infallible, error, fmt, io, mem}; -use std::{pin::Pin, task::{Context, Poll}, time::Duration}; - -/// Implements the `IntoProtocolsHandler` trait of libp2p. -/// -/// Every time a connection with a remote starts, an instance of this struct is created and -/// sent to a background task dedicated to this connection. Once the connection is established, -/// it is turned into a `LegacyProtoHandler`. It then handles all communications that are specific -/// to Substrate on that single connection. -/// -/// Note that there can be multiple instance of this struct simultaneously for same peer, -/// if there are multiple established connections to the peer. -/// -/// ## State of the handler -/// -/// There are six possible states for the handler: -/// -/// - Enabled and open, which is a normal operation. -/// - Enabled and closed, in which case it will try to open substreams. -/// - Disabled and open, in which case it will try to close substreams. -/// - Disabled and closed, in which case the handler is idle. The connection will be -/// garbage-collected after a few seconds if nothing more happens. -/// - Initializing and open. -/// - Initializing and closed, which is the state the handler starts in. -/// -/// The Init/Enabled/Disabled state is entirely controlled by the user by sending `Enable` or -/// `Disable` messages to the handler. The handler itself never transitions automatically between -/// these states. For example, if the handler reports a network misbehaviour, it will close the -/// substreams but it is the role of the user to send a `Disabled` event if it wants the connection -/// to close. Otherwise, the handler will try to reopen substreams. -/// -/// The handler starts in the "Initializing" state and must be transitionned to Enabled or Disabled -/// as soon as possible. -/// -/// The Open/Closed state is decided by the handler and is reported with the `CustomProtocolOpen` -/// and `CustomProtocolClosed` events. The `CustomMessage` event can only be generated if the -/// handler is open. -/// -/// ## How it works -/// -/// When the handler is created, it is initially in the `Init` state and waits for either a -/// `Disable` or an `Enable` message from the outer layer. At any time, the outer layer is free to -/// toggle the handler between the disabled and enabled states. -/// -/// When the handler switches to "enabled", it opens a substream and negotiates the protocol named -/// `/substrate/xxx`, where `xxx` is chosen by the user and depends on the chain. -/// -/// For backwards compatibility reasons, when we switch to "enabled" for the first time (while we -/// are still in "init" mode) and we are the connection listener, we don't open a substream. -/// -/// In order the handle the situation where both the remote and us get enabled at the same time, -/// we tolerate multiple substreams open at the same time. Messages are transmitted on an arbitrary -/// substream. The endpoints don't try to agree on a single substream. -/// -/// We consider that we are now "closed" if the remote closes all the existing substreams. -/// Re-opening it can then be performed by closing all active substream and re-opening one. -/// -pub struct LegacyProtoHandlerProto { - /// Configuration for the protocol upgrade to negotiate. - protocol: RegisteredProtocol, -} - -impl LegacyProtoHandlerProto { - /// Builds a new `LegacyProtoHandlerProto`. - pub fn new(protocol: RegisteredProtocol) -> Self { - LegacyProtoHandlerProto { - protocol, - } - } -} - -impl IntoProtocolsHandler for LegacyProtoHandlerProto { - type Handler = LegacyProtoHandler; - - fn inbound_protocol(&self) -> RegisteredProtocol { - self.protocol.clone() - } - - fn into_handler(self, remote_peer_id: &PeerId, _: &ConnectedPoint) -> Self::Handler { - LegacyProtoHandler { - protocol: self.protocol, - remote_peer_id: remote_peer_id.clone(), - state: ProtocolState::Init { - substreams: SmallVec::new(), - init_deadline: Delay::new(Duration::from_secs(20)) - }, - events_queue: VecDeque::new(), - } - } -} - -/// The actual handler once the connection has been established. -pub struct LegacyProtoHandler { - /// Configuration for the protocol upgrade to negotiate. - protocol: RegisteredProtocol, - - /// State of the communications with the remote. - state: ProtocolState, - - /// Identifier of the node we're talking to. Used only for logging purposes and shouldn't have - /// any influence on the behaviour. - remote_peer_id: PeerId, - - /// Queue of events to send to the outside. - /// - /// This queue must only ever be modified to insert elements at the back, or remove the first - /// element. - events_queue: VecDeque< - ProtocolsHandlerEvent - >, -} - -/// State of the handler. -enum ProtocolState { - /// Waiting for the behaviour to tell the handler whether it is enabled or disabled. - Init { - /// List of substreams opened by the remote but that haven't been processed yet. - /// For each substream, also includes the handshake message that we have received. - substreams: SmallVec<[(RegisteredProtocolSubstream, Vec); 6]>, - /// Deadline after which the initialization is abnormally long. - init_deadline: Delay, - }, - - /// Handler is ready to accept incoming substreams. - /// If we are in this state, we haven't sent any `CustomProtocolOpen` yet. - Opening, - - /// Normal operating mode. Contains the substreams that are open. - /// If we are in this state, we have sent a `CustomProtocolOpen` message to the outside. - Normal { - /// The substreams where bidirectional communications happen. - substreams: SmallVec<[RegisteredProtocolSubstream; 4]>, - /// Contains substreams which are being shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream; 4]>, - }, - - /// We are disabled. Contains substreams that are being closed. - /// If we are in this state, either we have sent a `CustomProtocolClosed` message to the - /// outside or we have never sent any `CustomProtocolOpen` in the first place. - Disabled { - /// List of substreams to shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream; 6]>, - - /// If true, we should reactivate the handler after all the substreams in `shutdown` have - /// been closed. - /// - /// Since we don't want to mix old and new substreams, we wait for all old substreams to - /// be closed before opening any new one. - reenable: bool, - }, - - /// In this state, we don't care about anything anymore and need to kill the connection as soon - /// as possible. - KillAsap, - - /// We sometimes temporarily switch to this state during processing. If we are in this state - /// at the beginning of a method, that means something bad happened in the source code. - Poisoned, -} - -/// Event that can be received by a `LegacyProtoHandler`. -#[derive(Debug)] -pub enum LegacyProtoHandlerIn { - /// The node should start using custom protocols. - Enable, - - /// The node should stop using custom protocols. - Disable, -} - -/// Event that can be emitted by a `LegacyProtoHandler`. -#[derive(Debug)] -pub enum LegacyProtoHandlerOut { - /// Opened a custom protocol with the remote. - CustomProtocolOpen { - /// Version of the protocol that has been opened. - version: u8, - /// Handshake message that has been sent to us. - /// This is normally a "Status" message, but this out of the concern of this code. - received_handshake: Vec, - }, - - /// Closed a custom protocol with the remote. - CustomProtocolClosed { - /// Reason why the substream closed, for diagnostic purposes. - reason: Cow<'static, str>, - }, - - /// Receives a message on a custom protocol substream. - CustomMessage { - /// Message that has been received. - message: BytesMut, - }, -} - -impl LegacyProtoHandler { - /// Enables the handler. - fn enable(&mut self) { - self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { - ProtocolState::Poisoned => { - error!(target: "sub-libp2p", "Handler with {:?} is in poisoned state", - self.remote_peer_id); - ProtocolState::Poisoned - } - - ProtocolState::Init { substreams: mut incoming, .. } => { - if incoming.is_empty() { - ProtocolState::Opening - } else { - let event = LegacyProtoHandlerOut::CustomProtocolOpen { - version: incoming[0].0.protocol_version(), - received_handshake: mem::replace(&mut incoming[0].1, Vec::new()), - }; - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(event)); - ProtocolState::Normal { - substreams: incoming.into_iter().map(|(s, _)| s).collect(), - shutdown: SmallVec::new() - } - } - } - - st @ ProtocolState::KillAsap => st, - st @ ProtocolState::Opening { .. } => st, - st @ ProtocolState::Normal { .. } => st, - ProtocolState::Disabled { shutdown, .. } => { - ProtocolState::Disabled { shutdown, reenable: true } - } - } - } - - /// Disables the handler. - fn disable(&mut self) { - self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { - ProtocolState::Poisoned => { - error!(target: "sub-libp2p", "Handler with {:?} is in poisoned state", - self.remote_peer_id); - ProtocolState::Poisoned - } - - ProtocolState::Init { substreams: shutdown, .. } => { - let mut shutdown = shutdown.into_iter().map(|(s, _)| s).collect::>(); - for s in &mut shutdown { - s.shutdown(); - } - ProtocolState::Disabled { shutdown, reenable: false } - } - - ProtocolState::Opening { .. } | ProtocolState::Normal { .. } => - // At the moment, if we get disabled while things were working, we kill the entire - // connection in order to force a reset of the state. - // This is obviously an extremely shameful way to do things, but at the time of - // the writing of this comment, the networking works very poorly and a solution - // needs to be found. - ProtocolState::KillAsap, - - ProtocolState::Disabled { shutdown, .. } => - ProtocolState::Disabled { shutdown, reenable: false }, - - ProtocolState::KillAsap => ProtocolState::KillAsap, - }; - } - - /// Polls the state for events. Optionally returns an event to produce. - #[must_use] - fn poll_state(&mut self, cx: &mut Context) - -> Option> { - match mem::replace(&mut self.state, ProtocolState::Poisoned) { - ProtocolState::Poisoned => { - error!(target: "sub-libp2p", "Handler with {:?} is in poisoned state", - self.remote_peer_id); - self.state = ProtocolState::Poisoned; - None - } - - ProtocolState::Init { substreams, mut init_deadline } => { - match Pin::new(&mut init_deadline).poll(cx) { - Poll::Ready(()) => { - error!(target: "sub-libp2p", "Handler initialization process is too long \ - with {:?}", self.remote_peer_id); - self.state = ProtocolState::KillAsap; - }, - Poll::Pending => { - self.state = ProtocolState::Init { substreams, init_deadline }; - } - } - - None - } - - ProtocolState::Opening => { - self.state = ProtocolState::Opening; - None - } - - ProtocolState::Normal { mut substreams, mut shutdown } => { - for n in (0..substreams.len()).rev() { - let mut substream = substreams.swap_remove(n); - match Pin::new(&mut substream).poll_next(cx) { - Poll::Pending => substreams.push(substream), - Poll::Ready(Some(Ok(RegisteredProtocolEvent::Message(message)))) => { - let event = LegacyProtoHandlerOut::CustomMessage { - message - }; - substreams.push(substream); - self.state = ProtocolState::Normal { substreams, shutdown }; - return Some(ProtocolsHandlerEvent::Custom(event)); - }, - Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged))) => { - shutdown.push(substream); - if substreams.is_empty() { - let event = LegacyProtoHandlerOut::CustomProtocolClosed { - reason: "Legacy substream clogged".into(), - }; - self.state = ProtocolState::Disabled { - shutdown: shutdown.into_iter().collect(), - reenable: true - }; - return Some(ProtocolsHandlerEvent::Custom(event)); - } - } - Poll::Ready(None) => { - shutdown.push(substream); - if substreams.is_empty() { - let event = LegacyProtoHandlerOut::CustomProtocolClosed { - reason: "All substreams have been closed by the remote".into(), - }; - self.state = ProtocolState::Disabled { - shutdown: shutdown.into_iter().collect(), - reenable: true - }; - return Some(ProtocolsHandlerEvent::Custom(event)); - } - } - Poll::Ready(Some(Err(err))) => { - if substreams.is_empty() { - let event = LegacyProtoHandlerOut::CustomProtocolClosed { - reason: format!("Error on the last substream: {:?}", err).into(), - }; - self.state = ProtocolState::Disabled { - shutdown: shutdown.into_iter().collect(), - reenable: true - }; - return Some(ProtocolsHandlerEvent::Custom(event)); - } else { - debug!(target: "sub-libp2p", "Error on extra substream: {:?}", err); - } - } - } - } - - // This code is reached is none if and only if none of the substreams are in a ready state. - self.state = ProtocolState::Normal { substreams, shutdown }; - None - } - - ProtocolState::Disabled { mut shutdown, reenable } => { - shutdown_list(&mut shutdown, cx); - // If `reenable` is `true`, that means we should open the substreams system again - // after all the substreams are closed. - if reenable && shutdown.is_empty() { - self.state = ProtocolState::Opening; - } else { - self.state = ProtocolState::Disabled { shutdown, reenable }; - } - None - } - - ProtocolState::KillAsap => None, - } - } -} - -impl ProtocolsHandler for LegacyProtoHandler { - type InEvent = LegacyProtoHandlerIn; - type OutEvent = LegacyProtoHandlerOut; - type Error = ConnectionKillError; - type InboundProtocol = RegisteredProtocol; - type OutboundProtocol = RegisteredProtocol; - type OutboundOpenInfo = Infallible; - type InboundOpenInfo = (); - - fn listen_protocol(&self) -> SubstreamProtocol { - SubstreamProtocol::new(self.protocol.clone(), ()) - } - - fn inject_fully_negotiated_inbound( - &mut self, - (mut substream, received_handshake): >::Output, - (): () - ) { - self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { - ProtocolState::Poisoned => { - error!(target: "sub-libp2p", "Handler with {:?} is in poisoned state", - self.remote_peer_id); - ProtocolState::Poisoned - } - - ProtocolState::Init { mut substreams, init_deadline } => { - if substream.endpoint() == Endpoint::Dialer { - error!(target: "sub-libp2p", "Opened dialing substream with {:?} before \ - initialization", self.remote_peer_id); - } - substreams.push((substream, received_handshake)); - ProtocolState::Init { substreams, init_deadline } - } - - ProtocolState::Opening { .. } => { - let event = LegacyProtoHandlerOut::CustomProtocolOpen { - version: substream.protocol_version(), - received_handshake, - }; - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(event)); - ProtocolState::Normal { - substreams: smallvec![substream], - shutdown: SmallVec::new() - } - } - - ProtocolState::Normal { substreams: mut existing, shutdown } => { - existing.push(substream); - ProtocolState::Normal { substreams: existing, shutdown } - } - - ProtocolState::Disabled { mut shutdown, .. } => { - substream.shutdown(); - shutdown.push(substream); - ProtocolState::Disabled { shutdown, reenable: false } - } - - ProtocolState::KillAsap => ProtocolState::KillAsap, - }; - } - - fn inject_fully_negotiated_outbound( - &mut self, - _: >::Output, - unreachable: Self::OutboundOpenInfo - ) { - match unreachable {} - } - - fn inject_event(&mut self, message: LegacyProtoHandlerIn) { - match message { - LegacyProtoHandlerIn::Disable => self.disable(), - LegacyProtoHandlerIn::Enable => self.enable(), - } - } - - fn inject_dial_upgrade_error( - &mut self, - unreachable: Self::OutboundOpenInfo, - _: ProtocolsHandlerUpgrErr - ) { - match unreachable {} - } - - fn connection_keep_alive(&self) -> KeepAlive { - match self.state { - ProtocolState::Init { .. } | ProtocolState::Normal { .. } => KeepAlive::Yes, - ProtocolState::Opening { .. } | ProtocolState::Disabled { .. } | - ProtocolState::Poisoned | ProtocolState::KillAsap => KeepAlive::No, - } - } - - fn poll( - &mut self, - cx: &mut Context, - ) -> Poll< - ProtocolsHandlerEvent - > { - // Flush the events queue if necessary. - if let Some(event) = self.events_queue.pop_front() { - return Poll::Ready(event) - } - - // Kill the connection if needed. - if let ProtocolState::KillAsap = self.state { - return Poll::Ready(ProtocolsHandlerEvent::Close(ConnectionKillError)); - } - - // Process all the substreams. - if let Some(event) = self.poll_state(cx) { - return Poll::Ready(event) - } - - Poll::Pending - } -} - -impl fmt::Debug for LegacyProtoHandler { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - f.debug_struct("LegacyProtoHandler") - .finish() - } -} - -/// Given a list of substreams, tries to shut them down. The substreams that have been successfully -/// shut down are removed from the list. -fn shutdown_list - (list: &mut SmallVec>>, - cx: &mut Context) -{ - 'outer: for n in (0..list.len()).rev() { - let mut substream = list.swap_remove(n); - loop { - match substream.poll_next_unpin(cx) { - Poll::Ready(Some(Ok(_))) => {} - Poll::Pending => break, - Poll::Ready(Some(Err(_))) | Poll::Ready(None) => continue 'outer, - } - } - list.push(substream); - } -} - -/// Error returned when switching from normal to disabled. -#[derive(Debug)] -pub struct ConnectionKillError; - -impl error::Error for ConnectionKillError { -} - -impl fmt::Display for ConnectionKillError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Connection kill when switching from normal to disabled") - } -} diff --git a/client/network/src/protocol/generic_proto/handler/notif_in.rs b/client/network/src/protocol/generic_proto/handler/notif_in.rs deleted file mode 100644 index d3b505e0de3..00000000000 --- a/client/network/src/protocol/generic_proto/handler/notif_in.rs +++ /dev/null @@ -1,293 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2020 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 . - -//! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for ingoing -//! substreams for a single gossiping protocol. -//! -//! > **Note**: Each instance corresponds to a single protocol. In order to support multiple -//! > protocols, you need to create multiple instances and group them. -//! - -use crate::protocol::generic_proto::upgrade::{NotificationsIn, NotificationsInSubstream}; -use bytes::BytesMut; -use futures::prelude::*; -use libp2p::core::{ConnectedPoint, PeerId}; -use libp2p::core::upgrade::{DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; -use libp2p::swarm::{ - ProtocolsHandler, ProtocolsHandlerEvent, - IntoProtocolsHandler, - KeepAlive, - ProtocolsHandlerUpgrErr, - SubstreamProtocol, - NegotiatedSubstream, -}; -use log::{error, warn}; -use std::{borrow::Cow, collections::VecDeque, fmt, pin::Pin, task::{Context, Poll}}; - -/// Implements the `IntoProtocolsHandler` trait of libp2p. -/// -/// Every time a connection with a remote starts, an instance of this struct is created and -/// sent to a background task dedicated to this connection. Once the connection is established, -/// it is turned into a [`NotifsInHandler`]. -pub struct NotifsInHandlerProto { - /// Configuration for the protocol upgrade to negotiate. - in_protocol: NotificationsIn, -} - -/// The actual handler once the connection has been established. -pub struct NotifsInHandler { - /// Configuration for the protocol upgrade to negotiate for inbound substreams. - in_protocol: NotificationsIn, - - /// Substream that is open with the remote. - substream: Option>, - - /// If the substream is opened and closed rapidly, we can emit several `OpenRequest` and - /// `Closed` messages in a row without the handler having time to respond with `Accept` or - /// `Refuse`. - /// - /// In order to keep the state consistent, we increment this variable every time an - /// `OpenRequest` is emitted and decrement it every time an `Accept` or `Refuse` is received. - pending_accept_refuses: usize, - - /// Queue of events to send to the outside. - /// - /// This queue is only ever modified to insert elements at the back, or remove the first - /// element. - events_queue: VecDeque>, -} - -/// Event that can be received by a `NotifsInHandler`. -#[derive(Debug, Clone)] -pub enum NotifsInHandlerIn { - /// Can be sent back as a response to an `OpenRequest`. Contains the status message to send - /// to the remote. - /// - /// After sending this to the handler, the substream is now considered open and `Notif` events - /// can be received. - Accept(Vec), - - /// Can be sent back as a response to an `OpenRequest`. - Refuse, -} - -/// Event that can be emitted by a `NotifsInHandler`. -#[derive(Debug)] -pub enum NotifsInHandlerOut { - /// The remote wants to open a substream. Contains the initial message sent by the remote - /// when the substream has been opened. - /// - /// Every time this event is emitted, a corresponding `Accepted` or `Refused` **must** be sent - /// back even if a `Closed` is received. - OpenRequest(Vec), - - /// The notifications substream has been closed by the remote. In order to avoid race - /// conditions, this does **not** cancel any previously-sent `OpenRequest`. - Closed, - - /// Received a message on the notifications substream. - /// - /// Can only happen after an `Accept` and before a `Closed`. - Notif(BytesMut), -} - -impl NotifsInHandlerProto { - /// Builds a new `NotifsInHandlerProto`. - pub fn new( - protocol_name: impl Into> - ) -> Self { - NotifsInHandlerProto { - in_protocol: NotificationsIn::new(protocol_name), - } - } -} - -impl IntoProtocolsHandler for NotifsInHandlerProto { - type Handler = NotifsInHandler; - - fn inbound_protocol(&self) -> NotificationsIn { - self.in_protocol.clone() - } - - fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self::Handler { - NotifsInHandler { - in_protocol: self.in_protocol, - substream: None, - pending_accept_refuses: 0, - events_queue: VecDeque::new(), - } - } -} - -impl NotifsInHandler { - /// Returns the name of the protocol that we accept. - pub fn protocol_name(&self) -> &Cow<'static, str> { - self.in_protocol.protocol_name() - } - - /// Equivalent to the `poll` method of `ProtocolsHandler`, except that it is guaranteed to - /// never generate [`NotifsInHandlerOut::Notif`]. - /// - /// Use this method in situations where it is not desirable to receive events but still - /// necessary to drive any potential incoming handshake or request. - pub fn poll_process( - &mut self, - cx: &mut Context - ) -> Poll< - ProtocolsHandlerEvent - > { - if let Some(event) = self.events_queue.pop_front() { - return Poll::Ready(event) - } - - match self.substream.as_mut().map(|s| NotificationsInSubstream::poll_process(Pin::new(s), cx)) { - None | Some(Poll::Pending) => {}, - Some(Poll::Ready(Ok(v))) => match v {}, - Some(Poll::Ready(Err(_))) => { - self.substream = None; - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); - }, - } - - Poll::Pending - } -} - -impl ProtocolsHandler for NotifsInHandler { - type InEvent = NotifsInHandlerIn; - type OutEvent = NotifsInHandlerOut; - type Error = void::Void; - type InboundProtocol = NotificationsIn; - type OutboundProtocol = DeniedUpgrade; - type OutboundOpenInfo = (); - type InboundOpenInfo = (); - - fn listen_protocol(&self) -> SubstreamProtocol { - SubstreamProtocol::new(self.in_protocol.clone(), ()) - } - - fn inject_fully_negotiated_inbound( - &mut self, - (msg, proto): >::Output, - (): () - ) { - // If a substream already exists, we drop it and replace it with the new incoming one. - if self.substream.is_some() { - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); - } - - // Note that we drop the existing substream, which will send an equivalent to a TCP "RST" - // to the remote and force-close the substream. It might seem like an unclean way to get - // rid of a substream. However, keep in mind that it is invalid for the remote to open - // multiple such substreams, and therefore sending a "RST" is not an incorrect thing to do. - self.substream = Some(proto); - - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(msg))); - self.pending_accept_refuses = self.pending_accept_refuses - .checked_add(1) - .unwrap_or_else(|| { - error!(target: "sub-libp2p", "Overflow in pending_accept_refuses"); - usize::max_value() - }); - } - - fn inject_fully_negotiated_outbound( - &mut self, - out: >::Output, - _: Self::OutboundOpenInfo - ) { - // We never emit any outgoing substream. - void::unreachable(out) - } - - fn inject_event(&mut self, message: NotifsInHandlerIn) { - self.pending_accept_refuses = match self.pending_accept_refuses.checked_sub(1) { - Some(v) => v, - None => { - error!( - target: "sub-libp2p", - "Inconsistent state: received Accept/Refuse when no pending request exists" - ); - return; - } - }; - - // If we send multiple `OpenRequest`s in a row, we will receive back multiple - // `Accept`/`Refuse` messages. All of them are obsolete except the last one. - if self.pending_accept_refuses != 0 { - return; - } - - match (message, self.substream.as_mut()) { - (NotifsInHandlerIn::Accept(message), Some(sub)) => sub.send_handshake(message), - (NotifsInHandlerIn::Accept(_), None) => {}, - (NotifsInHandlerIn::Refuse, _) => self.substream = None, - } - } - - fn inject_dial_upgrade_error(&mut self, _: (), _: ProtocolsHandlerUpgrErr) { - error!(target: "sub-libp2p", "Received dial upgrade error in inbound-only handler"); - } - - fn connection_keep_alive(&self) -> KeepAlive { - if self.substream.is_some() { - KeepAlive::Yes - } else { - KeepAlive::No - } - } - - fn poll( - &mut self, - cx: &mut Context, - ) -> Poll< - ProtocolsHandlerEvent - > { - // Flush the events queue if necessary. - if let Some(event) = self.events_queue.pop_front() { - return Poll::Ready(event) - } - - match self.substream.as_mut().map(|s| Stream::poll_next(Pin::new(s), cx)) { - None | Some(Poll::Pending) => {}, - Some(Poll::Ready(Some(Ok(msg)))) => { - if self.pending_accept_refuses != 0 { - warn!( - target: "sub-libp2p", - "Bad state in inbound-only handler: notif before accepting substream" - ); - } - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(msg))) - }, - Some(Poll::Ready(None)) | Some(Poll::Ready(Some(Err(_)))) => { - self.substream = None; - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); - }, - } - - Poll::Pending - } -} - -impl fmt::Debug for NotifsInHandler { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - f.debug_struct("NotifsInHandler") - .field("substream_open", &self.substream.is_some()) - .finish() - } -} diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs deleted file mode 100644 index 414e62c0d13..00000000000 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ /dev/null @@ -1,444 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for outgoing -//! substreams of a single gossiping protocol. -//! -//! > **Note**: Each instance corresponds to a single protocol. In order to support multiple -//! > protocols, you need to create multiple instances and group them. -//! - -use crate::protocol::generic_proto::upgrade::{NotificationsOut, NotificationsOutSubstream, NotificationsHandshakeError}; -use futures::prelude::*; -use libp2p::core::{ConnectedPoint, PeerId}; -use libp2p::core::upgrade::{DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; -use libp2p::swarm::{ - ProtocolsHandler, ProtocolsHandlerEvent, - IntoProtocolsHandler, - KeepAlive, - ProtocolsHandlerUpgrErr, - SubstreamProtocol, - NegotiatedSubstream, -}; -use log::{debug, warn, error}; -use std::{ - borrow::Cow, collections::VecDeque, fmt, mem, pin::Pin, task::{Context, Poll, Waker}, - time::Duration -}; -use wasm_timer::Instant; - -/// Maximum duration to open a substream and receive the handshake message. After that, we -/// consider that we failed to open the substream. -const OPEN_TIMEOUT: Duration = Duration::from_secs(10); -/// After successfully establishing a connection with the remote, we keep the connection open for -/// at least this amount of time in order to give the rest of the code the chance to notify us to -/// open substreams. -const INITIAL_KEEPALIVE_TIME: Duration = Duration::from_secs(5); - -/// Implements the `IntoProtocolsHandler` trait of libp2p. -/// -/// Every time a connection with a remote starts, an instance of this struct is created and -/// sent to a background task dedicated to this connection. Once the connection is established, -/// it is turned into a [`NotifsOutHandler`]. -/// -/// See the documentation of [`NotifsOutHandler`] for more information. -pub struct NotifsOutHandlerProto { - /// Name of the protocol to negotiate. - protocol_name: Cow<'static, str>, -} - -impl NotifsOutHandlerProto { - /// Builds a new [`NotifsOutHandlerProto`]. Will use the given protocol name for the - /// notifications substream. - pub fn new(protocol_name: impl Into>) -> Self { - NotifsOutHandlerProto { - protocol_name: protocol_name.into(), - } - } -} - -impl IntoProtocolsHandler for NotifsOutHandlerProto { - type Handler = NotifsOutHandler; - - fn inbound_protocol(&self) -> DeniedUpgrade { - DeniedUpgrade - } - - fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self::Handler { - NotifsOutHandler { - protocol_name: self.protocol_name, - when_connection_open: Instant::now(), - state: State::Disabled, - events_queue: VecDeque::new(), - } - } -} - -/// Handler for an outbound notification substream. -/// -/// When a connection is established, this handler starts in the "disabled" state, meaning that -/// no substream will be open. -/// -/// One can try open a substream by sending an [`NotifsOutHandlerIn::Enable`] message to the -/// handler. Once done, the handler will try to establish then maintain an outbound substream with -/// the remote for the purpose of sending notifications to it. -pub struct NotifsOutHandler { - /// Name of the protocol to negotiate. - protocol_name: Cow<'static, str>, - - /// Relationship with the node we're connected to. - state: State, - - /// When the connection with the remote has been successfully established. - when_connection_open: Instant, - - /// Queue of events to send to the outside. - /// - /// This queue must only ever be modified to insert elements at the back, or remove the first - /// element. - events_queue: VecDeque>, -} - -/// Our relationship with the node we're connected to. -enum State { - /// The handler is disabled and idle. No substream is open. - Disabled, - - /// The handler is disabled. A substream is still open and needs to be closed. - /// - /// > **Important**: Having this state means that `poll_close` has been called at least once, - /// > but the `Sink` API is unclear about whether or not the stream can then - /// > be recovered. Because of that, we must never switch from the - /// > `DisabledOpen` state to the `Open` state while keeping the same substream. - DisabledOpen(NotificationsOutSubstream), - - /// The handler is disabled but we are still trying to open a substream with the remote. - /// - /// If the handler gets enabled again, we can immediately switch to `Opening`. - DisabledOpening, - - /// The handler is enabled and we are trying to open a substream with the remote. - Opening { - /// The initial message that we sent. Necessary if we need to re-open a substream. - initial_message: Vec, - }, - - /// The handler is enabled. We have tried opening a substream in the past but the remote - /// refused it. - Refused, - - /// The handler is enabled and substream is open. - Open { - /// Substream that is currently open. - substream: NotificationsOutSubstream, - /// Waker for the last task that got `Poll::Pending` from `poll_ready`, to notify - /// when the open substream closes due to being disabled or encountering an - /// error, i.e. to notify the task as soon as the substream becomes unavailable, - /// without waiting for an underlying I/O task wakeup. - close_waker: Option, - /// The initial message that we sent. Necessary if we need to re-open a substream. - initial_message: Vec, - }, - - /// Poisoned state. Shouldn't be found in the wild. - Poisoned, -} - -/// Event that can be received by a `NotifsOutHandler`. -#[derive(Debug)] -pub enum NotifsOutHandlerIn { - /// Enables the notifications substream for this node. The handler will try to maintain a - /// substream with the remote. - Enable { - /// Initial message to send to remote nodes when we open substreams. - initial_message: Vec, - }, - - /// Disables the notifications substream for this node. This is the default state. - Disable, -} - -/// Event that can be emitted by a `NotifsOutHandler`. -#[derive(Debug)] -pub enum NotifsOutHandlerOut { - /// The notifications substream has been accepted by the remote. - Open { - /// Handshake message sent by the remote after we opened the substream. - handshake: Vec, - }, - - /// The notifications substream has been closed by the remote. - Closed, - - /// We tried to open a notifications substream, but the remote refused it. - /// - /// Can only happen if we're in a closed state. - Refused, -} - -impl NotifsOutHandler { - /// Returns true if the substream is currently open. - pub fn is_open(&self) -> bool { - match &self.state { - State::Disabled => false, - State::DisabledOpening => false, - State::DisabledOpen(_) => true, - State::Opening { .. } => false, - State::Refused => false, - State::Open { .. } => true, - State::Poisoned => false, - } - } - - /// Returns `true` if there has been an attempt to open the substream, but the remote refused - /// the substream. - /// - /// Always returns `false` if the handler is in a disabled state. - pub fn is_refused(&self) -> bool { - match &self.state { - State::Disabled => false, - State::DisabledOpening => false, - State::DisabledOpen(_) => false, - State::Opening { .. } => false, - State::Refused => true, - State::Open { .. } => false, - State::Poisoned => false, - } - } - - /// Returns the name of the protocol that we negotiate. - pub fn protocol_name(&self) -> &Cow<'static, str> { - &self.protocol_name - } - - /// Polls whether the outbound substream is ready to send a notification. - /// - /// - Returns `Poll::Pending` if the substream is open but not ready to send a notification. - /// - Returns `Poll::Ready(true)` if the substream is ready to send a notification. - /// - Returns `Poll::Ready(false)` if the substream is closed. - /// - pub fn poll_ready(&mut self, cx: &mut Context) -> Poll { - if let State::Open { substream, close_waker, .. } = &mut self.state { - match substream.poll_ready_unpin(cx) { - Poll::Ready(Ok(())) => Poll::Ready(true), - Poll::Ready(Err(_)) => Poll::Ready(false), - Poll::Pending => { - *close_waker = Some(cx.waker().clone()); - Poll::Pending - } - } - } else { - Poll::Ready(false) - } - } - - /// Sends out a notification. - /// - /// If the substream is closed, or not ready to send out a notification yet, then the - /// notification is silently discarded. - /// - /// You are encouraged to call [`NotifsOutHandler::poll_ready`] beforehand to determine - /// whether this will succeed. If `Poll::Ready(true)` is returned, then this method will send - /// out a notification. - pub fn send_or_discard(&mut self, notification: Vec) { - if let State::Open { substream, .. } = &mut self.state { - let _ = substream.start_send_unpin(notification); - } - } -} - -impl ProtocolsHandler for NotifsOutHandler { - type InEvent = NotifsOutHandlerIn; - type OutEvent = NotifsOutHandlerOut; - type Error = void::Void; - type InboundProtocol = DeniedUpgrade; - type OutboundProtocol = NotificationsOut; - type OutboundOpenInfo = (); - type InboundOpenInfo = (); - - fn listen_protocol(&self) -> SubstreamProtocol { - SubstreamProtocol::new(DeniedUpgrade, ()) - } - - fn inject_fully_negotiated_inbound( - &mut self, - proto: >::Output, - (): () - ) { - // We should never reach here. `proto` is a `Void`. - void::unreachable(proto) - } - - fn inject_fully_negotiated_outbound( - &mut self, - (handshake_msg, substream): >::Output, - _: () - ) { - match mem::replace(&mut self.state, State::Poisoned) { - State::Opening { initial_message } => { - let ev = NotifsOutHandlerOut::Open { handshake: handshake_msg }; - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(ev)); - self.state = State::Open { substream, initial_message, close_waker: None }; - }, - // If the handler was disabled while we were negotiating the protocol, immediately - // close it. - State::DisabledOpening => self.state = State::DisabledOpen(substream), - - // Any other situation should never happen. - State::Disabled | State::Refused | State::Open { .. } | State::DisabledOpen(_) => - error!("☎️ State mismatch in notifications handler: substream already open"), - State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), - } - } - - fn inject_event(&mut self, message: NotifsOutHandlerIn) { - match message { - NotifsOutHandlerIn::Enable { initial_message } => { - match mem::replace(&mut self.state, State::Poisoned) { - State::Disabled => { - let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message.clone()); - self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(proto, ()).with_timeout(OPEN_TIMEOUT), - }); - self.state = State::Opening { initial_message }; - }, - State::DisabledOpening => self.state = State::Opening { initial_message }, - State::DisabledOpen(mut sub) => { - // As documented above, in this state we have already called `poll_close` - // once on the substream, and it is unclear whether the substream can then - // be recovered. When in doubt, let's drop the existing substream and - // open a new one. - if sub.close().now_or_never().is_none() { - warn!( - target: "sub-libp2p", - "📞 Improperly closed outbound notifications substream" - ); - } - - let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message.clone()); - self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(proto, ()).with_timeout(OPEN_TIMEOUT), - }); - self.state = State::Opening { initial_message }; - }, - st @ State::Opening { .. } | st @ State::Refused | st @ State::Open { .. } => { - debug!(target: "sub-libp2p", - "Tried to enable notifications handler that was already enabled"); - self.state = st; - } - State::Poisoned => error!("Notifications handler in a poisoned state"), - } - } - - NotifsOutHandlerIn::Disable => { - match mem::replace(&mut self.state, State::Poisoned) { - st @ State::Disabled | st @ State::DisabledOpen(_) | st @ State::DisabledOpening => { - debug!(target: "sub-libp2p", - "Tried to disable notifications handler that was already disabled"); - self.state = st; - } - State::Opening { .. } => self.state = State::DisabledOpening, - State::Refused => self.state = State::Disabled, - State::Open { substream, close_waker, .. } => { - if let Some(close_waker) = close_waker { - close_waker.wake(); - } - self.state = State::DisabledOpen(substream) - }, - State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), - } - } - } - } - - fn inject_dial_upgrade_error(&mut self, _: (), _: ProtocolsHandlerUpgrErr) { - match mem::replace(&mut self.state, State::Poisoned) { - State::Disabled => {}, - State::DisabledOpen(_) | State::Refused | State::Open { .. } => - error!("☎️ State mismatch in NotificationsOut"), - State::Opening { .. } => { - self.state = State::Refused; - let ev = NotifsOutHandlerOut::Refused; - self.events_queue.push_back(ProtocolsHandlerEvent::Custom(ev)); - }, - State::DisabledOpening => self.state = State::Disabled, - State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), - } - } - - fn connection_keep_alive(&self) -> KeepAlive { - match self.state { - // We have a small grace period of `INITIAL_KEEPALIVE_TIME` during which we keep the - // connection open no matter what, in order to avoid closing and reopening - // connections all the time. - State::Disabled | State::DisabledOpen(_) | State::DisabledOpening => - KeepAlive::Until(self.when_connection_open + INITIAL_KEEPALIVE_TIME), - State::Opening { .. } | State::Open { .. } => KeepAlive::Yes, - State::Refused | State::Poisoned => KeepAlive::No, - } - } - - fn poll( - &mut self, - cx: &mut Context, - ) -> Poll> { - // Flush the events queue if necessary. - if let Some(event) = self.events_queue.pop_front() { - return Poll::Ready(event) - } - - match &mut self.state { - State::Open { substream, initial_message, close_waker } => - match Sink::poll_flush(Pin::new(substream), cx) { - Poll::Pending | Poll::Ready(Ok(())) => {}, - Poll::Ready(Err(_)) => { - if let Some(close_waker) = close_waker.take() { - close_waker.wake(); - } - - // We try to re-open a substream. - let initial_message = mem::replace(initial_message, Vec::new()); - self.state = State::Opening { initial_message: initial_message.clone() }; - let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message); - self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(proto, ()).with_timeout(OPEN_TIMEOUT), - }); - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Closed)); - } - }, - - State::DisabledOpen(sub) => match Sink::poll_close(Pin::new(sub), cx) { - Poll::Pending => {}, - Poll::Ready(Ok(())) | Poll::Ready(Err(_)) => { - self.state = State::Disabled; - return Poll::Ready(ProtocolsHandlerEvent::Custom(NotifsOutHandlerOut::Closed)); - }, - }, - - _ => {} - } - - Poll::Pending - } -} - -impl fmt::Debug for NotifsOutHandler { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - f.debug_struct("NotifsOutHandler") - .field("open", &self.is_open()) - .finish() - } -} diff --git a/client/network/src/protocol/generic_proto/upgrade/legacy.rs b/client/network/src/protocol/generic_proto/upgrade/legacy.rs index 1b2b97253d1..91282d0cf57 100644 --- a/client/network/src/protocol/generic_proto/upgrade/legacy.rs +++ b/client/network/src/protocol/generic_proto/upgrade/legacy.rs @@ -20,7 +20,7 @@ use crate::config::ProtocolId; use bytes::BytesMut; use futures::prelude::*; use futures_codec::Framed; -use libp2p::core::{Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; +use libp2p::core::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; use parking_lot::RwLock; use std::{collections::VecDeque, io, pin::Pin, sync::Arc, vec::IntoIter as VecIntoIter}; use std::task::{Context, Poll}; @@ -85,34 +85,18 @@ impl Clone for RegisteredProtocol { pub struct RegisteredProtocolSubstream { /// If true, we are in the process of closing the sink. is_closing: bool, - /// Whether the local node opened this substream (dialer), or we received this substream from - /// the remote (listener). - endpoint: Endpoint, /// Buffer of packets to send. send_queue: VecDeque, /// If true, we should call `poll_complete` on the inner sink. requires_poll_flush: bool, /// The underlying substream. inner: stream::Fuse>>, - /// Version of the protocol that was negotiated. - protocol_version: u8, /// If true, we have sent a "remote is clogged" event recently and shouldn't send another one /// unless the buffer empties then fills itself again. clogged_fuse: bool, } impl RegisteredProtocolSubstream { - /// Returns the version of the protocol that was negotiated. - pub fn protocol_version(&self) -> u8 { - self.protocol_version - } - - /// Returns whether the local node opened this substream (dialer), or we received this - /// substream from the remote (listener). - pub fn endpoint(&self) -> Endpoint { - self.endpoint - } - /// Starts a graceful shutdown process on this substream. /// /// Note that "graceful" means that we sent a closing message. We don't wait for any @@ -246,7 +230,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, fn upgrade_inbound( self, socket: TSubstream, - info: Self::Info, + _: Self::Info, ) -> Self::Future { Box::pin(async move { let mut framed = { @@ -262,11 +246,9 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, Ok((RegisteredProtocolSubstream { is_closing: false, - endpoint: Endpoint::Listener, send_queue: VecDeque::new(), requires_poll_flush: false, inner: framed.fuse(), - protocol_version: info.version, clogged_fuse: false, }, received_handshake.to_vec())) }) @@ -283,7 +265,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, fn upgrade_outbound( self, socket: TSubstream, - info: Self::Info, + _: Self::Info, ) -> Self::Future { Box::pin(async move { let mut framed = { @@ -301,11 +283,9 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, Ok((RegisteredProtocolSubstream { is_closing: false, - endpoint: Endpoint::Dialer, send_queue: VecDeque::new(), requires_poll_flush: false, inner: framed.fuse(), - protocol_version: info.version, clogged_fuse: false, }, received_handshake.to_vec())) }) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 93abbbad024..5fc8485947f 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -39,7 +39,7 @@ use crate::{ }, on_demand_layer::AlwaysBadChecker, light_client_handler, block_requests, finality_requests, - protocol::{self, event::Event, NotifsHandlerError, LegacyConnectionKillError, NotificationsSink, Ready, sync::SyncState, PeerInfo, Protocol}, + protocol::{self, event::Event, NotifsHandlerError, NotificationsSink, Ready, sync::SyncState, PeerInfo, Protocol}, transport, ReputationChange, }; use futures::{channel::oneshot, prelude::*}; @@ -1589,9 +1589,6 @@ impl Future for NetworkWorker { Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::A(EitherError::A(EitherError::B( EitherError::A(PingFailure::Timeout)))))))))) => "ping-timeout", - Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( - EitherError::A(EitherError::A(EitherError::A(EitherError::A( - NotifsHandlerError::Legacy(LegacyConnectionKillError)))))))))) => "force-closed", Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::A(EitherError::A(EitherError::A( NotifsHandlerError::SyncNotificationsClogged))))))))) => "sync-notifications-clogged", -- GitLab From 08b217a0650635f8430655979c581f0cebe4bed3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 16 Nov 2020 19:49:50 +0100 Subject: [PATCH 018/163] *: Update to libp2p v0.30.0 (#7508) * *: Update to libp2p v0.30.0 * Cargo.lock: Update * *: Update to libp2p v0.30.1 --- Cargo.lock | 223 ++++++++++-------- bin/node/browser-testing/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 +- client/network/src/discovery.rs | 16 +- client/network/src/light_client_handler.rs | 2 +- .../src/protocol/generic_proto/tests.rs | 2 +- client/network/src/request_responses.rs | 4 +- client/network/src/transport.rs | 8 +- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 16 files changed, 148 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fca7a32c96d..1b8b13c2e2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38628c78a34f111c5a6b98fc87dfc056cd1590b61afe748b145be4623c56d194" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "concurrent-queue", "fastrand", "futures-lite", @@ -389,7 +389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" dependencies = [ "addr2line", - "cfg-if", + "cfg-if 0.1.10", "libc", "miniz_oxide", "object 0.20.0", @@ -438,7 +438,7 @@ checksum = "66c0bb6167449588ff70803f4127f0684f9063097eca5016f37eb52b92c2cf36" dependencies = [ "bitflags", "cexpr", - "cfg-if", + "cfg-if 0.1.10", "clang-sys", "clap", "env_logger", @@ -605,6 +605,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + [[package]] name = "bstr" version = "0.2.13" @@ -718,6 +724,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "chacha20" version = "0.4.3" @@ -827,7 +839,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "wasm-bindgen", ] @@ -987,7 +999,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -1044,7 +1056,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ "autocfg 1.0.0", - "cfg-if", + "cfg-if 0.1.10", "crossbeam-utils", "lazy_static", "maybe-uninit", @@ -1058,7 +1070,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "crossbeam-utils", "maybe-uninit", ] @@ -1070,7 +1082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg 1.0.0", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -1225,7 +1237,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "dirs-sys", ] @@ -1577,7 +1589,7 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "crc32fast", "libc", "libz-sys", @@ -2065,7 +2077,7 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi", "wasm-bindgen", @@ -2077,7 +2089,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi", ] @@ -2885,9 +2897,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.29.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021f703bfef6e3da78ef9828c8a244d639b8d57eedf58360922aca5ff69dfdcd" +checksum = "e3c2b4c99f8798be90746fc226acf95d3e6cff0655883634cc30dab1f64f438b" dependencies = [ "atomic", "bytes 0.5.6", @@ -2924,12 +2936,12 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3960524389409633550567e8a9e0684d25a33f4f8408887ff897dd9fdfbdb771" +checksum = "1b8186060d6bd415e4e928e6cb44c4fe7e7a7dd53437bd936ce7e5f421e45a51" dependencies = [ "asn1_der", - "bs58", + "bs58 0.4.0", "ed25519-dalek", "either", "fnv", @@ -2968,9 +2980,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567962c5c5f8a1282979441300e1739ba939024010757c3dbfab4d462189df77" +checksum = "34aea69349e70a58ef9ecd21ac12c5eaa36255ac6986828079d26393f9e618cb" dependencies = [ "flate2", "futures 0.3.5", @@ -2979,9 +2991,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436280f5fe21a58fcaff82c2606945579241f32bc0eaf2d39321aa4624a66e7f" +checksum = "0baeff71fb5cb1fe1604f74a712a44b66a8c5900f4022411a1d550f09d6bb776" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -2990,9 +3002,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc175613c5915332fd6458895407ec242ea055ae3b107a586626d5e3349350a" +checksum = "db0f925a45f310b678e70faf71a10023b829d02eb9cc2628a63de928936f3ade" dependencies = [ "cuckoofilter", "fnv", @@ -3008,9 +3020,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d500ad89ba14de4d18bebdff61a0ce3e769f1c5c5a95026c5da90187e5fff5c9" +checksum = "efeb65567174974f551a91f9f5719445b6695cad56f6a7a47a27111f37efb6b8" dependencies = [ "base64 0.13.0", "byteorder", @@ -3034,9 +3046,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b90b350e37f398b73d778bd94422f4e6a3afa2c1582742ce2446b8a0dba787" +checksum = "e074124669840484de564901d47f2d0892e73f6d8ee7c37e9c2644af1b217bf4" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3050,9 +3062,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb78341f114bf686d5fe50b33ff1a804d88fb326c0d39ee1c22db4346b21fc27" +checksum = "78a2653b2e3254a3bbeb66bfc3f0dca7d6cba6aa2a96791db114003dec1b5394" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.6", @@ -3077,9 +3089,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b575514fce0a3ccbd065d6aa377bd4d5102001b05c1a22a5eee49c450254ef0f" +checksum = "786b068098794322239f8f04df88a52daeb7863b2e77501c4d85d32e0a8f2d26" dependencies = [ "async-std", "data-encoding", @@ -3099,9 +3111,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "696c8ee8b42496690b88b0de84a96387caf6e09880bcc8e794bb88afa054e995" +checksum = "ed764eab613a8fb6b7dcf6c796f55a06fef2270e528329903e25cd3311b99663" dependencies = [ "bytes 0.5.6", "futures 0.3.5", @@ -3117,9 +3129,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c77142e3e5b18fefa7d267305c777c9cbe9b2232ec489979390100bebcc1e6" +checksum = "fb441fb015ec16690099c5d910fcba271d357763b3dcb784db7b27bbb0b68372" dependencies = [ "bytes 0.5.6", "curve25519-dalek 3.0.0", @@ -3139,9 +3151,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7257135609e8877f4d286935cbe1e572b2018946881c3e7f63054577074a7ee7" +checksum = "82e5c50936cfdbe96a514e8992f304fa44cd3a681b6f779505f1ae62b3474705" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3154,9 +3166,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c88d59ba3e710a8c8e0535cb4a52e9e46534924cbbea4691f8c3aaad17b58c61" +checksum = "21026557c335d3639591f247b19b7536195772034ec7e9c463137227f95eaaa1" dependencies = [ "bytes 0.5.6", "futures 0.3.5", @@ -3185,9 +3197,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02ba1aa5727ccc118c09ba5111480873f2fe5608cb304e258fd12c173ecf27c9" +checksum = "2dd9a1e0e6563dec1c9e702f7e68bdaa43da62a84536aa06372d3fed3e25d4ca" dependencies = [ "async-trait", "bytes 0.5.6", @@ -3205,9 +3217,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa6fa33b16956b8a58afbfebe1406866011a1ab8960765bd36868952d7be6a1" +checksum = "565f0e06674b4033c978471e4083d5aaa8e03cef0719a0ec0905aaeaad39a919" dependencies = [ "either", "futures 0.3.5", @@ -3221,9 +3233,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0b6f4ef48d9493607fae069deecce0579320a1f3de6cb056770b151018a9a5" +checksum = "33f3dce259c0d3127af5167f45c275b6c047320efdd0e40fde947482487af0a3" dependencies = [ "async-std", "futures 0.3.5", @@ -3237,9 +3249,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945bed3c989a1b290b5a0d4e8fa6e44e01840efb9a5ab3f0d3d174f0e451ac0e" +checksum = "5e0aba04370a00d8d0236e350bc862926c1b42542a169aa6a481e660e5b990fe" dependencies = [ "async-std", "futures 0.3.5", @@ -3249,9 +3261,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66518a4455e15c283637b4d7b579aef928b75a3fc6c50a41e7e6b9fa86672ca0" +checksum = "6c703816f4170477a375b49c56d349e535ce68388f81ba1d9a3c8e2517effa82" dependencies = [ "futures 0.3.5", "js-sys", @@ -3263,9 +3275,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc561870477523245efaaea1b6b743c70115f10c670e62bcbbe4d3153be5f0c" +checksum = "8d5e7268a959748040a0cf7456ad655be55b87f0ceda03bdb5b53674726b28f7" dependencies = [ "async-tls", "either", @@ -3283,9 +3295,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0c9b6ef7a168c2ae854170b0b6b77550599afe06cc3ac390eb45c5d9c7110" +checksum = "1a0798cbb58535162c40858493d09af06eac42a26e4966e58de0df701f559348" dependencies = [ "futures 0.3.5", "libp2p-core", @@ -3411,7 +3423,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -3548,18 +3560,18 @@ dependencies = [ [[package]] name = "minicbor" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2ef6aa869726518c5d8206fa5d1337bda8a0442807611be617891c018fa781" +checksum = "0164190d1771b1458c3742075b057ed55d25cd9dfb930aade99315a1eb1fe12d" dependencies = [ "minicbor-derive", ] [[package]] name = "minicbor-derive" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3569c0dbfff1b8d5f1434c642b67f5bf81c0f354a3f5f8f180b549dba3c07c" +checksum = "2e071b3159835ee91df62dbdbfdd7ec366b7ea77c838f43aff4acda6b61bcfb9" dependencies = [ "proc-macro2", "quote", @@ -3581,7 +3593,7 @@ version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", @@ -3659,17 +3671,17 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multihash" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75db05d738947aa5389863aadafbcf2e509d7ba099dc2ddcdf4fc66bf7a9e03" +checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6" dependencies = [ "blake2b_simd", "blake2s_simd", - "digest 0.8.1", - "sha-1", - "sha2 0.8.2", - "sha3 0.8.2", - "unsigned-varint 0.3.3", + "digest 0.9.0", + "sha-1 0.9.2", + "sha2 0.9.1", + "sha3 0.9.1", + "unsigned-varint 0.5.1", ] [[package]] @@ -3680,9 +3692,9 @@ checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a6aa6e32fbaf16795142335967214b8564a7a4661eb6dc846ef343a6e00ac1" +checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75" dependencies = [ "bytes 0.5.6", "futures 0.3.5", @@ -3724,7 +3736,7 @@ version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "winapi 0.3.9", ] @@ -3737,7 +3749,7 @@ checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 0.1.10", "libc", "void", ] @@ -5215,12 +5227,12 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7ad66970bbab360c97179b60906e2dc4aef1f7fca8ab4e5c5db8c97b16814a" +checksum = "22fe99b938abd57507e37f8d4ef30cd74b33c71face2809b37b8beb71bab15ab" dependencies = [ "arrayref", - "bs58", + "bs58 0.4.0", "byteorder", "data-encoding", "multihash", @@ -5287,7 +5299,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "ethereum-types", "hashbrown 0.8.1", "impl-trait-for-tuples", @@ -5338,7 +5350,7 @@ dependencies = [ "mio", "mio-extras", "rand 0.7.3", - "sha-1", + "sha-1 0.8.2", "slab", "url 2.1.1", ] @@ -5410,7 +5422,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.0.3", "libc", "redox_syscall", @@ -5425,7 +5437,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.0.3", "libc", "redox_syscall", @@ -5439,7 +5451,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi 0.1.0", "instant", "libc", @@ -5557,7 +5569,7 @@ checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" dependencies = [ "maplit", "pest", - "sha-1", + "sha-1 0.8.2", ] [[package]] @@ -5652,7 +5664,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0720e0b9ea9d52451cf29d3413ba8a9303f8815d9d9653ef70e03ff73e65566" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "log", "wepoll-sys-stjepang", @@ -5674,7 +5686,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9a50142b55ab3ed0e9f68dfb3709f1d90d29da24e91033f28b96330643107dc" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "universal-hash", ] @@ -5797,7 +5809,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d70cf4412832bcac9cffe27906f4a66e450d323525e977168c70d1b36120ae" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fnv", "lazy_static", "parking_lot 0.11.0", @@ -7153,7 +7165,7 @@ dependencies = [ "async-std", "async-trait", "bitflags", - "bs58", + "bs58 0.3.1", "bytes 0.5.6", "derive_more", "either", @@ -7842,6 +7854,19 @@ dependencies = [ "opaque-debug 0.2.3", ] +[[package]] +name = "sha-1" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpuid-bool", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + [[package]] name = "sha2" version = "0.8.2" @@ -7861,7 +7886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 0.1.10", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -8012,7 +8037,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_syscall", "winapi 0.3.9", @@ -8031,7 +8056,7 @@ dependencies = [ "httparse", "log", "rand 0.7.3", - "sha-1", + "sha-1 0.8.2", ] [[package]] @@ -9049,7 +9074,7 @@ dependencies = [ name = "substrate-test-runtime" version = "2.0.0" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "frame-executive", "frame-support", "frame-system", @@ -9237,7 +9262,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand 0.7.3", "redox_syscall", @@ -9685,7 +9710,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "log", "pin-project-lite", "tracing-attributes", @@ -9928,12 +9953,6 @@ dependencies = [ "subtle 2.2.3", ] -[[package]] -name = "unsigned-varint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f67332660eb59a6f1eb24ff1220c9e8d01738a8503c6002e30bcfe4bd9f2b4a9" - [[package]] name = "unsigned-varint" version = "0.4.0" @@ -10075,7 +10094,7 @@ version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "serde", "serde_json", "wasm-bindgen-macro", @@ -10102,7 +10121,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "js-sys", "wasm-bindgen", "web-sys", @@ -10232,7 +10251,7 @@ checksum = "1cd3c4f449382779ef6e0a7c3ec6752ae614e20a42e4100000c3efdc973100e2" dependencies = [ "anyhow", "backtrace", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", "libc", "log", @@ -10274,7 +10293,7 @@ dependencies = [ "anyhow", "base64 0.12.3", "bincode", - "cfg-if", + "cfg-if 0.1.10", "cranelift-codegen", "cranelift-entity", "cranelift-frontend", @@ -10303,7 +10322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e914c013c7a9f15f4e429d5431f2830fb8adb56e40567661b69c5ec1d645be23" dependencies = [ "anyhow", - "cfg-if", + "cfg-if 0.1.10", "cranelift-codegen", "cranelift-entity", "cranelift-frontend", @@ -10346,7 +10365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8d4d1af8dd5f7096cfcc89dd668d358e52980c38cce199643372ffd6590e27" dependencies = [ "anyhow", - "cfg-if", + "cfg-if 0.1.10", "gimli 0.21.0", "lazy_static", "libc", @@ -10366,7 +10385,7 @@ checksum = "3a25f140bbbaadb07c531cba99ce1a966dba216138dc1b2a0ddecec851a01a93" dependencies = [ "backtrace", "cc", - "cfg-if", + "cfg-if 0.1.10", "indexmap", "lazy_static", "libc", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index c90c4a293f4..fade57d8124 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index ff6c26bbee5..40b929fc8a0 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -24,7 +24,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.29.1", default-features = false, features = ["kad"] } +libp2p = { version = "0.30.1", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 51c499828ac..942d30e90db 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -21,7 +21,7 @@ ansi_term = "0.12.1" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.29.1" +libp2p = "0.30.1" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 94d9272f4bb..c120ff515c7 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } log = "0.4.8" lru = "0.4.3" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index f5ebee39db5..6b66fd0cdee 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -64,13 +64,13 @@ wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.29.1" +version = "0.30.1" default-features = false features = ["identify", "kad", "mdns-async-std", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index f9bda6aabf5..60d35dbdf1a 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -51,11 +51,11 @@ use futures::prelude::*; use futures_timer::Delay; use ip_network::IpNetwork; use libp2p::core::{connection::{ConnectionId, ListenerId}, ConnectedPoint, Multiaddr, PeerId, PublicKey}; -use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler}; -use libp2p::swarm::protocols_handler::multi::MultiHandler; +use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler, IntoProtocolsHandler}; +use libp2p::swarm::protocols_handler::multi::IntoMultiHandler; use libp2p::kad::{Kademlia, KademliaBucketInserts, KademliaConfig, KademliaEvent, QueryResult, Quorum, Record}; use libp2p::kad::GetClosestPeersError; -use libp2p::kad::handler::KademliaHandler; +use libp2p::kad::handler::KademliaHandlerProto; use libp2p::kad::QueryId; use libp2p::kad::record::{self, store::{MemoryStore, RecordStore}}; #[cfg(not(target_os = "unknown"))] @@ -444,14 +444,14 @@ pub enum DiscoveryOut { } impl NetworkBehaviour for DiscoveryBehaviour { - type ProtocolsHandler = MultiHandler>; + type ProtocolsHandler = IntoMultiHandler>; type OutEvent = DiscoveryOut; fn new_handler(&mut self) -> Self::ProtocolsHandler { let iter = self.kademlias.iter_mut() .map(|(p, k)| (p.clone(), NetworkBehaviour::new_handler(k))); - MultiHandler::try_from_iter(iter) + IntoMultiHandler::try_from_iter(iter) .expect("There can be at most one handler per `ProtocolId` and \ protocol names contain the `ProtocolId` so no two protocol \ names in `self.kademlias` can be equal which is the only error \ @@ -534,7 +534,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { &mut self, peer_id: PeerId, connection: ConnectionId, - (pid, event): ::OutEvent, + (pid, event): <::Handler as ProtocolsHandler>::OutEvent, ) { if let Some(kad) = self.kademlias.get_mut(&pid) { return kad.inject_event(peer_id, connection, event) @@ -598,7 +598,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { params: &mut impl PollParameters, ) -> Poll< NetworkBehaviourAction< - ::InEvent, + <::Handler as ProtocolsHandler>::InEvent, Self::OutEvent, >, > { @@ -816,7 +816,7 @@ mod tests { let transport = MemoryTransport .upgrade(upgrade::Version::V1) .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) - .multiplex(yamux::Config::default()) + .multiplex(yamux::YamuxConfig::default()) .boxed(); let behaviour = { diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index e7c5e9c1c9b..b72362fdfc3 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -1355,7 +1355,7 @@ mod tests { let transport = MemoryTransport::default() .upgrade(upgrade::Version::V1) .authenticate(NoiseConfig::xx(dh_key).into_authenticated()) - .multiplex(yamux::Config::default()) + .multiplex(yamux::YamuxConfig::default()) .boxed(); Swarm::new(transport, LightClientHandler::new(cf, client, checker, ps), local_peer) } diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 7a040a403af..9c45c62f8bb 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -54,7 +54,7 @@ fn build_nodes() -> (Swarm, Swarm) { let transport = MemoryTransport .upgrade(upgrade::Version::V1) .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) - .multiplex(yamux::Config::default()) + .multiplex(yamux::YamuxConfig::default()) .timeout(Duration::from_secs(20)) .boxed(); diff --git a/client/network/src/request_responses.rs b/client/network/src/request_responses.rs index 5e414248674..a3a68f719d6 100644 --- a/client/network/src/request_responses.rs +++ b/client/network/src/request_responses.rs @@ -680,7 +680,7 @@ mod tests { let transport = MemoryTransport .upgrade(upgrade::Version::V1) .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) - .multiplex(libp2p::yamux::Config::default()) + .multiplex(libp2p::yamux::YamuxConfig::default()) .boxed(); let behaviour = { @@ -783,7 +783,7 @@ mod tests { let transport = MemoryTransport .upgrade(upgrade::Version::V1) .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) - .multiplex(libp2p::yamux::Config::default()) + .multiplex(libp2p::yamux::YamuxConfig::default()) .boxed(); let behaviour = { diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index 80d897633fd..035b3a9716a 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -104,13 +104,13 @@ pub fn build_transport( let multiplexing_config = { let mut mplex_config = mplex::MplexConfig::new(); - mplex_config.max_buffer_len_behaviour(mplex::MaxBufferBehaviour::Block); - mplex_config.max_buffer_len(usize::MAX); + mplex_config.set_max_buffer_behaviour(mplex::MaxBufferBehaviour::Block); + mplex_config.set_max_buffer_size(usize::MAX); - let mut yamux_config = libp2p::yamux::Config::default(); + let mut yamux_config = libp2p::yamux::YamuxConfig::default(); // Enable proper flow-control: window updates are only sent when // buffered data has been consumed. - yamux_config.set_window_update_mode(libp2p::yamux::WindowUpdateMode::OnRead); + yamux_config.set_window_update_mode(libp2p::yamux::WindowUpdateMode::on_read()); core::upgrade::SelectUpgrade::new(yamux_config, mplex_config) }; diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index a8bf98a75ed..a74aa90d4f4 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 459f4a93020..efca00a24de 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 18812a8c71e..bff7842bec4 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.29.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.30.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index db85244dcfa..001f0e36794 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.29.1", default-features = false } +libp2p = { version = "0.30.1", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 90668f4e51f..9efc8c39668 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] futures = { version = "0.3", features = ["compat"] } futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.23", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.24", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From 11ace4ef8b2ad176293ad6db2b3dd795befd2c79 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 16 Nov 2020 22:50:44 +0100 Subject: [PATCH 019/163] make ClientConfig public (#7544) --- client/service/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 8e6b0037bdf..a23ebf3d553 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -80,7 +80,7 @@ pub use sc_tracing::TracingReceiver; pub use task_manager::SpawnTaskHandle; pub use task_manager::TaskManager; pub use sp_consensus::import_queue::ImportQueue; -pub use self::client::LocalCallExecutor; +pub use self::client::{LocalCallExecutor, ClientConfig}; use sc_client_api::{blockchain::HeaderBackend, BlockchainEvents}; const DEFAULT_PROTOCOL_ID: &str = "sup"; -- GitLab From 407cd3af06b03201a506b645c9ee587e5d4748bb Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Wed, 18 Nov 2020 13:56:16 +0800 Subject: [PATCH 020/163] sc-basic-authorship: remove useless dependencies (#7550) Signed-off-by: koushiro --- Cargo.lock | 66 ++++-------------------------- client/basic-authorship/Cargo.toml | 1 - 2 files changed, 8 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b8b13c2e2a..3a87dfec664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1878,27 +1878,12 @@ dependencies = [ "futures-sink", ] -[[package]] -name = "futures-channel-preview" -version = "0.3.0-alpha.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" -dependencies = [ - "futures-core-preview", -] - [[package]] name = "futures-core" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" -[[package]] -name = "futures-core-preview" -version = "0.3.0-alpha.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" - [[package]] name = "futures-cpupool" version = "0.1.8" @@ -2022,18 +2007,6 @@ dependencies = [ "slab", ] -[[package]] -name = "futures-util-preview" -version = "0.3.0-alpha.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" -dependencies = [ - "futures-channel-preview", - "futures-core-preview", - "pin-utils", - "slab", -] - [[package]] name = "futures_codec" version = "0.4.1" @@ -2412,7 +2385,7 @@ dependencies = [ "time", "tokio 0.1.22", "tokio-buf", - "tokio-executor 0.1.10", + "tokio-executor", "tokio-io", "tokio-reactor", "tokio-tcp", @@ -6518,7 +6491,6 @@ dependencies = [ "sp-transaction-pool", "substrate-prometheus-endpoint", "substrate-test-runtime-client", - "tokio-executor 0.2.0-alpha.6", ] [[package]] @@ -9404,11 +9376,11 @@ dependencies = [ "num_cpus", "tokio-codec", "tokio-current-thread", - "tokio-executor 0.1.10", + "tokio-executor", "tokio-fs", "tokio-io", "tokio-reactor", - "tokio-sync 0.1.8", + "tokio-sync", "tokio-tcp", "tokio-threadpool", "tokio-timer", @@ -9468,7 +9440,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ "futures 0.1.29", - "tokio-executor 0.1.10", + "tokio-executor", ] [[package]] @@ -9481,17 +9453,6 @@ dependencies = [ "futures 0.1.29", ] -[[package]] -name = "tokio-executor" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee9ceecf69145923834ea73f32ba40c790fd877b74a7817dd0b089f1eb9c7c8" -dependencies = [ - "futures-util-preview", - "lazy_static", - "tokio-sync 0.2.0-alpha.6", -] - [[package]] name = "tokio-fs" version = "0.1.7" @@ -9552,9 +9513,9 @@ dependencies = [ "num_cpus", "parking_lot 0.9.0", "slab", - "tokio-executor 0.1.10", + "tokio-executor", "tokio-io", - "tokio-sync 0.1.8", + "tokio-sync", ] [[package]] @@ -9588,17 +9549,6 @@ dependencies = [ "futures 0.1.29", ] -[[package]] -name = "tokio-sync" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1aaeb685540f7407ea0e27f1c9757d258c7c6bf4e3eb19da6fc59b747239d2" -dependencies = [ - "fnv", - "futures-core-preview", - "futures-util-preview", -] - [[package]] name = "tokio-tcp" version = "0.1.4" @@ -9627,7 +9577,7 @@ dependencies = [ "log", "num_cpus", "slab", - "tokio-executor 0.1.10", + "tokio-executor", ] [[package]] @@ -9639,7 +9589,7 @@ dependencies = [ "crossbeam-utils", "futures 0.1.29", "slab", - "tokio-executor 0.1.10", + "tokio-executor", ] [[package]] diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 1b1d8921bcf..f097d8044f6 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -29,7 +29,6 @@ sc-telemetry = { version = "2.0.0", path = "../telemetry" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } sc-block-builder = { version = "0.8.0", path = "../block-builder" } sc-proposer-metrics = { version = "0.8.0", path = "../proposer-metrics" } -tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } [dev-dependencies] sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } -- GitLab From 2d97a12fb7070a5fbc3dcc9d2918247df69d6245 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 18 Nov 2020 12:19:22 +0100 Subject: [PATCH 021/163] Add slashing events to elections-phragmen. (#7543) * Add slashing events to elections-phragmen. * Fix build * Apply suggestions from code review * Update frame/elections-phragmen/src/lib.rs * Update frame/elections-phragmen/src/lib.rs Co-authored-by: Guillaume Thiolliere Co-authored-by: Guillaume Thiolliere --- frame/elections-phragmen/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index cf3864f2e3f..be47b5adcce 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -682,6 +682,10 @@ decl_event!( /// A \[member\] has been removed. This should always be followed by either `NewTerm` or /// `EmptyTerm`. MemberKicked(AccountId), + /// A candidate was slashed due to failing to obtain a seat as member or runner-up + CandidateSlashed(AccountId, Balance), + /// A seat holder (member or runner-up) was slashed due to failing to retaining their position. + SeatHolderSlashed(AccountId, Balance), /// A \[member\] has renounced their candidacy. MemberRenounced(AccountId), /// A voter was reported with the the report being successful or not. @@ -995,6 +999,7 @@ impl Module { new_runners_up_ids_sorted.binary_search(&c).is_err() { let (imbalance, _) = T::Currency::slash_reserved(&c, T::CandidacyBond::get()); + Self::deposit_event(RawEvent::CandidateSlashed(c, T::CandidacyBond::get())); T::LoserCandidate::on_unbalanced(imbalance); } }); @@ -1002,6 +1007,7 @@ impl Module { // Burn outgoing bonds to_burn_bond.into_iter().for_each(|x| { let (imbalance, _) = T::Currency::slash_reserved(&x, T::CandidacyBond::get()); + Self::deposit_event(RawEvent::SeatHolderSlashed(x, T::CandidacyBond::get())); T::LoserCandidate::on_unbalanced(imbalance); }); -- GitLab From c180950de63dbdfaa11053a8a56f35e694ed9e36 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 18 Nov 2020 16:05:35 +0100 Subject: [PATCH 022/163] Remove necessity to pass ConsensusEngineId when registering notifications protocol (#7549) * Remove necessity to pass ConsensusEngineId when registering notifications protocol * Line width * Fix tests protocol name * Other renames * Doc update * Change issue in TODO --- .../finality-grandpa/src/communication/mod.rs | 2 - .../src/communication/tests.rs | 23 ++-- client/finality-grandpa/src/lib.rs | 1 - client/finality-grandpa/src/tests.rs | 4 +- client/network-gossip/src/bridge.rs | 51 ++++--- client/network-gossip/src/lib.rs | 18 ++- client/network-gossip/src/state_machine.rs | 54 +++++--- client/network/src/behaviour.rs | 31 ++--- client/network/src/config.rs | 7 +- client/network/src/gossip.rs | 9 +- client/network/src/gossip/tests.rs | 14 +- client/network/src/protocol.rs | 82 ++++------- client/network/src/protocol/event.rs | 8 +- client/network/src/protocol/message.rs | 2 +- client/network/src/service.rs | 127 +++++++----------- client/network/src/service/out_events.rs | 29 ++-- client/network/src/service/tests.rs | 46 +++---- client/network/test/src/lib.rs | 4 +- 18 files changed, 228 insertions(+), 284 deletions(-) diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 3daffcb9f25..038d82a8cdc 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -68,7 +68,6 @@ mod periodic; #[cfg(test)] pub(crate) mod tests; -pub use sp_finality_grandpa::GRANDPA_ENGINE_ID; pub const GRANDPA_PROTOCOL_NAME: &'static str = "/paritytech/grandpa/1"; // cost scalars for reporting peers. @@ -215,7 +214,6 @@ impl> NetworkBridge { let validator = Arc::new(validator); let gossip_engine = Arc::new(Mutex::new(GossipEngine::new( service.clone(), - GRANDPA_ENGINE_ID, GRANDPA_PROTOCOL_NAME, validator.clone() ))); diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index 1a773acd6d0..e1685256f7b 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -24,10 +24,11 @@ use sc_network_gossip::Validator; use std::sync::Arc; use sp_keyring::Ed25519Keyring; use parity_scale_codec::Encode; -use sp_runtime::{ConsensusEngineId, traits::NumberFor}; +use sp_runtime::traits::NumberFor; use std::{borrow::Cow, pin::Pin, task::{Context, Poll}}; +use crate::communication::GRANDPA_PROTOCOL_NAME; use crate::environment::SharedVoterSetState; -use sp_finality_grandpa::{AuthorityList, GRANDPA_ENGINE_ID}; +use sp_finality_grandpa::AuthorityList; use super::gossip::{self, GossipValidator}; use super::{VoterSet, Round, SetId}; @@ -57,11 +58,11 @@ impl sc_network_gossip::Network for TestNetwork { fn disconnect_peer(&self, _: PeerId) {} - fn write_notification(&self, who: PeerId, _: ConsensusEngineId, message: Vec) { + fn write_notification(&self, who: PeerId, _: Cow<'static, str>, message: Vec) { let _ = self.sender.unbounded_send(Event::WriteNotification(who, message)); } - fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, str>) {} + fn register_notifications_protocol(&self, _: Cow<'static, str>) {} fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); @@ -86,7 +87,7 @@ impl sc_network_gossip::ValidatorContext for TestNetwork { >::write_notification( self, who.clone(), - GRANDPA_ENGINE_ID, + GRANDPA_PROTOCOL_NAME.into(), data, ); } @@ -287,20 +288,20 @@ fn good_commit_leads_to_relay() { // Add the sending peer and send the commit let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: sender_id.clone(), - engine_id: GRANDPA_ENGINE_ID, + protocol: GRANDPA_PROTOCOL_NAME.into(), role: ObservedRole::Full, }); let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { remote: sender_id.clone(), - messages: vec![(GRANDPA_ENGINE_ID, commit_to_send.clone().into())], + messages: vec![(GRANDPA_PROTOCOL_NAME.into(), commit_to_send.clone().into())], }); // Add a random peer which will be the recipient of this message let receiver_id = sc_network::PeerId::random(); let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: receiver_id.clone(), - engine_id: GRANDPA_ENGINE_ID, + protocol: GRANDPA_PROTOCOL_NAME.into(), role: ObservedRole::Full, }); @@ -319,7 +320,7 @@ fn good_commit_leads_to_relay() { sender.unbounded_send(NetworkEvent::NotificationsReceived { remote: receiver_id, - messages: vec![(GRANDPA_ENGINE_ID, msg.encode().into())], + messages: vec![(GRANDPA_PROTOCOL_NAME.into(), msg.encode().into())], }) }; @@ -434,12 +435,12 @@ fn bad_commit_leads_to_report() { Event::EventStream(sender) => { let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { remote: sender_id.clone(), - engine_id: GRANDPA_ENGINE_ID, + protocol: GRANDPA_PROTOCOL_NAME.into(), role: ObservedRole::Full, }); let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { remote: sender_id.clone(), - messages: vec![(GRANDPA_ENGINE_ID, commit_to_send.clone().into())], + messages: vec![(GRANDPA_PROTOCOL_NAME.into(), commit_to_send.clone().into())], }); true diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 6ab95d7eac9..18b439abf5e 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -1085,7 +1085,6 @@ where // to receive GRANDPA messages on the network. We don't process the // messages. network.register_notifications_protocol( - communication::GRANDPA_ENGINE_ID, From::from(communication::GRANDPA_PROTOCOL_NAME), ); diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 175c5360b2c..44503d3c85d 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -99,9 +99,7 @@ impl TestNetFactory for GrandpaTestNet { fn add_full_peer(&mut self) { self.add_full_peer_with_config(FullPeerConfig { - notifications_protocols: vec![ - (communication::GRANDPA_ENGINE_ID, communication::GRANDPA_PROTOCOL_NAME.into()) - ], + notifications_protocols: vec![communication::GRANDPA_PROTOCOL_NAME.into()], ..Default::default() }) } diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 70c2942597a..98ada69590f 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -23,7 +23,7 @@ use futures::prelude::*; use futures::channel::mpsc::{channel, Sender, Receiver}; use libp2p::PeerId; use log::trace; -use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use sp_runtime::traits::Block as BlockT; use std::{ borrow::Cow, collections::{HashMap, VecDeque}, @@ -38,7 +38,7 @@ pub struct GossipEngine { state_machine: ConsensusGossip, network: Box + Send>, periodic_maintenance_interval: futures_timer::Delay, - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, /// Incoming events from the network. network_event_stream: Pin + Send>>, @@ -68,20 +68,21 @@ impl GossipEngine { /// Create a new instance. pub fn new + Send + Clone + 'static>( network: N, - engine_id: ConsensusEngineId, - protocol_name: impl Into>, + protocol: impl Into>, validator: Arc>, ) -> Self where B: 'static { + let protocol = protocol.into(); + // We grab the event stream before registering the notifications protocol, otherwise we // might miss events. let network_event_stream = network.event_stream(); - network.register_notifications_protocol(engine_id, protocol_name.into()); + network.register_notifications_protocol(protocol.clone()); GossipEngine { - state_machine: ConsensusGossip::new(validator, engine_id), + state_machine: ConsensusGossip::new(validator, protocol.clone()), network: Box::new(network), periodic_maintenance_interval: futures_timer::Delay::new(PERIODIC_MAINTENANCE_INTERVAL), - engine_id, + protocol, network_event_stream, message_sinks: HashMap::new(), @@ -181,21 +182,21 @@ impl Future for GossipEngine { ForwardingState::Idle => { match this.network_event_stream.poll_next_unpin(cx) { Poll::Ready(Some(event)) => match event { - Event::NotificationStreamOpened { remote, engine_id, role } => { - if engine_id != this.engine_id { + Event::NotificationStreamOpened { remote, protocol, role } => { + if protocol != this.protocol { continue; } this.state_machine.new_peer(&mut *this.network, remote, role); } - Event::NotificationStreamClosed { remote, engine_id } => { - if engine_id != this.engine_id { + Event::NotificationStreamClosed { remote, protocol } => { + if protocol != this.protocol { continue; } this.state_machine.peer_disconnected(&mut *this.network, remote); }, Event::NotificationsReceived { remote, messages } => { let messages = messages.into_iter().filter_map(|(engine, data)| { - if engine == this.engine_id { + if engine == this.protocol { Some(data.to_vec()) } else { None @@ -299,6 +300,7 @@ mod tests { use rand::Rng; use sc_network::ObservedRole; use sp_runtime::{testing::H256, traits::{Block as BlockT}}; + use std::borrow::Cow; use std::convert::TryInto; use std::sync::{Arc, Mutex}; use substrate_test_runtime_client::runtime::Block; @@ -329,11 +331,11 @@ mod tests { unimplemented!(); } - fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec) { + fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec) { unimplemented!(); } - fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, str>) {} + fn register_notifications_protocol(&self, _: Cow<'static, str>) {} fn announce(&self, _: B::Hash, _: Vec) { unimplemented!(); @@ -361,8 +363,7 @@ mod tests { let network = TestNetwork::default(); let mut gossip_engine = GossipEngine::::new( network.clone(), - [1, 2, 3, 4], - "my_protocol", + "/my_protocol", Arc::new(AllowAll{}), ); @@ -383,14 +384,13 @@ mod tests { #[test] fn keeps_multiple_subscribers_per_topic_updated_with_both_old_and_new_messages() { let topic = H256::default(); - let engine_id = [1, 2, 3, 4]; + let protocol = Cow::Borrowed("/my_protocol"); let remote_peer = PeerId::random(); let network = TestNetwork::default(); let mut gossip_engine = GossipEngine::::new( network.clone(), - engine_id.clone(), - "my_protocol", + protocol.clone(), Arc::new(AllowAll{}), ); @@ -404,7 +404,7 @@ mod tests { event_sender.start_send( Event::NotificationStreamOpened { remote: remote_peer.clone(), - engine_id: engine_id.clone(), + protocol: protocol.clone(), role: ObservedRole::Authority, } ).expect("Event stream is unbounded; qed."); @@ -413,7 +413,7 @@ mod tests { let events = messages.iter().cloned().map(|m| { Event::NotificationsReceived { remote: remote_peer.clone(), - messages: vec![(engine_id, m.into())] + messages: vec![(protocol.clone(), m.into())] } }).collect::>(); @@ -498,7 +498,7 @@ mod tests { } fn prop(channels: Vec, notifications: Vec>) { - let engine_id = [1, 2, 3, 4]; + let protocol = Cow::Borrowed("/my_protocol"); let remote_peer = PeerId::random(); let network = TestNetwork::default(); @@ -524,8 +524,7 @@ mod tests { let mut gossip_engine = GossipEngine::::new( network.clone(), - engine_id.clone(), - "my_protocol", + protocol.clone(), Arc::new(TestValidator{}), ); @@ -558,7 +557,7 @@ mod tests { event_sender.start_send( Event::NotificationStreamOpened { remote: remote_peer.clone(), - engine_id: engine_id.clone(), + protocol: protocol.clone(), role: ObservedRole::Authority, } ).expect("Event stream is unbounded; qed."); @@ -576,7 +575,7 @@ mod tests { message.push(i_notification.try_into().unwrap()); message.push(i_message.try_into().unwrap()); - (engine_id, message.into()) + (protocol.clone(), message.into()) }).collect(); event_sender.start_send(Event::NotificationsReceived { diff --git a/client/network-gossip/src/lib.rs b/client/network-gossip/src/lib.rs index 1d566ed3cbb..09e946d1a1e 100644 --- a/client/network-gossip/src/lib.rs +++ b/client/network-gossip/src/lib.rs @@ -33,7 +33,7 @@ //! - Implement the `Network` trait, representing the low-level networking primitives. It is //! already implemented on `sc_network::NetworkService`. //! - Implement the `Validator` trait. See the section below. -//! - Decide on a `ConsensusEngineId`. Each gossiping protocol should have a different one. +//! - Decide on a protocol name. Each gossiping protocol should have a different one. //! - Build a `GossipEngine` using these three elements. //! - Use the methods of the `GossipEngine` in order to send out messages and receive incoming //! messages. @@ -60,7 +60,7 @@ pub use self::validator::{DiscardAll, MessageIntent, Validator, ValidatorContext use futures::prelude::*; use sc_network::{Event, ExHashT, NetworkService, PeerId, ReputationChange}; -use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use sp_runtime::{traits::Block as BlockT}; use std::{borrow::Cow, pin::Pin, sync::Arc}; mod bridge; @@ -79,15 +79,14 @@ pub trait Network { fn disconnect_peer(&self, who: PeerId); /// Send a notification to a peer. - fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec); + fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec); /// Registers a notifications protocol. /// /// See the documentation of [`NetworkService:register_notifications_protocol`] for more information. fn register_notifications_protocol( &self, - engine_id: ConsensusEngineId, - protocol_name: Cow<'static, str>, + protocol: Cow<'static, str>, ); /// Notify everyone we're connected to that we have the given block. @@ -110,16 +109,15 @@ impl Network for Arc> { NetworkService::disconnect_peer(self, who) } - fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec) { - NetworkService::write_notification(self, who, engine_id, message) + fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec) { + NetworkService::write_notification(self, who, protocol, message) } fn register_notifications_protocol( &self, - engine_id: ConsensusEngineId, - protocol_name: Cow<'static, str>, + protocol: Cow<'static, str>, ) { - NetworkService::register_notifications_protocol(self, engine_id, protocol_name) + NetworkService::register_notifications_protocol(self, protocol) } fn announce(&self, block: B::Hash, associated_data: Vec) { diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 60c669ecb66..8bd6d9df019 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -18,6 +18,7 @@ use crate::{Network, MessageIntent, Validator, ValidatorContext, ValidationResult}; +use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::iter; @@ -26,7 +27,6 @@ use log::{error, trace}; use lru::LruCache; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; -use sp_runtime::ConsensusEngineId; use sc_network::ObservedRole; use wasm_timer::Instant; @@ -89,7 +89,7 @@ impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { /// Send addressed message to a peer. fn send_message(&mut self, who: &PeerId, message: Vec) { - self.network.write_notification(who.clone(), self.gossip.engine_id, message); + self.network.write_notification(who.clone(), self.gossip.protocol.clone(), message); } /// Send all messages with given topic to a peer. @@ -100,7 +100,7 @@ impl<'g, 'p, B: BlockT> ValidatorContext for NetworkContext<'g, 'p, B> { fn propagate<'a, B: BlockT, I>( network: &mut dyn Network, - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, messages: I, intent: MessageIntent, peers: &mut HashMap>, @@ -138,7 +138,7 @@ fn propagate<'a, B: BlockT, I>( peer.known_messages.insert(message_hash.clone()); trace!(target: "gossip", "Propagating to {}: {:?}", id, message); - network.write_notification(id.clone(), engine_id, message.clone()); + network.write_notification(id.clone(), protocol.clone(), message.clone()); } } } @@ -148,19 +148,19 @@ pub struct ConsensusGossip { peers: HashMap>, messages: Vec>, known_messages: LruCache, - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, validator: Arc>, next_broadcast: Instant, } impl ConsensusGossip { /// Create a new instance using the given validator. - pub fn new(validator: Arc>, engine_id: ConsensusEngineId) -> Self { + pub fn new(validator: Arc>, protocol: Cow<'static, str>) -> Self { ConsensusGossip { peers: HashMap::new(), messages: Default::default(), known_messages: LruCache::new(KNOWN_MESSAGES_CACHE_SIZE), - engine_id, + protocol, validator, next_broadcast: Instant::now() + REBROADCAST_INTERVAL, } @@ -235,7 +235,14 @@ impl ConsensusGossip { fn rebroadcast(&mut self, network: &mut dyn Network) { let messages = self.messages.iter() .map(|entry| (&entry.message_hash, &entry.topic, &entry.message)); - propagate(network, self.engine_id, messages, MessageIntent::PeriodicRebroadcast, &mut self.peers, &self.validator); + propagate( + network, + self.protocol.clone(), + messages, + MessageIntent::PeriodicRebroadcast, + &mut self.peers, + &self.validator + ); } /// Broadcast all messages with given topic. @@ -247,7 +254,7 @@ impl ConsensusGossip { } else { None } ); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; - propagate(network, self.engine_id, messages, intent, &mut self.peers, &self.validator); + propagate(network, self.protocol.clone(), messages, intent, &mut self.peers, &self.validator); } /// Prune old or no longer relevant consensus messages. Provide a predicate @@ -374,7 +381,7 @@ impl ConsensusGossip { peer.known_messages.insert(entry.message_hash.clone()); trace!(target: "gossip", "Sending topic message to {}: {:?}", who, entry.message); - network.write_notification(who.clone(), self.engine_id, entry.message.clone()); + network.write_notification(who.clone(), self.protocol.clone(), entry.message.clone()); } } } @@ -390,7 +397,14 @@ impl ConsensusGossip { let message_hash = HashFor::::hash(&message); self.register_message_hashed(message_hash, topic, message.clone(), None); let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast }; - propagate(network, self.engine_id, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validator); + propagate( + network, + self.protocol.clone(), + iter::once((&message_hash, &topic, &message)), + intent, + &mut self.peers, + &self.validator + ); } /// Send addressed message to a peer. The message is not kept or multicast @@ -411,7 +425,7 @@ impl ConsensusGossip { trace!(target: "gossip", "Sending direct to {}: {:?}", who, message); peer.known_messages.insert(message_hash); - network.write_notification(who.clone(), self.engine_id, message); + network.write_notification(who.clone(), self.protocol.clone(), message); } } @@ -485,11 +499,11 @@ mod tests { unimplemented!(); } - fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec) { + fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec) { unimplemented!(); } - fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, str>) {} + fn register_notifications_protocol(&self, _: Cow<'static, str>) {} fn announce(&self, _: B::Hash, _: Vec) { unimplemented!(); @@ -520,7 +534,7 @@ mod tests { let prev_hash = H256::random(); let best_hash = H256::random(); - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), "/foo".into()); let m1_hash = H256::random(); let m2_hash = H256::random(); let m1 = vec![1, 2, 3]; @@ -547,7 +561,7 @@ mod tests { #[test] fn message_stream_include_those_sent_before_asking() { - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), "/foo".into()); // Register message. let message = vec![4, 5, 6]; @@ -562,7 +576,7 @@ mod tests { #[test] fn can_keep_multiple_messages_per_topic() { - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), "/foo".into()); let topic = [1; 32].into(); let msg_a = vec![1, 2, 3]; @@ -576,7 +590,7 @@ mod tests { #[test] fn peer_is_removed_on_disconnect() { - let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), [0, 0, 0, 0]); + let mut consensus = ConsensusGossip::::new(Arc::new(AllowAll), "/foo".into()); let mut network = NoOpNetwork::default(); @@ -592,7 +606,7 @@ mod tests { fn on_incoming_ignores_discarded_messages() { let to_forward = ConsensusGossip::::new( Arc::new(DiscardAll), - [0, 0, 0, 0], + "/foo".into(), ).on_incoming( &mut NoOpNetwork::default(), PeerId::random(), @@ -612,7 +626,7 @@ mod tests { let to_forward = ConsensusGossip::::new( Arc::new(AllowAll), - [0, 0, 0, 0], + "/foo".into(), ).on_incoming( &mut network, // Unregistered peer. diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index c8684eba625..41723d9068c 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -30,7 +30,7 @@ use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; -use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; +use sp_runtime::{traits::{Block as BlockT, NumberFor}, Justification}; use std::{ borrow::Cow, collections::{HashSet, VecDeque}, @@ -131,7 +131,7 @@ pub enum BehaviourOut { /// Node we opened the substream with. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, /// Object that permits sending notifications to the peer. notifications_sink: NotificationsSink, /// Role of the remote. @@ -147,7 +147,7 @@ pub enum BehaviourOut { /// Id of the peer we are connected to. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, /// Replacement for the previous [`NotificationsSink`]. notifications_sink: NotificationsSink, }, @@ -158,7 +158,7 @@ pub enum BehaviourOut { /// Node we closed the substream with. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, }, /// Received one or more messages from the given node using the given protocol. @@ -166,7 +166,7 @@ pub enum BehaviourOut { /// Node we received the message from. remote: PeerId, /// Concerned protocol and associated message. - messages: Vec<(ConsensusEngineId, Bytes)>, + messages: Vec<(Cow<'static, str>, Bytes)>, }, /// Events generated by a DHT as a response to get_value or put_value requests as well as the @@ -257,19 +257,20 @@ impl Behaviour { /// will retain the protocols that were registered then, and not any new one. pub fn register_notifications_protocol( &mut self, - engine_id: ConsensusEngineId, - protocol_name: impl Into>, + protocol: impl Into>, ) { + let protocol = protocol.into(); + // This is the message that we will send to the remote as part of the initial handshake. // At the moment, we force this to be an encoded `Roles`. let handshake_message = Roles::from(&self.role).encode(); - let list = self.substrate.register_notifications_protocol(engine_id, protocol_name, handshake_message); + let list = self.substrate.register_notifications_protocol(protocol.clone(), handshake_message); for (remote, roles, notifications_sink) in list { let role = reported_roles_to_observed_role(&self.role, remote, roles); self.events.push_back(BehaviourOut::NotificationStreamOpened { remote: remote.clone(), - engine_id, + protocol: protocol.clone(), role, notifications_sink: notifications_sink.clone(), }); @@ -363,28 +364,28 @@ Behaviour { }, CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles, notifications_sink } => { let role = reported_roles_to_observed_role(&self.role, &remote, roles); - for engine_id in protocols { + for protocol in protocols { self.events.push_back(BehaviourOut::NotificationStreamOpened { remote: remote.clone(), - engine_id, + protocol, role: role.clone(), notifications_sink: notifications_sink.clone(), }); } }, CustomMessageOutcome::NotificationStreamReplaced { remote, protocols, notifications_sink } => - for engine_id in protocols { + for protocol in protocols { self.events.push_back(BehaviourOut::NotificationStreamReplaced { remote: remote.clone(), - engine_id, + protocol, notifications_sink: notifications_sink.clone(), }); }, CustomMessageOutcome::NotificationStreamClosed { remote, protocols } => - for engine_id in protocols { + for protocol in protocols { self.events.push_back(BehaviourOut::NotificationStreamClosed { remote: remote.clone(), - engine_id, + protocol, }); }, CustomMessageOutcome::NotificationsReceived { remote, messages } => { diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 86450dc6e79..db33623a2e3 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -41,7 +41,7 @@ use libp2p::{ }; use prometheus_endpoint::Registry; use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; -use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use sp_runtime::traits::Block as BlockT; use std::{borrow::Cow, convert::TryFrom, future::Future, pin::Pin, str::FromStr}; use std::{ collections::HashMap, @@ -400,9 +400,8 @@ pub struct NetworkConfiguration { pub boot_nodes: Vec, /// The node key configuration, which determines the node's network identity keypair. pub node_key: NodeKeyConfig, - /// List of notifications protocols that the node supports. Must also include a - /// `ConsensusEngineId` for backwards-compatibility. - pub notifications_protocols: Vec<(ConsensusEngineId, Cow<'static, str>)>, + /// List of names of notifications protocols that the node supports. + pub notifications_protocols: Vec>, /// List of request-response protocols that the node supports. pub request_response_protocols: Vec, /// Maximum allowed number of incoming connections. diff --git a/client/network/src/gossip.rs b/client/network/src/gossip.rs index 9d20229288a..ac3f92e9d37 100644 --- a/client/network/src/gossip.rs +++ b/client/network/src/gossip.rs @@ -53,8 +53,9 @@ use async_std::sync::{Mutex, MutexGuard}; use futures::prelude::*; use futures::channel::mpsc::{channel, Receiver, Sender}; use libp2p::PeerId; -use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use sp_runtime::traits::Block as BlockT; use std::{ + borrow::Cow, collections::VecDeque, fmt, sync::Arc, @@ -82,7 +83,7 @@ impl QueuedSender { pub fn new( service: Arc>, peer_id: PeerId, - protocol: ConsensusEngineId, + protocol: Cow<'static, str>, queue_size_limit: usize, messages_encode: F ) -> (Self, impl Future + Send + 'static) @@ -193,7 +194,7 @@ async fn create_background_future Vec> mut wait_for_sender: Receiver<()>, service: Arc>, peer_id: PeerId, - protocol: ConsensusEngineId, + protocol: Cow<'static, str>, shared_message_queue: SharedMessageQueue, messages_encode: F, ) { @@ -212,7 +213,7 @@ async fn create_background_future Vec> // Starting from below, we try to send the message. If an error happens when sending, // the only sane option we have is to silently discard the message. - let sender = match service.notification_sender(peer_id.clone(), protocol) { + let sender = match service.notification_sender(peer_id.clone(), protocol.clone()) { Ok(s) => s, Err(_) => continue, }; diff --git a/client/network/src/gossip/tests.rs b/client/network/src/gossip/tests.rs index 0f01ed81bff..e94052c0e4d 100644 --- a/client/network/src/gossip/tests.rs +++ b/client/network/src/gossip/tests.rs @@ -20,7 +20,7 @@ use crate::{config, gossip::QueuedSender, Event, NetworkService, NetworkWorker}; use futures::prelude::*; use sp_runtime::traits::{Block as BlockT, Header as _}; -use std::{sync::Arc, time::Duration}; +use std::{borrow::Cow, sync::Arc, time::Duration}; use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt as _}; type TestNetworkService = NetworkService< @@ -120,24 +120,24 @@ fn build_test_full_node(config: config::NetworkConfiguration) (service, event_stream) } -const ENGINE_ID: sp_runtime::ConsensusEngineId = *b"foo\0"; +const PROTOCOL_NAME: Cow<'static, str> = Cow::Borrowed("/foo"); /// Builds two nodes and their associated events stream. -/// The nodes are connected together and have the `ENGINE_ID` protocol registered. +/// The nodes are connected together and have the `PROTOCOL_NAME` protocol registered. fn build_nodes_one_proto() -> (Arc, impl Stream, Arc, impl Stream) { let listen_addr = config::build_multiaddr![Memory(rand::random::())]; let (node1, events_stream1) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![listen_addr.clone()], transport: config::TransportConfig::MemoryOnly, .. config::NetworkConfiguration::new_local() }); let (node2, events_stream2) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![], reserved_nodes: vec![config::MultiaddrWithPeerId { multiaddr: listen_addr, @@ -165,7 +165,7 @@ fn basic_works() { Event::NotificationStreamClosed { .. } => panic!(), Event::NotificationsReceived { messages, .. } => { for message in messages { - assert_eq!(message.0, ENGINE_ID); + assert_eq!(message.0, PROTOCOL_NAME); assert_eq!(message.1, &b"message"[..]); received_notifications += 1; } @@ -181,7 +181,7 @@ fn basic_works() { async_std::task::block_on(async move { let (mut sender, bg_future) = - QueuedSender::new(node1, node2_id, ENGINE_ID, NUM_NOTIFS, |msg| msg); + QueuedSender::new(node1, node2_id, PROTOCOL_NAME, NUM_NOTIFS, |msg| msg); async_std::task::spawn(bg_future); // Wait for the `NotificationStreamOpened`. diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 9403e471b0f..d0b6b2823a2 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -37,7 +37,7 @@ use sp_consensus::{ import_queue::{BlockImportResult, BlockImportError, IncomingBlock, Origin} }; use codec::{Decode, DecodeAll, Encode}; -use sp_runtime::{generic::BlockId, ConsensusEngineId, Justification}; +use sp_runtime::{generic::BlockId, Justification}; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, Zero, CheckedSub }; @@ -231,8 +231,8 @@ pub struct Protocol { transaction_pool: Arc>, /// Handles opening the unique substream and sending and receiving raw messages. behaviour: GenericProto, - /// For each legacy gossiping engine ID, the corresponding new protocol name. - protocol_name_by_engine: HashMap>, + /// List of notifications protocols that have been registered. + notification_protocols: Vec>, /// For each protocol name, the legacy equivalent. legacy_equiv_by_name: HashMap, Fallback>, /// Name of the protocol used for transactions. @@ -252,6 +252,7 @@ struct PacketStats { count_in: u64, count_out: u64, } + /// Peer information #[derive(Debug, Clone)] struct Peer { @@ -349,8 +350,8 @@ fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc /// Fallback mechanism to use to send a notification if no substream is open. #[derive(Debug, Clone, PartialEq, Eq)] enum Fallback { - /// Use a `Message::Consensus` with the given engine ID. - Consensus(ConsensusEngineId), + /// Formerly-known as `Consensus` messages. Now regular notifications. + Consensus, /// The message is the bytes encoding of a `Transactions` (which is itself defined as a `Vec`). Transactions, /// The message is the bytes encoding of a `BlockAnnounce`. @@ -446,7 +447,7 @@ impl Protocol { transaction_pool, peerset_handle: peerset_handle.clone(), behaviour, - protocol_name_by_engine: HashMap::new(), + notification_protocols: Vec::new(), legacy_equiv_by_name, transactions_protocol, block_announces_protocol, @@ -621,7 +622,9 @@ impl Protocol { GenericMessage::RemoteCallRequest(_) | GenericMessage::RemoteReadRequest(_) | GenericMessage::RemoteHeaderRequest(_) | - GenericMessage::RemoteChangesRequest(_) => { + GenericMessage::RemoteChangesRequest(_) | + GenericMessage::Consensus(_) | + GenericMessage::ConsensusBatch(_) => { debug!( target: "sub-libp2p", "Received no longer supported legacy request from {:?}", @@ -630,38 +633,6 @@ impl Protocol { self.disconnect_peer(&who); self.peerset_handle.report_peer(who, rep::BAD_PROTOCOL); }, - GenericMessage::Consensus(msg) => - return if self.protocol_name_by_engine.contains_key(&msg.engine_id) { - CustomMessageOutcome::NotificationsReceived { - remote: who, - messages: vec![(msg.engine_id, From::from(msg.data))], - } - } else { - debug!(target: "sync", "Received message on non-registered protocol: {:?}", msg.engine_id); - CustomMessageOutcome::None - }, - GenericMessage::ConsensusBatch(messages) => { - let messages = messages - .into_iter() - .filter_map(|msg| { - if self.protocol_name_by_engine.contains_key(&msg.engine_id) { - Some((msg.engine_id, From::from(msg.data))) - } else { - debug!(target: "sync", "Received message on non-registered protocol: {:?}", msg.engine_id); - None - } - }) - .collect::>(); - - return if !messages.is_empty() { - CustomMessageOutcome::NotificationsReceived { - remote: who, - messages, - } - } else { - CustomMessageOutcome::None - }; - }, } CustomMessageOutcome::None @@ -685,7 +656,7 @@ impl Protocol { // Notify all the notification protocols as closed. CustomMessageOutcome::NotificationStreamClosed { remote: peer, - protocols: self.protocol_name_by_engine.keys().cloned().collect(), + protocols: self.notification_protocols.clone(), } } else { CustomMessageOutcome::None @@ -939,7 +910,7 @@ impl Protocol { // Notify all the notification protocols as open. CustomMessageOutcome::NotificationStreamOpened { remote: who, - protocols: self.protocol_name_by_engine.keys().cloned().collect(), + protocols: self.notification_protocols.clone(), roles: info.roles, notifications_sink, } @@ -952,16 +923,17 @@ impl Protocol { /// returns a list of substreams to open as a result. pub fn register_notifications_protocol<'a>( &'a mut self, - engine_id: ConsensusEngineId, - protocol_name: impl Into>, + protocol: impl Into>, handshake_message: Vec, ) -> impl Iterator + 'a { - let protocol_name = protocol_name.into(); - if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() { - error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name); + let protocol = protocol.into(); + + if self.notification_protocols.iter().any(|p| *p == protocol) { + error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol); } else { - self.behaviour.register_notif_protocol(protocol_name.clone(), handshake_message); - self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id)); + self.notification_protocols.push(protocol.clone()); + self.behaviour.register_notif_protocol(protocol.clone(), handshake_message); + self.legacy_equiv_by_name.insert(protocol, Fallback::Consensus); } let behaviour = &self.behaviour; @@ -1450,20 +1422,20 @@ pub enum CustomMessageOutcome { /// Notification protocols have been opened with a remote. NotificationStreamOpened { remote: PeerId, - protocols: Vec, + protocols: Vec>, roles: Roles, notifications_sink: NotificationsSink }, /// The [`NotificationsSink`] of some notification protocols need an update. NotificationStreamReplaced { remote: PeerId, - protocols: Vec, + protocols: Vec>, notifications_sink: NotificationsSink, }, /// Notification protocols have been closed with a remote. - NotificationStreamClosed { remote: PeerId, protocols: Vec }, + NotificationStreamClosed { remote: PeerId, protocols: Vec> }, /// Messages have been received on one or more notifications protocols. - NotificationsReceived { remote: PeerId, messages: Vec<(ConsensusEngineId, Bytes)> }, + NotificationsReceived { remote: PeerId, messages: Vec<(Cow<'static, str>, Bytes)> }, /// A new block request must be emitted. /// You must later call either [`Protocol::on_block_response`] or /// [`Protocol::on_block_request_failed`]. @@ -1664,7 +1636,7 @@ impl NetworkBehaviour for Protocol { GenericProtoOut::CustomProtocolReplaced { peer_id, notifications_sink, .. } => { CustomMessageOutcome::NotificationStreamReplaced { remote: peer_id, - protocols: self.protocol_name_by_engine.keys().cloned().collect(), + protocols: self.notification_protocols.clone(), notifications_sink, } }, @@ -1675,10 +1647,10 @@ impl NetworkBehaviour for Protocol { self.on_custom_message(peer_id, message), GenericProtoOut::Notification { peer_id, protocol_name, message } => match self.legacy_equiv_by_name.get(&protocol_name) { - Some(Fallback::Consensus(engine_id)) => { + Some(Fallback::Consensus) => { CustomMessageOutcome::NotificationsReceived { remote: peer_id, - messages: vec![(*engine_id, message.freeze())], + messages: vec![(protocol_name, message.freeze())], } } Some(Fallback::Transactions) => { diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index 637bf805b50..86cb93bef26 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -20,7 +20,7 @@ use bytes::Bytes; use libp2p::core::PeerId; use libp2p::kad::record::Key; -use sp_runtime::ConsensusEngineId; +use std::borrow::Cow; /// Events generated by DHT as a response to get_value and put_value requests. #[derive(Debug, Clone)] @@ -53,7 +53,7 @@ pub enum Event { /// Node we opened the substream with. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, /// Role of the remote. role: ObservedRole, }, @@ -64,7 +64,7 @@ pub enum Event { /// Node we closed the substream with. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, }, /// Received one or more messages from the given node using the given protocol. @@ -72,7 +72,7 @@ pub enum Event { /// Node we received the message from. remote: PeerId, /// Concerned protocol and associated message. - messages: Vec<(ConsensusEngineId, Bytes)>, + messages: Vec<(Cow<'static, str>, Bytes)>, }, } diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index 1cd78c0ed1d..dae7b86db87 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -216,7 +216,7 @@ pub mod generic { #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct ConsensusMessage { /// Identifies consensus engine. - pub engine_id: ConsensusEngineId, + pub protocol: ConsensusEngineId, /// Message payload. pub data: Vec, } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 5fc8485947f..3296a97d71b 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -53,10 +53,7 @@ use metrics::{Metrics, MetricSources, Histogram, HistogramVec}; use parking_lot::Mutex; use sc_peerset::PeersetHandle; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; -use sp_runtime::{ - traits::{Block as BlockT, NumberFor}, - ConsensusEngineId, -}; +use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use std::{ borrow::Cow, @@ -100,9 +97,7 @@ pub struct NetworkService { to_worker: TracingUnboundedSender>, /// For each peer and protocol combination, an object that allows sending notifications to /// that peer. Updated by the [`NetworkWorker`]. - peers_notifications_sinks: Arc>>, - /// For each legacy gossiping engine ID, the corresponding new protocol name. - protocol_name_by_engine: Mutex>>, + peers_notifications_sinks: Arc), NotificationsSink>>>, /// Field extracted from the [`Metrics`] struct and necessary to report the /// notifications-related metrics. notifications_sizes_metric: Option, @@ -331,8 +326,8 @@ impl NetworkWorker { } }; - for (engine_id, protocol_name) in ¶ms.network_config.notifications_protocols { - behaviour.register_notifications_protocol(*engine_id, protocol_name.clone()); + for protocol in ¶ms.network_config.notifications_protocols { + behaviour.register_notifications_protocol(protocol.clone()); } let (transport, bandwidth) = { let (config_mem, config_wasm) = match params.network_config.transport { @@ -384,9 +379,6 @@ impl NetworkWorker { let external_addresses = Arc::new(Mutex::new(Vec::new())); let peers_notifications_sinks = Arc::new(Mutex::new(HashMap::new())); - let protocol_name_by_engine = Mutex::new({ - params.network_config.notifications_protocols.iter().cloned().collect() - }); let service = Arc::new(NetworkService { bandwidth, @@ -397,7 +389,6 @@ impl NetworkWorker { local_peer_id, to_worker, peers_notifications_sinks: peers_notifications_sinks.clone(), - protocol_name_by_engine, notifications_sizes_metric: metrics.as_ref().map(|metrics| metrics.notifications_sizes.clone()), _marker: PhantomData, @@ -640,40 +631,32 @@ impl NetworkService { /// The protocol must have been registered with `register_notifications_protocol` or /// [`NetworkConfiguration::notifications_protocols`](crate::config::NetworkConfiguration::notifications_protocols). /// - pub fn write_notification(&self, target: PeerId, engine_id: ConsensusEngineId, message: Vec) { + pub fn write_notification(&self, target: PeerId, protocol: Cow<'static, str>, message: Vec) { // We clone the `NotificationsSink` in order to be able to unlock the network-wide // `peers_notifications_sinks` mutex as soon as possible. let sink = { let peers_notifications_sinks = self.peers_notifications_sinks.lock(); - if let Some(sink) = peers_notifications_sinks.get(&(target, engine_id)) { + if let Some(sink) = peers_notifications_sinks.get(&(target, protocol.clone())) { sink.clone() } else { // Notification silently discarded, as documented. + log::error!( + target: "sub-libp2p", + "Attempted to send notification on unknown protocol: {:?}", + protocol, + ); return; } }; - // Used later for the metrics report. - let message_len = message.len(); - - // Determine the wire protocol name corresponding to this `engine_id`. - let protocol_name = self.protocol_name_by_engine.lock().get(&engine_id).cloned(); - if let Some(protocol_name) = protocol_name { - sink.send_sync_notification(protocol_name, message); - } else { - log::error!( - target: "sub-libp2p", - "Attempted to send notification on unknown protocol: {:?}", - engine_id, - ); - return; - } - if let Some(notifications_sizes_metric) = self.notifications_sizes_metric.as_ref() { notifications_sizes_metric - .with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) - .observe(message_len as f64); + .with_label_values(&["out", &protocol]) + .observe(message.len() as f64); } + + // Sending is communicated to the `NotificationsSink`. + sink.send_sync_notification(protocol, message); } /// Obtains a [`NotificationSender`] for a connected peer, if it exists. @@ -746,31 +729,27 @@ impl NetworkService { pub fn notification_sender( &self, target: PeerId, - engine_id: ConsensusEngineId, + protocol: Cow<'static, str>, ) -> Result { // We clone the `NotificationsSink` in order to be able to unlock the network-wide // `peers_notifications_sinks` mutex as soon as possible. let sink = { let peers_notifications_sinks = self.peers_notifications_sinks.lock(); - if let Some(sink) = peers_notifications_sinks.get(&(target, engine_id)) { + if let Some(sink) = peers_notifications_sinks.get(&(target, protocol.clone())) { sink.clone() } else { return Err(NotificationSenderError::Closed); } }; - // Determine the wire protocol name corresponding to this `engine_id`. - let protocol_name = match self.protocol_name_by_engine.lock().get(&engine_id).cloned() { - Some(p) => p, - None => return Err(NotificationSenderError::BadProtocol), - }; + let notification_size_metric = self.notifications_sizes_metric.as_ref().map(|histogram| { + histogram.with_label_values(&["out", &protocol]) + }); Ok(NotificationSender { sink, - protocol_name, - notification_size_metric: self.notifications_sizes_metric.as_ref().map(|histogram| { - histogram.with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) - }), + protocol_name: protocol, + notification_size_metric, }) } @@ -841,17 +820,13 @@ impl NetworkService { /// /// Please call `event_stream` before registering a protocol, otherwise you may miss events /// about the protocol that you have registered. - // TODO: remove this method after https://github.com/paritytech/substrate/issues/4587 + // TODO: remove this method after https://github.com/paritytech/substrate/issues/6827 pub fn register_notifications_protocol( &self, - engine_id: ConsensusEngineId, protocol_name: impl Into>, ) { - let protocol_name = protocol_name.into(); - self.protocol_name_by_engine.lock().insert(engine_id, protocol_name.clone()); let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::RegisterNotifProtocol { - engine_id, - protocol_name, + protocol_name: protocol_name.into(), }); } @@ -1209,7 +1184,6 @@ enum ServiceToWorkerMsg { pending_response: oneshot::Sender, RequestFailure>>, }, RegisterNotifProtocol { - engine_id: ConsensusEngineId, protocol_name: Cow<'static, str>, }, DisconnectPeer(PeerId), @@ -1253,7 +1227,7 @@ pub struct NetworkWorker { >, /// For each peer and protocol combination, an object that allows sending notifications to /// that peer. Shared with the [`NetworkService`]. - peers_notifications_sinks: Arc>>, + peers_notifications_sinks: Arc), NotificationsSink>>>, } impl Future for NetworkWorker { @@ -1347,10 +1321,8 @@ impl Future for NetworkWorker { }, } }, - ServiceToWorkerMsg::RegisterNotifProtocol { engine_id, protocol_name } => { - this.network_service - .register_notifications_protocol(engine_id, protocol_name); - }, + ServiceToWorkerMsg::RegisterNotifProtocol { protocol_name } => + this.network_service.register_notifications_protocol(protocol_name), ServiceToWorkerMsg::DisconnectPeer(who) => this.network_service.user_protocol_mut().disconnect_peer(&who), ServiceToWorkerMsg::UpdateChain => @@ -1474,24 +1446,28 @@ impl Future for NetworkWorker { .inc(); } }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamOpened { remote, engine_id, notifications_sink, role })) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamOpened { + remote, protocol, notifications_sink, role + })) => { if let Some(metrics) = this.metrics.as_ref() { metrics.notifications_streams_opened_total - .with_label_values(&[&maybe_utf8_bytes_to_string(&engine_id)]).inc(); + .with_label_values(&[&protocol]).inc(); } { let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); - peers_notifications_sinks.insert((remote.clone(), engine_id), notifications_sink); + peers_notifications_sinks.insert((remote.clone(), protocol.clone()), notifications_sink); } this.event_streams.send(Event::NotificationStreamOpened { remote, - engine_id, + protocol, role, }); }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamReplaced { remote, engine_id, notifications_sink })) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamReplaced { + remote, protocol, notifications_sink + })) => { let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); - if let Some(s) = peers_notifications_sinks.get_mut(&(remote, engine_id)) { + if let Some(s) = peers_notifications_sinks.get_mut(&(remote, protocol)) { *s = notifications_sink; } else { log::error!( @@ -1513,33 +1489,33 @@ impl Future for NetworkWorker { // https://github.com/paritytech/substrate/issues/6403. /*this.event_streams.send(Event::NotificationStreamClosed { remote, - engine_id, + protocol, }); this.event_streams.send(Event::NotificationStreamOpened { remote, - engine_id, + protocol, role, });*/ }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamClosed { remote, engine_id })) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamClosed { remote, protocol })) => { if let Some(metrics) = this.metrics.as_ref() { metrics.notifications_streams_closed_total - .with_label_values(&[&maybe_utf8_bytes_to_string(&engine_id[..])]).inc(); + .with_label_values(&[&protocol[..]]).inc(); } this.event_streams.send(Event::NotificationStreamClosed { remote: remote.clone(), - engine_id, + protocol: protocol.clone(), }); { let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); - peers_notifications_sinks.remove(&(remote.clone(), engine_id)); + peers_notifications_sinks.remove(&(remote.clone(), protocol)); } }, Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationsReceived { remote, messages })) => { if let Some(metrics) = this.metrics.as_ref() { - for (engine_id, message) in &messages { + for (protocol, message) in &messages { metrics.notifications_sizes - .with_label_values(&["in", &maybe_utf8_bytes_to_string(engine_id)]) + .with_label_values(&["in", protocol]) .observe(message.len() as f64); } } @@ -1748,17 +1724,6 @@ impl Future for NetworkWorker { impl Unpin for NetworkWorker { } -/// Turns bytes that are potentially UTF-8 into a reasonable representable string. -/// -/// Meant to be used only for debugging or metrics-reporting purposes. -pub(crate) fn maybe_utf8_bytes_to_string(id: &[u8]) -> Cow { - if let Ok(s) = std::str::from_utf8(&id[..]) { - Cow::Borrowed(s) - } else { - Cow::Owned(format!("{:?}", id)) - } -} - /// The libp2p swarm, customized for our needs. type Swarm = libp2p::swarm::Swarm>; diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index 1b86a5fa431..976548f6ed4 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -33,7 +33,6 @@ //! use crate::Event; -use super::maybe_utf8_bytes_to_string; use futures::{prelude::*, channel::mpsc, ready, stream::FusedStream}; use parking_lot::Mutex; @@ -228,23 +227,23 @@ impl Metrics { .with_label_values(&["dht", "sent", name]) .inc_by(num); } - Event::NotificationStreamOpened { engine_id, .. } => { + Event::NotificationStreamOpened { protocol, .. } => { self.events_total - .with_label_values(&[&format!("notif-open-{:?}", engine_id), "sent", name]) + .with_label_values(&[&format!("notif-open-{:?}", protocol), "sent", name]) .inc_by(num); }, - Event::NotificationStreamClosed { engine_id, .. } => { + Event::NotificationStreamClosed { protocol, .. } => { self.events_total - .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "sent", name]) + .with_label_values(&[&format!("notif-closed-{:?}", protocol), "sent", name]) .inc_by(num); }, Event::NotificationsReceived { messages, .. } => { - for (engine_id, message) in messages { + for (protocol, message) in messages { self.events_total - .with_label_values(&[&format!("notif-{:?}", engine_id), "sent", name]) + .with_label_values(&[&format!("notif-{:?}", protocol), "sent", name]) .inc_by(num); self.notifications_sizes - .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id), "sent", name]) + .with_label_values(&[protocol, "sent", name]) .inc_by(num.saturating_mul(u64::try_from(message.len()).unwrap_or(u64::max_value()))); } }, @@ -258,23 +257,23 @@ impl Metrics { .with_label_values(&["dht", "received", name]) .inc(); } - Event::NotificationStreamOpened { engine_id, .. } => { + Event::NotificationStreamOpened { protocol, .. } => { self.events_total - .with_label_values(&[&format!("notif-open-{:?}", engine_id), "received", name]) + .with_label_values(&[&format!("notif-open-{:?}", protocol), "received", name]) .inc(); }, - Event::NotificationStreamClosed { engine_id, .. } => { + Event::NotificationStreamClosed { protocol, .. } => { self.events_total - .with_label_values(&[&format!("notif-closed-{:?}", engine_id), "received", name]) + .with_label_values(&[&format!("notif-closed-{:?}", protocol), "received", name]) .inc(); }, Event::NotificationsReceived { messages, .. } => { - for (engine_id, message) in messages { + for (protocol, message) in messages { self.events_total - .with_label_values(&[&format!("notif-{:?}", engine_id), "received", name]) + .with_label_values(&[&format!("notif-{:?}", protocol), "received", name]) .inc(); self.notifications_sizes - .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id), "received", name]) + .with_label_values(&[&protocol, "received", name]) .inc_by(u64::try_from(message.len()).unwrap_or(u64::max_value())); } }, diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 4b6f9dd1564..76a924748ad 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -21,7 +21,7 @@ use crate::{config, Event, NetworkService, NetworkWorker}; use libp2p::PeerId; use futures::prelude::*; use sp_runtime::traits::{Block as BlockT, Header as _}; -use std::{sync::Arc, time::Duration}; +use std::{borrow::Cow, sync::Arc, time::Duration}; use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt as _}; type TestNetworkService = NetworkService< @@ -121,24 +121,24 @@ fn build_test_full_node(config: config::NetworkConfiguration) (service, event_stream) } -const ENGINE_ID: sp_runtime::ConsensusEngineId = *b"foo\0"; +const PROTOCOL_NAME: Cow<'static, str> = Cow::Borrowed("/foo"); /// Builds two nodes and their associated events stream. -/// The nodes are connected together and have the `ENGINE_ID` protocol registered. +/// The nodes are connected together and have the `PROTOCOL_NAME` protocol registered. fn build_nodes_one_proto() -> (Arc, impl Stream, Arc, impl Stream) { let listen_addr = config::build_multiaddr![Memory(rand::random::())]; let (node1, events_stream1) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![listen_addr.clone()], transport: config::TransportConfig::MemoryOnly, .. config::NetworkConfiguration::new_local() }); let (node2, events_stream2) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![], reserved_nodes: vec![config::MultiaddrWithPeerId { multiaddr: listen_addr, @@ -161,10 +161,10 @@ fn notifications_state_consistent() { // Write some initial notifications that shouldn't get through. for _ in 0..(rand::random::() % 5) { - node1.write_notification(node2.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + node1.write_notification(node2.local_peer_id().clone(), PROTOCOL_NAME, b"hello world".to_vec()); } for _ in 0..(rand::random::() % 5) { - node2.write_notification(node1.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + node2.write_notification(node1.local_peer_id().clone(), PROTOCOL_NAME, b"hello world".to_vec()); } async_std::task::block_on(async move { @@ -187,10 +187,10 @@ fn notifications_state_consistent() { // Start by sending a notification from node1 to node2 and vice-versa. Part of the // test consists in ensuring that notifications get ignored if the stream isn't open. if rand::random::() % 5 >= 3 { - node1.write_notification(node2.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + node1.write_notification(node2.local_peer_id().clone(), PROTOCOL_NAME, b"hello world".to_vec()); } if rand::random::() % 5 >= 3 { - node2.write_notification(node1.local_peer_id().clone(), ENGINE_ID, b"hello world".to_vec()); + node2.write_notification(node1.local_peer_id().clone(), PROTOCOL_NAME, b"hello world".to_vec()); } // Also randomly disconnect the two nodes from time to time. @@ -219,31 +219,31 @@ fn notifications_state_consistent() { }; match next_event { - future::Either::Left(Event::NotificationStreamOpened { remote, engine_id, .. }) => { + future::Either::Left(Event::NotificationStreamOpened { remote, protocol, .. }) => { something_happened = true; assert!(!node1_to_node2_open); node1_to_node2_open = true; assert_eq!(remote, *node2.local_peer_id()); - assert_eq!(engine_id, ENGINE_ID); + assert_eq!(protocol, PROTOCOL_NAME); } - future::Either::Right(Event::NotificationStreamOpened { remote, engine_id, .. }) => { + future::Either::Right(Event::NotificationStreamOpened { remote, protocol, .. }) => { something_happened = true; assert!(!node2_to_node1_open); node2_to_node1_open = true; assert_eq!(remote, *node1.local_peer_id()); - assert_eq!(engine_id, ENGINE_ID); + assert_eq!(protocol, PROTOCOL_NAME); } - future::Either::Left(Event::NotificationStreamClosed { remote, engine_id, .. }) => { + future::Either::Left(Event::NotificationStreamClosed { remote, protocol, .. }) => { assert!(node1_to_node2_open); node1_to_node2_open = false; assert_eq!(remote, *node2.local_peer_id()); - assert_eq!(engine_id, ENGINE_ID); + assert_eq!(protocol, PROTOCOL_NAME); } - future::Either::Right(Event::NotificationStreamClosed { remote, engine_id, .. }) => { + future::Either::Right(Event::NotificationStreamClosed { remote, protocol, .. }) => { assert!(node2_to_node1_open); node2_to_node1_open = false; assert_eq!(remote, *node1.local_peer_id()); - assert_eq!(engine_id, ENGINE_ID); + assert_eq!(protocol, PROTOCOL_NAME); } future::Either::Left(Event::NotificationsReceived { remote, .. }) => { assert!(node1_to_node2_open); @@ -251,7 +251,7 @@ fn notifications_state_consistent() { if rand::random::() % 5 >= 4 { node1.write_notification( node2.local_peer_id().clone(), - ENGINE_ID, + PROTOCOL_NAME, b"hello world".to_vec() ); } @@ -262,7 +262,7 @@ fn notifications_state_consistent() { if rand::random::() % 5 >= 4 { node2.write_notification( node1.local_peer_id().clone(), - ENGINE_ID, + PROTOCOL_NAME, b"hello world".to_vec() ); } @@ -281,7 +281,7 @@ fn lots_of_incoming_peers_works() { let listen_addr = config::build_multiaddr![Memory(rand::random::())]; let (main_node, _) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![listen_addr.clone()], in_peers: u32::max_value(), transport: config::TransportConfig::MemoryOnly, @@ -298,7 +298,7 @@ fn lots_of_incoming_peers_works() { let main_node_peer_id = main_node_peer_id.clone(); let (_dialing_node, event_stream) = build_test_full_node(config::NetworkConfiguration { - notifications_protocols: vec![(ENGINE_ID, From::from("/foo"))], + notifications_protocols: vec![PROTOCOL_NAME], listen_addresses: vec![], reserved_nodes: vec![config::MultiaddrWithPeerId { multiaddr: listen_addr.clone(), @@ -364,7 +364,7 @@ fn notifications_back_pressure() { Event::NotificationStreamClosed { .. } => panic!(), Event::NotificationsReceived { messages, .. } => { for message in messages { - assert_eq!(message.0, ENGINE_ID); + assert_eq!(message.0, PROTOCOL_NAME); assert_eq!(message.1, format!("hello #{}", received_notifications)); received_notifications += 1; } @@ -389,7 +389,7 @@ fn notifications_back_pressure() { // Sending! for num in 0..TOTAL_NOTIFS { - let notif = node1.notification_sender(node2_id.clone(), ENGINE_ID).unwrap(); + let notif = node1.notification_sender(node2_id.clone(), PROTOCOL_NAME).unwrap(); notif.ready().await.unwrap().send(format!("hello #{}", num)).unwrap(); } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 587feebe55c..1aec3dae22b 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -58,7 +58,7 @@ use sp_core::H256; use sc_network::config::ProtocolConfig; use sp_runtime::generic::{BlockId, OpaqueDigestItemId}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use sp_runtime::{ConsensusEngineId, Justification}; +use sp_runtime::Justification; use substrate_test_runtime_client::{self, AccountKeyring}; use sc_service::client::Client; pub use sc_network::config::EmptyTransactionPool; @@ -557,7 +557,7 @@ pub struct FullPeerConfig { /// Block announce validator. pub block_announce_validator: Option + Send + Sync>>, /// List of notification protocols that the network must support. - pub notifications_protocols: Vec<(ConsensusEngineId, Cow<'static, str>)>, + pub notifications_protocols: Vec>, } pub trait TestNetFactory: Sized { -- GitLab From 9d65d983a08c59f4239965f4fb65bd7d0099c788 Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Thu, 19 Nov 2020 03:43:41 +0800 Subject: [PATCH 023/163] sc-cli: replace bip39 with tiny-bip39 (#7551) Signed-off-by: koushiro --- Cargo.lock | 99 ++++++------------------------------------- client/cli/Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a87dfec664..43af7d1a316 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ dependencies = [ "concurrent-queue", "fastrand", "futures-lite", - "once_cell 1.4.1", + "once_cell", "vec-arena", ] @@ -253,7 +253,7 @@ dependencies = [ "async-io", "futures-lite", "num_cpus", - "once_cell 1.4.1", + "once_cell", ] [[package]] @@ -268,7 +268,7 @@ dependencies = [ "futures-lite", "libc", "log", - "once_cell 1.4.1", + "once_cell", "parking", "polling", "socket2", @@ -307,7 +307,7 @@ dependencies = [ "log", "memchr", "num_cpus", - "once_cell 1.4.1", + "once_cell", "pin-project-lite", "pin-utils", "slab", @@ -454,21 +454,6 @@ dependencies = [ "which", ] -[[package]] -name = "bip39" -version = "0.6.0-beta.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4" -dependencies = [ - "failure", - "hashbrown 0.1.8", - "hmac 0.7.1", - "once_cell 0.1.8", - "pbkdf2 0.3.0", - "rand 0.6.5", - "sha2 0.8.2", -] - [[package]] name = "bitflags" version = "1.2.1" @@ -596,7 +581,7 @@ dependencies = [ "atomic-waker", "fastrand", "futures-lite", - "once_cell 1.4.1", + "once_cell", ] [[package]] @@ -1061,7 +1046,7 @@ dependencies = [ "lazy_static", "maybe-uninit", "memoffset", - "scopeguard 1.1.0", + "scopeguard", ] [[package]] @@ -1688,7 +1673,7 @@ dependencies = [ "frame-system", "impl-trait-for-tuples", "log", - "once_cell 1.4.1", + "once_cell", "parity-scale-codec", "parity-util-mem", "paste 0.1.18", @@ -1967,7 +1952,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" dependencies = [ - "once_cell 1.4.1", + "once_cell", ] [[package]] @@ -2197,16 +2182,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -dependencies = [ - "byteorder", - "scopeguard 0.3.3", -] - [[package]] name = "hashbrown" version = "0.6.3" @@ -3363,22 +3338,13 @@ dependencies = [ "paste 0.1.18", ] -[[package]] -name = "lock_api" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -dependencies = [ - "scopeguard 0.3.3", -] - [[package]] name = "lock_api" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" dependencies = [ - "scopeguard 1.1.0", + "scopeguard", ] [[package]] @@ -3387,7 +3353,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" dependencies = [ - "scopeguard 1.1.0", + "scopeguard", ] [[package]] @@ -4250,15 +4216,6 @@ dependencies = [ "wasmparser 0.57.0", ] -[[package]] -name = "once_cell" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -dependencies = [ - "parking_lot 0.7.1", -] - [[package]] name = "once_cell" version = "1.4.1" @@ -5334,16 +5291,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" -[[package]] -name = "parking_lot" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -dependencies = [ - "lock_api 0.1.5", - "parking_lot_core 0.4.0", -] - [[package]] name = "parking_lot" version = "0.9.0" @@ -5376,19 +5323,6 @@ dependencies = [ "parking_lot_core 0.8.0", ] -[[package]] -name = "parking_lot_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -dependencies = [ - "libc", - "rand 0.6.5", - "rustc_version", - "smallvec 0.6.13", - "winapi 0.3.9", -] - [[package]] name = "parking_lot_core" version = "0.6.2" @@ -5466,7 +5400,6 @@ checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ "byteorder", "crypto-mac 0.7.0", - "rayon", ] [[package]] @@ -6269,7 +6202,7 @@ checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" dependencies = [ "cc", "libc", - "once_cell 1.4.1", + "once_cell", "spin", "untrusted", "web-sys", @@ -6547,7 +6480,6 @@ version = "0.8.0" dependencies = [ "ansi_term 0.12.1", "atty", - "bip39", "chrono", "fdlimit", "futures 0.3.5", @@ -6580,6 +6512,7 @@ dependencies = [ "structopt", "tempfile", "thiserror", + "tiny-bip39", "tokio 0.2.22", "tracing", "tracing-log", @@ -7647,12 +7580,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" -[[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" - [[package]] name = "scopeguard" version = "1.1.0" @@ -9329,7 +9256,7 @@ checksum = "d9e44c4759bae7f1032e286a7ef990bd9ed23fe831b7eeba0beb97484c2e59b8" dependencies = [ "anyhow", "hmac 0.8.1", - "once_cell 1.4.1", + "once_cell", "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 942d30e90db..b0662c5eddf 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -25,7 +25,7 @@ libp2p = "0.30.1" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" -bip39 = "0.6.0-beta.1" +tiny-bip39 = "0.8.0" serde_json = "1.0.41" sc-keystore = { version = "2.0.0", path = "../keystore" } sp-panic-handler = { version = "2.0.0", path = "../../primitives/panic-handler" } -- GitLab From 69198d1e5735798c8baa1921c6e2091c93260752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 18 Nov 2020 21:10:00 +0100 Subject: [PATCH 024/163] Add extra docs to on_initialize (#7552) * Add some extra on_initialize docs. * Address review comments. --- frame/support/src/traits.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index bc1700a43c3..b40ebe3dba6 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1265,7 +1265,7 @@ pub trait ChangeMembers { Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); } - /// Compute diff between new and old members; they **must already be sorted**. + /// Compute diff between new and old members; they **must already be sorted**. /// /// Returns incoming and outgoing members. fn compute_members_diff( @@ -1427,6 +1427,9 @@ pub trait GetCallMetadata { #[impl_for_tuples(30)] pub trait OnFinalize { /// The block is being finalized. Implement to have something happen. + /// + /// NOTE: This function is called AFTER ALL extrinsics in a block are applied, + /// including inherent extrinsics. fn on_finalize(_n: BlockNumber) {} } @@ -1438,6 +1441,10 @@ pub trait OnInitialize { /// The block is being initialized. Implement to have something happen. /// /// Return the non-negotiable weight consumed in the block. + /// + /// NOTE: This function is called BEFORE ANY extrinsic in a block is applied, + /// including inherent extrinsics. Hence for instance, if you runtime includes + /// `pallet_timestamp`, the `timestamp` is not yet up to date at this point. fn on_initialize(_n: BlockNumber) -> crate::weights::Weight { 0 } } @@ -1569,7 +1576,7 @@ pub mod schedule { /// Reschedule a task. For one-off tasks, this dispatch is guaranteed to succeed /// only if it is executed *before* the currently scheduled block. For periodic tasks, /// this dispatch is guaranteed to succeed only before the *initial* execution; for - /// others, use `reschedule_named`. + /// others, use `reschedule_named`. /// /// Will return an error if the `address` is invalid. fn reschedule( -- GitLab From f74de63d23214b530ac24ac3ea4ead1180e22e83 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 19 Nov 2020 12:40:12 +0100 Subject: [PATCH 025/163] More Extensible Multiaddress Format (#7380) * More extensible multiaddress format * update name * Don't depend on indices to define multiaddress type * Use MultiAddress in Node Template too! * reduce traits, fix build * support multiple `StaticLookup` * bump tx version * feedback --- bin/node-template/runtime/src/lib.rs | 6 +- bin/node/executor/tests/basic.rs | 2 +- bin/node/runtime/src/lib.rs | 4 +- bin/node/testing/src/bench.rs | 6 +- bin/node/testing/src/keyring.rs | 2 +- frame/indices/src/address.rs | 159 ------------------------- frame/indices/src/lib.rs | 15 ++- primitives/runtime/src/lib.rs | 4 + primitives/runtime/src/multiaddress.rs | 66 ++++++++++ primitives/runtime/src/traits.rs | 38 ++++++ 10 files changed, 125 insertions(+), 177 deletions(-) delete mode 100644 frame/indices/src/address.rs create mode 100644 primitives/runtime/src/multiaddress.rs diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index d67a5bde964..aadfd931cdb 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -13,7 +13,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, IdentityLookup, Verify, IdentifyAccount, NumberFor, Saturating, + BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor, Saturating, }; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -148,7 +148,7 @@ impl frame_system::Trait for Runtime { /// The aggregated dispatch type that is available for extrinsics. type Call = Call; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; + type Lookup = AccountIdLookup; /// The index type for storing how many extrinsics an account has signed. type Index = Index; /// The index type for blocks. @@ -293,7 +293,7 @@ construct_runtime!( ); /// The address format for describing accounts. -pub type Address = AccountId; +pub type Address = sp_runtime::MultiAddress; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 723e3a7e4ba..a48efaea2d6 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -621,7 +621,7 @@ fn deploying_wasm_contract_should_work() { signed: Some((charlie(), signed_extra(2, 0))), function: Call::Contracts( pallet_contracts::Call::call::( - pallet_indices::address::Address::Id(addr.clone()), + sp_runtime::MultiAddress::Id(addr.clone()), 10, 500_000_000, vec![0x00, 0x01, 0x02, 0x03] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bfa412e8820..3e08b2cf8a6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -111,7 +111,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 260, impl_version: 0, apis: RUNTIME_API_VERSIONS, - transaction_version: 1, + transaction_version: 2, }; /// Native version. @@ -931,7 +931,7 @@ construct_runtime!( ); /// The address format for describing accounts. -pub type Address = ::Source; +pub type Address = sp_runtime::MultiAddress; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 153a52375c2..32e4bab9773 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -317,7 +317,7 @@ impl<'a> Iterator for BlockContentIterator<'a> { BlockType::RandomTransfersKeepAlive => { Call::Balances( BalancesCall::transfer_keep_alive( - pallet_indices::address::Address::Id(receiver), + sp_runtime::MultiAddress::Id(receiver), node_runtime::ExistentialDeposit::get() + 1, ) ) @@ -325,7 +325,7 @@ impl<'a> Iterator for BlockContentIterator<'a> { BlockType::RandomTransfersReaping => { Call::Balances( BalancesCall::transfer( - pallet_indices::address::Address::Id(receiver), + sp_runtime::MultiAddress::Id(receiver), // Transfer so that ending balance would be 1 less than existential deposit // so that we kill the sender account. 100*DOLLARS - (node_runtime::ExistentialDeposit::get() - 1), @@ -591,7 +591,7 @@ impl BenchKeyring { } }).into(); UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } } diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 34137485636..f0b8ff70729 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -94,7 +94,7 @@ pub fn sign(xt: CheckedExtrinsic, spec_version: u32, tx_version: u32, genesis_ha } }).into(); UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } } diff --git a/frame/indices/src/address.rs b/frame/indices/src/address.rs deleted file mode 100644 index 0fd89333813..00000000000 --- a/frame/indices/src/address.rs +++ /dev/null @@ -1,159 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 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. - -//! Address type that is union of index and id for an account. - -#[cfg(feature = "std")] -use std::fmt; -use sp_std::convert::TryInto; -use crate::Member; -use codec::{Encode, Decode, Input, Output, Error}; - -/// An indices-aware address, which can be either a direct `AccountId` or -/// an index. -#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Hash))] -pub enum Address where - AccountId: Member, - AccountIndex: Member, -{ - /// It's an account ID (pubkey). - Id(AccountId), - /// It's an account index. - Index(AccountIndex), -} - -#[cfg(feature = "std")] -impl fmt::Display for Address where - AccountId: Member, - AccountIndex: Member, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl From for Address where - AccountId: Member, - AccountIndex: Member, -{ - fn from(a: AccountId) -> Self { - Address::Id(a) - } -} - -fn need_more_than(a: T, b: T) -> Result { - if a < b { Ok(b) } else { Err("Invalid range".into()) } -} - -impl Decode for Address where - AccountId: Member + Decode, - AccountIndex: Member + Decode + PartialOrd + Ord + From + Copy, -{ - fn decode(input: &mut I) -> Result { - Ok(match input.read_byte()? { - x @ 0x00..=0xef => Address::Index(AccountIndex::from(x as u32)), - 0xfc => Address::Index(AccountIndex::from( - need_more_than(0xef, u16::decode(input)?)? as u32 - )), - 0xfd => Address::Index(AccountIndex::from( - need_more_than(0xffff, u32::decode(input)?)? - )), - 0xfe => Address::Index( - need_more_than(0xffffffffu32.into(), Decode::decode(input)?)? - ), - 0xff => Address::Id(Decode::decode(input)?), - _ => return Err("Invalid address variant".into()), - }) - } -} - -impl Encode for Address where - AccountId: Member + Encode, - AccountIndex: Member + Encode + PartialOrd + Ord + Copy + From + TryInto, -{ - fn encode_to(&self, dest: &mut T) { - match *self { - Address::Id(ref i) => { - dest.push_byte(255); - dest.push(i); - } - Address::Index(i) => { - let maybe_u32: Result = i.try_into(); - if let Ok(x) = maybe_u32 { - if x > 0xffff { - dest.push_byte(253); - dest.push(&x); - } - else if x >= 0xf0 { - dest.push_byte(252); - dest.push(&(x as u16)); - } - else { - dest.push_byte(x as u8); - } - - } else { - dest.push_byte(254); - dest.push(&i); - } - }, - } - } -} - -impl codec::EncodeLike for Address where - AccountId: Member + Encode, - AccountIndex: Member + Encode + PartialOrd + Ord + Copy + From + TryInto, -{} - -impl Default for Address where - AccountId: Member + Default, - AccountIndex: Member, -{ - fn default() -> Self { - Address::Id(Default::default()) - } -} - -#[cfg(test)] -mod tests { - use codec::{Encode, Decode}; - - type Address = super::Address<[u8; 8], u32>; - fn index(i: u32) -> Address { super::Address::Index(i) } - fn id(i: [u8; 8]) -> Address { super::Address::Id(i) } - - fn compare(a: Option

, d: &[u8]) { - if let Some(ref a) = a { - assert_eq!(d, &a.encode()[..]); - } - assert_eq!(Address::decode(&mut &d[..]).ok(), a); - } - - #[test] - fn it_should_work() { - compare(Some(index(2)), &[2][..]); - compare(None, &[240][..]); - compare(None, &[252, 239, 0][..]); - compare(Some(index(240)), &[252, 240, 0][..]); - compare(Some(index(304)), &[252, 48, 1][..]); - compare(None, &[253, 255, 255, 0, 0][..]); - compare(Some(index(0x10000)), &[253, 0, 0, 1, 0][..]); - compare(Some(id([42, 69, 42, 69, 42, 69, 42, 69])), &[255, 42, 69, 42, 69, 42, 69, 42, 69][..]); - } -} diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index fd2eb956f92..6d467aa6734 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -21,13 +21,13 @@ #![cfg_attr(not(feature = "std"), no_std)] mod mock; -pub mod address; mod tests; mod benchmarking; pub mod weights; use sp_std::prelude::*; use codec::Codec; +use sp_runtime::MultiAddress; use sp_runtime::traits::{ StaticLookup, Member, LookupError, Zero, Saturating, AtLeast32Bit }; @@ -35,10 +35,8 @@ use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; use frame_system::{ensure_signed, ensure_root}; -use self::address::Address as RawAddress; pub use weights::WeightInfo; -pub type Address = RawAddress<::AccountId, ::AccountIndex>; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// The module's config trait. @@ -287,17 +285,18 @@ impl Module { /// Lookup an address to get an Id, if there's one there. pub fn lookup_address( - a: address::Address + a: MultiAddress ) -> Option { match a { - address::Address::Id(i) => Some(i), - address::Address::Index(i) => Self::lookup_index(i), + MultiAddress::Id(i) => Some(i), + MultiAddress::Index(i) => Self::lookup_index(i), + _ => None, } } } impl StaticLookup for Module { - type Source = address::Address; + type Source = MultiAddress; type Target = T::AccountId; fn lookup(a: Self::Source) -> Result { @@ -305,6 +304,6 @@ impl StaticLookup for Module { } fn unlookup(a: Self::Target) -> Self::Source { - address::Address::Id(a) + MultiAddress::Id(a) } } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index e6c707e906e..ccd50334af6 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -56,9 +56,13 @@ pub mod traits; pub mod transaction_validity; pub mod random_number_generator; mod runtime_string; +mod multiaddress; pub use crate::runtime_string::*; +// Re-export Multiaddress +pub use multiaddress::MultiAddress; + /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs new file mode 100644 index 00000000000..bb352f7eb5f --- /dev/null +++ b/primitives/runtime/src/multiaddress.rs @@ -0,0 +1,66 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! MultiAddress type is a wrapper for multiple downstream account formats. + +use codec::{Encode, Decode}; +use sp_std::vec::Vec; + +/// A multi-format address wrapper for on-chain accounts. +#[derive(Encode, Decode, PartialEq, Eq, Clone, crate::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub enum MultiAddress { + /// It's an account ID (pubkey). + Id(AccountId), + /// It's an account index. + Index(#[codec(compact)] AccountIndex), + /// It's some arbitrary raw bytes. + Raw(Vec), + /// It's a 32 byte representation. + Address32([u8; 32]), + /// Its a 20 byte representation. + Address20([u8; 20]), +} + +#[cfg(feature = "std")] +impl std::fmt::Display for MultiAddress +where + AccountId: std::fmt::Debug, + AccountIndex: std::fmt::Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + use sp_core::hexdisplay::HexDisplay; + match self { + MultiAddress::Raw(inner) => write!(f, "MultiAddress::Raw({})", HexDisplay::from(inner)), + MultiAddress::Address32(inner) => write!(f, "MultiAddress::Address32({})", HexDisplay::from(inner)), + MultiAddress::Address20(inner) => write!(f, "MultiAddress::Address20({})", HexDisplay::from(inner)), + _ => write!(f, "{:?}", self), + } + } +} + +impl From for MultiAddress { + fn from(a: AccountId) -> Self { + MultiAddress::Id(a) + } +} + +impl Default for MultiAddress { + fn default() -> Self { + MultiAddress::Id(Default::default()) + } +} diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 4d2b1f062f7..4ce9ac0afa9 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -209,6 +209,44 @@ impl Lookup for IdentityLookup { fn lookup(&self, x: T) -> Result { Ok(x) } } +/// A lookup implementation returning the `AccountId` from a `MultiAddress`. +pub struct AccountIdLookup(PhantomData<(AccountId, AccountIndex)>); +impl StaticLookup for AccountIdLookup +where + AccountId: Codec + Clone + PartialEq + Debug, + AccountIndex: Codec + Clone + PartialEq + Debug, + crate::MultiAddress: Codec, +{ + type Source = crate::MultiAddress; + type Target = AccountId; + fn lookup(x: Self::Source) -> Result { + match x { + crate::MultiAddress::Id(i) => Ok(i), + _ => Err(LookupError), + } + } + fn unlookup(x: Self::Target) -> Self::Source { + crate::MultiAddress::Id(x) + } +} + +/// Perform a StaticLookup where there are multiple lookup sources of the same type. +impl StaticLookup for (A, B) +where + A: StaticLookup, + B: StaticLookup, +{ + type Source = A::Source; + type Target = A::Target; + + fn lookup(x: Self::Source) -> Result { + A::lookup(x.clone()).or_else(|_| B::lookup(x)) + } + fn unlookup(x: Self::Target) -> Self::Source { + A::unlookup(x) + } +} + /// Extensible conversion trait. Generic over both source and destination types. pub trait Convert { /// Make conversion. -- GitLab From 1c122c6d138f7f58f1ed7ce1414cf3dd283cd4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 20 Nov 2020 13:24:02 +0100 Subject: [PATCH 026/163] Fix weight template to remove ugliness in rust doc (#7565) fixed weight template --- .maintain/frame-weight-template.hbs | 3 ++- utils/frame/benchmarking-cli/src/template.hbs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.maintain/frame-weight-template.hbs b/.maintain/frame-weight-template.hbs index 146cc4cfcbd..aac37f0833c 100644 --- a/.maintain/frame-weight-template.hbs +++ b/.maintain/frame-weight-template.hbs @@ -15,7 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Weights for {{pallet}} +//! Autogenerated weights for {{pallet}} +//! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} //! DATE: {{date}}, STEPS: {{cmd.steps}}, REPEAT: {{cmd.repeat}}, LOW RANGE: {{cmd.lowest_range_values}}, HIGH RANGE: {{cmd.highest_range_values}} //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} diff --git a/utils/frame/benchmarking-cli/src/template.hbs b/utils/frame/benchmarking-cli/src/template.hbs index 7f7e2d6dcb9..fd066b1a3a8 100644 --- a/utils/frame/benchmarking-cli/src/template.hbs +++ b/utils/frame/benchmarking-cli/src/template.hbs @@ -1,5 +1,6 @@ {{header}} -//! Weights for {{pallet}} +//! Autogenerated weights for {{pallet}} +//! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} //! DATE: {{date}}, STEPS: {{cmd.steps}}, REPEAT: {{cmd.repeat}}, LOW RANGE: {{cmd.lowest_range_values}}, HIGH RANGE: {{cmd.highest_range_values}} //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} -- GitLab From a0e8b7ecd1d1d44bfdad1e67ef4028121f7d9d82 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 20 Nov 2020 13:59:02 +0100 Subject: [PATCH 027/163] Cargo.lock: Run cargo update (#7553) * Cargo.lock: Run cargo update * Cargo.lock: Downgrade cc to v1.0.62 * Cargo.lock: Revert wasm-* updates --- Cargo.lock | 1420 ++++++++++++++++++--------------- bin/node/bench/src/tempdb.rs | 4 +- bin/node/testing/src/bench.rs | 2 +- 3 files changed, 778 insertions(+), 648 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43af7d1a316..c2e9cda8f31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,11 +12,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" dependencies = [ - "gimli 0.22.0", + "gimli 0.23.0", ] [[package]] @@ -31,52 +31,52 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] name = "aes" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7001367fde4c768a19d1029f0a8be5abd9308e1119846d5bd9ad26297b8faf5" +checksum = "dd2bc6d3f370b5666245ff421e231cba4353df936e26986d2918e61a8fd6aef6" dependencies = [ "aes-soft", "aesni", - "block-cipher 0.7.1", + "block-cipher", ] [[package]] name = "aes-gcm" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f5007801316299f922a6198d1d09a0bae95786815d066d5880d13f7c45ead1" +checksum = "0301c9e9c443494d970a07885e8cf3e587bae8356a1d5abd0999068413f7205f" dependencies = [ "aead", "aes", - "block-cipher 0.7.1", + "block-cipher", "ghash", - "subtle 2.2.3", + "subtle 2.3.0", ] [[package]] name = "aes-soft" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4925647ee64e5056cf231608957ce7c81e12d6d6e316b9ce1404778cc1d35fa7" +checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6" dependencies = [ - "block-cipher 0.7.1", + "block-cipher", "byteorder", - "opaque-debug 0.2.3", + "opaque-debug 0.3.0", ] [[package]] name = "aesni" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050d39b0b7688b3a3254394c3e30a9d66c41dcf9b05b0e2dbdc623f6505d264" +checksum = "0a6fe808308bb07d393e2ea47780043ec47683fcf19cf5efc8ca51c50cc8c68a" dependencies = [ - "block-cipher 0.7.1", - "opaque-debug 0.2.3", + "block-cipher", + "opaque-debug 0.3.0", ] [[package]] @@ -94,11 +94,17 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" +[[package]] +name = "ahash" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6789e291be47ace86a60303502173d84af8327e3627ecf334356ee0f87a164c" + [[package]] name = "aho-corasick" -version = "0.7.13" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" dependencies = [ "memchr", ] @@ -149,9 +155,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" +checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569" [[package]] name = "arc-swap" @@ -176,9 +182,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "asn1_der" @@ -214,9 +220,9 @@ dependencies = [ [[package]] name = "assert_matches" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" +checksum = "695579f0f2520f3774bb40461e5adb066459d4e0af4d59d20175484fb8e9edf1" [[package]] name = "async-channel" @@ -231,9 +237,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d373d78ded7d0b3fa8039375718cde0aace493f2e34fb60f51cbf567562ca801" +checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" dependencies = [ "async-task", "concurrent-queue", @@ -245,9 +251,9 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fefeb39da249f4c33af940b779a56723ce45809ef5c54dad84bb538d4ffb6d9e" +checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04" dependencies = [ "async-executor", "async-io", @@ -258,23 +264,21 @@ dependencies = [ [[package]] name = "async-io" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38628c78a34f111c5a6b98fc87dfc056cd1590b61afe748b145be4623c56d194" +checksum = "40a0b2bb8ae20fede194e779150fe283f65a4a08461b496de546ec366b174ad9" dependencies = [ - "cfg-if 0.1.10", "concurrent-queue", "fastrand", "futures-lite", "libc", "log", + "nb-connect", "once_cell", "parking", "polling", - "socket2", "vec-arena", "waker-fn", - "wepoll-sys-stjepang", "winapi 0.3.9", ] @@ -289,15 +293,15 @@ dependencies = [ [[package]] name = "async-std" -version = "1.6.5" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9fa76751505e8df1c7a77762f60486f60c71bbd9b8557f4da6ad47d083732ed" +checksum = "a7e82538bc65a25dbdff70e4c5439d52f068048ab97cdea0acd73f131594caa1" dependencies = [ "async-global-executor", "async-io", "async-mutex", "blocking", - "crossbeam-utils", + "crossbeam-utils 0.8.0", "futures-channel", "futures-core", "futures-io", @@ -316,9 +320,9 @@ dependencies = [ [[package]] name = "async-task" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ab27c1aa62945039e44edaeee1dc23c74cc0c303dd5fe0fb462a184f1c3a518" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-tls" @@ -335,9 +339,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.37" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caae68055714ff28740f310927e04f2eba76ff580b16fb18ed90073ee71646f7" +checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" dependencies = [ "proc-macro2", "quote", @@ -350,7 +354,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", ] [[package]] @@ -378,21 +382,21 @@ checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] name = "autocfg" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.50" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" +checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28" dependencies = [ "addr2line", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.20.0", + "object 0.22.0", "rustc-demangle", ] @@ -402,12 +406,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "base64" version = "0.12.3" @@ -472,15 +470,13 @@ dependencies = [ [[package]] name = "blake2" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ce5b6108f8e154604bd4eb76a2f726066c3464d5a552a4229262a18c9bb471" +checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4" dependencies = [ - "byte-tools", - "byteorder", "crypto-mac 0.8.0", "digest 0.9.0", - "opaque-debug 0.2.3", + "opaque-debug 0.3.0", ] [[package]] @@ -495,23 +491,23 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "constant_time_eq", ] [[package]] name = "blake2s_simd" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "constant_time_eq", ] @@ -534,16 +530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ "block-padding 0.2.1", - "generic-array 0.14.3", -] - -[[package]] -name = "block-cipher" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10" -dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -552,7 +539,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -598,9 +585,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" +checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" dependencies = [ "lazy_static", "memchr", @@ -666,11 +653,11 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" [[package]] name = "cargo_metadata" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052dbdd9db69a339d5fa9ac87bfe2e1319f709119f0345988a597af82bb1011c" +checksum = "b8de60b887edf6d74370fc8eb177040da4847d971d6234c7b13a6da324ef0caf" dependencies = [ - "semver 0.10.0", + "semver 0.9.0", "serde", "serde_derive", "serde_json", @@ -687,9 +674,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.58" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" +checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40" dependencies = [ "jobserver", ] @@ -717,24 +704,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c0f07ac275808b7bf9a39f2fd013aae1498be83632814c8c4e0bd53f2dc58" +checksum = "244fbce0d47e97e8ef2f63b81d5e05882cb518c68531eb33194990d7b7e85845" dependencies = [ - "stream-cipher 0.4.1", + "stream-cipher", "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18b0c90556d8e3fec7cf18d84a2f53d27b21288f2fe481b830fadcf809e48205" +checksum = "9bf18d374d66df0c05cdddd528a7db98f78c28e2519b120855c4f84c5027b1f5" dependencies = [ "aead", "chacha20", "poly1305", - "stream-cipher 0.4.1", + "stream-cipher", "zeroize", ] @@ -754,15 +741,17 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.13" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "js-sys", + "libc", "num-integer", "num-traits", "time", "wasm-bindgen", + "winapi 0.3.9", ] [[package]] @@ -778,9 +767,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.1" +version = "2.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term 0.11.0", "atty", @@ -858,6 +847,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "const_fn" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -910,7 +905,7 @@ dependencies = [ "log", "regalloc", "serde", - "smallvec 1.4.1", + "smallvec 1.5.0", "target-lexicon", "thiserror", ] @@ -948,7 +943,7 @@ checksum = "2ef419efb4f94ecc02e5d9fbcc910d2bb7f0040e2de570e63a454f883bc891d6" dependencies = [ "cranelift-codegen", "log", - "smallvec 1.4.1", + "smallvec 1.5.0", "target-lexicon", ] @@ -980,11 +975,11 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", ] [[package]] @@ -1023,32 +1018,67 @@ dependencies = [ "itertools 0.9.0", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils 0.8.0", +] + [[package]] name = "crossbeam-deque" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", "maybe-uninit", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch 0.9.0", + "crossbeam-utils 0.8.0", +] + [[package]] name = "crossbeam-epoch" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "cfg-if 0.1.10", - "crossbeam-utils", + "crossbeam-utils 0.7.2", "lazy_static", "maybe-uninit", "memoffset", "scopeguard", ] +[[package]] +name = "crossbeam-epoch" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" +dependencies = [ + "cfg-if 1.0.0", + "const_fn", + "crossbeam-utils 0.8.0", + "lazy_static", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-queue" version = "0.2.3" @@ -1056,7 +1086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ "cfg-if 0.1.10", - "crossbeam-utils", + "crossbeam-utils 0.7.2", "maybe-uninit", ] @@ -1066,11 +1096,23 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "cfg-if 0.1.10", "lazy_static", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +dependencies = [ + "autocfg 1.0.1", + "cfg-if 1.0.0", + "const_fn", + "lazy_static", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1093,15 +1135,15 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.3", - "subtle 2.2.3", + "generic-array 0.14.4", + "subtle 2.3.0", ] [[package]] name = "csv" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" +checksum = "fc4666154fd004af3fd6f1da2e81a96fd5a81927fe8ddb6ecc79e2aa6e138b54" dependencies = [ "bstr", "csv-core", @@ -1130,9 +1172,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39858aa5bac06462d4dd4b9164848eb81ffc4aa5c479746393598fd193afa227" +checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484" dependencies = [ "quote", "syn", @@ -1158,7 +1200,7 @@ dependencies = [ "byteorder", "digest 0.8.1", "rand_core 0.5.1", - "subtle 2.2.3", + "subtle 2.3.0", "zeroize", ] @@ -1171,21 +1213,21 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.2.3", + "subtle 2.3.0", "zeroize", ] [[package]] name = "data-encoding" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72aa14c04dfae8dd7d8a2b1cb7ca2152618cd01336dbfe704b8dcbf8d41dbd69" +checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908" [[package]] name = "derive_more" -version = "0.99.9" +version = "0.99.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" +checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" dependencies = [ "proc-macro2", "quote", @@ -1213,7 +1255,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -1282,15 +1324,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82" +checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804" [[package]] name = "ed25519" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc" +checksum = "37c66a534cbb46ab4ea03477eae19d5c22c01da8258030280b7bd9d8433fb6ef" dependencies = [ "signature", ] @@ -1305,15 +1347,15 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.1", + "sha2 0.9.2", "zeroize", ] [[package]] name = "either" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "enumflags2" @@ -1365,9 +1407,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01" +checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe" dependencies = [ "errno-dragonfly", "libc", @@ -1397,6 +1439,23 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "ethereum" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df706418ff7d3874b9506424b04ea0bef569a2b39412b43a27ea86e679be108e" +dependencies = [ + "ethereum-types", + "hash-db", + "hash256-std-hasher", + "parity-scale-codec", + "rlp", + "rlp-derive", + "serde", + "sha3 0.9.1", + "triehash", +] + [[package]] name = "ethereum-types" version = "0.9.2" @@ -1419,13 +1478,16 @@ checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" [[package]] name = "evm" -version = "0.17.0" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68224b0aa788720ef0c8a23030a4412a021ed73df069a922bee8f0db9ed617e2" +checksum = "16c8deca0ec3efa361b03d9cae6fe94321a1d2d0a523437edd720b3d140e3c08" dependencies = [ + "ethereum", "evm-core", "evm-gasometer", "evm-runtime", + "log", + "parity-scale-codec", "primitive-types", "rlp", "serde", @@ -1434,18 +1496,19 @@ dependencies = [ [[package]] name = "evm-core" -version = "0.17.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a040378759577447945c89da1b07d6e33fda32a97a104afe0ec3fa1c382949d" +checksum = "cf2d732b3c36df36833761cf67df8f65866be1d368d20508bc3e13e6f256c8c5" dependencies = [ + "log", "primitive-types", ] [[package]] name = "evm-gasometer" -version = "0.17.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb5bc051afad6bb0735c82b46656bbdfac41917861307a608b1404a546fec42" +checksum = "46de1b91ccd744627484183729f1b5af484b3bf15505007fc28cc54264cb9ea1" dependencies = [ "evm-core", "evm-runtime", @@ -1454,9 +1517,9 @@ dependencies = [ [[package]] name = "evm-runtime" -version = "0.17.0" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7410f5677a52203d3fca02b0eb8f96f9799f3a45cff82946a8ed28379e6b1b04" +checksum = "f2c1d1ffe96f833788512c890d702457d790dba4917ac6f64f8f60fbd9bc40b8" dependencies = [ "evm-core", "primitive-types", @@ -1469,7 +1532,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", ] [[package]] @@ -1526,9 +1589,9 @@ dependencies = [ [[package]] name = "file-per-thread-logger" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3937f028664bd0e13df401ba49a4567ccda587420365823242977f06609ed1" +checksum = "4fdbe0d94371f9ce939b555dd342d0686cc4c0cadbcd4b61d70af5ff97eb4126" dependencies = [ "env_logger", "log", @@ -1541,7 +1604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b" dependencies = [ "either", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 2.0.2", "log", "num-traits", @@ -1570,11 +1633,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.16" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e" +checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "crc32fast", "libc", "libz-sys", @@ -1594,6 +1657,16 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "form_urlencoded" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +dependencies = [ + "matches", + "percent-encoding 2.1.0", +] + [[package]] name = "frame-benchmarking" version = "2.0.0" @@ -1679,7 +1752,7 @@ dependencies = [ "paste 0.1.18", "pretty_assertions", "serde", - "smallvec 1.4.1", + "smallvec 1.5.0", "sp-api", "sp-arithmetic", "sp-core", @@ -1806,9 +1879,9 @@ dependencies = [ [[package]] name = "fs_extra" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "fuchsia-cprng" @@ -1834,15 +1907,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +checksum = "4c7e4c2612746b0df8fed4ce0c69156021b704c9aefa360311c04e6e9e002eed" [[package]] name = "futures" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" +checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" dependencies = [ "futures-channel", "futures-core", @@ -1855,9 +1928,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" +checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" dependencies = [ "futures-core", "futures-sink", @@ -1865,9 +1938,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" +checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" [[package]] name = "futures-cpupool" @@ -1875,7 +1948,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "num_cpus", ] @@ -1885,21 +1958,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9" dependencies = [ - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "lazy_static", "log", "parking_lot 0.9.0", - "pin-project 0.4.22", + "pin-project 0.4.27", "serde", "serde_json", ] [[package]] name = "futures-executor" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" +checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65" dependencies = [ "futures-core", "futures-task", @@ -1909,15 +1982,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" +checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" [[package]] name = "futures-lite" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "381a7ad57b1bad34693f63f6f377e1abded7a9c85c9d3eb6771e11c60aaadab9" +checksum = "5e6c079abfac3ab269e2927ec048dabc89d009ebfdda6b8ee86624f30c689658" dependencies = [ "fastrand", "futures-core", @@ -1930,9 +2003,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" +checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -1942,15 +2015,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" +checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" [[package]] name = "futures-task" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" dependencies = [ "once_cell", ] @@ -1973,11 +2046,11 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" +checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "futures-channel", "futures-core", "futures-io", @@ -1985,7 +2058,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project 0.4.22", + "pin-project 1.0.2", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -1999,9 +2072,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "memchr", - "pin-project 0.4.22", + "pin-project 0.4.27", ] [[package]] @@ -2010,6 +2083,19 @@ version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +[[package]] +name = "generator" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc" +dependencies = [ + "cc", + "libc", + "log", + "rustc_version", + "winapi 0.3.9", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -2021,9 +2107,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", "version_check", @@ -2031,13 +2117,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -2049,7 +2135,7 @@ checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" dependencies = [ "cfg-if 0.1.10", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] @@ -2074,9 +2160,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" [[package]] name = "glob" @@ -2086,9 +2172,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad1da430bd7281dde2576f44c84cc3f0f7b475e7202cd503042dff01a8c8120" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" dependencies = [ "aho-corasick", "bstr", @@ -2119,7 +2205,7 @@ dependencies = [ "byteorder", "bytes 0.4.12", "fnv", - "futures 0.1.29", + "futures 0.1.30", "http 0.1.21", "indexmap", "log", @@ -2130,9 +2216,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" dependencies = [ "bytes 0.5.6", "fnv", @@ -2142,9 +2228,10 @@ dependencies = [ "http 0.2.1", "indexmap", "slab", - "tokio 0.2.22", + "tokio 0.2.23", "tokio-util", "tracing", + "tracing-futures", ] [[package]] @@ -2155,9 +2242,9 @@ checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177" [[package]] name = "handlebars" -version = "3.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd1b5399b9884f9ae18b5d4105d180720c8f602aeb73d3ceae9d6b1d13a5fa7" +checksum = "2764f9796c0ddca4b82c07f25dd2cb3db30b9a8f47940e78e1c883d9e95c3db9" dependencies = [ "log", "pest", @@ -2194,12 +2281,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" +checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" dependencies = [ "ahash 0.3.8", - "autocfg 1.0.0", + "autocfg 1.0.1", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash 0.4.6", ] [[package]] @@ -2213,9 +2309,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" dependencies = [ "libc", ] @@ -2271,9 +2367,9 @@ dependencies = [ [[package]] name = "honggfuzz" -version = "0.5.49" +version = "0.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832bac18a82ec7d6c21887daa8616b238fe90d5d5e762d0d4b9372cdaa9e097f" +checksum = "6f085725a5828d7e959f014f624773094dfe20acc91be310ef106923c30594bc" dependencies = [ "arbitrary", "lazy_static", @@ -2309,7 +2405,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "http 0.1.21", "tokio-buf", ] @@ -2330,6 +2426,12 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +[[package]] +name = "httpdate" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" + [[package]] name = "humantime" version = "1.3.0" @@ -2346,7 +2448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "futures-cpupool", "h2 0.1.26", "http 0.1.21", @@ -2371,23 +2473,23 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.7" +version = "0.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb" +checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf" dependencies = [ "bytes 0.5.6", "futures-channel", "futures-core", "futures-util", - "h2 0.2.6", + "h2 0.2.7", "http 0.2.1", "http-body 0.3.1", "httparse", + "httpdate", "itoa", - "pin-project 0.4.22", + "pin-project 1.0.2", "socket2", - "time", - "tokio 0.2.22", + "tokio 0.2.23", "tower-service", "tracing", "want 0.3.0", @@ -2402,11 +2504,11 @@ dependencies = [ "bytes 0.5.6", "ct-logs", "futures-util", - "hyper 0.13.7", + "hyper 0.13.9", "log", "rustls", "rustls-native-certs", - "tokio 0.2.22", + "tokio 0.2.23", "tokio-rustls", "webpki", ] @@ -2435,9 +2537,9 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12906406f12abf5569643c46b29aec78313dc1537b17dd5c5250169790c4db9" +checksum = "28538916eb3f3976311f5dfbe67b5362d0add1293d0a9cad17debf86f8e3aa48" dependencies = [ "if-addrs-sys", "libc", @@ -2446,9 +2548,9 @@ dependencies = [ [[package]] name = "if-addrs-sys" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e2556f16544202bcfe0aa5d20a01a6b815f736b136b3ad76dc547ee6b5bb1df" +checksum = "de74b9dd780476e837e5eb5ab7c88b49ed304126e412030a0adba99c8efe79ea" dependencies = [ "cc", "libc", @@ -2494,26 +2596,32 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" +checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" dependencies = [ - "autocfg 1.0.0", - "hashbrown 0.8.1", + "autocfg 1.0.1", + "hashbrown 0.9.1", "serde", ] [[package]] name = "instant" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485" +checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613" +dependencies = [ + "cfg-if 1.0.0", +] [[package]] name = "integer-sqrt" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] [[package]] name = "intervalier" @@ -2521,7 +2629,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 2.0.2", ] @@ -2581,9 +2689,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.39" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7" +checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73" dependencies = [ "wasm-bindgen", ] @@ -2595,7 +2703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "489b9c612e60c766f751ab40fcb43cbb55a1e10bb44a9b4307ed510ca598cbd7" dependencies = [ "failure", - "futures 0.1.29", + "futures 0.1.30", "hyper 0.12.35", "jsonrpc-core", "jsonrpc-pubsub", @@ -2611,7 +2719,7 @@ version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0745a6379e3edc893c84ec203589790774e4247420033e71a76d3ab4687991fa" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "log", "serde", "serde_derive", @@ -2754,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a" dependencies = [ "parity-util-mem", - "smallvec 1.4.1", + "smallvec 1.5.0", ] [[package]] @@ -2783,7 +2891,7 @@ dependencies = [ "parking_lot 0.10.2", "regex", "rocksdb", - "smallvec 1.4.1", + "smallvec 1.5.0", ] [[package]] @@ -2792,7 +2900,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2701a1369d6ea4f1b9f606db46e5e2a4a8e47f22530a07823d653f85ab1f6c34" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "js-sys", "kvdb", "kvdb-memorydb", @@ -2811,9 +2919,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leb128" @@ -2823,9 +2931,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "libloading" @@ -2851,7 +2959,7 @@ checksum = "e3c2b4c99f8798be90746fc226acf95d3e6cff0655883634cc30dab1f64f438b" dependencies = [ "atomic", "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "lazy_static", "libp2p-core", "libp2p-core-derive", @@ -2876,9 +2984,9 @@ dependencies = [ "libp2p-yamux", "multihash", "parity-multiaddr", - "parking_lot 0.11.0", - "pin-project 1.0.1", - "smallvec 1.4.1", + "parking_lot 0.11.1", + "pin-project 1.0.2", + "smallvec 1.5.0", "wasm-timer", ] @@ -2893,7 +3001,7 @@ dependencies = [ "ed25519-dalek", "either", "fnv", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", @@ -2901,15 +3009,15 @@ dependencies = [ "multihash", "multistream-select", "parity-multiaddr", - "parking_lot 0.11.0", - "pin-project 1.0.1", + "parking_lot 0.11.1", + "pin-project 1.0.2", "prost", "prost-build", "rand 0.7.3", "ring", "rw-stream-sink", - "sha2 0.9.1", - "smallvec 1.4.1", + "sha2 0.9.2", + "smallvec 1.5.0", "thiserror", "unsigned-varint 0.5.1", "void", @@ -2933,7 +3041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aea69349e70a58ef9ecd21ac12c5eaa36255ac6986828079d26393f9e618cb" dependencies = [ "flate2", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", ] @@ -2943,7 +3051,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0baeff71fb5cb1fe1604f74a712a44b66a8c5900f4022411a1d550f09d6bb776" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "log", ] @@ -2956,14 +3064,14 @@ checksum = "db0f925a45f310b678e70faf71a10023b829d02eb9cc2628a63de928936f3ade" dependencies = [ "cuckoofilter", "fnv", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "libp2p-swarm", "log", "prost", "prost-build", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", ] [[package]] @@ -2976,7 +3084,7 @@ dependencies = [ "byteorder", "bytes 0.5.6", "fnv", - "futures 0.3.5", + "futures 0.3.8", "futures_codec", "hex_fmt", "libp2p-core", @@ -2986,8 +3094,8 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "sha2 0.9.1", - "smallvec 1.4.1", + "sha2 0.9.2", + "smallvec 1.5.0", "unsigned-varint 0.5.1", "wasm-timer", ] @@ -2998,13 +3106,13 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e074124669840484de564901d47f2d0892e73f6d8ee7c37e9c2644af1b217bf4" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "libp2p-swarm", "log", "prost", "prost-build", - "smallvec 1.4.1", + "smallvec 1.5.0", "wasm-timer", ] @@ -3014,11 +3122,11 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78a2653b2e3254a3bbeb66bfc3f0dca7d6cba6aa2a96791db114003dec1b5394" dependencies = [ - "arrayvec 0.5.1", + "arrayvec 0.5.2", "bytes 0.5.6", "either", "fnv", - "futures 0.3.5", + "futures 0.3.8", "futures_codec", "libp2p-core", "libp2p-swarm", @@ -3027,8 +3135,8 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "sha2 0.9.1", - "smallvec 1.4.1", + "sha2 0.9.2", + "smallvec 1.5.0", "uint", "unsigned-varint 0.5.1", "void", @@ -3045,14 +3153,14 @@ dependencies = [ "data-encoding", "dns-parser", "either", - "futures 0.3.5", + "futures 0.3.8", "lazy_static", "libp2p-core", "libp2p-swarm", "log", "net2", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", "void", "wasm-timer", ] @@ -3064,14 +3172,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed764eab613a8fb6b7dcf6c796f55a06fef2270e528329903e25cd3311b99663" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "futures_codec", "libp2p-core", "log", "nohash-hasher", - "parking_lot 0.11.0", + "parking_lot 0.11.1", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", "unsigned-varint 0.5.1", ] @@ -3083,17 +3191,17 @@ checksum = "fb441fb015ec16690099c5d910fcba271d357763b3dcb784db7b27bbb0b68372" dependencies = [ "bytes 0.5.6", "curve25519-dalek 3.0.0", - "futures 0.3.5", + "futures 0.3.8", "lazy_static", "libp2p-core", "log", "prost", "prost-build", "rand 0.7.3", - "sha2 0.9.1", + "sha2 0.9.2", "snow", "static_assertions", - "x25519-dalek 1.1.0", + "x25519-dalek", "zeroize", ] @@ -3103,7 +3211,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e5c50936cfdbe96a514e8992f304fa44cd3a681b6f779505f1ae62b3474705" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "libp2p-swarm", "log", @@ -3119,7 +3227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21026557c335d3639591f247b19b7536195772034ec7e9c463137227f95eaaa1" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "futures_codec", "libp2p-core", "log", @@ -3135,9 +3243,9 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "log", - "pin-project 0.4.22", + "pin-project 0.4.27", "rand 0.7.3", "salsa20", "sha3 0.9.1", @@ -3151,14 +3259,14 @@ checksum = "2dd9a1e0e6563dec1c9e702f7e68bdaa43da62a84536aa06372d3fed3e25d4ca" dependencies = [ "async-trait", "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "libp2p-swarm", "log", - "lru 0.6.0", + "lru 0.6.1", "minicbor", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", "unsigned-varint 0.5.1", "wasm-timer", ] @@ -3170,11 +3278,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "565f0e06674b4033c978471e4083d5aaa8e03cef0719a0ec0905aaeaad39a919" dependencies = [ "either", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "log", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", "void", "wasm-timer", ] @@ -3186,7 +3294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33f3dce259c0d3127af5167f45c275b6c047320efdd0e40fde947482487af0a3" dependencies = [ "async-std", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "if-addrs", "ipnet", @@ -3202,7 +3310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e0aba04370a00d8d0236e350bc862926c1b42542a169aa6a481e660e5b990fe" dependencies = [ "async-std", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "log", ] @@ -3213,7 +3321,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c703816f4170477a375b49c56d349e535ce68388f81ba1d9a3c8e2517effa82" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -3229,14 +3337,14 @@ checksum = "8d5e7268a959748040a0cf7456ad655be55b87f0ceda03bdb5b53674726b28f7" dependencies = [ "async-tls", "either", - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", "log", "quicksink", "rustls", "rw-stream-sink", "soketto", - "url 2.1.1", + "url 2.2.0", "webpki", "webpki-roots", ] @@ -3247,9 +3355,9 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a0798cbb58535162c40858493d09af06eac42a26e4966e58de0df701f559348" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "libp2p-core", - "parking_lot 0.11.0", + "parking_lot 0.11.1", "thiserror", "yamux", ] @@ -3278,18 +3386,17 @@ dependencies = [ "hmac-drbg", "rand 0.7.3", "sha2 0.8.2", - "subtle 2.2.3", + "subtle 2.3.0", "typenum", ] [[package]] name = "libz-sys" -version = "1.0.25" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" +checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" dependencies = [ "cc", - "libc", "pkg-config", "vcpkg", ] @@ -3322,9 +3429,9 @@ dependencies = [ [[package]] name = "lite-json" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c73e713a23ac6e12074c9e96ef2dfb770921e0cb9244c093bd38424209e0e523" +checksum = "0460d985423a026b4d9b828a7c6eed1bcf606f476322f3f9b507529686a61715" dependencies = [ "lite-parser", ] @@ -3349,9 +3456,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" dependencies = [ "scopeguard", ] @@ -3365,6 +3472,19 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "loom" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed" +dependencies = [ + "cfg-if 0.1.10", + "generator", + "scoped-tls", + "serde", + "serde_json", +] + [[package]] name = "lru" version = "0.4.3" @@ -3385,11 +3505,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111b945ac72ec09eb7bc62a0fbdc3cc6e80555a7245f52a69d3921a75b53b153" +checksum = "be716eb6878ca2263eb5d00a781aa13264a794f519fe6af4fbb2668b2d5441c0" dependencies = [ - "hashbrown 0.8.1", + "hashbrown 0.9.1", ] [[package]] @@ -3445,9 +3565,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "memmap" @@ -3461,11 +3581,11 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", ] [[package]] @@ -3475,7 +3595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a" dependencies = [ "hash-db", - "hashbrown 0.8.1", + "hashbrown 0.8.2", "parity-util-mem", ] @@ -3519,11 +3639,12 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" dependencies = [ "adler", + "autocfg 1.0.1", ] [[package]] @@ -3565,7 +3686,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", "mio", - "miow 0.3.5", + "miow 0.3.6", "winapi 0.3.9", ] @@ -3594,9 +3715,9 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" dependencies = [ "socket2", "winapi 0.3.9", @@ -3618,16 +3739,16 @@ dependencies = [ "blake2s_simd", "digest 0.9.0", "sha-1 0.9.2", - "sha2 0.9.1", + "sha2 0.9.2", "sha3 0.9.1", "unsigned-varint 0.5.1", ] [[package]] name = "multimap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" +checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" [[package]] name = "multistream-select" @@ -3636,10 +3757,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75" dependencies = [ "bytes 0.5.6", - "futures 0.3.5", + "futures 0.3.8", "log", - "pin-project 1.0.1", - "smallvec 1.4.1", + "pin-project 1.0.2", + "smallvec 1.5.0", "unsigned-varint 0.5.1", ] @@ -3669,11 +3790,21 @@ dependencies = [ "rand 0.3.23", ] +[[package]] +name = "nb-connect" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "net2" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +checksum = "3ebc3ec692ed7c9a255596c67808dee269f64655d8baf7b4f0638e51ba1d6853" dependencies = [ "cfg-if 0.1.10", "libc", @@ -3699,7 +3830,7 @@ version = "0.8.0" dependencies = [ "derive_more", "fs_extra", - "futures 0.3.5", + "futures 0.3.8", "hash-db", "hex", "kvdb", @@ -3735,7 +3866,7 @@ dependencies = [ name = "node-browser-testing" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "jsonrpc-core", "libp2p", @@ -3756,7 +3887,7 @@ dependencies = [ "frame-benchmarking-cli", "frame-support", "frame-system", - "futures 0.3.5", + "futures 0.3.8", "hex-literal", "log", "nix", @@ -3923,7 +4054,7 @@ dependencies = [ name = "node-rpc-client" version = "2.0.0" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "hyper 0.12.35", "jsonrpc-core-client", "log", @@ -4078,7 +4209,7 @@ dependencies = [ "frame-support", "frame-system", "fs_extra", - "futures 0.3.5", + "futures 0.3.8", "log", "node-executor", "node-primitives", @@ -4142,7 +4273,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-integer", "num-traits", ] @@ -4153,17 +4284,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-traits", ] [[package]] name = "num-integer" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-traits", ] @@ -4173,7 +4304,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "num-bigint", "num-integer", "num-traits", @@ -4181,11 +4312,11 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.0", + "autocfg 1.0.1", "libm", ] @@ -4216,13 +4347,19 @@ dependencies = [ "wasmparser 0.57.0", ] +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + [[package]] name = "once_cell" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" +checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" dependencies = [ - "parking_lot 0.11.0", + "parking_lot 0.11.1", ] [[package]] @@ -4430,7 +4567,7 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "parity-wasm 0.41.0", - "paste 1.0.0", + "paste 1.0.3", "pretty_assertions", "pwasm-utils 0.16.0", "rand 0.7.3", @@ -5051,7 +5188,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "serde", - "smallvec 1.4.1", + "smallvec 1.5.0", "sp-core", "sp-io", "sp-runtime", @@ -5157,9 +5294,9 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.9.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fe99b938abd57507e37f8d4ef30cd74b33c71face2809b37b8beb71bab15ab" +checksum = "43244a26dc1ddd3097216bb12eaa6cf8a07b060c72718d9ebd60fd297d6401df" dependencies = [ "arrayref", "bs58 0.4.0", @@ -5170,16 +5307,16 @@ dependencies = [ "serde", "static_assertions", "unsigned-varint 0.5.1", - "url 2.1.1", + "url 2.2.0", ] [[package]] name = "parity-scale-codec" -version = "1.3.4" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d38aeaffc032ec69faa476b3caaca8d4dd7f3f798137ff30359e5c7869ceb6" +checksum = "7c740e5fbcb6847058b40ac7e5574766c6388f585e184d769910fe0d3a2ca861" dependencies = [ - "arrayvec 0.5.1", + "arrayvec 0.5.2", "bitvec", "byte-slice-cast", "parity-scale-codec-derive", @@ -5188,9 +5325,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd20ff7e0399b274a5f5bb37b712fccb5b3a64b9128200d1c3cc40fe709cb073" +checksum = "198db82bb1c18fc00176004462dd809b2a6d851669550aa17af6dacd21ae0c14" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5211,11 +5348,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "libc", "log", "mio-named-pipes", - "miow 0.3.5", + "miow 0.3.6", "rand 0.7.3", "tokio 0.1.22", "tokio-named-pipes", @@ -5231,13 +5368,13 @@ checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ "cfg-if 0.1.10", "ethereum-types", - "hashbrown 0.8.1", + "hashbrown 0.8.2", "impl-trait-for-tuples", "lru 0.5.3", "parity-util-mem-derive", "parking_lot 0.10.2", "primitive-types", - "smallvec 1.4.1", + "smallvec 1.5.0", "winapi 0.3.9", ] @@ -5282,7 +5419,7 @@ dependencies = [ "rand 0.7.3", "sha-1 0.8.2", "slab", - "url 2.1.1", + "url 2.2.0", ] [[package]] @@ -5314,12 +5451,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", - "lock_api 0.4.1", + "lock_api 0.4.2", "parking_lot_core 0.8.0", ] @@ -5348,7 +5485,7 @@ dependencies = [ "cloudabi 0.0.3", "libc", "redox_syscall", - "smallvec 1.4.1", + "smallvec 1.5.0", "winapi 0.3.9", ] @@ -5363,7 +5500,7 @@ dependencies = [ "instant", "libc", "redox_syscall", - "smallvec 1.4.1", + "smallvec 1.5.0", "winapi 0.3.9", ] @@ -5379,9 +5516,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ddc8e145de01d9180ac7b78b9676f95a9c2447f6a88b2c2a04702211bc5d71" +checksum = "7151b083b0664ed58ed669fcdd92f01c3d2fdbf10af4931a301474950b52bfa9" [[package]] name = "paste-impl" @@ -5490,27 +5627,27 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" dependencies = [ - "pin-project-internal 0.4.22", + "pin-project-internal 0.4.27", ] [[package]] name = "pin-project" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee41d838744f60d959d7074e3afb6b35c7456d0f61cad38a24e35e6553f73841" +checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" dependencies = [ - "pin-project-internal 1.0.1", + "pin-project-internal 1.0.2", ] [[package]] name = "pin-project-internal" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" +checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" dependencies = [ "proc-macro2", "quote", @@ -5519,9 +5656,9 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86" +checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f" dependencies = [ "proc-macro2", "quote", @@ -5530,9 +5667,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.1.7" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" [[package]] name = "pin-utils" @@ -5542,9 +5679,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" [[package]] name = "platforms" @@ -5566,31 +5703,31 @@ dependencies = [ [[package]] name = "polling" -version = "1.1.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0720e0b9ea9d52451cf29d3413ba8a9303f8815d9d9653ef70e03ff73e65566" +checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" dependencies = [ "cfg-if 0.1.10", "libc", "log", - "wepoll-sys-stjepang", + "wepoll-sys", "winapi 0.3.9", ] [[package]] name = "poly1305" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b42192ab143ed7619bf888a7f9c6733a9a2153b218e2cd557cfdb52fbf9bb1" +checksum = "22ce46de8e53ee414ca4d02bfefac75d8c12fba948b76622a40b4be34dfce980" dependencies = [ "universal-hash", ] [[package]] name = "polyval" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a50142b55ab3ed0e9f68dfb3709f1d90d29da24e91033f28b96330643107dc" +checksum = "a5884790f1ce3553ad55fec37b5aaac5882e0e845a2612df744d6c85c9bf046c" dependencies = [ "cfg-if 0.1.10", "universal-hash", @@ -5598,9 +5735,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "predicates" @@ -5642,9 +5779,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" +checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" dependencies = [ "fixed-hash", "impl-codec", @@ -5664,9 +5801,9 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -5677,22 +5814,20 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "syn", - "syn-mid", "version_check", ] [[package]] name = "proc-macro-hack" -version = "0.5.16" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro-nested" @@ -5718,7 +5853,7 @@ dependencies = [ "cfg-if 0.1.10", "fnv", "lazy_static", - "parking_lot 0.11.0", + "parking_lot 0.11.1", "regex", "thiserror", ] @@ -5907,7 +6042,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14", + "getrandom 0.1.15", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -5956,7 +6091,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14", + "getrandom 0.1.15", ] [[package]] @@ -6059,25 +6194,25 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.3.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" +checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ - "autocfg 1.0.0", - "crossbeam-deque", + "autocfg 1.0.1", + "crossbeam-deque 0.8.0", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" +checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils", + "crossbeam-channel", + "crossbeam-deque 0.8.0", + "crossbeam-utils 0.8.0", "lazy_static", "num_cpus", ] @@ -6099,29 +6234,29 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ - "getrandom 0.1.14", + "getrandom 0.1.15", "redox_syscall", "rust-argon2", ] [[package]] name = "ref-cast" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" +checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" +checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72" dependencies = [ "proc-macro2", "quote", @@ -6136,7 +6271,7 @@ checksum = "b9ba8aaf5fe7cf307c6dbdaeed85478961d29e25e3bee5169e11b92fa9f027a8" dependencies = [ "log", "rustc-hash", - "smallvec 1.4.1", + "smallvec 1.5.0", ] [[package]] @@ -6196,9 +6331,9 @@ checksum = "e005d658ad26eacc2b6c506dfde519f4e277e328d0eb3379ca61647d70a8f531" [[package]] name = "ring" -version = "0.16.15" +version = "0.16.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" +checksum = "b72b84d47e8ec5a4f2872e8262b8f8256c5be1c938a7d6d3a867a3ba8f722f74" dependencies = [ "cc", "libc", @@ -6222,13 +6357,24 @@ dependencies = [ [[package]] name = "rlp" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" +checksum = "1190dcc8c3a512f1eef5d09bb8c84c7f39e1054e174d1795482e18f5272f2e73" dependencies = [ "rustc-hex", ] +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "rocksdb" version = "0.15.0" @@ -6251,21 +6397,21 @@ dependencies = [ [[package]] name = "rust-argon2" -version = "0.7.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" +checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" dependencies = [ - "base64 0.11.0", + "base64 0.12.3", "blake2b_simd", "constant_time_eq", - "crossbeam-utils", + "crossbeam-utils 0.7.2", ] [[package]] name = "rustc-demangle" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" [[package]] name = "rustc-hash" @@ -6290,9 +6436,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693" +checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" dependencies = [ "base64 0.12.3", "log", @@ -6315,14 +6461,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" [[package]] name = "rw-stream-sink" @@ -6330,8 +6471,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.5", - "pin-project 0.4.22", + "futures 0.3.8", + "pin-project 0.4.27", "static_assertions", ] @@ -6356,7 +6497,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395" dependencies = [ - "stream-cipher 0.7.1", + "stream-cipher", ] [[package]] @@ -6376,7 +6517,7 @@ dependencies = [ "bytes 0.5.6", "derive_more", "either", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "libp2p", "log", @@ -6405,7 +6546,7 @@ dependencies = [ name = "sc-basic-authorship" version = "0.8.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6482,7 +6623,7 @@ dependencies = [ "atty", "chrono", "fdlimit", - "futures 0.3.5", + "futures 0.3.8", "hex", "lazy_static", "libp2p", @@ -6513,7 +6654,7 @@ dependencies = [ "tempfile", "thiserror", "tiny-bip39", - "tokio 0.2.22", + "tokio 0.2.23", "tracing", "tracing-log", "tracing-subscriber", @@ -6535,7 +6676,7 @@ version = "2.0.0" dependencies = [ "derive_more", "fnv", - "futures 0.3.5", + "futures 0.3.8", "hash-db", "hex-literal", "kvdb", @@ -6617,7 +6758,7 @@ name = "sc-consensus-aura" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6657,7 +6798,7 @@ version = "0.8.0" dependencies = [ "derive_more", "fork-tree", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "merlin", @@ -6710,7 +6851,7 @@ name = "sc-consensus-babe-rpc" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6752,7 +6893,7 @@ version = "0.8.0" dependencies = [ "assert_matches", "derive_more", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6780,7 +6921,7 @@ dependencies = [ "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] @@ -6788,7 +6929,7 @@ name = "sc-consensus-pow" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6810,7 +6951,7 @@ dependencies = [ name = "sc-consensus-slots" version = "0.8.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6940,12 +7081,12 @@ dependencies = [ "derive_more", "finality-grandpa", "fork-tree", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "log", "parity-scale-codec", "parking_lot 0.10.2", - "pin-project 0.4.22", + "pin-project 0.4.27", "rand 0.7.3", "sc-block-builder", "sc-client-api", @@ -6974,7 +7115,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] @@ -6983,7 +7124,7 @@ version = "0.8.0" dependencies = [ "derive_more", "finality-grandpa", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -7012,7 +7153,7 @@ name = "sc-informant" version = "0.8.0" dependencies = [ "ansi_term 0.12.1", - "futures 0.3.5", + "futures 0.3.8", "log", "parity-util-mem", "sc-client-api", @@ -7030,7 +7171,7 @@ version = "2.0.0" dependencies = [ "async-trait", "derive_more", - "futures 0.3.5", + "futures 0.3.8", "futures-util", "hex", "merlin", @@ -7040,7 +7181,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-keystore", - "subtle 2.2.3", + "subtle 2.3.0", "tempfile", ] @@ -7077,7 +7218,7 @@ dependencies = [ "erased-serde", "fnv", "fork-tree", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "futures_codec", "hex", @@ -7090,7 +7231,7 @@ dependencies = [ "nohash-hasher", "parity-scale-codec", "parking_lot 0.10.2", - "pin-project 0.4.22", + "pin-project 0.4.27", "prost", "prost-build", "quickcheck", @@ -7128,7 +7269,7 @@ name = "sc-network-gossip" version = "0.8.0" dependencies = [ "async-std", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "libp2p", "log", @@ -7145,7 +7286,7 @@ dependencies = [ name = "sc-network-test" version = "0.8.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "libp2p", "log", @@ -7173,9 +7314,9 @@ version = "2.0.0" dependencies = [ "bytes 0.5.6", "fnv", - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", - "hyper 0.13.7", + "hyper 0.13.9", "hyper-rustls", "lazy_static", "log", @@ -7197,14 +7338,14 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] name = "sc-peerset" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "libp2p", "log", "rand 0.7.3", @@ -7226,8 +7367,8 @@ name = "sc-rpc" version = "2.0.0" dependencies = [ "assert_matches", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "hash-db", "jsonrpc-core", "jsonrpc-pubsub", @@ -7266,7 +7407,7 @@ name = "sc-rpc-api" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -7288,7 +7429,7 @@ dependencies = [ name = "sc-rpc-server" version = "2.0.0" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "jsonrpc-core", "jsonrpc-http-server", "jsonrpc-ipc-server", @@ -7323,8 +7464,8 @@ dependencies = [ "derive_more", "directories", "exit-future", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "futures-timer 3.0.2", "hash-db", "jsonrpc-core", @@ -7334,7 +7475,7 @@ dependencies = [ "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", - "pin-project 0.4.22", + "pin-project 0.4.27", "rand 0.7.3", "sc-block-builder", "sc-chain-spec", @@ -7379,7 +7520,7 @@ dependencies = [ "substrate-test-runtime", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.22", + "tokio 0.2.23", "tracing", "tracing-futures", "wasm-timer", @@ -7390,8 +7531,8 @@ name = "sc-service-test" version = "2.0.0" dependencies = [ "fdlimit", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "hex-literal", "log", "parity-scale-codec", @@ -7456,12 +7597,12 @@ dependencies = [ name = "sc-telemetry" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "libp2p", "log", "parking_lot 0.10.2", - "pin-project 0.4.22", + "pin-project 0.4.27", "rand 0.7.3", "serde", "slog", @@ -7497,7 +7638,7 @@ dependencies = [ "assert_matches", "criterion", "derive_more", - "futures 0.3.5", + "futures 0.3.8", "linked-hash-map", "log", "parity-scale-codec", @@ -7520,7 +7661,7 @@ version = "2.0.0" dependencies = [ "assert_matches", "derive_more", - "futures 0.3.5", + "futures 0.3.8", "futures-diagnose", "hex", "intervalier", @@ -7563,14 +7704,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" dependencies = [ "arrayref", - "arrayvec 0.5.1", + "arrayvec 0.5.2", "curve25519-dalek 2.1.0", - "getrandom 0.1.14", + "getrandom 0.1.15", "merlin", "rand 0.7.3", "rand_core 0.5.1", "sha2 0.8.2", - "subtle 2.2.3", + "subtle 2.3.0", "zeroize", ] @@ -7588,18 +7729,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scroll" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1" +checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" dependencies = [ "scroll_derive", ] [[package]] name = "scroll_derive" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9" +checksum = "b12bd20b94c7cdfda8c7ba9b92ad0d9a56e3fa018c25fca83b51aa664c9b4c0d" dependencies = [ "proc-macro2", "quote", @@ -7662,15 +7803,6 @@ name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190" dependencies = [ "semver-parser", "serde", @@ -7702,9 +7834,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] @@ -7721,9 +7853,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ "proc-macro2", "quote", @@ -7732,9 +7864,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", @@ -7780,12 +7912,12 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" dependencies = [ "block-buffer 0.9.0", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -7818,11 +7950,12 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.0.9" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e" +checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127" dependencies = [ "lazy_static", + "loom", ] [[package]] @@ -7833,19 +7966,18 @@ checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal-hook-registry" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab" dependencies = [ - "arc-swap", "libc", ] [[package]] name = "signature" -version = "1.1.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65211b7b6fc3f14ff9fc7a2011a434e3e6880585bd2e9e9396315ae24cbf7852" +checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" [[package]] name = "slab" @@ -7908,15 +8040,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" +checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" [[package]] name = "snow" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32bf8474159a95551661246cda4976e89356999e3cbfef36f493dacc3fae1e8e" +checksum = "795dd7aeeee24468e5a32661f6d27f7b5cbed802031b2d7640c7b10f8fb2dd50" dependencies = [ "aes-gcm", "blake2", @@ -7925,16 +8057,16 @@ dependencies = [ "rand_core 0.5.1", "ring", "rustc_version", - "sha2 0.9.1", - "subtle 2.2.3", - "x25519-dalek 0.6.0", + "sha2 0.9.2", + "subtle 2.3.0", + "x25519-dalek", ] [[package]] name = "socket2" -version = "0.3.12" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" +checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d" dependencies = [ "cfg-if 0.1.10", "libc", @@ -7944,18 +8076,18 @@ dependencies = [ [[package]] name = "soketto" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85457366ae0c6ce56bf05a958aef14cd38513c236568618edbcd9a8c52cb80b0" +checksum = "b5c71ed3d54db0a699f4948e1bb3e45b450fa31fe602621dee6680361d569c88" dependencies = [ "base64 0.12.3", "bytes 0.5.6", "flate2", - "futures 0.3.5", + "futures 0.3.8", "httparse", "log", "rand 0.7.3", - "sha-1 0.8.2", + "sha-1 0.9.2", ] [[package]] @@ -8124,7 +8256,7 @@ dependencies = [ name = "sp-consensus" version = "0.8.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-timer 3.0.2", "libp2p", "log", @@ -8218,7 +8350,7 @@ dependencies = [ "criterion", "dyn-clonable", "ed25519-dalek", - "futures 0.3.5", + "futures 0.3.8", "hash-db", "hash256-std-hasher", "hex", @@ -8315,7 +8447,7 @@ dependencies = [ name = "sp-io" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "hash-db", "libsecp256k1", "log", @@ -8350,7 +8482,7 @@ version = "0.8.0" dependencies = [ "async-trait", "derive_more", - "futures 0.3.5", + "futures 0.3.8", "merlin", "parity-scale-codec", "parking_lot 0.10.2", @@ -8572,7 +8704,7 @@ dependencies = [ "parking_lot 0.10.2", "pretty_assertions", "rand 0.7.3", - "smallvec 1.4.1", + "smallvec 1.5.0", "sp-core", "sp-externalities", "sp-panic-handler", @@ -8655,7 +8787,7 @@ name = "sp-transaction-pool" version = "2.0.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "log", "parity-scale-codec", "serde", @@ -8686,7 +8818,7 @@ dependencies = [ name = "sp-utils" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "futures-core", "futures-timer 3.0.2", "lazy_static", @@ -8741,23 +8873,14 @@ dependencies = [ "rand 0.5.6", ] -[[package]] -name = "stream-cipher" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f8ed9974042b8c3672ff3030a69fcc03b74c47c3d1ecb7755e8a3626011e88" -dependencies = [ - "generic-array 0.14.3", -] - [[package]] name = "stream-cipher" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c80e15f898d8d8f25db24c253ea615cc14acf418ff307822995814e7d42cfa89" dependencies = [ - "block-cipher 0.8.0", - "generic-array 0.14.3", + "block-cipher", + "generic-array 0.14.4", ] [[package]] @@ -8777,9 +8900,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.15" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" +checksum = "126d630294ec449fae0b16f964e35bf3c74f940da9dca17ee9b905f7b3112eb8" dependencies = [ "clap", "lazy_static", @@ -8788,9 +8911,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.8" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" +checksum = "65e51c492f9e23a220534971ff5afc14037289de430e3c83f9daf6a1b6ae91e8" dependencies = [ "heck", "proc-macro-error", @@ -8853,8 +8976,8 @@ dependencies = [ "chrono", "console_error_panic_hook", "console_log", - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "futures-timer 3.0.2", "js-sys", "kvdb-web", @@ -8895,14 +9018,14 @@ version = "2.0.0" dependencies = [ "frame-support", "frame-system", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-client-transports", "jsonrpc-core", "parity-scale-codec", "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] @@ -8910,7 +9033,7 @@ name = "substrate-frame-rpc-system" version = "2.0.0" dependencies = [ "frame-system-rpc-runtime-api", - "futures 0.3.5", + "futures 0.3.8", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -8937,18 +9060,18 @@ dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.7", + "hyper 0.13.9", "log", "prometheus", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] name = "substrate-test-client" version = "2.0.0" dependencies = [ - "futures 0.1.29", - "futures 0.3.5", + "futures 0.1.30", + "futures 0.3.8", "hash-db", "hex", "parity-scale-codec", @@ -9017,7 +9140,7 @@ dependencies = [ name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "parity-scale-codec", "sc-block-builder", "sc-client-api", @@ -9038,7 +9161,7 @@ name = "substrate-test-runtime-transaction-pool" version = "2.0.0" dependencies = [ "derive_more", - "futures 0.3.5", + "futures 0.3.8", "parity-scale-codec", "parking_lot 0.10.2", "sc-transaction-graph", @@ -9052,10 +9175,10 @@ dependencies = [ name = "substrate-test-utils" version = "2.0.0" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "sc-service", "substrate-test-utils-derive", - "tokio 0.2.22", + "tokio 0.2.23", "trybuild", ] @@ -9074,7 +9197,7 @@ version = "0.1.0" dependencies = [ "sc-service", "substrate-test-utils", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] @@ -9105,9 +9228,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" +checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" [[package]] name = "syn" @@ -9120,17 +9243,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "syn-mid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "synstructure" version = "0.12.4" @@ -9171,9 +9283,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +checksum = "bf11676eb135389f21fcda654382c4859bbfc1d2f36e4425a2f829bb41b1e20e" dependencies = [ "winapi-util", ] @@ -9240,11 +9352,12 @@ dependencies = [ [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi 0.3.9", ] @@ -9260,7 +9373,7 @@ dependencies = [ "pbkdf2 0.4.0", "rand 0.7.3", "rustc-hash", - "sha2 0.9.1", + "sha2 0.9.2", "thiserror", "unicode-normalization", "zeroize", @@ -9287,9 +9400,18 @@ dependencies = [ [[package]] name = "tinyvec" -version = "0.3.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +checksum = "b78a366903f506d2ad52ca8dc552102ffdd3e937ba8a227f024dc1d1eae28575" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" @@ -9298,7 +9420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "mio", "num_cpus", "tokio-codec", @@ -9317,9 +9439,9 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" +checksum = "a6d7ad61edd59bfcc7e80dababf0f4aed2e6d5e0ba1659356ae889752dfc12ff" dependencies = [ "bytes 0.5.6", "fnv", @@ -9346,7 +9468,7 @@ checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ "bytes 0.4.12", "either", - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -9356,7 +9478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "tokio-io", ] @@ -9366,7 +9488,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "tokio-executor", ] @@ -9376,8 +9498,8 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", ] [[package]] @@ -9386,7 +9508,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "tokio-io", "tokio-threadpool", ] @@ -9398,15 +9520,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "log", ] [[package]] name = "tokio-macros" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ "proc-macro2", "quote", @@ -9420,7 +9542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "mio", "mio-named-pipes", "tokio 0.1.22", @@ -9432,8 +9554,8 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "lazy_static", "log", "mio", @@ -9447,13 +9569,13 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9" +checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a" dependencies = [ "futures-core", "rustls", - "tokio 0.2.22", + "tokio 0.2.23", "webpki", ] @@ -9463,7 +9585,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -9473,7 +9595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", - "futures 0.1.29", + "futures 0.1.30", ] [[package]] @@ -9483,7 +9605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "iovec", "mio", "tokio-io", @@ -9496,10 +9618,10 @@ version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" dependencies = [ - "crossbeam-deque", + "crossbeam-deque 0.7.3", "crossbeam-queue", - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "lazy_static", "log", "num_cpus", @@ -9513,8 +9635,8 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ - "crossbeam-utils", - "futures 0.1.29", + "crossbeam-utils 0.7.2", + "futures 0.1.30", "slab", "tokio-executor", ] @@ -9526,7 +9648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "log", "mio", "tokio-codec", @@ -9541,7 +9663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" dependencies = [ "bytes 0.4.12", - "futures 0.1.29", + "futures 0.1.30", "iovec", "libc", "log", @@ -9563,14 +9685,14 @@ dependencies = [ "futures-sink", "log", "pin-project-lite", - "tokio 0.2.22", + "tokio 0.2.23", ] [[package]] name = "toml" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" dependencies = [ "serde", ] @@ -9620,7 +9742,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" dependencies = [ - "pin-project 0.4.22", + "pin-project 0.4.27", "tracing", ] @@ -9647,9 +9769,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd" +checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -9659,7 +9781,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec 1.4.1", + "smallvec 1.5.0", "thread_local", "tracing", "tracing-core", @@ -9691,15 +9813,15 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f1a9a9252d38c5337cf0c5392988821a5cf1b2103245016968f2ab41de9e38" +checksum = "9e55f7ace33d6237e14137e386f4e1672e2a5c6bbc97fef9f438581a143971f0" dependencies = [ "hash-db", - "hashbrown 0.8.1", + "hashbrown 0.8.2", "log", "rustc-hex", - "smallvec 1.4.1", + "smallvec 1.5.0", ] [[package]] @@ -9721,6 +9843,16 @@ dependencies = [ "keccak-hasher", ] +[[package]] +name = "triehash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f490aa7aa4e4d07edeba442c007e42e3e7f43aafb5112c5b047fff0b1aa5449c" +dependencies = [ + "hash-db", + "rlp", +] + [[package]] name = "try-lock" version = "0.2.3" @@ -9744,11 +9876,13 @@ dependencies = [ [[package]] name = "twox-hash" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" +checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ + "cfg-if 0.1.10", "rand 0.7.3", + "static_assertions", ] [[package]] @@ -9765,9 +9899,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "uint" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173cd16430c206dc1a430af8a89a0e9c076cf15cb42b4aedb10e8cc8fee73681" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" dependencies = [ "byteorder", "crunchy", @@ -9795,18 +9929,18 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +checksum = "db8716a166f290ff49dabc18b44aa407cb7c6dbe1aa0971b44b8a24b0ca35aae" [[package]] name = "unicode-width" @@ -9826,8 +9960,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" dependencies = [ - "generic-array 0.14.3", - "subtle 2.2.3", + "generic-array 0.14.4", + "subtle 2.3.0", ] [[package]] @@ -9873,10 +10007,11 @@ dependencies = [ [[package]] name = "url" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" dependencies = [ + "form_urlencoded", "idna 0.2.0", "matches", "percent-encoding 2.1.0", @@ -9923,9 +10058,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" @@ -9944,7 +10079,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ - "futures 0.1.29", + "futures 0.1.30", "log", "try-lock", ] @@ -9965,6 +10100,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasm-bindgen" version = "0.2.67" @@ -10074,7 +10215,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "js-sys", "parking_lot 0.9.0", "pin-utils", @@ -10134,7 +10275,7 @@ dependencies = [ "log", "region", "rustc-demangle", - "smallvec 1.4.1", + "smallvec 1.5.0", "target-lexicon", "wasmparser 0.59.0", "wasmtime-environ", @@ -10277,27 +10418,27 @@ dependencies = [ [[package]] name = "wast" -version = "21.0.0" +version = "27.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1844f66a2bc8526d71690104c0e78a8e59ffa1597b7245769d174ebb91deb5" +checksum = "c2c3ef5f6a72dffa44c24d5811123f704e18a1dbc83637d347b1852b41d3835c" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.22" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce85d72b74242c340e9e3492cfb602652d7bb324c3172dd441b5577e39a2e18c" +checksum = "835cf59c907f67e2bbc20f50157e08f35006fe2a8444d8ec9f5683e22f937045" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.39" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642" +checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47" dependencies = [ "js-sys", "wasm-bindgen", @@ -10323,10 +10464,10 @@ dependencies = [ ] [[package]] -name = "wepoll-sys-stjepang" -version = "1.0.6" +name = "wepoll-sys" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" +checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" dependencies = [ "cc", ] @@ -10393,17 +10534,6 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "x25519-dalek" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" -dependencies = [ - "curve25519-dalek 2.1.0", - "rand_core 0.5.1", - "zeroize", -] - [[package]] name = "x25519-dalek" version = "1.1.0" @@ -10421,10 +10551,10 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aeb8c4043cac71c3c299dff107171c220d179492350ea198e109a414981b83c" dependencies = [ - "futures 0.3.5", + "futures 0.3.8", "log", "nohash-hasher", - "parking_lot 0.11.0", + "parking_lot 0.11.1", "rand 0.7.3", "static_assertions", ] @@ -10440,9 +10570,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" +checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ "proc-macro2", "quote", diff --git a/bin/node/bench/src/tempdb.rs b/bin/node/bench/src/tempdb.rs index 4020fd10293..abce7daa518 100644 --- a/bin/node/bench/src/tempdb.rs +++ b/bin/node/bench/src/tempdb.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use std::{io, sync::Arc}; +use std::{io, path::PathBuf, sync::Arc}; use kvdb::{KeyValueDB, DBTransaction}; use kvdb_rocksdb::{DatabaseConfig, Database}; @@ -124,7 +124,7 @@ impl Clone for TempDatabase { .map(|f_result| f_result.expect("failed to read file in seed db") .path() - ).collect(); + ).collect::>(); fs_extra::copy_items( &self_db_files, new_dir.path(), diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 32e4bab9773..a123da25301 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -172,7 +172,7 @@ impl Clone for BenchDb { .map(|f_result| f_result.expect("failed to read file in seed db") .path() - ).collect(); + ).collect::>(); fs_extra::copy_items( &seed_db_files, dir.path(), -- GitLab From 5f17393cdd9748993b8370d7f166d9538ccdb29c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 20 Nov 2020 14:34:19 +0100 Subject: [PATCH 028/163] .github: Add dependabot config and thus enable dependabot (#7509) * .github: Add dependabot config and thus enable dependabot * Update .github/dependabot.yml Co-authored-by: Pierre Krieger Co-authored-by: Pierre Krieger --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..d782bb80f75 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + labels: ["A2-insubstantial", "B0-silent", "C1-low"] + schedule: + interval: "daily" -- GitLab From faad534b30d78a7e3ff8979cb839635a34680c5b Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 20 Nov 2020 18:54:19 +0100 Subject: [PATCH 029/163] Thread-local parameter_types for testing. (#7542) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Thread-local parameter_types for testing. * Better docs. * Some minors * Merge'em * Update frame/support/src/lib.rs Co-authored-by: Bastian Köcher * Align more to basti's trick * Update frame/support/src/lib.rs * Update frame/support/src/lib.rs Co-authored-by: Bastian Köcher Co-authored-by: Bastian Köcher --- frame/balances/src/tests_composite.rs | 12 +--- frame/balances/src/tests_local.rs | 13 +--- frame/contracts/src/tests.rs | 13 +--- frame/democracy/src/tests.rs | 16 +---- frame/elections-phragmen/src/lib.rs | 38 ++--------- frame/elections/src/mock.rs | 46 ++++---------- frame/elections/src/tests.rs | 12 ++-- frame/membership/src/lib.rs | 8 +-- frame/staking/src/mock.rs | 62 +++--------------- frame/support/src/lib.rs | 92 ++++++++++++++++++++++++--- frame/transaction-payment/src/lib.rs | 23 +------ frame/vesting/src/lib.rs | 10 +-- 12 files changed, 128 insertions(+), 217 deletions(-) diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 88b73b47273..fd4ba1fd3c3 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -27,10 +27,8 @@ use sp_runtime::{ use sp_core::H256; use sp_io; use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; -use frame_support::traits::Get; use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; use pallet_transaction_payment::CurrencyAdapter; -use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; use frame_system as system; @@ -49,15 +47,6 @@ impl_outer_event! { } } -thread_local! { - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); -} - -pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; @@ -66,6 +55,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub static ExistentialDeposit: u64 = 0; } impl frame_system::Trait for Test { type BaseCallFilter = (); diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 319fb3640b4..c0a5d23ff1a 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -27,9 +27,8 @@ use sp_runtime::{ use sp_core::H256; use sp_io; use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; -use frame_support::traits::{Get, StorageMapShim}; +use frame_support::traits::StorageMapShim; use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; -use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; use pallet_transaction_payment::CurrencyAdapter; @@ -49,15 +48,6 @@ impl_outer_event! { } } -thread_local! { - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); -} - -pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; @@ -66,6 +56,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub static ExistentialDeposit: u64 = 0; } impl frame_system::Trait for Test { type BaseCallFilter = (); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index c2d9ed66425..05e46a3ab15 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -30,11 +30,10 @@ use sp_runtime::{ use frame_support::{ assert_ok, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, StorageMap, StorageValue, - traits::{Currency, Get, ReservableCurrency}, + traits::{Currency, ReservableCurrency}, weights::{Weight, PostDispatchInfo}, dispatch::DispatchErrorWithPostInfo, }; -use std::cell::RefCell; use frame_system::{self as system, EventRecord, Phase}; mod contracts { @@ -99,15 +98,6 @@ pub mod test_utils { } } -thread_local! { - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); -} - -pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } -} - #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; parameter_types! { @@ -115,6 +105,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub static ExistentialDeposit: u64 = 0; } impl frame_system::Trait for Test { type BaseCallFilter = (); diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index bcc7099bb34..25209901109 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -18,7 +18,6 @@ //! The crate's tests. use super::*; -use std::cell::RefCell; use codec::Encode; use frame_support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, @@ -154,6 +153,8 @@ parameter_types! { pub const CooloffPeriod: u64 = 2; pub const MaxVotes: u32 = 100; pub const MaxProposals: u32 = MAX_PROPOSALS; + pub static PreimageByteDeposit: u64 = 0; + pub static InstantAllowed: bool = false; } ord_parameter_types! { pub const One: u64 = 1; @@ -171,18 +172,7 @@ impl Contains for OneToFive { #[cfg(feature = "runtime-benchmarks")] fn add(_m: &u64) {} } -thread_local! { - static PREIMAGE_BYTE_DEPOSIT: RefCell = RefCell::new(0); - static INSTANT_ALLOWED: RefCell = RefCell::new(false); -} -pub struct PreimageByteDeposit; -impl Get for PreimageByteDeposit { - fn get() -> u64 { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow()) } -} -pub struct InstantAllowed; -impl Get for InstantAllowed { - fn get() -> bool { INSTANT_ALLOWED.with(|v| *v.borrow()) } -} + impl super::Trait for Test { type Proposal = Call; type Event = Event; diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index be47b5adcce..8279f9cf11f 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1058,7 +1058,6 @@ impl ContainsLengthBound for Module { #[cfg(test)] mod tests { use super::*; - use std::cell::RefCell; use frame_support::{assert_ok, assert_noop, assert_err_with_weight, parameter_types, weights::Weight, }; @@ -1123,36 +1122,13 @@ mod tests { pub const CandidacyBond: u64 = 3; } - thread_local! { - static VOTING_BOND: RefCell = RefCell::new(2); - static DESIRED_MEMBERS: RefCell = RefCell::new(2); - static DESIRED_RUNNERS_UP: RefCell = RefCell::new(2); - static TERM_DURATION: RefCell = RefCell::new(5); - } - - pub struct VotingBond; - impl Get for VotingBond { - fn get() -> u64 { VOTING_BOND.with(|v| *v.borrow()) } - } - - pub struct DesiredMembers; - impl Get for DesiredMembers { - fn get() -> u32 { DESIRED_MEMBERS.with(|v| *v.borrow()) } - } - - pub struct DesiredRunnersUp; - impl Get for DesiredRunnersUp { - fn get() -> u32 { DESIRED_RUNNERS_UP.with(|v| *v.borrow()) } - } - - pub struct TermDuration; - impl Get for TermDuration { - fn get() -> u64 { TERM_DURATION.with(|v| *v.borrow()) } - } - - thread_local! { - pub static MEMBERS: RefCell> = RefCell::new(vec![]); - pub static PRIME: RefCell> = RefCell::new(None); + frame_support::parameter_types! { + pub static VotingBond: u64 = 2; + pub static DesiredMembers: u32 = 2; + pub static DesiredRunnersUp: u32 = 2; + pub static TermDuration: u64 = 5; + pub static Members: Vec = vec![]; + pub static Prime: Option = None; } pub struct TestChangeMembers; diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index deec77da7b8..0d57089af5e 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -19,10 +19,9 @@ #![cfg(test)] -use std::cell::RefCell; use frame_support::{ StorageValue, StorageMap, parameter_types, assert_ok, - traits::{Get, ChangeMembers, Currency, LockIdentifier}, + traits::{ChangeMembers, Currency, LockIdentifier}, weights::Weight, }; use sp_core::H256; @@ -85,34 +84,11 @@ parameter_types! { pub const InactiveGracePeriod: u32 = 1; pub const VotingPeriod: u64 = 4; pub const MinimumVotingLock: u64 = 5; -} - -thread_local! { - static VOTER_BOND: RefCell = RefCell::new(0); - static VOTING_FEE: RefCell = RefCell::new(0); - static PRESENT_SLASH_PER_VOTER: RefCell = RefCell::new(0); - static DECAY_RATIO: RefCell = RefCell::new(0); - static MEMBERS: RefCell> = RefCell::new(vec![]); -} - -pub struct VotingBond; -impl Get for VotingBond { - fn get() -> u64 { VOTER_BOND.with(|v| *v.borrow()) } -} - -pub struct VotingFee; -impl Get for VotingFee { - fn get() -> u64 { VOTING_FEE.with(|v| *v.borrow()) } -} - -pub struct PresentSlashPerVoter; -impl Get for PresentSlashPerVoter { - fn get() -> u64 { PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow()) } -} - -pub struct DecayRatio; -impl Get for DecayRatio { - fn get() -> u32 { DECAY_RATIO.with(|v| *v.borrow()) } + pub static VotingBond: u64 = 0; + pub static VotingFee: u64 = 0; + pub static PresentSlashPerVoter: u64 = 0; + pub static DecayRatio: u32 = 0; + pub static Members: Vec = vec![]; } pub struct TestChangeMembers; @@ -175,7 +151,7 @@ pub struct ExtBuilder { decay_ratio: u32, desired_seats: u32, voting_fee: u64, - voter_bond: u64, + voting_bond: u64, bad_presentation_punishment: u64, } @@ -186,7 +162,7 @@ impl Default for ExtBuilder { decay_ratio: 24, desired_seats: 2, voting_fee: 0, - voter_bond: 0, + voting_bond: 0, bad_presentation_punishment: 1, } } @@ -209,8 +185,8 @@ impl ExtBuilder { self.bad_presentation_punishment = fee; self } - pub fn voter_bond(mut self, fee: u64) -> Self { - self.voter_bond = fee; + pub fn voting_bond(mut self, fee: u64) -> Self { + self.voting_bond = fee; self } pub fn desired_seats(mut self, seats: u32) -> Self { @@ -218,7 +194,7 @@ impl ExtBuilder { self } pub fn build(self) -> sp_io::TestExternalities { - VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); + VOTING_BOND.with(|v| *v.borrow_mut() = self.voting_bond); VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index 92f6e11252b..d3579ca3374 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -298,7 +298,7 @@ fn voting_initial_set_approvals_ignores_voter_index() { } #[test] fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { - ExtBuilder::default().voting_fee(5).voter_bond(2).build().execute_with(|| { + ExtBuilder::default().voting_fee(5).voting_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); (1..=63).for_each(|i| vote(i, 0)); @@ -365,7 +365,7 @@ fn voting_cannot_lock_less_than_limit() { #[test] fn voting_locking_more_than_total_balance_is_moot() { - ExtBuilder::default().voter_bond(2).build().execute_with(|| { + ExtBuilder::default().voting_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_eq!(balances(&3), (30, 0)); @@ -381,7 +381,7 @@ fn voting_locking_more_than_total_balance_is_moot() { #[test] fn voting_locking_stake_and_reserving_bond_works() { - ExtBuilder::default().voter_bond(2).build().execute_with(|| { + ExtBuilder::default().voting_bond(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); assert_eq!(balances(&2), (20, 0)); @@ -558,7 +558,7 @@ fn retracting_inactive_voter_should_work() { #[test] fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - ExtBuilder::default().voter_bond(2).build().execute_with(|| { + ExtBuilder::default().voting_bond(2).build().execute_with(|| { System::set_block_number(4); assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); @@ -1107,7 +1107,7 @@ fn election_present_when_presenter_is_poor_should_not_work() { let test_present = |p| { ExtBuilder::default() .voting_fee(5) - .voter_bond(2) + .voting_bond(2) .bad_presentation_punishment(p) .build() .execute_with(|| { @@ -1507,7 +1507,7 @@ fn pot_winning_resets_accumulated_pot() { #[test] fn pot_resubmitting_approvals_stores_pot() { ExtBuilder::default() - .voter_bond(0) + .voting_bond(0) .voting_fee(0) .balance_factor(10) .build() diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 492fda88dd1..06188c42b21 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -278,7 +278,6 @@ impl, I: Instance> Contains for Module { mod tests { use super::*; - use std::cell::RefCell; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, ord_parameter_types @@ -298,6 +297,8 @@ mod tests { pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub static Members: Vec = vec![]; + pub static Prime: Option = None; } impl frame_system::Trait for Test { type BaseCallFilter = (); @@ -334,11 +335,6 @@ mod tests { pub const Five: u64 = 5; } - thread_local! { - static MEMBERS: RefCell> = RefCell::new(vec![]); - static PRIME: RefCell> = RefCell::new(None); - } - pub struct TestChangeMembers; impl ChangeMembers for TestChangeMembers { fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 055ebb97308..3aa3e9ae03d 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -47,12 +47,6 @@ pub(crate) type Balance = u128; thread_local! { static SESSION: RefCell<(Vec, HashSet)> = RefCell::new(Default::default()); - static SESSION_PER_ERA: RefCell = RefCell::new(3); - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); - static SLASH_DEFER_DURATION: RefCell = RefCell::new(0); - static ELECTION_LOOKAHEAD: RefCell = RefCell::new(0); - static PERIOD: RefCell = RefCell::new(1); - static MAX_ITERATIONS: RefCell = RefCell::new(0); } /// Another session handler struct to test on_disabled. @@ -92,53 +86,6 @@ pub fn is_disabled(controller: AccountId) -> bool { SESSION.with(|d| d.borrow().1.contains(&stash)) } -pub struct ExistentialDeposit; -impl Get for ExistentialDeposit { - fn get() -> Balance { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) - } -} - -pub struct SessionsPerEra; -impl Get for SessionsPerEra { - fn get() -> SessionIndex { - SESSION_PER_ERA.with(|v| *v.borrow()) - } -} -impl Get for SessionsPerEra { - fn get() -> BlockNumber { - SESSION_PER_ERA.with(|v| *v.borrow() as BlockNumber) - } -} - -pub struct ElectionLookahead; -impl Get for ElectionLookahead { - fn get() -> BlockNumber { - ELECTION_LOOKAHEAD.with(|v| *v.borrow()) - } -} - -pub struct Period; -impl Get for Period { - fn get() -> BlockNumber { - PERIOD.with(|v| *v.borrow()) - } -} - -pub struct SlashDeferDuration; -impl Get for SlashDeferDuration { - fn get() -> EraIndex { - SLASH_DEFER_DURATION.with(|v| *v.borrow()) - } -} - -pub struct MaxIterations; -impl Get for MaxIterations { - fn get() -> u32 { - MAX_ITERATIONS.with(|v| *v.borrow()) - } -} - impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } @@ -186,7 +133,14 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MaxLocks: u32 = 1024; + pub static SessionsPerEra: SessionIndex = 3; + pub static ExistentialDeposit: Balance = 0; + pub static SlashDeferDuration: EraIndex = 0; + pub static ElectionLookahead: BlockNumber = 0; + pub static Period: BlockNumber = 1; + pub static MaxIterations: u32 = 0; } + impl frame_system::Trait for Test { type BaseCallFilter = (); type Origin = Origin; @@ -437,7 +391,7 @@ impl ExtBuilder { pub fn set_associated_constants(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = self.slash_defer_duration); - SESSION_PER_ERA.with(|v| *v.borrow_mut() = self.session_per_era); + SESSIONS_PER_ERA.with(|v| *v.borrow_mut() = self.session_per_era); ELECTION_LOOKAHEAD.with(|v| *v.borrow_mut() = self.election_lookahead); PERIOD.with(|v| *v.borrow_mut() = self.session_length); MAX_ITERATIONS.with(|v| *v.borrow_mut() = self.max_offchain_iterations); diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index a132b787fd9..5dd452dbbe7 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -85,21 +85,27 @@ pub enum Never {} /// Create new implementations of the [`Get`](crate::traits::Get) trait. /// -/// The so-called parameter type can be created in three different ways: +/// The so-called parameter type can be created in four different ways: /// -/// - Using `const` to create a parameter type that provides a `const` getter. -/// It is required that the `value` is const. +/// - Using `const` to create a parameter type that provides a `const` getter. It is required that +/// the `value` is const. /// /// - Declare the parameter type without `const` to have more freedom when creating the value. /// -/// - Using `storage` to create a storage parameter type. This type is special as it tries to -/// load the value from the storage under a fixed key. If the value could not be found in the -/// storage, the given default value will be returned. It is required that the value implements -/// [`Encode`](codec::Encode) and [`Decode`](codec::Decode). The key for looking up the value -/// in the storage is built using the following formular: +/// - Using `storage` to create a storage parameter type. This type is special as it tries to load +/// the value from the storage under a fixed key. If the value could not be found in the storage, +/// the given default value will be returned. It is required that the value implements +/// [`Encode`](codec::Encode) and [`Decode`](codec::Decode). The key for looking up the value in +/// the storage is built using the following formula: /// /// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name. /// +/// - Using `static` to create a static parameter type. Its value is +/// being provided by a static variable with the equivalent name in `UPPER_SNAKE_CASE`. An +/// additional `set` function is provided in this case to alter the static variable. +/// +/// **This is intended for testing ONLY and is ONLY available when `std` is enabled** +/// /// # Examples /// /// ``` @@ -114,12 +120,14 @@ pub enum Never {} /// /// Visibility of the type is optional /// OtherArgument: u64 = non_const_expression(); /// pub storage StorageArgument: u64 = 5; +/// pub static StaticArgument: u32 = 7; /// } /// /// trait Config { /// type Parameter: Get; /// type OtherParameter: Get; /// type StorageParameter: Get; +/// type StaticParameter: Get; /// } /// /// struct Runtime; @@ -127,7 +135,10 @@ pub enum Never {} /// type Parameter = Argument; /// type OtherParameter = OtherArgument; /// type StorageParameter = StorageArgument; +/// type StaticParameter = StaticArgument; /// } +/// +/// // In testing, `StaticArgument` can be altered later: `StaticArgument::set(8)`. /// ``` /// /// # Invalid example: @@ -142,7 +153,6 @@ pub enum Never {} /// pub const Argument: u64 = non_const_expression(); /// } /// ``` - #[macro_export] macro_rules! parameter_types { ( @@ -235,7 +245,69 @@ macro_rules! parameter_types { I::from(Self::get()) } } - } + }; + ( + $( + $( #[ $attr:meta ] )* + $vis:vis static $name:ident: $type:ty = $value:expr; + )* + ) => ( + $crate::parameter_types_impl_thread_local!( + $( + $( #[ $attr ] )* + $vis static $name: $type = $value; + )* + ); + ); +} + +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! parameter_types_impl_thread_local { + ( $( $any:tt )* ) => { + compile_error!("static parameter types is only available in std and for testing."); + }; +} + +#[cfg(feature = "std")] +#[macro_export] +macro_rules! parameter_types_impl_thread_local { + ( + $( + $( #[ $attr:meta ] )* + $vis:vis static $name:ident: $type:ty = $value:expr; + )* + ) => { + $crate::parameter_types_impl_thread_local!( + IMPL_THREAD_LOCAL $( $vis, $name, $type, $value, )* + ); + $crate::paste::item! { + $crate::parameter_types!( + $( + $( #[ $attr ] )* + $vis $name: $type = [<$name:snake:upper>].with(|v| v.borrow().clone()); + )* + ); + $( + impl $name { + /// Set the internal value. + pub fn set(t: $type) { + [<$name:snake:upper>].with(|v| *v.borrow_mut() = t); + } + } + )* + } + }; + (IMPL_THREAD_LOCAL $( $vis:vis, $name:ident, $type:ty, $value:expr, )* ) => { + $crate::paste::item! { + thread_local! { + $( + pub static [<$name:snake:upper>]: std::cell::RefCell<$type> = + std::cell::RefCell::new($value); + )* + } + } + }; } /// Macro for easily creating a new implementation of both the `Get` and `Contains` traits. Use diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index dd310c26398..751aa57da0f 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -571,7 +571,6 @@ mod tests { traits::{BlakeTwo256, IdentityLookup}, Perbill, }; - use std::cell::RefCell; use smallvec::smallvec; const CALL: &::Call = @@ -599,20 +598,14 @@ mod tests { pub enum Origin for Runtime {} } - thread_local! { - static EXTRINSIC_BASE_WEIGHT: RefCell = RefCell::new(0); - } - - pub struct ExtrinsicBaseWeight; - impl Get for ExtrinsicBaseWeight { - fn get() -> u64 { EXTRINSIC_BASE_WEIGHT.with(|v| *v.borrow()) } - } - parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub static ExtrinsicBaseWeight: u64 = 0; + pub static TransactionByteFee: u64 = 1; + pub static WeightToFee: u64 = 1; } impl frame_system::Trait for Runtime { @@ -656,17 +649,7 @@ mod tests { type MaxLocks = (); type WeightInfo = (); } - thread_local! { - static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); - static WEIGHT_TO_FEE: RefCell = RefCell::new(1); - } - - pub struct TransactionByteFee; - impl Get for TransactionByteFee { - fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } - } - pub struct WeightToFee; impl WeightToFeePolynomial for WeightToFee { type Balance = u64; diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 8b78eac4fed..c09516c2cc2 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -390,10 +390,8 @@ impl VestingSchedule for Module where mod tests { use super::*; - use std::cell::RefCell; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, - traits::Get }; use sp_core::H256; use sp_runtime::{ @@ -456,6 +454,7 @@ mod tests { } parameter_types! { pub const MinVestedTransfer: u64 = 256 * 2; + pub static ExistentialDeposit: u64 = 0; } impl Trait for Test { type Event = (); @@ -468,13 +467,6 @@ mod tests { type Balances = pallet_balances::Module; type Vesting = Module; - thread_local! { - static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); - } - pub struct ExistentialDeposit; - impl Get for ExistentialDeposit { - fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } - } pub struct ExtBuilder { existential_deposit: u64, -- GitLab From a208da1608712c1bec40fb4a3878187b0a5ea404 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Nov 2020 21:45:51 +0100 Subject: [PATCH 030/163] Bump wasm-bindgen-test from 0.3.12 to 0.3.17 (#7567) * Bump wasm-bindgen-test from 0.3.12 to 0.3.17 Bumps [wasm-bindgen-test](https://github.com/rustwasm/wasm-bindgen) from 0.3.12 to 0.3.17. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) Signed-off-by: dependabot[bot] * Update wasm-bindgen pin to 0.2.68 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pierre Krieger --- Cargo.lock | 32 ++++++++++++++--------------- bin/node/browser-testing/Cargo.toml | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2e9cda8f31..3b905e4bd87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10108,9 +10108,9 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" +checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" dependencies = [ "cfg-if 0.1.10", "serde", @@ -10120,9 +10120,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0" +checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" dependencies = [ "bumpalo", "lazy_static", @@ -10135,9 +10135,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.12" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04" +checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699" dependencies = [ "cfg-if 0.1.10", "js-sys", @@ -10147,9 +10147,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2" +checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10157,9 +10157,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556" +checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" dependencies = [ "proc-macro2", "quote", @@ -10170,15 +10170,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.67" +version = "0.2.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092" +checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" [[package]] name = "wasm-bindgen-test" -version = "0.3.12" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8e9dad8040e378f0696b017570c6bc929aac373180e06b3d67ac5059c52da3" +checksum = "7d92df9d5715606f9e48f85df3b78cb77ae44a2ea9a5f2a785a97bd0066b9300" dependencies = [ "console_error_panic_hook", "js-sys", @@ -10190,9 +10190,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.12" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c358c8d2507c1bae25efa069e62ea907aa28700b25c8c33dafb0b15ba4603627" +checksum = "51611ce8e84cba89379d91fc5074bacc5530f69da1c09a2853d906129d12b3b8" dependencies = [ "proc-macro2", "quote", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index fade57d8124..3ca5a3feaee 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -12,9 +12,9 @@ libp2p = { version = "0.30.1", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" -wasm-bindgen = { version = "=0.2.67", features = ["serde-serialize"] } +wasm-bindgen = { version = "=0.2.68", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.10" -wasm-bindgen-test = "0.3.10" +wasm-bindgen-test = "0.3.17" futures = "0.3.4" node-cli = { path = "../cli", default-features = false, features = ["browser"] , version = "2.0.0"} -- GitLab From 23473cad4f7cf2d7dfc40fb40c98508ae72c612e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sun, 22 Nov 2020 10:01:05 +0100 Subject: [PATCH 031/163] pallet-evm: move to Frontier (Part IV) (#7573) --- Cargo.lock | 138 +------ Cargo.toml | 1 - docs/CODEOWNERS | 3 - frame/evm/Cargo.toml | 51 --- frame/evm/README.md | 29 -- frame/evm/src/backend.rs | 216 ----------- frame/evm/src/lib.rs | 678 ----------------------------------- frame/evm/src/precompiles.rs | 167 --------- frame/evm/src/tests.rs | 189 ---------- 9 files changed, 2 insertions(+), 1470 deletions(-) delete mode 100644 frame/evm/Cargo.toml delete mode 100644 frame/evm/README.md delete mode 100644 frame/evm/src/backend.rs delete mode 100644 frame/evm/src/lib.rs delete mode 100644 frame/evm/src/precompiles.rs delete mode 100644 frame/evm/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 3b905e4bd87..b36d4721b92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1439,23 +1439,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "ethereum" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df706418ff7d3874b9506424b04ea0bef569a2b39412b43a27ea86e679be108e" -dependencies = [ - "ethereum-types", - "hash-db", - "hash256-std-hasher", - "parity-scale-codec", - "rlp", - "rlp-derive", - "serde", - "sha3 0.9.1", - "triehash", -] - [[package]] name = "ethereum-types" version = "0.9.2" @@ -1476,56 +1459,6 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" -[[package]] -name = "evm" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c8deca0ec3efa361b03d9cae6fe94321a1d2d0a523437edd720b3d140e3c08" -dependencies = [ - "ethereum", - "evm-core", - "evm-gasometer", - "evm-runtime", - "log", - "parity-scale-codec", - "primitive-types", - "rlp", - "serde", - "sha3 0.8.2", -] - -[[package]] -name = "evm-core" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2d732b3c36df36833761cf67df8f65866be1d368d20508bc3e13e6f256c8c5" -dependencies = [ - "log", - "primitive-types", -] - -[[package]] -name = "evm-gasometer" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46de1b91ccd744627484183729f1b5af484b3bf15505007fc28cc54264cb9ea1" -dependencies = [ - "evm-core", - "evm-runtime", - "primitive-types", -] - -[[package]] -name = "evm-runtime" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c1d1ffe96f833788512c890d702457d790dba4917ac6f64f8f60fbd9bc40b8" -dependencies = [ - "evm-core", - "primitive-types", - "sha3 0.8.2", -] - [[package]] name = "exit-future" version = "0.2.0" @@ -3248,7 +3181,7 @@ dependencies = [ "pin-project 0.4.27", "rand 0.7.3", "salsa20", - "sha3 0.9.1", + "sha3", ] [[package]] @@ -3740,7 +3673,7 @@ dependencies = [ "digest 0.9.0", "sha-1 0.9.2", "sha2 0.9.2", - "sha3 0.9.1", + "sha3", "unsigned-varint 0.5.1", ] @@ -4686,28 +4619,6 @@ dependencies = [ "substrate-test-utils", ] -[[package]] -name = "pallet-evm" -version = "2.0.0" -dependencies = [ - "evm", - "frame-support", - "frame-system", - "impl-trait-for-tuples", - "pallet-balances", - "pallet-timestamp", - "parity-scale-codec", - "primitive-types", - "ripemd160", - "rlp", - "serde", - "sha3 0.8.2", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-example" version = "2.0.0" @@ -6344,17 +6255,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - [[package]] name = "rlp" version = "0.4.6" @@ -6364,17 +6264,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "rocksdb" version = "0.15.0" @@ -7923,19 +7812,6 @@ dependencies = [ "opaque-debug 0.3.0", ] -[[package]] -name = "sha3" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" -dependencies = [ - "block-buffer 0.7.3", - "byte-tools", - "digest 0.8.1", - "keccak", - "opaque-debug 0.2.3", -] - [[package]] name = "sha3" version = "0.9.1" @@ -9843,16 +9719,6 @@ dependencies = [ "keccak-hasher", ] -[[package]] -name = "triehash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f490aa7aa4e4d07edeba442c007e42e3e7f43aafb5112c5b047fff0b1aa5449c" -dependencies = [ - "hash-db", - "rlp", -] - [[package]] name = "try-lock" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index b78c4da0558..71bf56f9b0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,6 @@ members = [ "frame/democracy", "frame/elections-phragmen", "frame/elections", - "frame/evm", "frame/example", "frame/example-offchain-worker", "frame/example-parallel", diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index b195d5c6570..a3837e16778 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -45,9 +45,6 @@ # Contracts /frame/contracts/ @athei -# EVM -/frame/evm/ @sorpaas - # NPoS and election /frame/staking/ @kianenigma /frame/elections/ @kianenigma diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml deleted file mode 100644 index a228dfb566b..00000000000 --- a/frame/evm/Cargo.toml +++ /dev/null @@ -1,51 +0,0 @@ -[package] -name = "pallet-evm" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME EVM contracts pallet" -readme = "README.md" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } -frame-support = { version = "2.0.0", default-features = false, path = "../support" } -frame-system = { version = "2.0.0", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } -primitive-types = { version = "0.7.0", default-features = false, features = ["rlp", "byteorder"] } -rlp = { version = "0.4", default-features = false } -evm = { version = "0.17", default-features = false } -sha3 = { version = "0.8", default-features = false } -impl-trait-for-tuples = "0.1" -ripemd160 = { version = "0.9", default-features = false } - -[features] -default = ["std"] -std = [ - "serde", - "codec/std", - "sp-core/std", - "sp-runtime/std", - "frame-support/std", - "frame-system/std", - "pallet-balances/std", - "sp-io/std", - "sp-std/std", - "sha3/std", - "rlp/std", - "primitive-types/std", - "evm/std", - "pallet-timestamp/std", - "ripemd160/std", -] diff --git a/frame/evm/README.md b/frame/evm/README.md deleted file mode 100644 index 499a0761cfa..00000000000 --- a/frame/evm/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# EVM Module - -The EVM module allows unmodified EVM code to be executed in a Substrate-based blockchain. -- [`evm::Trait`](https://docs.rs/pallet-evm/2.0.0/pallet_evm/trait.Trait.html) - -## EVM Engine - -The EVM module uses [`SputnikVM`](https://github.com/rust-blockchain/evm) as the underlying EVM engine. The engine is overhauled so that it's [`modular`](https://github.com/corepaper/evm). - -## Execution Lifecycle - -There are a separate set of accounts managed by the EVM module. Substrate based accounts can call the EVM Module to deposit or withdraw balance from the Substrate base-currency into a different balance managed and used by the EVM module. Once a user has populated their balance, they can create and call smart contracts using this module. - -There's one-to-one mapping from Substrate accounts and EVM external accounts that is defined by a conversion function. - -## EVM Module vs Ethereum Network - -The EVM module should be able to produce nearly identical results compared to the Ethereum mainnet, including gas cost and balance changes. - -Observable differences include: - -- The available length of block hashes may not be 256 depending on the configuration of the System module in the Substrate runtime. -- Difficulty and coinbase, which do not make sense in this module and is currently hard coded to zero. - -We currently do not aim to make unobservable behaviors, such as state root, to be the same. We also don't aim to follow the exact same transaction / receipt format. However, given one Ethereum transaction and one Substrate account's private key, one should be able to convert any Ethereum transaction into a transaction compatible with this module. - -The gas configurations are configurable. Right now, a pre-defined Istanbul hard fork configuration option is provided. - -License: Apache-2.0 \ No newline at end of file diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs deleted file mode 100644 index b625c0c5480..00000000000 --- a/frame/evm/src/backend.rs +++ /dev/null @@ -1,216 +0,0 @@ -use sp_std::marker::PhantomData; -use sp_std::vec::Vec; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; -use codec::{Encode, Decode}; -use sp_core::{U256, H256, H160}; -use sp_runtime::traits::UniqueSaturatedInto; -use frame_support::traits::Get; -use frame_support::{debug, storage::{StorageMap, StorageDoubleMap}}; -use sha3::{Keccak256, Digest}; -use evm::backend::{Backend as BackendT, ApplyBackend, Apply}; -use crate::{Trait, AccountStorages, AccountCodes, Module, Event}; - -#[derive(Clone, Eq, PartialEq, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -/// Ethereum account nonce, balance and code. Used by storage. -pub struct Account { - /// Account nonce. - pub nonce: U256, - /// Account balance. - pub balance: U256, -} - -#[derive(Clone, Eq, PartialEq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -/// Ethereum log. Used for `deposit_event`. -pub struct Log { - /// Source address of the log. - pub address: H160, - /// Topics of the log. - pub topics: Vec, - /// Byte array data of the log. - pub data: Vec, -} - -#[derive(Clone, Eq, PartialEq, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -/// External input from the transaction. -pub struct Vicinity { - /// Current transaction gas price. - pub gas_price: U256, - /// Origin of the transaction. - pub origin: H160, -} - -/// Substrate backend for EVM. -pub struct Backend<'vicinity, T> { - vicinity: &'vicinity Vicinity, - _marker: PhantomData, -} - -impl<'vicinity, T> Backend<'vicinity, T> { - /// Create a new backend with given vicinity. - pub fn new(vicinity: &'vicinity Vicinity) -> Self { - Self { vicinity, _marker: PhantomData } - } -} - -impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { - fn gas_price(&self) -> U256 { self.vicinity.gas_price } - fn origin(&self) -> H160 { self.vicinity.origin } - - fn block_hash(&self, number: U256) -> H256 { - if number > U256::from(u32::max_value()) { - H256::default() - } else { - let number = T::BlockNumber::from(number.as_u32()); - H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) - } - } - - fn block_number(&self) -> U256 { - let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); - U256::from(number) - } - - fn block_coinbase(&self) -> H160 { - H160::default() - } - - fn block_timestamp(&self) -> U256 { - let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); - U256::from(now / 1000) - } - - fn block_difficulty(&self) -> U256 { - U256::zero() - } - - fn block_gas_limit(&self) -> U256 { - U256::zero() - } - - fn chain_id(&self) -> U256 { - U256::from(T::ChainId::get()) - } - - fn exists(&self, _address: H160) -> bool { - true - } - - fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Module::::account_basic(&address); - - evm::backend::Basic { - balance: account.balance, - nonce: account.nonce, - } - } - - fn code_size(&self, address: H160) -> usize { - AccountCodes::decode_len(&address).unwrap_or(0) - } - - fn code_hash(&self, address: H160) -> H256 { - H256::from_slice(Keccak256::digest(&AccountCodes::get(&address)).as_slice()) - } - - fn code(&self, address: H160) -> Vec { - AccountCodes::get(&address) - } - - fn storage(&self, address: H160, index: H256) -> H256 { - AccountStorages::get(address, index) - } -} - -impl<'vicinity, T: Trait> ApplyBackend for Backend<'vicinity, T> { - fn apply( - &mut self, - values: A, - logs: L, - delete_empty: bool, - ) where - A: IntoIterator>, - I: IntoIterator, - L: IntoIterator, - { - for apply in values { - match apply { - Apply::Modify { - address, basic, code, storage, reset_storage, - } => { - Module::::mutate_account_basic(&address, Account { - nonce: basic.nonce, - balance: basic.balance, - }); - - if let Some(code) = code { - debug::debug!( - target: "evm", - "Inserting code ({} bytes) at {:?}", - code.len(), - address - ); - AccountCodes::insert(address, code); - } - - if reset_storage { - AccountStorages::remove_prefix(address); - } - - for (index, value) in storage { - if value == H256::default() { - debug::debug!( - target: "evm", - "Removing storage for {:?} [index: {:?}]", - address, - index - ); - AccountStorages::remove(address, index); - } else { - debug::debug!( - target: "evm", - "Updating storage for {:?} [index: {:?}, value: {:?}]", - address, - index, - value - ); - AccountStorages::insert(address, index, value); - } - } - - if delete_empty { - Module::::remove_account_if_empty(&address); - } - }, - Apply::Delete { address } => { - debug::debug!( - target: "evm", - "Deleting account at {:?}", - address - ); - Module::::remove_account(&address) - }, - } - } - - for log in logs { - debug::trace!( - target: "evm", - "Inserting log for {:?}, topics ({}) {:?}, data ({}): {:?}]", - log.address, - log.topics.len(), - log.topics, - log.data.len(), - log.data - ); - Module::::deposit_event(Event::::Log(Log { - address: log.address, - topics: log.topics, - data: log.data, - })); - } - } -} diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs deleted file mode 100644 index e7812a55482..00000000000 --- a/frame/evm/src/lib.rs +++ /dev/null @@ -1,678 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 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. - -//! # EVM Module -//! -//! The EVM module allows unmodified EVM code to be executed in a Substrate-based blockchain. -//! - [`evm::Trait`] -//! -//! ## EVM Engine -//! -//! The EVM module uses [`SputnikVM`](https://github.com/rust-blockchain/evm) as the underlying EVM engine. -//! The engine is overhauled so that it's [`modular`](https://github.com/corepaper/evm). -//! -//! ## Execution Lifecycle -//! -//! There are a separate set of accounts managed by the EVM module. Substrate based accounts can call the EVM Module -//! to deposit or withdraw balance from the Substrate base-currency into a different balance managed and used by -//! the EVM module. Once a user has populated their balance, they can create and call smart contracts using this module. -//! -//! There's one-to-one mapping from Substrate accounts and EVM external accounts that is defined by a conversion function. -//! -//! ## EVM Module vs Ethereum Network -//! -//! The EVM module should be able to produce nearly identical results compared to the Ethereum mainnet, -//! including gas cost and balance changes. -//! -//! Observable differences include: -//! -//! - The available length of block hashes may not be 256 depending on the configuration of the System module -//! in the Substrate runtime. -//! - Difficulty and coinbase, which do not make sense in this module and is currently hard coded to zero. -//! -//! We currently do not aim to make unobservable behaviors, such as state root, to be the same. We also don't aim to follow -//! the exact same transaction / receipt format. However, given one Ethereum transaction and one Substrate account's -//! private key, one should be able to convert any Ethereum transaction into a transaction compatible with this module. -//! -//! The gas configurations are configurable. Right now, a pre-defined Istanbul hard fork configuration option is provided. - -// Ensure we're `no_std` when compiling for Wasm. -#![cfg_attr(not(feature = "std"), no_std)] - -mod backend; -mod tests; -pub mod precompiles; - -pub use crate::precompiles::{Precompile, Precompiles}; -pub use crate::backend::{Account, Log, Vicinity, Backend}; - -use sp_std::vec::Vec; -#[cfg(feature = "std")] -use codec::{Encode, Decode}; -#[cfg(feature = "std")] -use serde::{Serialize, Deserialize}; -use frame_support::{debug, ensure, decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{Weight, Pays}; -use frame_support::traits::{Currency, ExistenceRequirement, Get}; -use frame_support::dispatch::DispatchResultWithPostInfo; -use frame_system::RawOrigin; -use sp_core::{U256, H256, H160, Hasher}; -use sp_runtime::{AccountId32, traits::{UniqueSaturatedInto, SaturatedConversion, BadOrigin}}; -use sha3::{Digest, Keccak256}; -pub use evm::{ExitReason, ExitSucceed, ExitError, ExitRevert, ExitFatal}; -use evm::Config; -use evm::executor::StackExecutor; -use evm::backend::ApplyBackend; - -/// Type alias for currency balance. -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; - -/// Trait that outputs the current transaction gas price. -pub trait FeeCalculator { - /// Return the minimal required gas price. - fn min_gas_price() -> U256; -} - -impl FeeCalculator for () { - fn min_gas_price() -> U256 { U256::zero() } -} - -pub trait EnsureAddressOrigin { - /// Success return type. - type Success; - - /// Perform the origin check. - fn ensure_address_origin( - address: &H160, - origin: OuterOrigin, - ) -> Result { - Self::try_address_origin(address, origin).map_err(|_| BadOrigin) - } - - /// Try with origin. - fn try_address_origin( - address: &H160, - origin: OuterOrigin, - ) -> Result; -} - -/// Ensure that the EVM address is the same as the Substrate address. This only works if the account -/// ID is `H160`. -pub struct EnsureAddressSame; - -impl EnsureAddressOrigin for EnsureAddressSame where - OuterOrigin: Into, OuterOrigin>> + From>, -{ - type Success = H160; - - fn try_address_origin( - address: &H160, - origin: OuterOrigin, - ) -> Result { - origin.into().and_then(|o| match o { - RawOrigin::Signed(who) if &who == address => Ok(who), - r => Err(OuterOrigin::from(r)) - }) - } -} - -/// Ensure that the origin is root. -pub struct EnsureAddressRoot(sp_std::marker::PhantomData); - -impl EnsureAddressOrigin for EnsureAddressRoot where - OuterOrigin: Into, OuterOrigin>> + From>, -{ - type Success = (); - - fn try_address_origin( - _address: &H160, - origin: OuterOrigin, - ) -> Result<(), OuterOrigin> { - origin.into().and_then(|o| match o { - RawOrigin::Root => Ok(()), - r => Err(OuterOrigin::from(r)), - }) - } -} - -/// Ensure that the origin never happens. -pub struct EnsureAddressNever(sp_std::marker::PhantomData); - -impl EnsureAddressOrigin for EnsureAddressNever { - type Success = AccountId; - - fn try_address_origin( - _address: &H160, - origin: OuterOrigin, - ) -> Result { - Err(origin) - } -} - -/// Ensure that the address is truncated hash of the origin. Only works if the account id is -/// `AccountId32`. -pub struct EnsureAddressTruncated; - -impl EnsureAddressOrigin for EnsureAddressTruncated where - OuterOrigin: Into, OuterOrigin>> + From>, -{ - type Success = AccountId32; - - fn try_address_origin( - address: &H160, - origin: OuterOrigin, - ) -> Result { - origin.into().and_then(|o| match o { - RawOrigin::Signed(who) - if AsRef::<[u8; 32]>::as_ref(&who)[0..20] == address[0..20] => Ok(who), - r => Err(OuterOrigin::from(r)) - }) - } -} - -pub trait AddressMapping { - fn into_account_id(address: H160) -> A; -} - -/// Identity address mapping. -pub struct IdentityAddressMapping; - -impl AddressMapping for IdentityAddressMapping { - fn into_account_id(address: H160) -> H160 { address } -} - -/// Hashed address mapping. -pub struct HashedAddressMapping(sp_std::marker::PhantomData); - -impl> AddressMapping for HashedAddressMapping { - fn into_account_id(address: H160) -> AccountId32 { - let mut data = [0u8; 24]; - data[0..4].copy_from_slice(b"evm:"); - data[4..24].copy_from_slice(&address[..]); - let hash = H::hash(&data); - - AccountId32::from(Into::<[u8; 32]>::into(hash)) - } -} - -/// Substrate system chain ID. -pub struct SystemChainId; - -impl Get for SystemChainId { - fn get() -> u64 { - sp_io::misc::chain_id() - } -} - -static ISTANBUL_CONFIG: Config = Config::istanbul(); - -/// EVM module trait -pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { - /// Calculator for current gas price. - type FeeCalculator: FeeCalculator; - - /// Allow the origin to call on behalf of given address. - type CallOrigin: EnsureAddressOrigin; - /// Allow the origin to withdraw on behalf of given address. - type WithdrawOrigin: EnsureAddressOrigin; - - /// Mapping from address to account id. - type AddressMapping: AddressMapping; - /// Currency type for withdraw and balance storage. - type Currency: Currency; - - /// The overarching event type. - type Event: From> + Into<::Event>; - /// Precompiles associated with this EVM engine. - type Precompiles: Precompiles; - /// Chain ID of EVM. - type ChainId: Get; - - /// EVM config used in the module. - fn config() -> &'static Config { - &ISTANBUL_CONFIG - } -} - -#[cfg(feature = "std")] -#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, Serialize, Deserialize)] -/// Account definition used for genesis block construction. -pub struct GenesisAccount { - /// Account nonce. - pub nonce: U256, - /// Account balance. - pub balance: U256, - /// Full account storage. - pub storage: std::collections::BTreeMap, - /// Account code. - pub code: Vec, -} - -decl_storage! { - trait Store for Module as EVM { - AccountCodes get(fn account_codes): map hasher(blake2_128_concat) H160 => Vec; - AccountStorages get(fn account_storages): - double_map hasher(blake2_128_concat) H160, hasher(blake2_128_concat) H256 => H256; - } - - add_extra_genesis { - config(accounts): std::collections::BTreeMap; - build(|config: &GenesisConfig| { - for (address, account) in &config.accounts { - Module::::mutate_account_basic(&address, Account { - balance: account.balance, - nonce: account.nonce, - }); - AccountCodes::insert(address, &account.code); - - for (index, value) in &account.storage { - AccountStorages::insert(address, index, value); - } - } - }); - } -} - -decl_event! { - /// EVM events - pub enum Event where - ::AccountId, - { - /// Ethereum events from contracts. - Log(Log), - /// A contract has been created at given \[address\]. - Created(H160), - /// A \[contract\] was attempted to be created, but the execution failed. - CreatedFailed(H160), - /// A \[contract\] has been executed successfully with states applied. - Executed(H160), - /// A \[contract\] has been executed with errors. States are reverted with only gas fees applied. - ExecutedFailed(H160), - /// A deposit has been made at a given address. \[sender, address, value\] - BalanceDeposit(AccountId, H160, U256), - /// A withdrawal has been made from a given address. \[sender, address, value\] - BalanceWithdraw(AccountId, H160, U256), - } -} - -decl_error! { - pub enum Error for Module { - /// Not enough balance to perform action - BalanceLow, - /// Calculating total fee overflowed - FeeOverflow, - /// Calculating total payment overflowed - PaymentOverflow, - /// Withdraw fee failed - WithdrawFailed, - /// Gas price is too low. - GasPriceTooLow, - /// Nonce is invalid - InvalidNonce, - } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - - fn deposit_event() = default; - - /// Withdraw balance from EVM into currency/balances module. - #[weight = 0] - fn withdraw(origin, address: H160, value: BalanceOf) { - let destination = T::WithdrawOrigin::ensure_address_origin(&address, origin)?; - let address_account_id = T::AddressMapping::into_account_id(address); - - T::Currency::transfer( - &address_account_id, - &destination, - value, - ExistenceRequirement::AllowDeath - )?; - } - - /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] - fn call( - origin, - source: H160, - target: H160, - input: Vec, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - match Self::execute_call( - source, - target, - input, - value, - gas_limit, - gas_price, - nonce, - true, - )? { - (ExitReason::Succeed(_), _, _, _) => { - Module::::deposit_event(Event::::Executed(target)); - }, - (_, _, _, _) => { - Module::::deposit_event(Event::::ExecutedFailed(target)); - }, - } - - Ok(Pays::No.into()) - } - - /// Issue an EVM create operation. This is similar to a contract creation transaction in - /// Ethereum. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] - fn create( - origin, - source: H160, - init: Vec, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - match Self::execute_create( - source, - init, - value, - gas_limit, - gas_price, - nonce, - true, - )? { - (ExitReason::Succeed(_), create_address, _, _) => { - Module::::deposit_event(Event::::Created(create_address)); - }, - (_, create_address, _, _) => { - Module::::deposit_event(Event::::CreatedFailed(create_address)); - }, - } - - Ok(Pays::No.into()) - } - - /// Issue an EVM create2 operation. - #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] - fn create2( - origin, - source: H160, - init: Vec, - salt: H256, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - ) -> DispatchResultWithPostInfo { - T::CallOrigin::ensure_address_origin(&source, origin)?; - - match Self::execute_create2( - source, - init, - salt, - value, - gas_limit, - gas_price, - nonce, - true, - )? { - (ExitReason::Succeed(_), create_address, _, _) => { - Module::::deposit_event(Event::::Created(create_address)); - }, - (_, create_address, _, _) => { - Module::::deposit_event(Event::::CreatedFailed(create_address)); - }, - } - - Ok(Pays::No.into()) - } - } -} - -impl Module { - fn remove_account(address: &H160) { - AccountCodes::remove(address); - AccountStorages::remove_prefix(address); - } - - fn mutate_account_basic(address: &H160, new: Account) { - let account_id = T::AddressMapping::into_account_id(*address); - let current = Self::account_basic(address); - - if current.nonce < new.nonce { - // ASSUME: in one single EVM transaction, the nonce will not increase more than - // `u128::max_value()`. - for _ in 0..(new.nonce - current.nonce).low_u128() { - frame_system::Module::::inc_account_nonce(&account_id); - } - } - - if current.balance > new.balance { - let diff = current.balance - new.balance; - T::Currency::slash(&account_id, diff.low_u128().unique_saturated_into()); - } else if current.balance < new.balance { - let diff = new.balance - current.balance; - T::Currency::deposit_creating(&account_id, diff.low_u128().unique_saturated_into()); - } - } - - /// Check whether an account is empty. - pub fn is_account_empty(address: &H160) -> bool { - let account = Self::account_basic(address); - let code_len = AccountCodes::decode_len(address).unwrap_or(0); - - account.nonce == U256::zero() && - account.balance == U256::zero() && - code_len == 0 - } - - /// Remove an account if its empty. - pub fn remove_account_if_empty(address: &H160) { - if Self::is_account_empty(address) { - Self::remove_account(address); - } - } - - /// Get the account basic in EVM format. - pub fn account_basic(address: &H160) -> Account { - let account_id = T::AddressMapping::into_account_id(*address); - - let nonce = frame_system::Module::::account_nonce(&account_id); - let balance = T::Currency::free_balance(&account_id); - - Account { - nonce: U256::from(UniqueSaturatedInto::::unique_saturated_into(nonce)), - balance: U256::from(UniqueSaturatedInto::::unique_saturated_into(balance)), - } - } - - /// Execute a create transaction on behalf of given sender. - pub fn execute_create( - source: H160, - init: Vec, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - apply_state: bool, - ) -> Result<(ExitReason, H160, U256, Vec), Error> { - Self::execute_evm( - source, - value, - gas_limit, - gas_price, - nonce, - apply_state, - |executor| { - let address = executor.create_address( - evm::CreateScheme::Legacy { caller: source }, - ); - (executor.transact_create( - source, - value, - init, - gas_limit as usize, - ), address) - }, - ) - } - - /// Execute a create2 transaction on behalf of a given sender. - pub fn execute_create2( - source: H160, - init: Vec, - salt: H256, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - apply_state: bool, - ) -> Result<(ExitReason, H160, U256, Vec), Error> { - let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); - Self::execute_evm( - source, - value, - gas_limit, - gas_price, - nonce, - apply_state, - |executor| { - let address = executor.create_address( - evm::CreateScheme::Create2 { caller: source, code_hash, salt }, - ); - (executor.transact_create2( - source, - value, - init, - salt, - gas_limit as usize, - ), address) - }, - ) - } - - /// Execute a call transaction on behalf of a given sender. - pub fn execute_call( - source: H160, - target: H160, - input: Vec, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - apply_state: bool, - ) -> Result<(ExitReason, Vec, U256, Vec), Error> { - Self::execute_evm( - source, - value, - gas_limit, - gas_price, - nonce, - apply_state, - |executor| executor.transact_call( - source, - target, - value, - input, - gas_limit as usize, - ), - ) - } - - /// Execute an EVM operation. - fn execute_evm( - source: H160, - value: U256, - gas_limit: u32, - gas_price: U256, - nonce: Option, - apply_state: bool, - f: F, - ) -> Result<(ExitReason, R, U256, Vec), Error> where - F: FnOnce(&mut StackExecutor>) -> (ExitReason, R), - { - - // Gas price check is skipped when performing a gas estimation. - if apply_state { - ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); - } - - let vicinity = Vicinity { - gas_price, - origin: source, - }; - - let mut backend = Backend::::new(&vicinity); - let mut executor = StackExecutor::new_with_precompile( - &backend, - gas_limit as usize, - T::config(), - T::Precompiles::execute, - ); - - let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or(Error::::FeeOverflow)?; - let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Self::account_basic(&source); - ensure!(source_account.balance >= total_payment, Error::::BalanceLow); - executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; - - if let Some(nonce) = nonce { - ensure!(source_account.nonce == nonce, Error::::InvalidNonce); - } - - let (retv, reason) = f(&mut executor); - - let used_gas = U256::from(executor.used_gas()); - let actual_fee = executor.fee(gas_price); - debug::debug!( - target: "evm", - "Execution {:?} [source: {:?}, value: {}, gas_limit: {}, used_gas: {}, actual_fee: {}]", - retv, - source, - value, - gas_limit, - used_gas, - actual_fee - ); - executor.deposit(source, total_fee.saturating_sub(actual_fee)); - - let (values, logs) = executor.deconstruct(); - let logs_data = logs.into_iter().map(|x| x ).collect::>(); - let logs_result = logs_data.clone().into_iter().map(|it| { - Log { - address: it.address, - topics: it.topics, - data: it.data - } - }).collect(); - if apply_state { - backend.apply(values, logs_data, true); - } - - Ok((retv, reason, used_gas, logs_result)) - } -} diff --git a/frame/evm/src/precompiles.rs b/frame/evm/src/precompiles.rs deleted file mode 100644 index 440d9bf1c68..00000000000 --- a/frame/evm/src/precompiles.rs +++ /dev/null @@ -1,167 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 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. - -//! Builtin precompiles. - -use sp_std::{cmp::min, vec::Vec}; -use sp_core::H160; -use evm::{ExitError, ExitSucceed}; -use ripemd160::Digest; -use impl_trait_for_tuples::impl_for_tuples; - -/// Custom precompiles to be used by EVM engine. -pub trait Precompiles { - /// Try to execute the code address as precompile. If the code address is not - /// a precompile or the precompile is not yet available, return `None`. - /// Otherwise, calculate the amount of gas needed with given `input` and - /// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution - /// is successful. Otherwise return `Some(Err(_))`. - fn execute( - address: H160, - input: &[u8], - target_gas: Option, - ) -> Option, usize), ExitError>>; -} - -/// One single precompile used by EVM engine. -pub trait Precompile { - /// Try to execute the precompile. Calculate the amount of gas needed with given `input` and - /// `target_gas`. Return `Ok(status, output, gas_used)` if the execution is - /// successful. Otherwise return `Err(_)`. - fn execute( - input: &[u8], - target_gas: Option, - ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError>; -} - -#[impl_for_tuples(16)] -#[tuple_types_no_default_trait_bound] -impl Precompiles for Tuple { - for_tuples!( where #( Tuple: Precompile )* ); - - fn execute( - address: H160, - input: &[u8], - target_gas: Option, - ) -> Option, usize), ExitError>> { - let mut index = 0; - - for_tuples!( #( - index += 1; - if address == H160::from_low_u64_be(index) { - return Some(Tuple::execute(input, target_gas)) - } - )* ); - - None - } -} - -/// Linear gas cost -fn ensure_linear_cost( - target_gas: Option, - len: usize, - base: usize, - word: usize -) -> Result { - let cost = base.checked_add( - word.checked_mul(len.saturating_add(31) / 32).ok_or(ExitError::OutOfGas)? - ).ok_or(ExitError::OutOfGas)?; - - if let Some(target_gas) = target_gas { - if cost > target_gas { - return Err(ExitError::OutOfGas) - } - } - - Ok(cost) -} - -/// The identity precompile. -pub struct Identity; - -impl Precompile for Identity { - fn execute( - input: &[u8], - target_gas: Option, - ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { - let cost = ensure_linear_cost(target_gas, input.len(), 15, 3)?; - - Ok((ExitSucceed::Returned, input.to_vec(), cost)) - } -} - -/// The ecrecover precompile. -pub struct ECRecover; - -impl Precompile for ECRecover { - fn execute( - i: &[u8], - target_gas: Option, - ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { - let cost = ensure_linear_cost(target_gas, i.len(), 3000, 0)?; - - let mut input = [0u8; 128]; - input[..min(i.len(), 128)].copy_from_slice(&i[..min(i.len(), 128)]); - - let mut msg = [0u8; 32]; - let mut sig = [0u8; 65]; - - msg[0..32].copy_from_slice(&input[0..32]); - sig[0..32].copy_from_slice(&input[64..96]); - sig[32..64].copy_from_slice(&input[96..128]); - sig[64] = input[63]; - - let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) - .map_err(|_| ExitError::Other("Public key recover failed"))?; - let mut address = sp_io::hashing::keccak_256(&pubkey); - address[0..12].copy_from_slice(&[0u8; 12]); - - Ok((ExitSucceed::Returned, address.to_vec(), cost)) - } -} - -/// The ripemd precompile. -pub struct Ripemd160; - -impl Precompile for Ripemd160 { - fn execute( - input: &[u8], - target_gas: Option, - ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { - let cost = ensure_linear_cost(target_gas, input.len(), 600, 120)?; - - let mut ret = [0u8; 32]; - ret[12..32].copy_from_slice(&ripemd160::Ripemd160::digest(input)); - Ok((ExitSucceed::Returned, ret.to_vec(), cost)) - } -} - -/// The sha256 precompile. -pub struct Sha256; - -impl Precompile for Sha256 { - fn execute( - input: &[u8], - target_gas: Option, - ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { - let cost = ensure_linear_cost(target_gas, input.len(), 60, 12)?; - - let ret = sp_io::hashing::sha2_256(input); - Ok((ExitSucceed::Returned, ret.to_vec(), cost)) - } -} diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs deleted file mode 100644 index d05fdca1407..00000000000 --- a/frame/evm/src/tests.rs +++ /dev/null @@ -1,189 +0,0 @@ -#![cfg(test)] - -use super::*; - -use std::{str::FromStr, collections::BTreeMap}; -use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, -}; -use sp_core::{Blake2Hasher, H256}; -use sp_runtime::{ - Perbill, - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, -}; - -impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} -} - -impl_outer_dispatch! { - pub enum OuterCall for Test where origin: Origin { - self::EVM, - } -} - -#[derive(Clone, Eq, PartialEq)] -pub struct Test; -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); -} -impl frame_system::Trait for Test { - type BaseCallFilter = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Call = OuterCall; - type Hashing = BlakeTwo256; - type AccountId = AccountId32; - type Lookup = IdentityLookup; - type Header = Header; - type Event = (); - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = (); - type PalletInfo = (); - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); -} - -parameter_types! { - pub const ExistentialDeposit: u64 = 1; -} -impl pallet_balances::Trait for Test { - type MaxLocks = (); - type Balance = u64; - type DustRemoval = (); - type Event = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); -} - -parameter_types! { - pub const MinimumPeriod: u64 = 1000; -} -impl pallet_timestamp::Trait for Test { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -/// Fixed gas price of `0`. -pub struct FixedGasPrice; -impl FeeCalculator for FixedGasPrice { - fn min_gas_price() -> U256 { - // Gas price is always one token per gas. - 0.into() - } -} - -impl Trait for Test { - type FeeCalculator = FixedGasPrice; - - type CallOrigin = EnsureAddressRoot; - type WithdrawOrigin = EnsureAddressNever; - - type AddressMapping = HashedAddressMapping; - type Currency = Balances; - - type Event = Event; - type Precompiles = (); - type ChainId = SystemChainId; -} - -type System = frame_system::Module; -type Balances = pallet_balances::Module; -type EVM = Module; - -pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - let mut accounts = BTreeMap::new(); - accounts.insert( - H160::from_str("1000000000000000000000000000000000000001").unwrap(), - GenesisAccount { - nonce: U256::from(1), - balance: U256::from(1000000), - storage: Default::default(), - code: vec![ - 0x00, // STOP - ], - } - ); - accounts.insert( - H160::from_str("1000000000000000000000000000000000000002").unwrap(), - GenesisAccount { - nonce: U256::from(1), - balance: U256::from(1000000), - storage: Default::default(), - code: vec![ - 0xff, // INVALID - ], - } - ); - - pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); - GenesisConfig { accounts }.assimilate_storage::(&mut t).unwrap(); - t.into() -} - -#[test] -fn fail_call_return_ok() { - new_test_ext().execute_with(|| { - assert_ok!(EVM::call( - Origin::root(), - H160::default(), - H160::from_str("1000000000000000000000000000000000000001").unwrap(), - Vec::new(), - U256::default(), - 1000000, - U256::default(), - None, - )); - - assert_ok!(EVM::call( - Origin::root(), - H160::default(), - H160::from_str("1000000000000000000000000000000000000002").unwrap(), - Vec::new(), - U256::default(), - 1000000, - U256::default(), - None, - )); - }); -} - -#[test] -fn mutate_account_works() { - new_test_ext().execute_with(|| { - EVM::mutate_account_basic( - &H160::from_str("1000000000000000000000000000000000000001").unwrap(), - Account { - nonce: U256::from(10), - balance: U256::from(1000), - }, - ); - - assert_eq!(EVM::account_basic( - &H160::from_str("1000000000000000000000000000000000000001").unwrap() - ), Account { - nonce: U256::from(10), - balance: U256::from(1000), - }); - }); -} -- GitLab From 24eec92e3f5a7a13440ad3ac5ba9829e6ba53fcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Nov 2020 12:57:21 +0100 Subject: [PATCH 032/163] Bump secrecy from 0.6.0 to 0.7.0 (#7568) * Bump secrecy from 0.6.0 to 0.7.0 Bumps [secrecy](https://github.com/iqlusioninc/crates) from 0.6.0 to 0.7.0. - [Release notes](https://github.com/iqlusioninc/crates/releases) - [Commits](https://github.com/iqlusioninc/crates/compare/secrecy/v0.6.0...secrecy/v0.7.0) Signed-off-by: dependabot[bot] * Fix compilation errors Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pierre Krieger --- Cargo.lock | 4 ++-- client/cli/src/params/keystore_params.rs | 23 +++++++---------------- primitives/core/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b36d4721b92..4741b67c6de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7648,9 +7648,9 @@ dependencies = [ [[package]] name = "secrecy" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +checksum = "0673d6a6449f5e7d12a1caf424fd9363e2af3a4953023ed455e3c4beef4597c0" dependencies = [ "zeroize", ] diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs index 3c04d631445..2ecd21cb3dd 100644 --- a/client/cli/src/params/keystore_params.rs +++ b/client/cli/src/params/keystore_params.rs @@ -22,8 +22,7 @@ use std::fs; use std::path::PathBuf; use structopt::StructOpt; use crate::error; -use sp_core::crypto::{SecretString, Zeroize}; -use std::str::FromStr; +use sp_core::crypto::SecretString; /// default sub directory for the key store const DEFAULT_KEYSTORE_CONFIG_PATH: &'static str = "keystore"; @@ -72,21 +71,15 @@ impl KeystoreParams { let password = if self.password_interactive { #[cfg(not(target_os = "unknown"))] { - let mut password = input_keystore_password()?; - let secret = std::str::FromStr::from_str(password.as_str()) - .map_err(|()| "Error reading password")?; - password.zeroize(); - Some(secret) + let password = input_keystore_password()?; + Some(SecretString::new(password)) } #[cfg(target_os = "unknown")] None } else if let Some(ref file) = self.password_filename { - let mut password = fs::read_to_string(file) + let password = fs::read_to_string(file) .map_err(|e| format!("{}", e))?; - let secret = std::str::FromStr::from_str(password.as_str()) - .map_err(|()| "Error reading password")?; - password.zeroize(); - Some(secret) + Some(SecretString::new(password)) } else { self.password.clone() }; @@ -104,10 +97,8 @@ impl KeystoreParams { let (password_interactive, password) = (self.password_interactive, self.password.clone()); let pass = if password_interactive { - let mut password = rpassword::read_password_from_tty(Some("Key password: "))?; - let pass = Some(FromStr::from_str(&password).map_err(|()| "Error reading password")?); - password.zeroize(); - pass + let password = rpassword::read_password_from_tty(Some("Key password: "))?; + Some(SecretString::new(password)) } else { password }; diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index f6989a0df4f..5044a1d6691 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -30,7 +30,7 @@ tiny-bip39 = { version = "0.8", optional = true } regex = { version = "1.3.1", optional = true } num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } -secrecy = { version = "0.6.0", default-features = false } +secrecy = { version = "0.7.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } -- GitLab From 756212f36693491b232d98942f437ad054a0510e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Nov 2020 21:04:39 +0100 Subject: [PATCH 033/163] Bump wasm-bindgen-futures from 0.4.17 to 0.4.18 (#7572) Bumps [wasm-bindgen-futures](https://github.com/rustwasm/wasm-bindgen) from 0.4.17 to 0.4.18. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- bin/node/browser-testing/Cargo.toml | 2 +- bin/node/cli/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4741b67c6de..52a1283fa06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2622,9 +2622,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.44" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73" +checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" dependencies = [ "wasm-bindgen", ] @@ -10001,9 +10001,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699" +checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da" dependencies = [ "cfg-if 0.1.10", "js-sys", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index 3ca5a3feaee..3b656a03225 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -13,7 +13,7 @@ jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" wasm-bindgen = { version = "=0.2.68", features = ["serde-serialize"] } -wasm-bindgen-futures = "0.4.10" +wasm-bindgen-futures = "0.4.18" wasm-bindgen-test = "0.3.17" futures = "0.3.4" diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 26a23ce36ec..604f4132ee1 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -102,7 +102,7 @@ node-inspect = { version = "0.8.0", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } -wasm-bindgen-futures = { version = "0.4.7", optional = true } +wasm-bindgen-futures = { version = "0.4.18", optional = true } browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0"} [target.'cfg(target_arch="x86_64")'.dependencies] diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 9efc8c39668..4f35cd98803 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -21,7 +21,7 @@ console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" wasm-bindgen = "0.2.57" -wasm-bindgen-futures = "0.4.7" +wasm-bindgen-futures = "0.4.18" kvdb-web = "0.7" sp-database = { version = "2.0.0", path = "../../primitives/database" } sc-informant = { version = "0.8.0", path = "../../client/informant" } -- GitLab From 6c83f394219ec4460f13d6acf1799842edcc79ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Nov 2020 12:05:14 +0100 Subject: [PATCH 034/163] Bump lru from 0.4.3 to 0.6.1 (#7577) Bumps [lru](https://github.com/jeromefroe/lru-rs) from 0.4.3 to 0.6.1. - [Release notes](https://github.com/jeromefroe/lru-rs/releases) - [Changelog](https://github.com/jeromefroe/lru-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/jeromefroe/lru-rs/compare/0.4.3...0.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 15 +++------------ client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- primitives/blockchain/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52a1283fa06..de67db412fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3418,15 +3418,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "lru" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237" -dependencies = [ - "hashbrown 0.6.3", -] - [[package]] name = "lru" version = "0.5.3" @@ -7116,7 +7107,7 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log", - "lru 0.4.3", + "lru 0.6.1", "nohash-hasher", "parity-scale-codec", "parking_lot 0.10.2", @@ -7162,7 +7153,7 @@ dependencies = [ "futures-timer 3.0.2", "libp2p", "log", - "lru 0.4.3", + "lru 0.6.1", "quickcheck", "rand 0.7.3", "sc-network", @@ -8109,7 +8100,7 @@ name = "sp-blockchain" version = "2.0.0" dependencies = [ "log", - "lru 0.4.3", + "lru 0.6.1", "parity-scale-codec", "parking_lot 0.10.2", "sp-block-builder", diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index c120ff515c7..02d93453239 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -19,7 +19,7 @@ futures = "0.3.4" futures-timer = "3.0.1" libp2p = { version = "0.30.1", default-features = false } log = "0.4.8" -lru = "0.4.3" +lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } wasm-timer = "0.2" diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 6b66fd0cdee..80353183ec9 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -36,7 +36,7 @@ ip_network = "0.3.4" linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" -lru = "0.4.0" +lru = "0.6.1" nohash-hasher = "0.2.0" parking_lot = "0.10.0" pin-project = "0.4.6" diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index f714aaaa1da..7b7c0f3446e 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.11" -lru = "0.4.0" +lru = "0.6.1" parking_lot = "0.10.0" thiserror = "1.0.21" codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -- GitLab From 40e08ee4c03a93b343781a3d667203fd87e8a105 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Nov 2020 12:06:56 +0100 Subject: [PATCH 035/163] Bump wasm-bindgen-test from 0.3.17 to 0.3.18 (#7579) Bumps [wasm-bindgen-test](https://github.com/rustwasm/wasm-bindgen) from 0.3.17 to 0.3.18. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- bin/node/browser-testing/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de67db412fc..a66618d92b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10033,9 +10033,9 @@ checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" [[package]] name = "wasm-bindgen-test" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d92df9d5715606f9e48f85df3b78cb77ae44a2ea9a5f2a785a97bd0066b9300" +checksum = "34d1cdc8b98a557f24733d50a1199c4b0635e465eecba9c45b214544da197f64" dependencies = [ "console_error_panic_hook", "js-sys", @@ -10047,9 +10047,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51611ce8e84cba89379d91fc5074bacc5530f69da1c09a2853d906129d12b3b8" +checksum = "e8fb9c67be7439ee8ab1b7db502a49c05e51e2835b66796c705134d9b8e1a585" dependencies = [ "proc-macro2", "quote", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index 3b656a03225..e072607a7b6 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -14,7 +14,7 @@ serde = "1.0.106" serde_json = "1.0.48" wasm-bindgen = { version = "=0.2.68", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.18" -wasm-bindgen-test = "0.3.17" +wasm-bindgen-test = "0.3.18" futures = "0.3.4" node-cli = { path = "../cli", default-features = false, features = ["browser"] , version = "2.0.0"} -- GitLab From 0fcbef2e12abe14d9502e4273b335a7a245a8193 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Nov 2020 13:16:43 +0100 Subject: [PATCH 036/163] Bump wasm-timer from 0.2.4 to 0.2.5 (#7578) Bumps [wasm-timer](https://github.com/tomaka/wasm-timer) from 0.2.4 to 0.2.5. - [Release notes](https://github.com/tomaka/wasm-timer/releases) - [Commits](https://github.com/tomaka/wasm-timer/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 +++---------- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a66618d92b3..70d60f0d9f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7694,12 +7694,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "send_wrapper" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" - [[package]] name = "send_wrapper" version = "0.3.0" @@ -10068,15 +10062,14 @@ dependencies = [ [[package]] name = "wasm-timer" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ "futures 0.3.8", "js-sys", - "parking_lot 0.9.0", + "parking_lot 0.11.1", "pin-utils", - "send_wrapper 0.2.0", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index bff7842bec4..fab0fe00869 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" -wasm-timer = "0.2.0" +wasm-timer = "0.2.5" libp2p = { version = "0.30.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 001f0e36794..938745048c1 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -33,7 +33,7 @@ codec = { package = "parity-scale-codec", version = "1.3.1", features = ["derive parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0"} -wasm-timer = "0.2.4" +wasm-timer = "0.2.5" [dev-dependencies] futures = "0.3.4" -- GitLab From f16acffe37285a93b793672c63146f8ecdab7a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Mon, 23 Nov 2020 14:28:55 +0000 Subject: [PATCH 037/163] grandpa: remove light-client specific block import pipeline (#7546) * grandpa: remove light-client specific block import * consensus, network: remove finality proofs --- .../substrate-dashboard.json | 102 -- bin/node-template/node/src/service.rs | 30 +- bin/node/cli/src/service.rs | 37 +- bin/node/testing/src/bench.rs | 1 - client/consensus/aura/src/lib.rs | 4 +- client/consensus/babe/src/lib.rs | 6 +- client/consensus/babe/src/tests.rs | 8 +- client/consensus/manual-seal/src/lib.rs | 4 - client/consensus/pow/src/lib.rs | 4 +- client/finality-grandpa/src/aux_schema.rs | 22 - .../finality-grandpa/src/consensus_changes.rs | 78 -- client/finality-grandpa/src/environment.rs | 91 +- client/finality-grandpa/src/finality_proof.rs | 41 +- client/finality-grandpa/src/import.rs | 15 +- client/finality-grandpa/src/lib.rs | 6 - client/finality-grandpa/src/light_import.rs | 880 ------------------ client/finality-grandpa/src/observer.rs | 5 - client/finality-grandpa/src/tests.rs | 186 +--- client/network/build.rs | 1 - client/network/src/behaviour.rs | 34 +- client/network/src/chain.rs | 12 - client/network/src/config.rs | 32 +- client/network/src/finality_requests.rs | 403 -------- client/network/src/gossip/tests.rs | 3 - client/network/src/lib.rs | 1 - client/network/src/protocol.rs | 77 +- client/network/src/protocol/message.rs | 32 +- client/network/src/protocol/sync.rs | 158 +--- .../src/protocol/sync/extra_requests.rs | 5 +- client/network/src/schema.rs | 3 - client/network/src/schema/finality.v1.proto | 19 - client/network/src/service.rs | 39 +- client/network/src/service/metrics.rs | 5 - client/network/src/service/tests.rs | 3 - client/network/test/src/block_import.rs | 1 - client/network/test/src/lib.rs | 35 +- client/service/src/builder.rs | 10 +- client/service/src/lib.rs | 2 +- .../consensus/common/src/block_import.rs | 24 +- .../consensus/common/src/import_queue.rs | 29 +- .../common/src/import_queue/basic_queue.rs | 128 +-- .../common/src/import_queue/buffered_link.rs | 20 - primitives/consensus/common/src/lib.rs | 2 +- primitives/consensus/common/src/metrics.rs | 10 - 44 files changed, 96 insertions(+), 2512 deletions(-) delete mode 100644 client/finality-grandpa/src/consensus_changes.rs delete mode 100644 client/finality-grandpa/src/light_import.rs delete mode 100644 client/network/src/finality_requests.rs delete mode 100644 client/network/src/schema/finality.v1.proto diff --git a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json index 629b22617b2..a61e8a49bad 100644 --- a/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json +++ b/.maintain/monitoring/grafana-dashboards/substrate-dashboard.json @@ -756,108 +756,6 @@ "alignLevel": null } }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 6, - "w": 6, - "x": 0, - "y": 12 - }, - "hiddenSeries": false, - "id": 23, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "dataLinks": [] - }, - "percentage": false, - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "[[metric_namespace]]_sync_extra_finality_proofs_active{instance=\"[[instance]]\",network=\"[[network]]\"}", - "legendFormat": "{{instance}} active", - "refId": "A" - }, - { - "expr": "[[metric_namespace]]_sync_extra_finality_proofs_failed{instance=\"[[instance]]\",network=\"[[network]]\"}", - "legendFormat": "{{instance}} failed", - "refId": "B" - }, - { - "expr": "[[metric_namespace]]_sync_extra_finality_proofs_importing{instance=\"[[instance]]\",network=\"[[network]]\"}", - "legendFormat": "{{instance}} importing", - "refId": "C" - }, - { - "expr": "[[metric_namespace]]_sync_extra_finality_proofs_pending{instance=\"[[instance]]\",network=\"[[network]]\"}", - "legendFormat": "{{instance}} pending", - "refId": "D" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Sync Proof", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, { "aliasColors": {}, "bars": false, diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index d85de7c840d..83481f8c152 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -9,7 +9,7 @@ use sp_inherents::InherentDataProviders; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; -use sc_finality_grandpa::{FinalityProofProvider as GrandpaFinalityProofProvider, SharedVoterState}; +use sc_finality_grandpa::SharedVoterState; // Our native executor instance. native_executor_instance!( @@ -64,7 +64,6 @@ pub fn new_partial(config: &Configuration) -> Result Result { other: (block_import, grandpa_link), } = new_partial(&config)?; - let finality_proof_provider = - GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); - let (network, network_status_sinks, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -99,8 +95,6 @@ pub fn new_full(config: Configuration) -> Result { import_queue, on_demand: None, block_announce_validator_builder: None, - finality_proof_request_builder: None, - finality_proof_provider: Some(finality_proof_provider.clone()), })?; if config.offchain_worker.enabled { @@ -229,6 +223,8 @@ pub fn new_light(config: Configuration) -> Result { let (client, backend, keystore_container, mut task_manager, on_demand) = sc_service::new_light_parts::(&config)?; + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( config.transaction_pool.clone(), config.prometheus_registry(), @@ -237,19 +233,16 @@ pub fn new_light(config: Configuration) -> Result { on_demand.clone(), )); - let grandpa_block_import = sc_finality_grandpa::light_block_import( - client.clone(), backend.clone(), &(client.clone() as Arc<_>), - Arc::new(on_demand.checker().clone()) as Arc<_>, + let (grandpa_block_import, _) = sc_finality_grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), )?; - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( sc_consensus_aura::slot_duration(&*client)?, - grandpa_block_import, - None, - Some(Box::new(finality_proof_import)), + grandpa_block_import.clone(), + Some(Box::new(grandpa_block_import)), client.clone(), InherentDataProviders::new(), &task_manager.spawn_handle(), @@ -257,9 +250,6 @@ pub fn new_light(config: Configuration) -> Result { sp_consensus::NeverCanAuthor, )?; - let finality_proof_provider = - GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); - let (network, network_status_sinks, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -269,8 +259,6 @@ pub fn new_light(config: Configuration) -> Result { import_queue, on_demand: Some(on_demand.clone()), block_announce_validator_builder: None, - finality_proof_request_builder: Some(finality_proof_request_builder), - finality_proof_provider: Some(finality_proof_provider), })?; if config.offchain_worker.enabled { diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 3bc406b84fc..9d7c9bb1b7a 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -22,7 +22,6 @@ use std::sync::Arc; use sc_consensus_babe; -use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_primitives::Block; use node_runtime::RuntimeApi; use sc_service::{ @@ -57,10 +56,7 @@ pub fn new_partial(config: &Configuration) -> Result, sc_consensus_babe::BabeLink, ), - ( - grandpa::SharedVoterState, - Arc>, - ), + grandpa::SharedVoterState, ) >, ServiceError> { let (client, backend, keystore_container, task_manager) = @@ -93,7 +89,6 @@ pub fn new_partial(config: &Configuration) -> Result Result Result<( on_demand.clone(), )); - let grandpa_block_import = grandpa::light_block_import( - client.clone(), backend.clone(), &(client.clone() as Arc<_>), - Arc::new(on_demand.checker().clone()), + let (grandpa_block_import, _) = grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain.clone(), )?; - - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); + let justification_import = grandpa_block_import.clone(); let (babe_block_import, babe_link) = sc_consensus_babe::block_import( sc_consensus_babe::Config::get_or_compute(&*client)?, @@ -383,8 +374,7 @@ pub fn new_light_base(config: Configuration) -> Result<( let import_queue = sc_consensus_babe::import_queue( babe_link, babe_block_import, - None, - Some(Box::new(finality_proof_import)), + Some(Box::new(justification_import)), client.clone(), select_chain.clone(), inherent_data_providers.clone(), @@ -393,9 +383,6 @@ pub fn new_light_base(config: Configuration) -> Result<( sp_consensus::NeverCanAuthor, )?; - let finality_proof_provider = - GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); - let (network, network_status_sinks, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -405,8 +392,6 @@ pub fn new_light_base(config: Configuration) -> Result<( import_queue, on_demand: Some(on_demand.clone()), block_announce_validator_builder: None, - finality_proof_request_builder: Some(finality_proof_request_builder), - finality_proof_provider: Some(finality_proof_provider), })?; network_starter.start_network(); diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index a123da25301..35af52a2f36 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -695,7 +695,6 @@ impl BenchContext { clear_justification_requests: false, needs_justification: false, bad_justification: false, - needs_finality_proof: false, is_new_best: true, } ) diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 97bfb217b93..246b3977127 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -47,7 +47,7 @@ use sp_consensus::{ BlockOrigin, Error as ConsensusError, SelectChain, SlotData, BlockCheckParams, ImportResult }; use sp_consensus::import_queue::{ - Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport, BoxFinalityProofImport, + Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport, }; use sc_client_api::{backend::AuxStore, BlockOf}; use sp_blockchain::{ @@ -836,7 +836,6 @@ pub fn import_queue( slot_duration: SlotDuration, block_import: I, justification_import: Option>, - finality_proof_import: Option>, client: Arc, inherent_data_providers: InherentDataProviders, spawner: &S, @@ -868,7 +867,6 @@ pub fn import_queue( verifier, Box::new(block_import), justification_import, - finality_proof_import, spawner, registry, )) diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index c672440d114..3f2a583482a 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -79,9 +79,7 @@ use std::{ any::Any, borrow::Cow, convert::TryInto, }; use sp_consensus::{ImportResult, CanAuthorWith}; -use sp_consensus::import_queue::{ - BoxJustificationImport, BoxFinalityProofImport, -}; +use sp_consensus::import_queue::BoxJustificationImport; use sp_core::crypto::Public; use sp_application_crypto::AppKey; use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; @@ -1484,7 +1482,6 @@ pub fn import_queue( babe_link: BabeLink, block_import: Inner, justification_import: Option>, - finality_proof_import: Option>, client: Arc, select_chain: SelectChain, inherent_data_providers: InherentDataProviders, @@ -1516,7 +1513,6 @@ pub fn import_queue( verifier, Box::new(block_import), justification_import, - finality_proof_import, spawner, registry, )) diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index b31699d13e0..6e0536c85ce 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -37,11 +37,11 @@ use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sp_consensus::{ NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor, - import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport}, + import_queue::{BoxBlockImport, BoxJustificationImport}, }; use sc_network_test::*; use sc_network_test::{Block as TestBlock, PeersClient}; -use sc_network::config::{BoxFinalityProofRequestBuilder, ProtocolConfig}; +use sc_network::config::ProtocolConfig; use sp_runtime::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use sc_client_api::{BlockchainEvents, backend::TransactionFor}; use log::debug; @@ -272,8 +272,6 @@ impl TestNetFactory for BabeTestNet { -> ( BlockImportAdapter, Option>, - Option>, - Option>, Option, ) { @@ -295,8 +293,6 @@ impl TestNetFactory for BabeTestNet { ( BlockImportAdapter::new_full(block_import), None, - None, - None, Some(PeerData { link, inherent_data_providers, block_import: data_block_import }), ) } diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index d025d6aaf68..5a1cd0f79b4 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -84,7 +84,6 @@ pub fn import_queue( ManualSealVerifier, block_import, None, - None, spawner, registry, ) @@ -349,7 +348,6 @@ mod tests { clear_justification_requests: false, needs_justification: false, bad_justification: false, - needs_finality_proof: false, is_new_best: true, } } @@ -416,7 +414,6 @@ mod tests { clear_justification_requests: false, needs_justification: false, bad_justification: false, - needs_finality_proof: false, is_new_best: true, } } @@ -494,7 +491,6 @@ mod tests { clear_justification_requests: false, needs_justification: false, bad_justification: false, - needs_finality_proof: false, is_new_best: true } } diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index b73b9aa91f8..e353ed6358a 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -56,7 +56,7 @@ use sp_consensus::{ BlockCheckParams, ImportResult, }; use sp_consensus::import_queue::{ - BoxBlockImport, BasicQueue, Verifier, BoxJustificationImport, BoxFinalityProofImport, + BoxBlockImport, BasicQueue, Verifier, BoxJustificationImport, }; use codec::{Encode, Decode}; use prometheus_endpoint::Registry; @@ -503,7 +503,6 @@ pub type PowImportQueue = BasicQueue; pub fn import_queue( block_import: BoxBlockImport, justification_import: Option>, - finality_proof_import: Option>, algorithm: Algorithm, inherent_data_providers: InherentDataProviders, spawner: &impl sp_core::traits::SpawnNamed, @@ -524,7 +523,6 @@ pub fn import_queue( verifier, block_import, justification_import, - finality_proof_import, spawner, registry, )) diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index 4ed96d058ac..97041f4081a 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -17,7 +17,6 @@ //! Schema for stuff in the aux-db. use std::fmt::Debug; -use std::sync::Arc; use parity_scale_codec::{Encode, Decode}; use sc_client_api::backend::AuxStore; use sp_blockchain::{Result as ClientResult, Error as ClientError}; @@ -28,7 +27,6 @@ use log::{info, warn}; use sp_finality_grandpa::{AuthorityList, SetId, RoundNumber}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind}; -use crate::consensus_changes::{SharedConsensusChanges, ConsensusChanges}; use crate::environment::{ CompletedRound, CompletedRounds, CurrentRounds, HasVoted, SharedVoterSetState, VoterSetState, }; @@ -38,7 +36,6 @@ const VERSION_KEY: &[u8] = b"grandpa_schema_version"; const SET_STATE_KEY: &[u8] = b"grandpa_completed_round"; const CONCLUDED_ROUNDS: &[u8] = b"grandpa_concluded_rounds"; const AUTHORITY_SET_KEY: &[u8] = b"grandpa_voters"; -const CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; const CURRENT_VERSION: u32 = 2; @@ -122,7 +119,6 @@ pub(crate) fn load_decode(backend: &B, key: &[u8]) -> Cl /// Persistent data kept between runs. pub(crate) struct PersistentData { pub(crate) authority_set: SharedAuthoritySet>, - pub(crate) consensus_changes: SharedConsensusChanges>, pub(crate) set_state: SharedVoterSetState, } @@ -272,8 +268,6 @@ pub(crate) fn load_persistent( G: FnOnce() -> ClientResult, { let version: Option = load_decode(backend, VERSION_KEY)?; - let consensus_changes = load_decode(backend, CONSENSUS_CHANGES_KEY)? - .unwrap_or_else(ConsensusChanges::>::empty); let make_genesis_round = move || RoundState::genesis((genesis_hash, genesis_number)); @@ -282,7 +276,6 @@ pub(crate) fn load_persistent( if let Some((new_set, set_state)) = migrate_from_version0::(backend, &make_genesis_round)? { return Ok(PersistentData { authority_set: new_set.into(), - consensus_changes: Arc::new(consensus_changes.into()), set_state: set_state.into(), }); } @@ -291,7 +284,6 @@ pub(crate) fn load_persistent( if let Some((new_set, set_state)) = migrate_from_version1::(backend, &make_genesis_round)? { return Ok(PersistentData { authority_set: new_set.into(), - consensus_changes: Arc::new(consensus_changes.into()), set_state: set_state.into(), }); } @@ -321,7 +313,6 @@ pub(crate) fn load_persistent( return Ok(PersistentData { authority_set: set.into(), - consensus_changes: Arc::new(consensus_changes.into()), set_state: set_state.into(), }); } @@ -359,7 +350,6 @@ pub(crate) fn load_persistent( Ok(PersistentData { authority_set: genesis_set.into(), set_state: genesis_state.into(), - consensus_changes: Arc::new(consensus_changes.into()), }) } @@ -421,18 +411,6 @@ pub(crate) fn write_concluded_round( backend.insert_aux(&[(&key[..], round_data.encode().as_slice())], &[]) } -/// Update the consensus changes. -pub(crate) fn update_consensus_changes( - set: &ConsensusChanges, - write_aux: F -) -> R where - H: Encode + Clone, - N: Encode + Clone, - F: FnOnce(&[(&'static [u8], &[u8])]) -> R, -{ - write_aux(&[(CONSENSUS_CHANGES_KEY, set.encode().as_slice())]) -} - #[cfg(test)] pub(crate) fn load_authorities(backend: &B) -> Option> { diff --git a/client/finality-grandpa/src/consensus_changes.rs b/client/finality-grandpa/src/consensus_changes.rs deleted file mode 100644 index 1ce7b551d0d..00000000000 --- a/client/finality-grandpa/src/consensus_changes.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use std::sync::Arc; -use parity_scale_codec::{Encode, Decode}; - -/// Consensus-related data changes tracker. -#[derive(Clone, Debug, Encode, Decode)] -pub(crate) struct ConsensusChanges { - pending_changes: Vec<(N, H)>, -} - -impl ConsensusChanges { - /// Create empty consensus changes. - pub(crate) fn empty() -> Self { - ConsensusChanges { pending_changes: Vec::new(), } - } -} - -impl ConsensusChanges { - - /// Returns reference to all pending changes. - pub fn pending_changes(&self) -> &[(N, H)] { - &self.pending_changes - } - - /// Note unfinalized change of consensus-related data. - pub(crate) fn note_change(&mut self, at: (N, H)) { - let idx = self.pending_changes - .binary_search_by_key(&at.0, |change| change.0) - .unwrap_or_else(|i| i); - self.pending_changes.insert(idx, at); - } - - /// Finalize all pending consensus changes that are finalized by given block. - /// Returns true if there any changes were finalized. - pub(crate) fn finalize ::sp_blockchain::Result>>( - &mut self, - block: (N, H), - canonical_at_height: F, - ) -> ::sp_blockchain::Result<(bool, bool)> { - let (split_idx, has_finalized_changes) = self.pending_changes.iter() - .enumerate() - .take_while(|(_, &(at_height, _))| at_height <= block.0) - .fold((None, Ok(false)), |(_, has_finalized_changes), (idx, ref at)| - ( - Some(idx), - has_finalized_changes - .and_then(|has_finalized_changes| if has_finalized_changes { - Ok(has_finalized_changes) - } else { - canonical_at_height(at.0).map(|can_hash| Some(at.1) == can_hash) - }), - )); - - let altered_changes = split_idx.is_some(); - if let Some(split_idx) = split_idx { - self.pending_changes = self.pending_changes.split_off(split_idx + 1); - } - has_finalized_changes.map(|has_finalized_changes| (altered_changes, has_finalized_changes)) - } -} - -/// Thread-safe consensus changes tracker reference. -pub(crate) type SharedConsensusChanges = Arc>>; diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 9b3a656d0cd..790be2a2217 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -34,10 +34,10 @@ use finality_grandpa::{ BlockNumberOps, Error as GrandpaError, round::State as RoundState, voter, voter_set::VoterSet, }; -use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as ClientError}; +use sp_blockchain::HeaderMetadata; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ - Block as BlockT, Header as HeaderT, NumberFor, One, Zero, + Block as BlockT, Header as HeaderT, NumberFor, Zero, }; use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; @@ -50,7 +50,6 @@ use sp_consensus::SelectChain; use crate::authorities::{AuthoritySet, SharedAuthoritySet}; use crate::communication::Network as NetworkT; -use crate::consensus_changes::SharedConsensusChanges; use crate::notification::GrandpaJustificationSender; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; @@ -440,7 +439,6 @@ pub(crate) struct Environment, SC, pub(crate) voters: Arc>, pub(crate) config: Config, pub(crate) authority_set: SharedAuthoritySet>, - pub(crate) consensus_changes: SharedConsensusChanges>, pub(crate) network: crate::communication::NetworkBridge, pub(crate) set_id: SetId, pub(crate) voter_set_state: SharedVoterSetState, @@ -1115,7 +1113,6 @@ where finalize_block( self.client.clone(), &self.authority_set, - &self.consensus_changes, Some(self.config.justification_period.into()), hash, number, @@ -1180,7 +1177,6 @@ impl From> for JustificationOrCommit< pub(crate) fn finalize_block( client: Arc, authority_set: &SharedAuthoritySet>, - consensus_changes: &SharedConsensusChanges>, justification_period: Option>, hash: Block::Hash, number: NumberFor, @@ -1215,15 +1211,6 @@ where // FIXME #1483: clone only when changed let old_authority_set = authority_set.clone(); - // holds the old consensus changes in case it is changed below, needed for - // reverting in case of failure - let mut old_consensus_changes = None; - - let mut consensus_changes = consensus_changes.lock(); - let canon_at_height = |canon_number| { - // "true" because the block is finalized - canonical_at_height(&*client, (hash, number), true, canon_number) - }; let update_res: Result<_, Error> = client.lock_import_and_run(|import_op| { let status = authority_set.apply_standard_changes( @@ -1233,26 +1220,6 @@ where initial_sync, ).map_err(|e| Error::Safety(e.to_string()))?; - // check if this is this is the first finalization of some consensus changes - let (alters_consensus_changes, finalizes_consensus_changes) = consensus_changes - .finalize((number, hash), &canon_at_height)?; - - if alters_consensus_changes { - old_consensus_changes = Some(consensus_changes.clone()); - - let write_result = crate::aux_schema::update_consensus_changes( - &*consensus_changes, - |insert| apply_aux(import_op, insert, &[]), - ); - - if let Err(e) = write_result { - warn!(target: "afg", "Failed to write updated consensus changes to disk. Bailing."); - warn!(target: "afg", "Node is in a potentially inconsistent state."); - - return Err(e.into()); - } - } - // send a justification notification if a sender exists and in case of error log it. fn notify_justification( justification_sender: Option<&GrandpaJustificationSender>, @@ -1280,9 +1247,7 @@ where let mut justification_required = // justification is always required when block that enacts new authorities // set is finalized - status.new_set_block.is_some() || - // justification is required when consensus changes are finalized - finalizes_consensus_changes; + status.new_set_block.is_some(); // justification is required every N blocks to be able to prove blocks // finalization to remote nodes @@ -1387,57 +1352,7 @@ where Err(e) => { *authority_set = old_authority_set; - if let Some(old_consensus_changes) = old_consensus_changes { - *consensus_changes = old_consensus_changes; - } - Err(CommandOrError::Error(e)) } } } - -/// Using the given base get the block at the given height on this chain. The -/// target block must be an ancestor of base, therefore `height <= base.height`. -pub(crate) fn canonical_at_height>( - provider: &C, - base: (Block::Hash, NumberFor), - base_is_canonical: bool, - height: NumberFor, -) -> Result, ClientError> { - if height > base.1 { - return Ok(None); - } - - if height == base.1 { - if base_is_canonical { - return Ok(Some(base.0)); - } else { - return Ok(provider.hash(height).unwrap_or(None)); - } - } else if base_is_canonical { - return Ok(provider.hash(height).unwrap_or(None)); - } - - let one = NumberFor::::one(); - - // start by getting _canonical_ block with number at parent position and then iterating - // backwards by hash. - let mut current = match provider.header(BlockId::Number(base.1 - one))? { - Some(header) => header, - _ => return Ok(None), - }; - - // we've already checked that base > height above. - let mut steps = base.1 - height - one; - - while steps > NumberFor::::zero() { - current = match provider.header(BlockId::Hash(*current.parent_hash()))? { - Some(header) => header, - _ => return Ok(None), - }; - - steps -= one; - } - - Ok(Some(current.hash())) -} diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index 33dd69cc11d..bf367ab3f4a 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -16,6 +16,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +// NOTE: should be removed with: https://github.com/paritytech/substrate/pull/7339 +#![allow(dead_code)] + //! GRANDPA block finality proof generation and check. //! //! Finality of block B is proved by providing: @@ -37,7 +40,7 @@ //! of the U) could be returned. use std::sync::Arc; -use log::{trace, warn}; +use log::trace; use sp_blockchain::{Backend as BlockchainBackend, Error as ClientError, Result as ClientResult}; use sc_client_api::{ @@ -206,34 +209,6 @@ impl FinalityProofProvider } } -impl sc_network::config::FinalityProofProvider for FinalityProofProvider - where - Block: BlockT, - NumberFor: BlockNumberOps, - B: Backend + Send + Sync + 'static, -{ - fn prove_finality( - &self, - for_block: Block::Hash, - request: &[u8], - ) -> Result>, ClientError> { - let request: FinalityProofRequest = Decode::decode(&mut &request[..]) - .map_err(|e| { - warn!(target: "afg", "Unable to decode finality proof request: {}", e.what()); - ClientError::Backend("Invalid finality proof request".to_string()) - })?; - match request { - FinalityProofRequest::Original(request) => prove_finality::<_, _, GrandpaJustification>( - &*self.backend.blockchain(), - &*self.authority_provider, - request.authorities_set_id, - request.last_finalized, - for_block, - ), - } - } -} - /// The effects of block finality. #[derive(Debug, PartialEq)] pub struct FinalityEffects { @@ -290,14 +265,6 @@ struct OriginalFinalityProofRequest { pub last_finalized: H, } -/// Prepare data blob associated with finality proof request. -pub(crate) fn make_finality_proof_request(last_finalized: H, authorities_set_id: u64) -> Vec { - FinalityProofRequest::Original(OriginalFinalityProofRequest { - authorities_set_id, - last_finalized, - }).encode() -} - /// Prepare proof-of-finality for the best possible block in the range: (begin; end]. /// /// It is assumed that the caller already have a proof-of-finality for the block 'begin'. diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index 04df95a3187..89f9d0c16ad 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -41,7 +41,6 @@ use sp_runtime::traits::{ use crate::{Error, CommandOrError, NewAuthoritySet, VoterCommand}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, DelayKind, PendingChange}; -use crate::consensus_changes::SharedConsensusChanges; use crate::environment::finalize_block; use crate::justification::GrandpaJustification; use crate::notification::GrandpaJustificationSender; @@ -61,7 +60,6 @@ pub struct GrandpaBlockImport { select_chain: SC, authority_set: SharedAuthoritySet>, send_voter_commands: TracingUnboundedSender>>, - consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: HashMap>>, justification_sender: GrandpaJustificationSender, _phantom: PhantomData, @@ -76,7 +74,6 @@ impl Clone for select_chain: self.select_chain.clone(), authority_set: self.authority_set.clone(), send_voter_commands: self.send_voter_commands.clone(), - consensus_changes: self.consensus_changes.clone(), authority_set_hard_forks: self.authority_set_hard_forks.clone(), justification_sender: self.justification_sender.clone(), _phantom: PhantomData, @@ -439,7 +436,6 @@ impl BlockImport // we don't want to finalize on `inner.import_block` let mut justification = block.justification.take(); - let enacts_consensus_change = !new_cache.is_empty(); let import_result = (&*self.inner).import_block(block, new_cache); let mut imported_aux = { @@ -517,7 +513,7 @@ impl BlockImport ); import_res.unwrap_or_else(|err| { - if needs_justification || enacts_consensus_change { + if needs_justification { debug!(target: "afg", "Imported block #{} that enacts authority set change with \ invalid justification: {:?}, requesting justification from peers.", number, err); imported_aux.bad_justification = true; @@ -535,12 +531,6 @@ impl BlockImport imported_aux.needs_justification = true; } - - // we have imported block with consensus data changes, but without justification - // => remember to create justification when next block will be finalized - if enacts_consensus_change { - self.consensus_changes.lock().note_change((number, hash)); - } } } @@ -561,7 +551,6 @@ impl GrandpaBlockImport>, send_voter_commands: TracingUnboundedSender>>, - consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: Vec<(SetId, PendingChange>)>, justification_sender: GrandpaJustificationSender, ) -> GrandpaBlockImport { @@ -605,7 +594,6 @@ impl GrandpaBlockImport. - -use std::collections::HashMap; -use std::sync::Arc; -use log::{info, trace, warn}; -use parking_lot::RwLock; -use sc_client_api::backend::{AuxStore, Backend, Finalizer, TransactionFor}; -use sp_blockchain::{HeaderBackend, Error as ClientError, well_known_cache_keys}; -use parity_scale_codec::{Encode, Decode}; -use sp_consensus::{ - import_queue::Verifier, - BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux, - BlockCheckParams, Error as ConsensusError, -}; -use sc_network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder}; -use sp_runtime::Justification; -use sp_runtime::traits::{NumberFor, Block as BlockT, Header as HeaderT, DigestFor}; -use sp_finality_grandpa::{self, AuthorityList}; -use sp_runtime::generic::BlockId; - -use crate::GenesisAuthoritySetProvider; -use crate::aux_schema::load_decode; -use crate::consensus_changes::ConsensusChanges; -use crate::environment::canonical_at_height; -use crate::finality_proof::{ - AuthoritySetForFinalityChecker, ProvableJustification, make_finality_proof_request, -}; -use crate::justification::GrandpaJustification; - -/// LightAuthoritySet is saved under this key in aux storage. -const LIGHT_AUTHORITY_SET_KEY: &[u8] = b"grandpa_voters"; -/// ConsensusChanges is saver under this key in aux storage. -const LIGHT_CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; - -/// Create light block importer. -pub fn light_block_import( - client: Arc, - backend: Arc, - genesis_authorities_provider: &dyn GenesisAuthoritySetProvider, - authority_set_provider: Arc>, -) -> Result, ClientError> - where - BE: Backend, - Client: crate::ClientForGrandpa, -{ - let info = client.info(); - let import_data = load_aux_import_data( - info.finalized_hash, - &*client, - genesis_authorities_provider, - )?; - Ok(GrandpaLightBlockImport { - client, - backend, - authority_set_provider, - data: Arc::new(RwLock::new(import_data)), - }) -} - -/// A light block-import handler for GRANDPA. -/// -/// It is responsible for: -/// - checking GRANDPA justifications; -/// - fetching finality proofs for blocks that are enacting consensus changes. -pub struct GrandpaLightBlockImport { - client: Arc, - backend: Arc, - authority_set_provider: Arc>, - data: Arc>>, -} - -impl Clone for GrandpaLightBlockImport { - fn clone(&self) -> Self { - GrandpaLightBlockImport { - client: self.client.clone(), - backend: self.backend.clone(), - authority_set_provider: self.authority_set_provider.clone(), - data: self.data.clone(), - } - } -} - -/// Mutable data of light block importer. -struct LightImportData { - last_finalized: Block::Hash, - authority_set: LightAuthoritySet, - consensus_changes: ConsensusChanges>, -} - -/// Latest authority set tracker. -#[derive(Debug, Encode, Decode)] -struct LightAuthoritySet { - set_id: u64, - authorities: AuthorityList, -} - -impl GrandpaLightBlockImport { - /// Create finality proof request builder. - pub fn create_finality_proof_request_builder(&self) -> BoxFinalityProofRequestBuilder { - Box::new(GrandpaFinalityProofRequestBuilder(self.data.clone())) as _ - } -} - -impl BlockImport - for GrandpaLightBlockImport where - NumberFor: finality_grandpa::BlockNumberOps, - DigestFor: Encode, - BE: Backend + 'static, - for<'a> &'a Client: - HeaderBackend - + BlockImport> - + Finalizer - + AuxStore, -{ - type Error = ConsensusError; - type Transaction = TransactionFor; - - fn import_block( - &mut self, - block: BlockImportParams, - new_cache: HashMap>, - ) -> Result { - do_import_block::<_, _, _, GrandpaJustification>( - &*self.client, &mut *self.data.write(), block, new_cache - ) - } - - fn check_block( - &mut self, - block: BlockCheckParams, - ) -> Result { - self.client.check_block(block) - } -} - -impl FinalityProofImport - for GrandpaLightBlockImport where - NumberFor: finality_grandpa::BlockNumberOps, - DigestFor: Encode, - BE: Backend + 'static, - for<'a> &'a Client: - HeaderBackend - + BlockImport> - + Finalizer - + AuxStore, -{ - type Error = ConsensusError; - - fn on_start(&mut self) -> Vec<(Block::Hash, NumberFor)> { - let mut out = Vec::new(); - let chain_info = (&*self.client).info(); - - let data = self.data.read(); - for (pending_number, pending_hash) in data.consensus_changes.pending_changes() { - if *pending_number > chain_info.finalized_number - && *pending_number <= chain_info.best_number - { - out.push((*pending_hash, *pending_number)); - } - } - - out - } - - fn import_finality_proof( - &mut self, - hash: Block::Hash, - number: NumberFor, - finality_proof: Vec, - verifier: &mut dyn Verifier, - ) -> Result<(Block::Hash, NumberFor), Self::Error> { - do_import_finality_proof::<_, _, _, GrandpaJustification>( - &*self.client, - self.backend.clone(), - &*self.authority_set_provider, - &mut *self.data.write(), - hash, - number, - finality_proof, - verifier, - ) - } -} - -impl LightAuthoritySet { - /// Get a genesis set with given authorities. - pub fn genesis(initial: AuthorityList) -> Self { - LightAuthoritySet { - set_id: sp_finality_grandpa::SetId::default(), - authorities: initial, - } - } - - /// Get latest set id. - pub fn set_id(&self) -> u64 { - self.set_id - } - - /// Get latest authorities set. - pub fn authorities(&self) -> AuthorityList { - self.authorities.clone() - } - - /// Set new authorities set. - pub fn update(&mut self, set_id: u64, authorities: AuthorityList) { - self.set_id = set_id; - self.authorities = authorities; - } -} - -struct GrandpaFinalityProofRequestBuilder(Arc>>); - -impl FinalityProofRequestBuilder for GrandpaFinalityProofRequestBuilder { - fn build_request_data(&mut self, _hash: &B::Hash) -> Vec { - let data = self.0.read(); - make_finality_proof_request( - data.last_finalized, - data.authority_set.set_id(), - ) - } -} - -/// Try to import new block. -fn do_import_block( - mut client: C, - data: &mut LightImportData, - mut block: BlockImportParams>, - new_cache: HashMap>, -) -> Result - where - C: HeaderBackend - + AuxStore - + Finalizer - + BlockImport> - + Clone, - B: Backend + 'static, - NumberFor: finality_grandpa::BlockNumberOps, - DigestFor: Encode, - J: ProvableJustification, -{ - let hash = block.post_hash(); - let number = *block.header.number(); - - // we don't want to finalize on `inner.import_block` - let justification = block.justification.take(); - let enacts_consensus_change = !new_cache.is_empty(); - let import_result = client.import_block(block, new_cache); - - let mut imported_aux = match import_result { - Ok(ImportResult::Imported(aux)) => aux, - Ok(r) => return Ok(r), - Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), - }; - - match justification { - Some(justification) => { - trace!( - target: "afg", - "Imported block {}{}. Importing justification.", - if enacts_consensus_change { " which enacts consensus changes" } else { "" }, - hash, - ); - - do_import_justification::<_, _, _, J>(client, data, hash, number, justification) - }, - None if enacts_consensus_change => { - trace!( - target: "afg", - "Imported block {} which enacts consensus changes. Requesting finality proof.", - hash, - ); - - // remember that we need finality proof for this block - imported_aux.needs_finality_proof = true; - data.consensus_changes.note_change((number, hash)); - Ok(ImportResult::Imported(imported_aux)) - }, - None => Ok(ImportResult::Imported(imported_aux)), - } -} - -/// Try to import finality proof. -fn do_import_finality_proof( - client: C, - backend: Arc, - authority_set_provider: &dyn AuthoritySetForFinalityChecker, - data: &mut LightImportData, - _hash: Block::Hash, - _number: NumberFor, - finality_proof: Vec, - verifier: &mut dyn Verifier, -) -> Result<(Block::Hash, NumberFor), ConsensusError> - where - C: HeaderBackend - + AuxStore - + Finalizer - + BlockImport> - + Clone, - B: Backend + 'static, - DigestFor: Encode, - NumberFor: finality_grandpa::BlockNumberOps, - J: ProvableJustification, -{ - let authority_set_id = data.authority_set.set_id(); - let authorities = data.authority_set.authorities(); - let finality_effects = crate::finality_proof::check_finality_proof::<_, _, J>( - backend.blockchain(), - authority_set_id, - authorities, - authority_set_provider, - finality_proof, - ).map_err(|e| ConsensusError::ClientImport(e.to_string()))?; - - // try to import all new headers - let block_origin = BlockOrigin::NetworkBroadcast; - for header_to_import in finality_effects.headers_to_import { - let (block_to_import, new_authorities) = verifier.verify( - block_origin, - header_to_import, - None, - None, - ).map_err(|e| ConsensusError::ClientImport(e))?; - assert!( - block_to_import.justification.is_none(), - "We have passed None as justification to verifier.verify", - ); - - let mut cache = HashMap::new(); - if let Some(authorities) = new_authorities { - cache.insert(well_known_cache_keys::AUTHORITIES, authorities.encode()); - } - do_import_block::<_, _, _, J>( - client.clone(), - data, - block_to_import.convert_transaction(), - cache, - )?; - } - - // try to import latest justification - let finalized_block_hash = finality_effects.block; - let finalized_block_number = backend.blockchain() - .expect_block_number_from_id(&BlockId::Hash(finality_effects.block)) - .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; - do_finalize_block( - client.clone(), - data, - finalized_block_hash, - finalized_block_number, - finality_effects.justification.encode(), - )?; - - // apply new authorities set - data.authority_set.update( - finality_effects.new_set_id, - finality_effects.new_authorities, - ); - - // store new authorities set - require_insert_aux( - &client, - LIGHT_AUTHORITY_SET_KEY, - &data.authority_set, - "authority set", - )?; - - Ok((finalized_block_hash, finalized_block_number)) -} - -/// Try to import justification. -fn do_import_justification( - client: C, - data: &mut LightImportData, - hash: Block::Hash, - number: NumberFor, - justification: Justification, -) -> Result - where - C: HeaderBackend - + AuxStore - + Finalizer - + Clone, - B: Backend + 'static, - NumberFor: finality_grandpa::BlockNumberOps, - J: ProvableJustification, -{ - // with justification, we have two cases - // - // optimistic: the same GRANDPA authorities set has generated intermediate justification - // => justification is verified using current authorities set + we could proceed further - // - // pessimistic scenario: the GRANDPA authorities set has changed - // => we need to fetch new authorities set (i.e. finality proof) from remote node - - // first, try to behave optimistically - let authority_set_id = data.authority_set.set_id(); - let justification = J::decode_and_verify( - &justification, - authority_set_id, - &data.authority_set.authorities(), - ); - - // BadJustification error means that justification has been successfully decoded, but - // it isn't valid within current authority set - let justification = match justification { - Err(ClientError::BadJustification(_)) => { - trace!( - target: "afg", - "Justification for {} is not valid within current authorities set. Requesting finality proof.", - hash, - ); - - let mut imported_aux = ImportedAux::default(); - imported_aux.needs_finality_proof = true; - return Ok(ImportResult::Imported(imported_aux)); - }, - Err(e) => { - trace!( - target: "afg", - "Justification for {} is not valid. Bailing.", - hash, - ); - - return Err(ConsensusError::ClientImport(e.to_string())); - }, - Ok(justification) => { - trace!( - target: "afg", - "Justification for {} is valid. Finalizing the block.", - hash, - ); - - justification - }, - }; - - // finalize the block - do_finalize_block(client, data, hash, number, justification.encode()) -} - -/// Finalize the block. -fn do_finalize_block( - client: C, - data: &mut LightImportData, - hash: Block::Hash, - number: NumberFor, - justification: Justification, -) -> Result - where - C: HeaderBackend - + AuxStore - + Finalizer - + Clone, - B: Backend + 'static, - NumberFor: finality_grandpa::BlockNumberOps, -{ - // finalize the block - client.finalize_block(BlockId::Hash(hash), Some(justification), true).map_err(|e| { - warn!(target: "afg", "Error applying finality to block {:?}: {:?}", (hash, number), e); - ConsensusError::ClientImport(e.to_string()) - })?; - - // forget obsoleted consensus changes - let consensus_finalization_res = data.consensus_changes - .finalize( - (number, hash), - |at_height| canonical_at_height(&client, (hash, number), true, at_height) - ); - match consensus_finalization_res { - Ok((true, _)) => require_insert_aux( - &client, - LIGHT_CONSENSUS_CHANGES_KEY, - &data.consensus_changes, - "consensus changes", - )?, - Ok(_) => (), - Err(error) => return Err(on_post_finalization_error(error, "consensus changes")), - } - - // update last finalized block reference - data.last_finalized = hash; - - // we just finalized this block, so if we were importing it, it is now the new best - Ok(ImportResult::imported(true)) -} - -/// Load light import aux data from the store. -fn load_aux_import_data( - last_finalized: Block::Hash, - aux_store: &B, - genesis_authorities_provider: &dyn GenesisAuthoritySetProvider, -) -> Result, ClientError> - where - B: AuxStore, - Block: BlockT, -{ - let authority_set = match load_decode(aux_store, LIGHT_AUTHORITY_SET_KEY)? { - Some(authority_set) => authority_set, - None => { - info!(target: "afg", "Loading GRANDPA authorities \ - from genesis on what appears to be first startup."); - - // no authority set on disk: fetch authorities from genesis state - let genesis_authorities = genesis_authorities_provider.get()?; - - let authority_set = LightAuthoritySet::genesis(genesis_authorities); - let encoded = authority_set.encode(); - aux_store.insert_aux(&[(LIGHT_AUTHORITY_SET_KEY, &encoded[..])], &[])?; - - authority_set - }, - }; - - let consensus_changes = match load_decode(aux_store, LIGHT_CONSENSUS_CHANGES_KEY)? { - Some(consensus_changes) => consensus_changes, - None => { - let consensus_changes = ConsensusChanges::>::empty(); - - let encoded = authority_set.encode(); - aux_store.insert_aux(&[(LIGHT_CONSENSUS_CHANGES_KEY, &encoded[..])], &[])?; - - consensus_changes - }, - }; - - Ok(LightImportData { - last_finalized, - authority_set, - consensus_changes, - }) -} - -/// Insert into aux store. If failed, return error && show inconsistency warning. -fn require_insert_aux( - store: &A, - key: &[u8], - value: &T, - value_type: &str, -) -> Result<(), ConsensusError> { - let encoded = value.encode(); - let update_res = store.insert_aux(&[(key, &encoded[..])], &[]); - if let Err(error) = update_res { - return Err(on_post_finalization_error(error, value_type)); - } - - Ok(()) -} - -/// Display inconsistency warning. -fn on_post_finalization_error(error: ClientError, value_type: &str) -> ConsensusError { - warn!(target: "afg", "Failed to write updated {} to disk. Bailing.", value_type); - warn!(target: "afg", "Node is in a potentially inconsistent state."); - ConsensusError::ClientImport(error.to_string()) -} - -#[cfg(test)] -pub mod tests { - use super::*; - use sp_consensus::{import_queue::CacheKeyId, ForkChoiceStrategy, BlockImport}; - use sp_finality_grandpa::AuthorityId; - use sp_core::{H256, crypto::Public}; - use sc_client_api::{in_mem::Blockchain as InMemoryAuxStore, StorageProof, BlockBackend}; - use substrate_test_runtime_client::runtime::{Block, Header}; - use crate::tests::TestApi; - use crate::finality_proof::{ - FinalityProofFragment, - tests::{TestJustification, ClosureAuthoritySetForFinalityChecker}, - }; - - struct OkVerifier; - - impl Verifier for OkVerifier { - fn verify( - &mut self, - origin: BlockOrigin, - header: Header, - _justification: Option, - _body: Option::Extrinsic>>, - ) -> Result<(BlockImportParams, Option)>>), String> { - Ok((BlockImportParams::new(origin, header), None)) - } - } - - pub struct NoJustificationsImport( - pub GrandpaLightBlockImport - ); - - impl Clone - for NoJustificationsImport where - NumberFor: finality_grandpa::BlockNumberOps, - DigestFor: Encode, - BE: Backend + 'static, - { - fn clone(&self) -> Self { - NoJustificationsImport(self.0.clone()) - } - } - - impl BlockImport - for NoJustificationsImport where - NumberFor: finality_grandpa::BlockNumberOps, - DigestFor: Encode, - BE: Backend + 'static, - for <'a > &'a Client: - HeaderBackend - + BlockImport> - + Finalizer - + AuxStore, - GrandpaLightBlockImport: - BlockImport, Error = ConsensusError> - { - type Error = ConsensusError; - type Transaction = TransactionFor; - - fn import_block( - &mut self, - mut block: BlockImportParams, - new_cache: HashMap>, - ) -> Result { - block.justification.take(); - self.0.import_block(block, new_cache) - } - - fn check_block( - &mut self, - block: BlockCheckParams, - ) -> Result { - self.0.check_block(block) - } - } - - impl FinalityProofImport - for NoJustificationsImport where - NumberFor: finality_grandpa::BlockNumberOps, - BE: Backend + 'static, - DigestFor: Encode, - for <'a > &'a Client: - HeaderBackend - + BlockImport> - + Finalizer - + AuxStore, - { - type Error = ConsensusError; - - fn on_start(&mut self) -> Vec<(Block::Hash, NumberFor)> { - self.0.on_start() - } - - fn import_finality_proof( - &mut self, - hash: Block::Hash, - number: NumberFor, - finality_proof: Vec, - verifier: &mut dyn Verifier, - ) -> Result<(Block::Hash, NumberFor), Self::Error> { - self.0.import_finality_proof(hash, number, finality_proof, verifier) - } - } - - /// Creates light block import that ignores justifications that came outside of finality proofs. - pub fn light_block_import_without_justifications( - client: Arc, - backend: Arc, - genesis_authorities_provider: &dyn GenesisAuthoritySetProvider, - authority_set_provider: Arc>, - ) -> Result, ClientError> - where - BE: Backend + 'static, - Client: crate::ClientForGrandpa, - { - light_block_import(client, backend, genesis_authorities_provider, authority_set_provider) - .map(NoJustificationsImport) - } - - fn import_block( - new_cache: HashMap>, - justification: Option, - ) -> ( - ImportResult, - substrate_test_runtime_client::client::Client, - Arc, - ) { - let (client, backend) = substrate_test_runtime_client::new_light(); - let mut import_data = LightImportData { - last_finalized: Default::default(), - authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]), - consensus_changes: ConsensusChanges::empty(), - }; - let mut block = BlockImportParams::new( - BlockOrigin::Own, - Header { - number: 1, - parent_hash: client.chain_info().best_hash, - state_root: Default::default(), - digest: Default::default(), - extrinsics_root: Default::default(), - }, - ); - block.justification = justification; - block.fork_choice = Some(ForkChoiceStrategy::LongestChain); - - ( - do_import_block::<_, _, _, TestJustification>( - &client, - &mut import_data, - block, - new_cache, - ).unwrap(), - client, - backend, - ) - } - - #[test] - fn finality_proof_not_required_when_consensus_data_does_not_changes_and_no_justification_provided() { - assert_eq!(import_block(HashMap::new(), None).0, ImportResult::Imported(ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: false, - is_new_best: true, - header_only: false, - })); - } - - #[test] - fn finality_proof_not_required_when_consensus_data_does_not_changes_and_correct_justification_provided() { - let justification = TestJustification((0, vec![(AuthorityId::from_slice(&[1; 32]), 1)]), Vec::new()).encode(); - assert_eq!(import_block(HashMap::new(), Some(justification)).0, ImportResult::Imported(ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: false, - is_new_best: true, - header_only: false, - })); - } - - #[test] - fn finality_proof_required_when_consensus_data_changes_and_no_justification_provided() { - let mut cache = HashMap::new(); - cache.insert(well_known_cache_keys::AUTHORITIES, vec![AuthorityId::from_slice(&[2; 32])].encode()); - assert_eq!(import_block(cache, None).0, ImportResult::Imported(ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: true, - is_new_best: true, - header_only: false, - })); - } - - #[test] - fn finality_proof_required_when_consensus_data_changes_and_incorrect_justification_provided() { - let justification = TestJustification((0, vec![]), Vec::new()).encode(); - let mut cache = HashMap::new(); - cache.insert(well_known_cache_keys::AUTHORITIES, vec![AuthorityId::from_slice(&[2; 32])].encode()); - assert_eq!( - import_block(cache, Some(justification)).0, - ImportResult::Imported(ImportedAux { - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: true, - is_new_best: false, - header_only: false, - }, - )); - } - - - #[test] - fn aux_data_updated_on_start() { - let aux_store = InMemoryAuxStore::::new(); - let api = TestApi::new(vec![(AuthorityId::from_slice(&[1; 32]), 1)]); - - // when aux store is empty initially - assert!(aux_store.get_aux(LIGHT_AUTHORITY_SET_KEY).unwrap().is_none()); - assert!(aux_store.get_aux(LIGHT_CONSENSUS_CHANGES_KEY).unwrap().is_none()); - - // it is updated on importer start - load_aux_import_data(Default::default(), &aux_store, &api).unwrap(); - assert!(aux_store.get_aux(LIGHT_AUTHORITY_SET_KEY).unwrap().is_some()); - assert!(aux_store.get_aux(LIGHT_CONSENSUS_CHANGES_KEY).unwrap().is_some()); - } - - #[test] - fn aux_data_loaded_on_restart() { - let aux_store = InMemoryAuxStore::::new(); - let api = TestApi::new(vec![(AuthorityId::from_slice(&[1; 32]), 1)]); - - // when aux store is non-empty initially - let mut consensus_changes = ConsensusChanges::::empty(); - consensus_changes.note_change((42, Default::default())); - aux_store.insert_aux( - &[ - ( - LIGHT_AUTHORITY_SET_KEY, - LightAuthoritySet::genesis( - vec![(AuthorityId::from_slice(&[42; 32]), 2)] - ).encode().as_slice(), - ), - ( - LIGHT_CONSENSUS_CHANGES_KEY, - consensus_changes.encode().as_slice(), - ), - ], - &[], - ).unwrap(); - - // importer uses it on start - let data = load_aux_import_data(Default::default(), &aux_store, &api).unwrap(); - assert_eq!(data.authority_set.authorities(), vec![(AuthorityId::from_slice(&[42; 32]), 2)]); - assert_eq!(data.consensus_changes.pending_changes(), &[(42, Default::default())]); - } - - #[test] - fn authority_set_is_updated_on_finality_proof_import() { - let initial_set_id = 0; - let initial_set = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; - let updated_set = vec![(AuthorityId::from_slice(&[2; 32]), 2)]; - let babe_set_signal = vec![AuthorityId::from_slice(&[42; 32])].encode(); - - // import block #1 without justification - let mut cache = HashMap::new(); - cache.insert(well_known_cache_keys::AUTHORITIES, babe_set_signal); - let (_, client, backend) = import_block(cache, None); - - // import finality proof for block #1 - let hash = client.block_hash(1).unwrap().unwrap(); - let mut verifier = OkVerifier; - let mut import_data = LightImportData { - last_finalized: Default::default(), - authority_set: LightAuthoritySet::genesis(initial_set.clone()), - consensus_changes: ConsensusChanges::empty(), - }; - - // import finality proof - do_import_finality_proof::<_, _, _, TestJustification>( - &client, - backend, - &ClosureAuthoritySetForFinalityChecker( - |_, _, _| Ok(updated_set.clone()) - ), - &mut import_data, - Default::default(), - Default::default(), - vec![ - FinalityProofFragment::
{ - block: hash, - justification: TestJustification( - (initial_set_id, initial_set.clone()), - Vec::new(), - ).encode(), - unknown_headers: Vec::new(), - authorities_proof: Some(StorageProof::new(vec![])), - }, - ].encode(), - &mut verifier, - ).unwrap(); - - // verify that new authorities set has been saved to the aux storage - let data = load_aux_import_data(Default::default(), &client, &TestApi::new(initial_set)).unwrap(); - assert_eq!(data.authority_set.authorities(), updated_set); - } -} diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index fd00b35c40a..c61998225e3 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -39,7 +39,6 @@ use crate::{ }; use crate::authorities::SharedAuthoritySet; use crate::communication::{Network as NetworkT, NetworkBridge}; -use crate::consensus_changes::SharedConsensusChanges; use crate::notification::GrandpaJustificationSender; use sp_finality_grandpa::AuthorityId; use std::marker::{PhantomData, Unpin}; @@ -68,7 +67,6 @@ impl<'a, Block, Client> finality_grandpa::Chain> fn grandpa_observer( client: &Arc, authority_set: &SharedAuthoritySet>, - consensus_changes: &SharedConsensusChanges>, voters: &Arc>, justification_sender: &Option>, last_finalized_number: NumberFor, @@ -83,7 +81,6 @@ where Client: crate::ClientForGrandpa, { let authority_set = authority_set.clone(); - let consensus_changes = consensus_changes.clone(); let client = client.clone(); let voters = voters.clone(); let justification_sender = justification_sender.clone(); @@ -123,7 +120,6 @@ where match environment::finalize_block( client.clone(), &authority_set, - &consensus_changes, None, finalized_hash, finalized_number, @@ -293,7 +289,6 @@ where let observer = grandpa_observer( &self.client, &self.persistent_data.authority_set, - &self.persistent_data.consensus_changes, &voters, &self.justification_sender, last_finalized_number, diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 44503d3c85d..ef8168e84f6 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -25,7 +25,7 @@ use sc_network_test::{ Block, BlockImportAdapter, Hash, PassThroughVerifier, Peer, PeersClient, PeersFullClient, TestClient, TestNetFactory, FullPeerConfig, }; -use sc_network::config::{ProtocolConfig, BoxFinalityProofRequestBuilder}; +use sc_network::config::ProtocolConfig; use parking_lot::{RwLock, Mutex}; use futures_timer::Delay; use tokio::runtime::{Runtime, Handle}; @@ -36,22 +36,21 @@ use sp_api::{ApiRef, StorageProof, ProvideRuntimeApi}; use substrate_test_runtime_client::runtime::BlockNumber; use sp_consensus::{ BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport, - import_queue::{BoxJustificationImport, BoxFinalityProofImport}, + import_queue::BoxJustificationImport, }; use std::{collections::{HashMap, HashSet}, pin::Pin}; use parity_scale_codec::Decode; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, HashFor}; use sp_runtime::generic::{BlockId, DigestItem}; -use sp_core::{H256, crypto::Public}; +use sp_core::H256; use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, EquivocationProof, GrandpaApi, OpaqueKeyOwnershipProof}; use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check}; use authorities::AuthoritySet; use finality_proof::{ - FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker, + AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker, }; -use consensus_changes::ConsensusChanges; use sc_block_builder::BlockBuilderProvider; use sc_consensus::LongestChain; use sc_keystore::LocalKeystore; @@ -117,8 +116,6 @@ impl TestNetFactory for GrandpaTestNet { -> ( BlockImportAdapter, Option>, - Option>, - Option>, PeerData, ) { @@ -133,45 +130,12 @@ impl TestNetFactory for GrandpaTestNet { ( BlockImportAdapter::new_full(import), Some(justification_import), - None, - None, Mutex::new(Some(link)), ) }, - PeersClient::Light(ref client, ref backend) => { - use crate::light_import::tests::light_block_import_without_justifications; - - let authorities_provider = Arc::new(self.test_config.clone()); - // forbid direct finalization using justification that came with the block - // => light clients will try to fetch finality proofs - let import = light_block_import_without_justifications( - client.clone(), - backend.clone(), - &self.test_config, - authorities_provider, - ).expect("Could not create block import for fresh peer."); - let finality_proof_req_builder = import.0.create_finality_proof_request_builder(); - let proof_import = Box::new(import.clone()); - ( - BlockImportAdapter::new_light(import), - None, - Some(proof_import), - Some(finality_proof_req_builder), - Mutex::new(None), - ) - }, - } - } - - fn make_finality_proof_provider( - &self, - client: PeersClient - ) -> Option>> { - match client { - PeersClient::Full(_, ref backend) => { - Some(Arc::new(FinalityProofProvider::new(backend.clone(), self.test_config.clone()))) + PeersClient::Light(..) => { + panic!("Light client is not used in tests."); }, - PeersClient::Light(_, _) => None, } } @@ -679,24 +643,6 @@ fn transition_3_voters_twice_1_full_observer() { block_until_complete(wait_for, &net, &mut runtime); } -#[test] -fn justification_is_emitted_when_consensus_data_changes() { - let mut runtime = Runtime::new().unwrap(); - let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; - let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); - - // import block#1 WITH consensus data change - let new_authorities = vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]; - net.peer(0).push_authorities_change_block(new_authorities); - net.block_until_sync(); - let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 1, net.clone(), peers); - - // ... and check that there's justification for block#1 - assert!(net.lock().peer(0).client().justification(&BlockId::Number(1)).unwrap().is_some(), - "Missing justification for block#1"); -} - #[test] fn justification_is_generated_periodically() { let mut runtime = Runtime::new().unwrap(); @@ -717,25 +663,6 @@ fn justification_is_generated_periodically() { } } -#[test] -fn consensus_changes_works() { - let mut changes = ConsensusChanges::::empty(); - - // pending changes are not finalized - changes.note_change((10, H256::from_low_u64_be(1))); - assert_eq!(changes.finalize((5, H256::from_low_u64_be(5)), |_| Ok(None)).unwrap(), (false, false)); - - // no change is selected from competing pending changes - changes.note_change((1, H256::from_low_u64_be(1))); - changes.note_change((1, H256::from_low_u64_be(101))); - assert_eq!(changes.finalize((10, H256::from_low_u64_be(10)), |_| Ok(Some(H256::from_low_u64_be(1001)))).unwrap(), (true, false)); - - // change is selected from competing pending changes - changes.note_change((1, H256::from_low_u64_be(1))); - changes.note_change((1, H256::from_low_u64_be(101))); - assert_eq!(changes.finalize((10, H256::from_low_u64_be(10)), |_| Ok(Some(H256::from_low_u64_be(1)))).unwrap(), (true, true)); -} - #[test] fn sync_justifications_on_change_blocks() { let mut runtime = Runtime::new().unwrap(); @@ -944,7 +871,6 @@ fn allows_reimporting_change_blocks() { needs_justification: true, clear_justification_requests: false, bad_justification: false, - needs_finality_proof: false, is_new_best: true, header_only: false, }), @@ -1069,7 +995,7 @@ fn voter_persists_its_votes() { Poll::Pending => return Poll::Pending, Poll::Ready(None) => return Poll::Ready(()), Poll::Ready(Some(())) => { - let (_block_import, _, _, _, link) = + let (_block_import, _, link) = this.net.lock() .make_block_import::< TransactionFor @@ -1144,7 +1070,7 @@ fn voter_persists_its_votes() { }; let set_state = { - let (_, _, _, _, link) = net.lock() + let (_, _, link) = net.lock() .make_block_import::< TransactionFor >(client); @@ -1311,100 +1237,6 @@ fn finalize_3_voters_1_light_observer() { }); } -#[test] -fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { - sp_tracing::try_init_simple(); - let mut runtime = Runtime::new().unwrap(); - - let peers = &[Ed25519Keyring::Alice]; - let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); - net.add_light_peer(); - - // import block#1 WITH consensus data change. Light client ignores justification - // && instead fetches finality proof for block #1 - net.peer(0).push_authorities_change_block(vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]); - let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 1, net.clone(), peers); - net.lock().block_until_sync(); - - // check that the block#1 is finalized on light client - runtime.block_on(futures::future::poll_fn(move |cx| { - if net.lock().peer(1).client().info().finalized_number == 1 { - Poll::Ready(()) - } else { - net.lock().poll(cx); - Poll::Pending - } - })); -} - -#[test] -fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different() { - // for debug: to ensure that without forced change light client will sync finality proof - const FORCE_CHANGE: bool = true; - - sp_tracing::try_init_simple(); - let mut runtime = Runtime::new().unwrap(); - - // two of these guys are offline. - let genesis_authorities = if FORCE_CHANGE { - vec![ - Ed25519Keyring::Alice, - Ed25519Keyring::Bob, - Ed25519Keyring::Charlie, - Ed25519Keyring::One, - Ed25519Keyring::Two, - ] - } else { - vec![ - Ed25519Keyring::Alice, - Ed25519Keyring::Bob, - Ed25519Keyring::Charlie, - ] - }; - let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; - let api = TestApi::new(make_ids(&genesis_authorities)); - - let voters = make_ids(peers_a); - let net = GrandpaTestNet::new(api, 3); - let net = Arc::new(Mutex::new(net)); - - // best is #1 - net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { - // add a forced transition at block 5. - let mut block = builder.build().unwrap().block; - if FORCE_CHANGE { - add_forced_change(&mut block, 0, ScheduledChange { - next_authorities: voters.clone(), - delay: 3, - }); - } - block - }); - - // ensure block#10 enacts authorities set change => justification is generated - // normally it will reach light client, but because of the forced change, it will not - net.lock().peer(0).push_blocks(8, false); // best is #9 - net.lock().peer(0).push_authorities_change_block( - vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])] - ); // #10 - net.lock().peer(0).push_blocks(1, false); // best is #11 - net.lock().block_until_sync(); - - // finalize block #11 on full clients - run_to_completion(&mut runtime, 11, net.clone(), peers_a); - - // request finalization by light client - net.lock().add_light_peer(); - net.lock().block_until_sync(); - - // check block, finalized on light client - assert_eq!( - net.lock().peer(3).client().info().finalized_number, - if FORCE_CHANGE { 0 } else { 10 }, - ); -} - #[test] fn voter_catches_up_to_latest_round_when_behind() { sp_tracing::try_init_simple(); @@ -1540,7 +1372,6 @@ where { let PersistentData { ref authority_set, - ref consensus_changes, ref set_state, .. } = link.persistent_data; @@ -1564,7 +1395,6 @@ where Environment { authority_set: authority_set.clone(), config: config.clone(), - consensus_changes: consensus_changes.clone(), client: link.client.clone(), select_chain: link.select_chain.clone(), set_id: authority_set.set_id(), diff --git a/client/network/build.rs b/client/network/build.rs index 8ed460f163e..2ccc72d99df 100644 --- a/client/network/build.rs +++ b/client/network/build.rs @@ -1,6 +1,5 @@ const PROTOS: &[&str] = &[ "src/schema/api.v1.proto", - "src/schema/finality.v1.proto", "src/schema/light.v1.proto" ]; diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 41723d9068c..b2914a5e0a7 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -15,9 +15,9 @@ // along with Substrate. If not, see . use crate::{ - config::{ProtocolId, Role}, block_requests, light_client_handler, finality_requests, + config::{ProtocolId, Role}, block_requests, light_client_handler, peer_info, request_responses, discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut}, - protocol::{message::{self, Roles}, CustomMessageOutcome, NotificationsSink, Protocol}, + protocol::{message::Roles, CustomMessageOutcome, NotificationsSink, Protocol}, ObservedRole, DhtEvent, ExHashT, }; @@ -58,8 +58,6 @@ pub struct Behaviour { request_responses: request_responses::RequestResponsesBehaviour, /// Block request handling. block_requests: block_requests::BlockRequests, - /// Finality proof request handling. - finality_proof_requests: finality_requests::FinalityProofRequests, /// Light client request handling. light_client_handler: light_client_handler::LightClientHandler, @@ -76,7 +74,6 @@ pub struct Behaviour { pub enum BehaviourOut { BlockImport(BlockOrigin, Vec>), JustificationImport(Origin, B::Hash, NumberFor, Justification), - FinalityProofImport(Origin, B::Hash, NumberFor, Vec), /// Started a random iterative Kademlia discovery query. RandomKademliaStarted(ProtocolId), @@ -182,7 +179,6 @@ impl Behaviour { user_agent: String, local_public_key: PublicKey, block_requests: block_requests::BlockRequests, - finality_proof_requests: finality_requests::FinalityProofRequests, light_client_handler: light_client_handler::LightClientHandler, disco_config: DiscoveryConfig, request_response_protocols: Vec, @@ -194,7 +190,6 @@ impl Behaviour { request_responses: request_responses::RequestResponsesBehaviour::new(request_response_protocols.into_iter())?, block_requests, - finality_proof_requests, light_client_handler, events: VecDeque::new(), role, @@ -334,8 +329,6 @@ Behaviour { self.events.push_back(BehaviourOut::BlockImport(origin, blocks)), CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) => self.events.push_back(BehaviourOut::JustificationImport(origin, hash, nb, justification)), - CustomMessageOutcome::FinalityProofImport(origin, hash, nb, proof) => - self.events.push_back(BehaviourOut::FinalityProofImport(origin, hash, nb, proof)), CustomMessageOutcome::BlockRequest { target, request } => { match self.block_requests.send_request(&target, request) { block_requests::SendRequestOutcome::Ok => { @@ -359,9 +352,6 @@ Behaviour { block_requests::SendRequestOutcome::EncodeError(_) => {}, } }, - CustomMessageOutcome::FinalityProofRequest { target, block_hash, request } => { - self.finality_proof_requests.send_request(&target, block_hash, request); - }, CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles, notifications_sink } => { let role = reported_roles_to_observed_role(&self.role, &remote, roles); for protocol in protocols { @@ -454,26 +444,6 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess> for Behaviour { - fn inject_event(&mut self, event: finality_requests::Event) { - match event { - finality_requests::Event::Response { peer, block_hash, proof } => { - let response = message::FinalityProofResponse { - id: 0, - block: block_hash, - proof: if !proof.is_empty() { - Some(proof) - } else { - None - }, - }; - let ev = self.substrate.on_finality_proof_response(peer, response); - self.inject_event(ev); - } - } - } -} - impl NetworkBehaviourEventProcess for Behaviour { fn inject_event(&mut self, event: peer_info::PeerInfoEvent) { diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 20fbe028439..61d19c10dae 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -32,15 +32,3 @@ impl Client for T T: HeaderBackend + ProofProvider + BlockIdTo + BlockBackend + HeaderMetadata + Send + Sync {} - -/// Finality proof provider. -pub trait FinalityProofProvider: Send + Sync { - /// Prove finality of the block. - fn prove_finality(&self, for_block: Block::Hash, request: &[u8]) -> Result>, Error>; -} - -impl FinalityProofProvider for () { - fn prove_finality(&self, _for_block: Block::Hash, _request: &[u8]) -> Result>, Error> { - Ok(None) - } -} diff --git a/client/network/src/config.rs b/client/network/src/config.rs index db33623a2e3..b7b113dc146 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -21,7 +21,7 @@ //! The [`Params`] struct is the struct that must be passed in order to initialize the networking. //! See the documentation of [`Params`]. -pub use crate::chain::{Client, FinalityProofProvider}; +pub use crate::chain::Client; pub use crate::on_demand_layer::{AlwaysBadChecker, OnDemand}; pub use crate::request_responses::{IncomingRequest, ProtocolConfig as RequestResponseConfig}; pub use libp2p::{identity, core::PublicKey, wasm_ext::ExtTransport, build_multiaddr}; @@ -70,17 +70,6 @@ pub struct Params { /// Client that contains the blockchain. pub chain: Arc>, - /// Finality proof provider. - /// - /// This object, if `Some`, is used when a node on the network requests a proof of finality - /// from us. - pub finality_proof_provider: Option>>, - - /// How to build requests for proofs of finality. - /// - /// This object, if `Some`, is used when we need a proof of finality from another node. - pub finality_proof_request_builder: Option>, - /// The `OnDemand` object acts as a "receiver" for block data requests from the client. /// If `Some`, the network worker will process these requests and answer them. /// Normally used only for light clients. @@ -153,25 +142,6 @@ impl fmt::Display for Role { } } -/// Finality proof request builder. -pub trait FinalityProofRequestBuilder: Send { - /// Build data blob, associated with the request. - fn build_request_data(&mut self, hash: &B::Hash) -> Vec; -} - -/// Implementation of `FinalityProofRequestBuilder` that builds a dummy empty request. -#[derive(Debug, Default)] -pub struct DummyFinalityProofRequestBuilder; - -impl FinalityProofRequestBuilder for DummyFinalityProofRequestBuilder { - fn build_request_data(&mut self, _: &B::Hash) -> Vec { - Vec::new() - } -} - -/// Shared finality proof request builder struct used by the queue. -pub type BoxFinalityProofRequestBuilder = Box + Send + Sync>; - /// Result of the transaction import. #[derive(Clone, Copy, Debug)] pub enum TransactionImport { diff --git a/client/network/src/finality_requests.rs b/client/network/src/finality_requests.rs deleted file mode 100644 index 55f56b9a0cc..00000000000 --- a/client/network/src/finality_requests.rs +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. -// -// Substrate 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. -// -// Substrate 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 Substrate. If not, see . - -//! `NetworkBehaviour` implementation which handles incoming finality proof requests. -//! -//! Every request is coming in on a separate connection substream which gets -//! closed after we have sent the response back. Incoming requests are encoded -//! as protocol buffers (cf. `finality.v1.proto`). - -#![allow(unused)] - -use bytes::Bytes; -use codec::{Encode, Decode}; -use crate::{ - chain::FinalityProofProvider, - config::ProtocolId, - protocol::message, - schema, -}; -use futures::{future::BoxFuture, prelude::*, stream::FuturesUnordered}; -use libp2p::{ - core::{ - ConnectedPoint, - Multiaddr, - PeerId, - connection::ConnectionId, - upgrade::{InboundUpgrade, OutboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, - upgrade::{DeniedUpgrade, read_one, write_one} - }, - swarm::{ - NegotiatedSubstream, - NetworkBehaviour, - NetworkBehaviourAction, - NotifyHandler, - OneShotHandler, - OneShotHandlerConfig, - PollParameters, - SubstreamProtocol - } -}; -use prost::Message; -use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; -use std::{ - cmp::min, - collections::VecDeque, - io, - iter, - marker::PhantomData, - sync::Arc, - time::Duration, - task::{Context, Poll} -}; -use void::{Void, unreachable}; - -// Type alias for convenience. -pub type Error = Box; - -/// Event generated by the finality proof requests behaviour. -#[derive(Debug)] -pub enum Event { - /// A response to a finality proof request has arrived. - Response { - peer: PeerId, - /// Block hash originally passed to `send_request`. - block_hash: B::Hash, - /// Finality proof returned by the remote. - proof: Vec, - }, -} - -/// Configuration options for `FinalityProofRequests`. -#[derive(Debug, Clone)] -pub struct Config { - max_request_len: usize, - max_response_len: usize, - inactivity_timeout: Duration, - protocol: Bytes, -} - -impl Config { - /// Create a fresh configuration with the following options: - /// - /// - max. request size = 1 MiB - /// - max. response size = 1 MiB - /// - inactivity timeout = 15s - pub fn new(id: &ProtocolId) -> Self { - let mut c = Config { - max_request_len: 1024 * 1024, - max_response_len: 1024 * 1024, - inactivity_timeout: Duration::from_secs(15), - protocol: Bytes::new(), - }; - c.set_protocol(id); - c - } - - /// Limit the max. length of incoming finality proof request bytes. - pub fn set_max_request_len(&mut self, v: usize) -> &mut Self { - self.max_request_len = v; - self - } - - /// Limit the max. length of incoming finality proof response bytes. - pub fn set_max_response_len(&mut self, v: usize) -> &mut Self { - self.max_response_len = v; - self - } - - /// Limit the max. duration the substream may remain inactive before closing it. - pub fn set_inactivity_timeout(&mut self, v: Duration) -> &mut Self { - self.inactivity_timeout = v; - self - } - - /// Set protocol to use for upgrade negotiation. - pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { - let mut v = Vec::new(); - v.extend_from_slice(b"/"); - v.extend_from_slice(id.as_ref().as_bytes()); - v.extend_from_slice(b"/finality-proof/1"); - self.protocol = v.into(); - self - } -} - -/// The finality proof request handling behaviour. -pub struct FinalityProofRequests { - /// This behaviour's configuration. - config: Config, - /// How to construct finality proofs. - finality_proof_provider: Option>>, - /// Futures sending back the finality proof request responses. - outgoing: FuturesUnordered>, - /// Events to return as soon as possible from `poll`. - pending_events: VecDeque, Event>>, -} - -impl FinalityProofRequests -where - B: Block, -{ - /// Initializes the behaviour. - /// - /// If the proof provider is `None`, then the behaviour will not support the finality proof - /// requests protocol. - pub fn new(cfg: Config, finality_proof_provider: Option>>) -> Self { - FinalityProofRequests { - config: cfg, - finality_proof_provider, - outgoing: FuturesUnordered::new(), - pending_events: VecDeque::new(), - } - } - - /// Issue a new finality proof request. - /// - /// If the response doesn't arrive in time, or if the remote answers improperly, the target - /// will be disconnected. - pub fn send_request(&mut self, target: &PeerId, block_hash: B::Hash, request: Vec) { - let protobuf_rq = schema::v1::finality::FinalityProofRequest { - block_hash: block_hash.encode(), - request, - }; - - let mut buf = Vec::with_capacity(protobuf_rq.encoded_len()); - if let Err(err) = protobuf_rq.encode(&mut buf) { - log::warn!("failed to encode finality proof request {:?}: {:?}", protobuf_rq, err); - return; - } - - log::trace!("enqueueing finality proof request to {:?}: {:?}", target, protobuf_rq); - self.pending_events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: target.clone(), - handler: NotifyHandler::Any, - event: OutboundProtocol { - request: buf, - block_hash, - max_response_size: self.config.max_response_len, - protocol: self.config.protocol.clone(), - }, - }); - } - - /// Callback, invoked when a new finality request has been received from remote. - fn on_finality_request(&mut self, peer: &PeerId, request: &schema::v1::finality::FinalityProofRequest) - -> Result - { - let block_hash = Decode::decode(&mut request.block_hash.as_ref())?; - - log::trace!(target: "sync", "Finality proof request from {} for {}", peer, block_hash); - - // Note that an empty Vec is sent if no proof is available. - let finality_proof = if let Some(provider) = &self.finality_proof_provider { - provider - .prove_finality(block_hash, &request.request)? - .unwrap_or_default() - } else { - log::error!("Answering a finality proof request while finality provider is empty"); - return Err(From::from("Empty finality proof provider".to_string())) - }; - - Ok(schema::v1::finality::FinalityProofResponse { proof: finality_proof }) - } -} - -impl NetworkBehaviour for FinalityProofRequests -where - B: Block -{ - type ProtocolsHandler = OneShotHandler, OutboundProtocol, NodeEvent>; - type OutEvent = Event; - - fn new_handler(&mut self) -> Self::ProtocolsHandler { - let p = InboundProtocol { - max_request_len: self.config.max_request_len, - protocol: if self.finality_proof_provider.is_some() { - Some(self.config.protocol.clone()) - } else { - None - }, - marker: PhantomData, - }; - let mut cfg = OneShotHandlerConfig::default(); - cfg.keep_alive_timeout = self.config.inactivity_timeout; - OneShotHandler::new(SubstreamProtocol::new(p, ()), cfg) - } - - fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { - Vec::new() - } - - fn inject_connected(&mut self, _peer: &PeerId) { - } - - fn inject_disconnected(&mut self, _peer: &PeerId) { - } - - fn inject_event( - &mut self, - peer: PeerId, - connection: ConnectionId, - event: NodeEvent - ) { - match event { - NodeEvent::Request(request, mut stream) => { - match self.on_finality_request(&peer, &request) { - Ok(res) => { - log::trace!("enqueueing finality response for peer {}", peer); - let mut data = Vec::with_capacity(res.encoded_len()); - if let Err(e) = res.encode(&mut data) { - log::debug!("error encoding finality response for peer {}: {}", peer, e) - } else { - let future = async move { - if let Err(e) = write_one(&mut stream, data).await { - log::debug!("error writing finality response: {}", e) - } - }; - self.outgoing.push(future.boxed()) - } - } - Err(e) => log::debug!("error handling finality request from peer {}: {}", peer, e) - } - } - NodeEvent::Response(response, block_hash) => { - let ev = Event::Response { - peer, - block_hash, - proof: response.proof, - }; - self.pending_events.push_back(NetworkBehaviourAction::GenerateEvent(ev)); - } - } - } - - fn poll(&mut self, cx: &mut Context, _: &mut impl PollParameters) - -> Poll, Event>> - { - if let Some(ev) = self.pending_events.pop_front() { - return Poll::Ready(ev); - } - - while let Poll::Ready(Some(_)) = self.outgoing.poll_next_unpin(cx) {} - Poll::Pending - } -} - -/// Output type of inbound and outbound substream upgrades. -#[derive(Debug)] -pub enum NodeEvent { - /// Incoming request from remote and substream to use for the response. - Request(schema::v1::finality::FinalityProofRequest, T), - /// Incoming response from remote. - Response(schema::v1::finality::FinalityProofResponse, B::Hash), -} - -/// Substream upgrade protocol. -/// -/// We attempt to parse an incoming protobuf encoded request (cf. `Request`) -/// which will be handled by the `FinalityProofRequests` behaviour, i.e. the request -/// will become visible via `inject_node_event` which then dispatches to the -/// relevant callback to process the message and prepare a response. -#[derive(Debug, Clone)] -pub struct InboundProtocol { - /// The max. request length in bytes. - max_request_len: usize, - /// The protocol to use during upgrade negotiation. If `None`, then the incoming protocol - /// is simply disabled. - protocol: Option, - /// Marker to pin the block type. - marker: PhantomData, -} - -impl UpgradeInfo for InboundProtocol { - type Info = Bytes; - // This iterator will return either 0 elements if `self.protocol` is `None`, or 1 element if - // it is `Some`. - type InfoIter = std::option::IntoIter; - - fn protocol_info(&self) -> Self::InfoIter { - self.protocol.clone().into_iter() - } -} - -impl InboundUpgrade for InboundProtocol -where - B: Block, - T: AsyncRead + AsyncWrite + Unpin + Send + 'static -{ - type Output = NodeEvent; - type Error = ReadOneError; - type Future = BoxFuture<'static, Result>; - - fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { - async move { - let len = self.max_request_len; - let vec = read_one(&mut s, len).await?; - match schema::v1::finality::FinalityProofRequest::decode(&vec[..]) { - Ok(r) => Ok(NodeEvent::Request(r, s)), - Err(e) => Err(ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e))) - } - }.boxed() - } -} - -/// Substream upgrade protocol. -/// -/// Sends a request to remote and awaits the response. -#[derive(Debug, Clone)] -pub struct OutboundProtocol { - /// The serialized protobuf request. - request: Vec, - /// Block hash that has been requested. - block_hash: B::Hash, - /// The max. response length in bytes. - max_response_size: usize, - /// The protocol to use for upgrade negotiation. - protocol: Bytes, -} - -impl UpgradeInfo for OutboundProtocol { - type Info = Bytes; - type InfoIter = iter::Once; - - fn protocol_info(&self) -> Self::InfoIter { - iter::once(self.protocol.clone()) - } -} - -impl OutboundUpgrade for OutboundProtocol -where - B: Block, - T: AsyncRead + AsyncWrite + Unpin + Send + 'static -{ - type Output = NodeEvent; - type Error = ReadOneError; - type Future = BoxFuture<'static, Result>; - - fn upgrade_outbound(self, mut s: T, _: Self::Info) -> Self::Future { - async move { - write_one(&mut s, &self.request).await?; - let vec = read_one(&mut s, self.max_response_size).await?; - - schema::v1::finality::FinalityProofResponse::decode(&vec[..]) - .map(|r| NodeEvent::Response(r, self.block_hash)) - .map_err(|e| { - ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e)) - }) - }.boxed() - } -} diff --git a/client/network/src/gossip/tests.rs b/client/network/src/gossip/tests.rs index e94052c0e4d..93b69f7b64c 100644 --- a/client/network/src/gossip/tests.rs +++ b/client/network/src/gossip/tests.rs @@ -86,7 +86,6 @@ fn build_test_full_node(config: config::NetworkConfiguration) PassThroughVerifier(false), Box::new(client.clone()), None, - None, &sp_core::testing::TaskExecutor::new(), None, )); @@ -96,8 +95,6 @@ fn build_test_full_node(config: config::NetworkConfiguration) executor: None, network_config: config, chain: client.clone(), - finality_proof_provider: None, - finality_proof_request_builder: None, on_demand: None, transaction_pool: Arc::new(crate::config::EmptyTransactionPool), protocol_id: config::ProtocolId::from("/test-protocol-name"), diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index 3fd01c33dcf..b050db8785a 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -249,7 +249,6 @@ mod block_requests; mod chain; mod peer_info; mod discovery; -mod finality_requests; mod light_client_handler; mod on_demand_layer; mod protocol; diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index d0b6b2823a2..597031b9018 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -19,7 +19,7 @@ use crate::{ ExHashT, chain::Client, - config::{BoxFinalityProofRequestBuilder, ProtocolId, TransactionPool, TransactionImportFuture, TransactionImport}, + config::{ProtocolId, TransactionPool, TransactionImportFuture, TransactionImport}, error, utils::{interval, LruHashSet}, }; @@ -131,7 +131,6 @@ struct Metrics { peers: Gauge, queued_blocks: Gauge, fork_targets: Gauge, - finality_proofs: GaugeVec, justifications: GaugeVec, propagated_transactions: Counter, } @@ -165,16 +164,6 @@ impl Metrics { )?; register(g, r)? }, - finality_proofs: { - let g = GaugeVec::new( - Opts::new( - "sync_extra_finality_proofs", - "Number of extra finality proof requests", - ), - &["status"], - )?; - register(g, r)? - }, propagated_transactions: register(Counter::new( "sync_propagated_transactions", "Number of transactions propagated to at least one peer", @@ -365,7 +354,6 @@ impl Protocol { local_peer_id: PeerId, chain: Arc>, transaction_pool: Arc>, - finality_proof_request_builder: Option>, protocol_id: ProtocolId, peerset_config: sc_peerset::PeersetConfig, block_announce_validator: Box + Send>, @@ -377,7 +365,6 @@ impl Protocol { config.roles, chain.clone(), &info, - finality_proof_request_builder, block_announce_validator, config.max_parallel_downloads, ); @@ -614,10 +601,7 @@ impl Protocol { warn!(target: "sub-libp2p", "Received unexpected RemoteHeaderResponse"), GenericMessage::RemoteChangesResponse(_) => warn!(target: "sub-libp2p", "Received unexpected RemoteChangesResponse"), - GenericMessage::FinalityProofResponse(_) => - warn!(target: "sub-libp2p", "Received unexpected FinalityProofResponse"), GenericMessage::BlockRequest(_) | - GenericMessage::FinalityProofRequest(_) | GenericMessage::RemoteReadChildRequest(_) | GenericMessage::RemoteCallRequest(_) | GenericMessage::RemoteReadRequest(_) | @@ -1314,13 +1298,6 @@ impl Protocol { self.sync.on_justification_import(hash, number, success) } - /// Request a finality proof for the given block. - /// - /// Queues a new finality proof request and tries to dispatch all pending requests. - pub fn request_finality_proof(&mut self, hash: &B::Hash, number: NumberFor) { - self.sync.request_finality_proof(&hash, number) - } - /// Notify the protocol that we have learned about the existence of nodes. /// /// Can be called multiple times with the same `PeerId`s. @@ -1328,34 +1305,6 @@ impl Protocol { self.behaviour.add_discovered_nodes(peer_ids) } - pub fn finality_proof_import_result( - &mut self, - request_block: (B::Hash, NumberFor), - finalization_result: Result<(B::Hash, NumberFor), ()>, - ) { - self.sync.on_finality_proof_import(request_block, finalization_result) - } - - /// Must be called after a [`CustomMessageOutcome::FinalityProofRequest`] has been emitted, - /// to notify of the response having arrived. - pub fn on_finality_proof_response( - &mut self, - who: PeerId, - response: message::FinalityProofResponse, - ) -> CustomMessageOutcome { - trace!(target: "sync", "Finality proof response from {} for {}", who, response.block); - match self.sync.on_block_finality_proof(who, response) { - Ok(sync::OnBlockFinalityProof::Nothing) => CustomMessageOutcome::None, - Ok(sync::OnBlockFinalityProof::Import { peer, hash, number, proof }) => - CustomMessageOutcome::FinalityProofImport(peer, hash, number, proof), - Err(sync::BadPeer(id, repu)) => { - self.behaviour.disconnect_peer(&id); - self.peerset_handle.report_peer(id, repu); - CustomMessageOutcome::None - } - } - } - fn format_stats(&self) -> String { let mut out = String::new(); for (id, stats) in &self.context_data.stats { @@ -1399,15 +1348,6 @@ impl Protocol { .set(m.justifications.failed_requests.into()); metrics.justifications.with_label_values(&["importing"]) .set(m.justifications.importing_requests.into()); - - metrics.finality_proofs.with_label_values(&["pending"]) - .set(m.finality_proofs.pending_requests.into()); - metrics.finality_proofs.with_label_values(&["active"]) - .set(m.finality_proofs.active_requests.into()); - metrics.finality_proofs.with_label_values(&["failed"]) - .set(m.finality_proofs.failed_requests.into()); - metrics.finality_proofs.with_label_values(&["importing"]) - .set(m.finality_proofs.importing_requests.into()); } } } @@ -1418,7 +1358,6 @@ impl Protocol { pub enum CustomMessageOutcome { BlockImport(BlockOrigin, Vec>), JustificationImport(Origin, B::Hash, NumberFor, Justification), - FinalityProofImport(Origin, B::Hash, NumberFor, Vec), /// Notification protocols have been opened with a remote. NotificationStreamOpened { remote: PeerId, @@ -1443,12 +1382,6 @@ pub enum CustomMessageOutcome { /// must be silently discarded. /// It is the responsibility of the handler to ensure that a timeout exists. BlockRequest { target: PeerId, request: message::BlockRequest }, - /// A new finality proof request must be emitted. - /// Once you have the response, you must call `Protocol::on_finality_proof_response`. - /// It is the responsibility of the handler to ensure that a timeout exists. - /// If the request times out, or the peer responds in an invalid way, the peer has to be - /// disconnect. This will inform the state machine that the request it has emitted is stale. - FinalityProofRequest { target: PeerId, block_hash: B::Hash, request: Vec }, /// Peer has a reported a new head of chain. PeerNewBest(PeerId, NumberFor), None, @@ -1545,14 +1478,6 @@ impl NetworkBehaviour for Protocol { }; self.pending_messages.push_back(event); } - for (id, r) in self.sync.finality_proof_requests() { - let event = CustomMessageOutcome::FinalityProofRequest { - target: id, - block_hash: r.block, - request: r.request, - }; - self.pending_messages.push_back(event); - } if let Poll::Ready(Some((tx_hash, result))) = self.pending_transactions.poll_next_unpin(cx) { if let Some(peers) = self.pending_transactions_peers.remove(&tx_hash) { peers.into_iter().for_each(|p| self.on_handle_transaction_import(p, result)); diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index dae7b86db87..4213d56bbf0 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -25,7 +25,6 @@ pub use self::generic::{ BlockAnnounce, RemoteCallRequest, RemoteReadRequest, RemoteHeaderRequest, RemoteHeaderResponse, RemoteChangesRequest, RemoteChangesResponse, - FinalityProofRequest, FinalityProofResponse, FromBlock, RemoteReadChildRequest, Roles, }; use sc_client_api::StorageProof; @@ -280,11 +279,10 @@ pub mod generic { RemoteChangesResponse(RemoteChangesResponse), /// Remote child storage read request. RemoteReadChildRequest(RemoteReadChildRequest), - /// Finality proof request. - FinalityProofRequest(FinalityProofRequest), - /// Finality proof response. - FinalityProofResponse(FinalityProofResponse), /// Batch of consensus protocol messages. + // NOTE: index is incremented by 2 due to finality proof related + // messages that were removed. + #[codec(index = "17")] ConsensusBatch(Vec), } @@ -307,8 +305,6 @@ pub mod generic { Message::RemoteChangesRequest(_) => "RemoteChangesRequest", Message::RemoteChangesResponse(_) => "RemoteChangesResponse", Message::RemoteReadChildRequest(_) => "RemoteReadChildRequest", - Message::FinalityProofRequest(_) => "FinalityProofRequest", - Message::FinalityProofResponse(_) => "FinalityProofResponse", Message::ConsensusBatch(_) => "ConsensusBatch", } } @@ -546,26 +542,4 @@ pub mod generic { /// Missing changes tries roots proof. pub roots_proof: StorageProof, } - - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] - /// Finality proof request. - pub struct FinalityProofRequest { - /// Unique request id. - pub id: RequestId, - /// Hash of the block to request proof for. - pub block: H, - /// Additional data blob (that both requester and provider understood) required for proving finality. - pub request: Vec, - } - - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] - /// Finality proof response. - pub struct FinalityProofResponse { - /// Id of a request this response was made for. - pub id: RequestId, - /// Hash of the block (the same as in the FinalityProofRequest). - pub block: H, - /// Finality proof (if available). - pub proof: Option>, - } } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 03714b05ace..ced789446da 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -35,9 +35,7 @@ use sp_consensus::{BlockOrigin, BlockStatus, import_queue::{IncomingBlock, BlockImportResult, BlockImportError} }; use crate::{ - config::BoxFinalityProofRequestBuilder, - protocol::message::{self, generic::FinalityProofRequest, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, - FinalityProofResponse, Roles}, + protocol::message::{self, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, Roles}, }; use either::Either; use extra_requests::ExtraRequests; @@ -116,9 +114,6 @@ mod rep { /// Reputation change for peers which send us a block with bad justifications. pub const BAD_JUSTIFICATION: Rep = Rep::new(-(1 << 16), "Bad justification"); - /// Reputation change for peers which send us a block with bad finality proof. - pub const BAD_FINALITY_PROOF: Rep = Rep::new(-(1 << 16), "Bad finality proof"); - /// Reputation change when a peer sent us invlid ancestry result. pub const UNKNOWN_ANCESTOR:Rep = Rep::new(-(1 << 16), "DB Error"); } @@ -185,8 +180,6 @@ pub struct ChainSync { /// What block attributes we require for this node, usually derived from /// what role we are, but could be customized required_block_attributes: message::BlockAttributes, - /// Any extra finality proof requests. - extra_finality_proofs: ExtraRequests, /// Any extra justification requests. extra_justifications: ExtraRequests, /// A set of hashes of blocks that are being downloaded or have been @@ -195,8 +188,6 @@ pub struct ChainSync { /// The best block number that was successfully imported into the chain. /// This can not decrease. best_imported_number: NumberFor, - /// Finality proof handler. - request_builder: Option>, /// Fork sync targets. fork_targets: HashMap>, /// A set of peers for which there might be potential block requests @@ -270,8 +261,6 @@ pub enum PeerSyncState { DownloadingStale(B::Hash), /// Downloading justification for given block hash. DownloadingJustification(B::Hash), - /// Downloading finality proof for given block hash. - DownloadingFinalityProof(B::Hash) } impl PeerSyncState { @@ -402,20 +391,6 @@ pub enum OnBlockJustification { } } -/// Result of [`ChainSync::on_block_finality_proof`]. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum OnBlockFinalityProof { - /// The proof needs no further handling. - Nothing, - /// The proof should be imported. - Import { - peer: PeerId, - hash: B::Hash, - number: NumberFor, - proof: Vec - } -} - /// Result of [`ChainSync::has_slot_for_block_announce_validation`]. enum HasSlotForBlockAnnounceValidation { /// Yes, there is a slot for the block announce validation. @@ -432,7 +407,6 @@ impl ChainSync { role: Roles, client: Arc>, info: &BlockchainInfo, - request_builder: Option>, block_announce_validator: Box + Send>, max_parallel_downloads: u32, ) -> Self { @@ -449,12 +423,10 @@ impl ChainSync { best_queued_hash: info.best_hash, best_queued_number: info.best_number, best_imported_number: info.best_number, - extra_finality_proofs: ExtraRequests::new("finality proof"), extra_justifications: ExtraRequests::new("justification"), role, required_block_attributes, queue_blocks: Default::default(), - request_builder, fork_targets: Default::default(), pending_requests: Default::default(), block_announce_validator, @@ -613,14 +585,6 @@ impl ChainSync { }) } - /// Schedule a finality proof request for the given block. - pub fn request_finality_proof(&mut self, hash: &B::Hash, number: NumberFor) { - let client = &self.client; - self.extra_finality_proofs.schedule((*hash, number), |base, block| { - is_descendent_of(&**client, base, block) - }) - } - /// Request syncing for the given block from given set of peers. // The implementation is similar to on_block_announce with unknown parent hash. pub fn set_sync_fork_request( @@ -700,30 +664,6 @@ impl ChainSync { }) } - /// Get an iterator over all scheduled finality proof requests. - pub fn finality_proof_requests(&mut self) -> impl Iterator)> + '_ { - let peers = &mut self.peers; - let request_builder = &mut self.request_builder; - let mut matcher = self.extra_finality_proofs.matcher(); - std::iter::from_fn(move || { - if let Some((peer, request)) = matcher.next(&peers) { - peers.get_mut(&peer) - .expect("`Matcher::next` guarantees the `PeerId` comes from the given peers; qed") - .state = PeerSyncState::DownloadingFinalityProof(request.0); - let req = message::generic::FinalityProofRequest { - id: 0, - block: request.0, - request: request_builder.as_mut() - .map(|builder| builder.build_request_data(&request.0)) - .unwrap_or_default() - }; - Some((peer, req)) - } else { - None - } - }) - } - /// Get an iterator over all block requests of all peers. pub fn block_requests(&mut self) -> impl Iterator)> + '_ { if self.pending_requests.is_empty() { @@ -920,8 +860,7 @@ impl ChainSync { } | PeerSyncState::Available - | PeerSyncState::DownloadingJustification(..) - | PeerSyncState::DownloadingFinalityProof(..) => Vec::new() + | PeerSyncState::DownloadingJustification(..) => Vec::new() } } else { // When request.is_none() this is a block announcement. Just accept blocks. @@ -1033,41 +972,6 @@ impl ChainSync { Ok(OnBlockJustification::Nothing) } - /// Handle new finality proof data. - pub fn on_block_finality_proof - (&mut self, who: PeerId, resp: FinalityProofResponse) -> Result, BadPeer> - { - let peer = - if let Some(peer) = self.peers.get_mut(&who) { - peer - } else { - error!(target: "sync", "💔 Called on_block_finality_proof_data with a bad peer ID"); - return Ok(OnBlockFinalityProof::Nothing) - }; - - self.pending_requests.add(&who); - if let PeerSyncState::DownloadingFinalityProof(hash) = peer.state { - peer.state = PeerSyncState::Available; - - // We only request one finality proof at a time. - if hash != resp.block { - info!( - target: "sync", - "💔 Invalid block finality proof provided: requested: {:?} got: {:?}", - hash, - resp.block - ); - return Err(BadPeer(who, rep::BAD_FINALITY_PROOF)); - } - - if let Some((peer, hash, number, p)) = self.extra_finality_proofs.on_response(who, resp.proof) { - return Ok(OnBlockFinalityProof::Import { peer, hash, number, proof: p }) - } - } - - Ok(OnBlockFinalityProof::Nothing) - } - /// A batch of blocks have been processed, with or without errors. /// /// Call this when a batch of blocks have been processed by the import @@ -1122,11 +1026,6 @@ impl ChainSync { } } - if aux.needs_finality_proof { - trace!(target: "sync", "Block imported but requires finality proof {}: {:?}", number, hash); - self.request_finality_proof(&hash, number); - } - if number > self.best_imported_number { self.best_imported_number = number; } @@ -1178,22 +1077,8 @@ impl ChainSync { self.pending_requests.set_all(); } - pub fn on_finality_proof_import(&mut self, req: (B::Hash, NumberFor), res: Result<(B::Hash, NumberFor), ()>) { - self.extra_finality_proofs.try_finalize_root(req, res, true); - self.pending_requests.set_all(); - } - /// Notify about finalization of the given block. pub fn on_block_finalized(&mut self, hash: &B::Hash, number: NumberFor) { - let client = &self.client; - let r = self.extra_finality_proofs.on_block_finalized(hash, number, |base, block| { - is_descendent_of(&**client, base, block) - }); - - if let Err(err) = r { - warn!(target: "sync", "💔 Error cleaning up pending extra finality proof data requests: {:?}", err) - } - let client = &self.client; let r = self.extra_justifications.on_block_finalized(hash, number, |base, block| { is_descendent_of(&**client, base, block) @@ -1506,14 +1391,12 @@ impl ChainSync { self.blocks.clear_peer_download(who); self.peers.remove(who); self.extra_justifications.peer_disconnected(who); - self.extra_finality_proofs.peer_disconnected(who); self.pending_requests.set_all(); } /// Restart the sync process. This will reset all pending block requests and return an iterator /// of new block requests to make to peers. Peers that were downloading finality data (i.e. - /// their state was `DownloadingJustification` or `DownloadingFinalityProof`) are unaffected and - /// will stay in the same state. + /// their state was `DownloadingJustification`) are unaffected and will stay in the same state. fn restart<'a>( &'a mut self, ) -> impl Iterator), BadPeer>> + 'a { @@ -1526,11 +1409,10 @@ impl ChainSync { let old_peers = std::mem::take(&mut self.peers); old_peers.into_iter().filter_map(move |(id, p)| { - // peers that were downloading justifications or finality proofs + // peers that were downloading justifications // should be kept in that state. match p.state { - PeerSyncState::DownloadingJustification(_) - | PeerSyncState::DownloadingFinalityProof(_) => { + PeerSyncState::DownloadingJustification(_) => { self.peers.insert(id, p); return None; } @@ -1570,7 +1452,6 @@ impl ChainSync { Metrics { queued_blocks: self.queue_blocks.len().try_into().unwrap_or(std::u32::MAX), fork_targets: self.fork_targets.len().try_into().unwrap_or(std::u32::MAX), - finality_proofs: self.extra_finality_proofs.metrics(), justifications: self.extra_justifications.metrics(), _priv: () } @@ -1581,7 +1462,6 @@ impl ChainSync { pub(crate) struct Metrics { pub(crate) queued_blocks: u32, pub(crate) fork_targets: u32, - pub(crate) finality_proofs: extra_requests::Metrics, pub(crate) justifications: extra_requests::Metrics, _priv: () } @@ -1835,7 +1715,6 @@ mod test { Roles::AUTHORITY, client.clone(), &info, - None, block_announce_validator, 1, ); @@ -1907,7 +1786,6 @@ mod test { Roles::AUTHORITY, client.clone(), &info, - None, Box::new(DefaultBlockAnnounceValidator), 1, ); @@ -1915,7 +1793,6 @@ mod test { let peer_id1 = PeerId::random(); let peer_id2 = PeerId::random(); let peer_id3 = PeerId::random(); - let peer_id4 = PeerId::random(); let mut new_blocks = |n| { for _ in 0..n { @@ -1928,7 +1805,6 @@ mod test { }; let (b1_hash, b1_number) = new_blocks(50); - let (b2_hash, b2_number) = new_blocks(10); // add 2 peers at blocks that we don't have locally sync.new_peer(peer_id1.clone(), Hash::random(), 42).unwrap(); @@ -1958,38 +1834,16 @@ mod test { PeerSyncState::DownloadingJustification(b1_hash), ); - // add another peer at a known later block - sync.new_peer(peer_id4.clone(), b2_hash, b2_number).unwrap(); - - // we request a finality proof for a block we have locally - sync.request_finality_proof(&b2_hash, b2_number); - - // the finality proof request should be scheduled to peer 4 - // which is at that block - assert!( - sync.finality_proof_requests().any(|(p, r)| { p == peer_id4 && r.block == b2_hash }) - ); - - assert_eq!( - sync.peers.get(&peer_id4).unwrap().state, - PeerSyncState::DownloadingFinalityProof(b2_hash), - ); - // we restart the sync state let block_requests = sync.restart(); // which should make us send out block requests to the first two peers assert!(block_requests.map(|r| r.unwrap()).all(|(p, _)| { p == peer_id1 || p == peer_id2 })); - // peer 3 and 4 should be unaffected as they were downloading finality data + // peer 3 should be unaffected it was downloading finality data assert_eq!( sync.peers.get(&peer_id3).unwrap().state, PeerSyncState::DownloadingJustification(b1_hash), ); - - assert_eq!( - sync.peers.get(&peer_id4).unwrap().state, - PeerSyncState::DownloadingFinalityProof(b2_hash), - ); } } diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index df336c25339..79f10c4a3bf 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -528,13 +528,12 @@ mod tests { impl Arbitrary for ArbitraryPeerSyncState { fn arbitrary(g: &mut G) -> Self { - let s = match g.gen::() % 5 { + let s = match g.gen::() % 4 { 0 => PeerSyncState::Available, // TODO: 1 => PeerSyncState::AncestorSearch(g.gen(), AncestorSearchState), 1 => PeerSyncState::DownloadingNew(g.gen::()), 2 => PeerSyncState::DownloadingStale(Hash::random()), - 3 => PeerSyncState::DownloadingJustification(Hash::random()), - _ => PeerSyncState::DownloadingFinalityProof(Hash::random()) + _ => PeerSyncState::DownloadingJustification(Hash::random()), }; ArbitraryPeerSyncState(s) } diff --git a/client/network/src/schema.rs b/client/network/src/schema.rs index 44fbbffd254..423d3ef5b41 100644 --- a/client/network/src/schema.rs +++ b/client/network/src/schema.rs @@ -20,9 +20,6 @@ pub mod v1 { include!(concat!(env!("OUT_DIR"), "/api.v1.rs")); - pub mod finality { - include!(concat!(env!("OUT_DIR"), "/api.v1.finality.rs")); - } pub mod light { include!(concat!(env!("OUT_DIR"), "/api.v1.light.rs")); } diff --git a/client/network/src/schema/finality.v1.proto b/client/network/src/schema/finality.v1.proto deleted file mode 100644 index 843bc4eca09..00000000000 --- a/client/network/src/schema/finality.v1.proto +++ /dev/null @@ -1,19 +0,0 @@ -// Schema definition for finality proof request/responses. - -syntax = "proto3"; - -package api.v1.finality; - -// Request a finality proof from a peer. -message FinalityProofRequest { - // SCALE-encoded hash of the block to request. - bytes block_hash = 1; - // Opaque chain-specific additional request data. - bytes request = 2; -} - -// Response to a finality proof request. -message FinalityProofResponse { - // Opaque chain-specific finality proof. Empty if no such proof exists. - bytes proof = 1; // optional -} diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 3296a97d71b..8ef76d48506 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -38,7 +38,7 @@ use crate::{ NetworkState, NotConnectedPeer as NetworkStateNotConnectedPeer, Peer as NetworkStatePeer, }, on_demand_layer::AlwaysBadChecker, - light_client_handler, block_requests, finality_requests, + light_client_handler, block_requests, protocol::{self, event::Event, NotifsHandlerError, NotificationsSink, Ready, sync::SyncState, PeerInfo, Protocol}, transport, ReputationChange, }; @@ -248,7 +248,6 @@ impl NetworkWorker { local_peer_id.clone(), params.chain.clone(), params.transaction_pool, - params.finality_proof_request_builder, params.protocol_id.clone(), peerset_config, params.block_announce_validator, @@ -267,10 +266,6 @@ impl NetworkWorker { let config = block_requests::Config::new(¶ms.protocol_id); block_requests::BlockRequests::new(config, params.chain.clone()) }; - let finality_proof_requests = { - let config = finality_requests::Config::new(¶ms.protocol_id); - finality_requests::FinalityProofRequests::new(config, params.finality_proof_provider.clone()) - }; let light_client_handler = { let config = light_client_handler::Config::new(¶ms.protocol_id); light_client_handler::LightClientHandler::new( @@ -310,7 +305,6 @@ impl NetworkWorker { user_agent, local_public, block_requests, - finality_proof_requests, light_client_handler, discovery_config, params.network_config.request_response_protocols, @@ -1361,12 +1355,6 @@ impl Future for NetworkWorker { } this.import_queue.import_justification(origin, hash, nb, justification); }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::FinalityProofImport(origin, hash, nb, proof))) => { - if let Some(metrics) = this.metrics.as_ref() { - metrics.import_queue_finality_proofs_submitted.inc(); - } - this.import_queue.import_finality_proof(origin, hash, nb, proof); - }, Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::InboundRequest { protocol, result, .. })) => { if let Some(metrics) = this.metrics.as_ref() { match result { @@ -1563,11 +1551,11 @@ impl Future for NetworkWorker { let reason = match cause { Some(ConnectionError::IO(_)) => "transport-error", Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( - EitherError::A(EitherError::A(EitherError::A(EitherError::B( - EitherError::A(PingFailure::Timeout)))))))))) => "ping-timeout", + EitherError::A(EitherError::A(EitherError::B( + EitherError::A(PingFailure::Timeout))))))))) => "ping-timeout", Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( - EitherError::A(EitherError::A(EitherError::A(EitherError::A( - NotifsHandlerError::SyncNotificationsClogged))))))))) => "sync-notifications-clogged", + EitherError::A(EitherError::A(EitherError::A( + NotifsHandlerError::SyncNotificationsClogged)))))))) => "sync-notifications-clogged", Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(_))) => "protocol-error", Some(ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout)) => "keep-alive-timeout", None => "actively-closed", @@ -1752,23 +1740,6 @@ impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { fn request_justification(&mut self, hash: &B::Hash, number: NumberFor) { self.protocol.user_protocol_mut().request_justification(hash, number) } - fn request_finality_proof(&mut self, hash: &B::Hash, number: NumberFor) { - self.protocol.user_protocol_mut().request_finality_proof(hash, number) - } - fn finality_proof_imported( - &mut self, - who: PeerId, - request_block: (B::Hash, NumberFor), - finalization_result: Result<(B::Hash, NumberFor), ()>, - ) { - let success = finalization_result.is_ok(); - self.protocol.user_protocol_mut().finality_proof_import_result(request_block, finalization_result); - if !success { - info!("💔 Invalid finality proof provided by {} for #{}", who, request_block.0); - self.protocol.user_protocol_mut().disconnect_peer(&who); - self.protocol.user_protocol_mut().report_peer(who, ReputationChange::new_fatal("Invalid finality proof")); - } - } } fn ensure_addresses_consistent_with_transport<'a>( diff --git a/client/network/src/service/metrics.rs b/client/network/src/service/metrics.rs index a63ce7a18a5..614c24b522d 100644 --- a/client/network/src/service/metrics.rs +++ b/client/network/src/service/metrics.rs @@ -56,7 +56,6 @@ pub struct Metrics { pub distinct_peers_connections_closed_total: Counter, pub distinct_peers_connections_opened_total: Counter, pub import_queue_blocks_submitted: Counter, - pub import_queue_finality_proofs_submitted: Counter, pub import_queue_justifications_submitted: Counter, pub incoming_connections_errors_total: CounterVec, pub incoming_connections_total: Counter, @@ -112,10 +111,6 @@ impl Metrics { "import_queue_blocks_submitted", "Number of blocks submitted to the import queue.", )?, registry)?, - import_queue_finality_proofs_submitted: prometheus::register(Counter::new( - "import_queue_finality_proofs_submitted", - "Number of finality proofs submitted to the import queue.", - )?, registry)?, import_queue_justifications_submitted: prometheus::register(Counter::new( "import_queue_justifications_submitted", "Number of justifications submitted to the import queue.", diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 76a924748ad..225a3ae98ab 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -87,7 +87,6 @@ fn build_test_full_node(config: config::NetworkConfiguration) PassThroughVerifier(false), Box::new(client.clone()), None, - None, &sp_core::testing::TaskExecutor::new(), None, )); @@ -97,8 +96,6 @@ fn build_test_full_node(config: config::NetworkConfiguration) executor: None, network_config: config, chain: client.clone(), - finality_proof_provider: None, - finality_proof_request_builder: None, on_demand: None, transaction_pool: Arc::new(crate::config::EmptyTransactionPool), protocol_id: config::ProtocolId::from("/test-protocol-name"), diff --git a/client/network/test/src/block_import.rs b/client/network/test/src/block_import.rs index 1d2cd3d687d..a5d0600abef 100644 --- a/client/network/test/src/block_import.rs +++ b/client/network/test/src/block_import.rs @@ -107,7 +107,6 @@ fn async_import_queue_drops() { verifier, Box::new(substrate_test_runtime_client::new()), None, - None, &executor, None, ); diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 1aec3dae22b..6950ada4f84 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -29,7 +29,6 @@ use std::{ use libp2p::build_multiaddr; use log::trace; -use sc_network::config::FinalityProofProvider; use sp_blockchain::{ HeaderBackend, Result as ClientResult, well_known_cache_keys::{self, Id as CacheKeyId}, @@ -44,14 +43,14 @@ use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sc_network::config::Role; use sp_consensus::block_validation::{DefaultBlockAnnounceValidator, BlockAnnounceValidator}; use sp_consensus::import_queue::{ - BasicQueue, BoxJustificationImport, Verifier, BoxFinalityProofImport, + BasicQueue, BoxJustificationImport, Verifier, }; use sp_consensus::block_import::{BlockImport, ImportResult}; use sp_consensus::Error as ConsensusError; use sp_consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; use sc_network::{NetworkWorker, NetworkService, config::ProtocolId}; -use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; +use sc_network::config::{NetworkConfiguration, TransportConfig}; use libp2p::PeerId; use parking_lot::Mutex; use sp_core::H256; @@ -586,20 +585,10 @@ pub trait TestNetFactory: Sized { -> ( BlockImportAdapter, Option>, - Option>, - Option>, Self::PeerData, ) { - (client.as_block_import(), None, None, None, Default::default()) - } - - /// Get finality proof provider (if supported). - fn make_finality_proof_provider( - &self, - _client: PeersClient, - ) -> Option>> { - None + (client.as_block_import(), None, Default::default()) } fn default_config() -> ProtocolConfig { @@ -636,8 +625,6 @@ pub trait TestNetFactory: Sized { let ( block_import, justification_import, - finality_proof_import, - finality_proof_request_builder, data, ) = self.make_block_import(PeersClient::Full(client.clone(), backend.clone())); @@ -652,7 +639,6 @@ pub trait TestNetFactory: Sized { verifier.clone(), Box::new(block_import.clone()), justification_import, - finality_proof_import, &sp_core::testing::TaskExecutor::new(), None, )); @@ -675,10 +661,6 @@ pub trait TestNetFactory: Sized { executor: None, network_config, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider( - PeersClient::Full(client.clone(), backend.clone()), - ), - finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from("test-protocol-name"), @@ -717,8 +699,6 @@ pub trait TestNetFactory: Sized { let ( block_import, justification_import, - finality_proof_import, - finality_proof_request_builder, data, ) = self.make_block_import(PeersClient::Light(client.clone(), backend.clone())); @@ -733,7 +713,6 @@ pub trait TestNetFactory: Sized { verifier.clone(), Box::new(block_import.clone()), justification_import, - finality_proof_import, &sp_core::testing::TaskExecutor::new(), None, )); @@ -755,10 +734,6 @@ pub trait TestNetFactory: Sized { executor: None, network_config, chain: client.clone(), - finality_proof_provider: self.make_finality_proof_provider( - PeersClient::Light(client.clone(), backend.clone()) - ), - finality_proof_request_builder, on_demand: None, transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from("test-protocol-name"), @@ -989,16 +964,12 @@ impl TestNetFactory for JustificationTestNet { -> ( BlockImportAdapter, Option>, - Option>, - Option>, Self::PeerData, ) { ( client.as_block_import(), Some(Box::new(ForceFinalized(client))), - None, - None, Default::default(), ) } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 7d613f2bc62..d9dc0d1c6ba 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -41,7 +41,7 @@ use futures::{ }; use sc_keystore::LocalKeystore; use log::{info, warn}; -use sc_network::config::{Role, FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; +use sc_network::config::{Role, OnDemand}; use sc_network::NetworkService; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ @@ -830,10 +830,6 @@ pub struct BuildNetworkParams<'a, TBl: BlockT, TExPool, TImpQu, TCl> { pub block_announce_validator_builder: Option) -> Box + Send> + Send >>, - /// An optional finality proof request builder. - pub finality_proof_request_builder: Option>, - /// An optional, shared finality proof request provider. - pub finality_proof_provider: Option>>, } /// Build the network service, the network status sinks and an RPC sender. @@ -858,7 +854,7 @@ pub fn build_network( { let BuildNetworkParams { config, client, transaction_pool, spawn_handle, import_queue, on_demand, - block_announce_validator_builder, finality_proof_request_builder, finality_proof_provider, + block_announce_validator_builder, } = params; let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { @@ -896,8 +892,6 @@ pub fn build_network( }, network_config: config.network.clone(), chain: client.clone(), - finality_proof_provider, - finality_proof_request_builder, on_demand: on_demand, transaction_pool: transaction_pool_adapter as _, import_queue: Box::new(import_queue), diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index a23ebf3d553..fd5ad9ebac9 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -73,7 +73,7 @@ pub use sc_executor::NativeExecutionDispatch; pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] pub use sc_network::config::{ - FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder, TransactionImport, + OnDemand, TransactionImport, TransactionImportFuture, }; pub use sc_tracing::TracingReceiver; diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 5e593da1163..0100041fc0a 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -26,7 +26,7 @@ use std::sync::Arc; use std::any::Any; use crate::Error; -use crate::import_queue::{Verifier, CacheKeyId}; +use crate::import_queue::CacheKeyId; /// Block import result. #[derive(Debug, PartialEq, Eq)] @@ -54,8 +54,6 @@ pub struct ImportedAux { pub needs_justification: bool, /// Received a bad justification. pub bad_justification: bool, - /// Request a finality proof for the given block. - pub needs_finality_proof: bool, /// Whether the block that was imported is the new best block. pub is_new_best: bool, } @@ -63,7 +61,7 @@ pub struct ImportedAux { impl ImportResult { /// Returns default value for `ImportResult::Imported` with /// `clear_justification_requests`, `needs_justification`, - /// `bad_justification` and `needs_finality_proof` set to false. + /// `bad_justification` set to false. pub fn imported(is_new_best: bool) -> ImportResult { let mut aux = ImportedAux::default(); aux.is_new_best = is_new_best; @@ -345,21 +343,3 @@ pub trait JustificationImport { justification: Justification, ) -> Result<(), Self::Error>; } - -/// Finality proof import trait. -pub trait FinalityProofImport { - type Error: std::error::Error + Send + 'static; - - /// Called by the import queue when it is started. Returns a list of finality proofs to request - /// from the network. - fn on_start(&mut self) -> Vec<(B::Hash, NumberFor)> { Vec::new() } - - /// Import a Block justification and finalize the given block. Returns finalized block or error. - fn import_finality_proof( - &mut self, - hash: B::Hash, - number: NumberFor, - finality_proof: Vec, - verifier: &mut dyn Verifier, - ) -> Result<(B::Hash, NumberFor), Self::Error>; -} diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index 92bd9966d75..3ad8c7c92e0 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -34,7 +34,7 @@ use crate::{ error::Error as ConsensusError, block_import::{ BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, - BlockCheckParams, FinalityProofImport, + BlockCheckParams, }, metrics::Metrics, }; @@ -56,11 +56,6 @@ pub type BoxBlockImport = Box< /// Shared justification import struct used by the queue. pub type BoxJustificationImport = Box + Send + Sync>; -/// Shared finality proof import struct used by the queue. -pub type BoxFinalityProofImport = Box< - dyn FinalityProofImport + Send + Sync ->; - /// Maps to the Origin used by the network. pub type Origin = libp2p::PeerId; @@ -115,15 +110,6 @@ pub trait ImportQueue: Send { number: NumberFor, justification: Justification ); - /// Import block finality proof. - fn import_finality_proof( - &mut self, - who: Origin, - hash: B::Hash, - number: NumberFor, - finality_proof: Vec - ); - /// Polls for actions to perform on the network. /// /// This method should behave in a way similar to `Future::poll`. It can register the current @@ -146,19 +132,6 @@ pub trait Link: Send { fn justification_imported(&mut self, _who: Origin, _hash: &B::Hash, _number: NumberFor, _success: bool) {} /// Request a justification for the given block. fn request_justification(&mut self, _hash: &B::Hash, _number: NumberFor) {} - /// Finality proof import result. - /// - /// Even though we have asked for finality proof of block A, provider could return proof of - /// some earlier block B, if the proof for A was too large. The sync module should continue - /// asking for proof of A in this case. - fn finality_proof_imported( - &mut self, - _who: Origin, - _request_block: (B::Hash, NumberFor), - _finalization_result: Result<(B::Hash, NumberFor), ()>, - ) {} - /// Request a finality proof for the given block. - fn request_finality_proof(&mut self, _hash: &B::Hash, _number: NumberFor) {} } /// Block import successful result. diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index ea0ca2cf3ee..b426c39100e 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -25,7 +25,7 @@ use prometheus_endpoint::Registry; use crate::{ block_import::BlockOrigin, import_queue::{ - BlockImportResult, BlockImportError, Verifier, BoxBlockImport, BoxFinalityProofImport, + BlockImportResult, BlockImportError, Verifier, BoxBlockImport, BoxJustificationImport, ImportQueue, Link, Origin, IncomingBlock, import_single_block_metered, buffered_link::{self, BufferedLinkSender, BufferedLinkReceiver}, @@ -36,8 +36,8 @@ use crate::{ /// Interface to a basic block import queue that is importing blocks sequentially in a separate /// task, with plugable verification. pub struct BasicQueue { - /// Channel to send finality work messages to the background task. - finality_sender: TracingUnboundedSender>, + /// Channel to send justifcation import messages to the background task. + justification_sender: TracingUnboundedSender>, /// Channel to send block import messages to the background task. block_import_sender: TracingUnboundedSender>, /// Results coming from the worker task. @@ -48,7 +48,7 @@ pub struct BasicQueue { impl Drop for BasicQueue { fn drop(&mut self) { // Flush the queue and close the receiver to terminate the future. - self.finality_sender.close_channel(); + self.justification_sender.close_channel(); self.block_import_sender.close_channel(); self.result_port.close(); } @@ -57,13 +57,11 @@ impl Drop for BasicQueue { impl BasicQueue { /// Instantiate a new basic queue, with given verifier. /// - /// This creates a background task, and calls `on_start` on the justification importer and - /// finality proof importer. + /// This creates a background task, and calls `on_start` on the justification importer. pub fn new>( verifier: V, block_import: BoxBlockImport, justification_import: Option>, - finality_proof_import: Option>, spawner: &impl sp_core::traits::SpawnNamed, prometheus_registry: Option<&Registry>, ) -> Self { @@ -77,19 +75,18 @@ impl BasicQueue { .ok() }); - let (future, finality_sender, block_import_sender) = BlockImportWorker::new( + let (future, justification_sender, block_import_sender) = BlockImportWorker::new( result_sender, verifier, block_import, justification_import, - finality_proof_import, metrics, ); spawner.spawn_blocking("basic-block-import-worker", future.boxed()); Self { - finality_sender, + justification_sender, block_import_sender, result_port, _phantom: PhantomData, @@ -122,8 +119,8 @@ impl ImportQueue for BasicQueue number: NumberFor, justification: Justification, ) { - let res = self.finality_sender.unbounded_send( - worker_messages::Finality::ImportJustification(who, hash, number, justification), + let res = self.justification_sender.unbounded_send( + worker_messages::ImportJustification(who, hash, number, justification), ); if res.is_err() { @@ -134,26 +131,6 @@ impl ImportQueue for BasicQueue } } - fn import_finality_proof( - &mut self, - who: Origin, - hash: B::Hash, - number: NumberFor, - finality_proof: Vec, - ) { - trace!(target: "sync", "Scheduling finality proof of {}/{} for import", number, hash); - let res = self.finality_sender.unbounded_send( - worker_messages::Finality::ImportFinalityProof(who, hash, number, finality_proof), - ); - - if res.is_err() { - log::error!( - target: "sync", - "import_finality_proof: Background import task is no longer alive" - ); - } - } - fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link) { if self.result_port.poll_actions(cx, link).is_err() { log::error!(target: "sync", "poll_actions: Background import task is no longer alive"); @@ -166,17 +143,12 @@ mod worker_messages { use super::*; pub struct ImportBlocks(pub BlockOrigin, pub Vec>); - - pub enum Finality { - ImportJustification(Origin, B::Hash, NumberFor, Justification), - ImportFinalityProof(Origin, B::Hash, NumberFor, Vec), - } + pub struct ImportJustification(pub Origin, pub B::Hash, pub NumberFor, pub Justification); } struct BlockImportWorker { result_sender: BufferedLinkSender, justification_import: Option>, - finality_proof_import: Option>, delay_between_blocks: Duration, metrics: Option, _phantom: PhantomData, @@ -188,17 +160,16 @@ impl BlockImportWorker { verifier: V, block_import: BoxBlockImport, justification_import: Option>, - finality_proof_import: Option>, metrics: Option, ) -> ( impl Future + Send, - TracingUnboundedSender>, + TracingUnboundedSender>, TracingUnboundedSender>, ) { use worker_messages::*; - let (finality_sender, mut finality_port) = - tracing_unbounded("mpsc_import_queue_worker_finality"); + let (justification_sender, mut justification_port) = + tracing_unbounded("mpsc_import_queue_worker_justification"); let (block_import_sender, mut block_import_port) = tracing_unbounded("mpsc_import_queue_worker_blocks"); @@ -206,23 +177,17 @@ impl BlockImportWorker { let mut worker = BlockImportWorker { result_sender, justification_import, - finality_proof_import, delay_between_blocks: Duration::new(0, 0), metrics, _phantom: PhantomData, }; - // Let's initialize `justification_import` and `finality_proof_import`. + // Let's initialize `justification_import` if let Some(justification_import) = worker.justification_import.as_mut() { for (hash, number) in justification_import.on_start() { worker.result_sender.request_justification(&hash, number); } } - if let Some(finality_proof_import) = worker.finality_proof_import.as_mut() { - for (hash, number) in finality_proof_import.on_start() { - worker.result_sender.request_finality_proof(&hash, number); - } - } // The future below has two possible states: // @@ -230,7 +195,7 @@ impl BlockImportWorker { // `Future`, and `block_import` is `None`. // - Something else, in which case `block_import` is `Some` and `importing` is None. // - // Additionally, the task will prioritize processing of finality work messages over + // Additionally, the task will prioritize processing of justification import messages over // block import messages, hence why two distinct channels are used. let mut block_import_verifier = Some((block_import, verifier)); let mut importing = None; @@ -243,28 +208,15 @@ impl BlockImportWorker { return Poll::Ready(()) } - // Grab the next finality action request sent to the import queue. - let finality_work = match Stream::poll_next(Pin::new(&mut finality_port), cx) { - Poll::Ready(Some(msg)) => Some(msg), - Poll::Ready(None) => return Poll::Ready(()), - Poll::Pending => None, - }; - - match finality_work { - Some(Finality::ImportFinalityProof(who, hash, number, proof)) => { - let (_, verif) = block_import_verifier - .as_mut() - .expect("block_import_verifier is always Some; qed"); - - worker.import_finality_proof(verif, who, hash, number, proof); - continue; - } - Some(Finality::ImportJustification(who, hash, number, justification)) => { + // Grab the next justification import request sent to the import queue. + match Stream::poll_next(Pin::new(&mut justification_port), cx) { + Poll::Ready(Some(ImportJustification(who, hash, number, justification))) => { worker.import_justification(who, hash, number, justification); continue; - } - None => {} - } + }, + Poll::Ready(None) => return Poll::Ready(()), + Poll::Pending => {}, + }; // If we are in the process of importing a bunch of blocks, let's resume this // process before doing anything more. @@ -299,7 +251,7 @@ impl BlockImportWorker { } }); - (future, finality_sender, block_import_sender) + (future, justification_sender, block_import_sender) } /// Returns a `Future` that imports the given blocks and sends the results on @@ -324,36 +276,6 @@ impl BlockImportWorker { }) } - fn import_finality_proof>( - &mut self, - verifier: &mut V, - who: Origin, - hash: B::Hash, - number: NumberFor, - finality_proof: Vec - ) { - let started = wasm_timer::Instant::now(); - let result = self.finality_proof_import.as_mut().map(|finality_proof_import| { - finality_proof_import.import_finality_proof(hash, number, finality_proof, verifier) - .map_err(|e| { - debug!( - "Finality proof import failed with {:?} for hash: {:?} number: {:?} coming from node: {:?}", - e, - hash, - number, - who, - ); - }) - }).unwrap_or(Err(())); - - if let Some(metrics) = self.metrics.as_ref() { - metrics.finality_proof_import_time.observe(started.elapsed().as_secs_f64()); - } - - trace!(target: "sync", "Imported finality proof for {}/{}", number, hash); - self.result_sender.finality_proof_imported(who, (hash, number), result); - } - fn import_justification( &mut self, who: Origin, @@ -596,7 +518,7 @@ mod tests { let (result_sender, mut result_port) = buffered_link::buffered_link(); let (mut worker, mut finality_sender, mut block_import_sender) = - BlockImportWorker::new(result_sender, (), Box::new(()), Some(Box::new(())), None, None); + BlockImportWorker::new(result_sender, (), Box::new(()), Some(Box::new(())), None); let mut import_block = |n| { let header = Header { @@ -629,7 +551,7 @@ mod tests { let mut import_justification = || { let hash = Hash::random(); - block_on(finality_sender.send(worker_messages::Finality::ImportJustification( + block_on(finality_sender.send(worker_messages::ImportJustification( libp2p::PeerId::random(), hash, 1, diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index a37d4c53c26..db9bcc8f0ad 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -81,8 +81,6 @@ enum BlockImportWorkerMsg { BlocksProcessed(usize, usize, Vec<(Result>, BlockImportError>, B::Hash)>), JustificationImported(Origin, B::Hash, NumberFor, bool), RequestJustification(B::Hash, NumberFor), - FinalityProofImported(Origin, (B::Hash, NumberFor), Result<(B::Hash, NumberFor), ()>), - RequestFinalityProof(B::Hash, NumberFor), } impl Link for BufferedLinkSender { @@ -109,20 +107,6 @@ impl Link for BufferedLinkSender { fn request_justification(&mut self, hash: &B::Hash, number: NumberFor) { let _ = self.tx.unbounded_send(BlockImportWorkerMsg::RequestJustification(hash.clone(), number)); } - - fn finality_proof_imported( - &mut self, - who: Origin, - request_block: (B::Hash, NumberFor), - finalization_result: Result<(B::Hash, NumberFor), ()>, - ) { - let msg = BlockImportWorkerMsg::FinalityProofImported(who, request_block, finalization_result); - let _ = self.tx.unbounded_send(msg); - } - - fn request_finality_proof(&mut self, hash: &B::Hash, number: NumberFor) { - let _ = self.tx.unbounded_send(BlockImportWorkerMsg::RequestFinalityProof(hash.clone(), number)); - } } /// See [`buffered_link`]. @@ -154,10 +138,6 @@ impl BufferedLinkReceiver { link.justification_imported(who, &hash, number, success), BlockImportWorkerMsg::RequestJustification(hash, number) => link.request_justification(&hash, number), - BlockImportWorkerMsg::FinalityProofImported(who, block, result) => - link.finality_proof_imported(who, block, result), - BlockImportWorkerMsg::RequestFinalityProof(hash, number) => - link.request_finality_proof(&hash, number), } } } diff --git a/primitives/consensus/common/src/lib.rs b/primitives/consensus/common/src/lib.rs index 988aa7a816c..10fe8a2b315 100644 --- a/primitives/consensus/common/src/lib.rs +++ b/primitives/consensus/common/src/lib.rs @@ -49,7 +49,7 @@ mod metrics; pub use self::error::Error; pub use block_import::{ BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, BlockCheckParams, - ImportResult, JustificationImport, FinalityProofImport, + ImportResult, JustificationImport, }; pub use select_chain::SelectChain; pub use sp_state_machine::Backend as StateBackend; diff --git a/primitives/consensus/common/src/metrics.rs b/primitives/consensus/common/src/metrics.rs index a35b7c4968f..6e6b582e125 100644 --- a/primitives/consensus/common/src/metrics.rs +++ b/primitives/consensus/common/src/metrics.rs @@ -30,7 +30,6 @@ pub(crate) struct Metrics { pub import_queue_processed: CounterVec, pub block_verification_time: HistogramVec, pub block_verification_and_import_time: Histogram, - pub finality_proof_import_time: Histogram, pub justification_import_time: Histogram, } @@ -63,15 +62,6 @@ impl Metrics { )?, registry, )?, - finality_proof_import_time: register( - Histogram::with_opts( - HistogramOpts::new( - "finality_proof_import_time", - "Time taken to import finality proofs", - ), - )?, - registry, - )?, justification_import_time: register( Histogram::with_opts( HistogramOpts::new( -- GitLab From 0840c58849bc84e7fd72627745bda243741adcd8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 23 Nov 2020 17:34:37 +0100 Subject: [PATCH 038/163] client/authority-discovery: Publish and query on exponential interval (#7545) * client/authority-discovery: Publish and query on exponential interval When a node starts up publishing and querying might fail due to various reasons, for example due to being not yet fully bootstrapped on the DHT. Thus one should retry rather sooner than later. On the other hand, a long running node is likely well connected and thus timely retries are not needed. For this reasoning use an exponentially increasing interval for `publish_interval`, `query_interval` and `priority_group_set_interval` instead of a constant interval. * client/authority-discovery/src/interval.rs: Add license header * .maintain/gitlab: Ensure adder collator tests are run on CI --- .../gitlab/check_polkadot_companion_build.sh | 3 + client/authority-discovery/src/interval.rs | 62 ++++++++++++++++ client/authority-discovery/src/lib.rs | 51 ++++++------- client/authority-discovery/src/worker.rs | 73 ++++++++----------- .../authority-discovery/src/worker/tests.rs | 60 --------------- client/network/src/discovery.rs | 6 +- 6 files changed, 119 insertions(+), 136 deletions(-) create mode 100644 client/authority-discovery/src/interval.rs diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 73a5a36ff8a..4b6e45c267e 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -92,3 +92,6 @@ cd polkadot # Test Polkadot pr or master branch with this Substrate commit. cargo update -p sp-io time cargo test --all --release --verbose --features=real-overseer + +cd parachain/test-parachains/adder/collator/ +time cargo test --release --verbose --locked --features=real-overseer diff --git a/client/authority-discovery/src/interval.rs b/client/authority-discovery/src/interval.rs new file mode 100644 index 00000000000..b3aa5b1c0f6 --- /dev/null +++ b/client/authority-discovery/src/interval.rs @@ -0,0 +1,62 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use futures::stream::Stream; +use futures::future::FutureExt; +use futures::ready; +use futures_timer::Delay; +use std::pin::Pin; +use std::task::{Context, Poll}; +use std::time::Duration; + +/// Exponentially increasing interval +/// +/// Doubles interval duration on each tick until the configured maximum is reached. +pub struct ExpIncInterval { + max: Duration, + next: Duration, + delay: Delay, +} + +impl ExpIncInterval { + /// Create a new [`ExpIncInterval`]. + pub fn new(start: Duration, max: Duration) -> Self { + let delay = Delay::new(start); + Self { + max, + next: start * 2, + delay, + } + } + + /// Fast forward the exponentially increasing interval to the configured maximum. + pub fn set_to_max(&mut self) { + self.next = self.max; + self.delay = Delay::new(self.next); + } +} + +impl Stream for ExpIncInterval { + type Item = (); + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + ready!(self.delay.poll_unpin(cx)); + self.delay = Delay::new(self.next); + self.next = std::cmp::min(self.max, self.next * 2); + + Poll::Ready(Some(())) + } +} diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 4ee57f31e04..41aa01e56bd 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -38,50 +38,41 @@ use sp_runtime::traits::Block as BlockT; use sp_api::ProvideRuntimeApi; mod error; +mod interval; mod service; +mod worker; + #[cfg(test)] mod tests; -mod worker; /// Configuration of [`Worker`]. pub struct WorkerConfig { - /// The interval in which the node will publish its own address on the DHT. + /// The maximum interval in which the node will publish its own address on the DHT. /// - /// By default this is set to 12 hours. - pub publish_interval: Duration, - /// The interval in which the node will query the DHT for new entries. + /// By default this is set to 1 hour. + pub max_publish_interval: Duration, + /// The maximum interval in which the node will query the DHT for new entries. /// /// By default this is set to 10 minutes. - pub query_interval: Duration, - /// The time the node will wait before triggering the first DHT query or publish. - /// - /// By default this is set to 30 seconds. - /// - /// This default is based on the rough boostrap time required by libp2p Kademlia. - pub query_start_delay: Duration, - /// The interval in which the worker will instruct the peerset to connect to a random subset - /// of discovered validators. - /// - /// By default this is set to 10 minutes. - pub priority_group_set_interval: Duration, - /// The time the worker will wait after each query interval tick to pass a subset of - /// the cached authority addresses down to the peerset. - /// - /// Be aware that the actual delay will be computed by [`Self::query_start_delay`] + - /// [`Self::priority_group_set_start_delay`] - /// - /// By default this is set to 5 minutes. - pub priority_group_set_offset: Duration, + pub max_query_interval: Duration, } impl Default for WorkerConfig { fn default() -> Self { Self { - publish_interval: Duration::from_secs(12 * 60 * 60), - query_interval: Duration::from_secs(10 * 60), - query_start_delay: Duration::from_secs(30), - priority_group_set_interval: Duration::from_secs(10 * 60), - priority_group_set_offset: Duration::from_secs(5 * 60), + // Kademlia's default time-to-live for Dht records is 36h, republishing records every + // 24h through libp2p-kad. Given that a node could restart at any point in time, one can + // not depend on the republishing process, thus publishing own external addresses should + // happen on an interval < 36h. + max_publish_interval: Duration::from_secs(1 * 60 * 60), + // External addresses of remote authorities can change at any given point in time. The + // interval on which to trigger new queries for the current and next authorities is a trade + // off between efficiency and performance. + // + // Querying 700 [`AuthorityId`]s takes ~8m on the Kusama DHT (16th Nov 2020) when + // comparing `authority_discovery_authority_addresses_requested_total` and + // `authority_discovery_dht_event_received`. + max_query_interval: Duration::from_secs(10 * 60), } } } diff --git a/client/authority-discovery/src/worker.rs b/client/authority-discovery/src/worker.rs index 42ae3a5213f..c8e7a9f7aee 100644 --- a/client/authority-discovery/src/worker.rs +++ b/client/authority-discovery/src/worker.rs @@ -14,17 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{error::{Error, Result}, ServicetoWorkerMsg}; +use crate::{error::{Error, Result}, interval::ExpIncInterval, ServicetoWorkerMsg}; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::marker::PhantomData; use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::time::Duration; use futures::channel::mpsc; use futures::{FutureExt, Stream, StreamExt, stream::Fuse}; -use futures_timer::Delay; use addr_cache::AddrCache; use async_trait::async_trait; @@ -54,8 +53,6 @@ mod schema { include!(concat!(env!("OUT_DIR"), "/authority_discovery.rs")); } #[cfg(test)] pub mod tests; -type Interval = Box + Unpin + Send + Sync>; - const LOG_TARGET: &'static str = "sub-authority-discovery"; /// Name of the Substrate peerset priority group for authorities discovered through the authority @@ -113,12 +110,12 @@ pub struct Worker { dht_event_rx: DhtEventStream, /// Interval to be proactive, publishing own addresses. - publish_interval: Interval, + publish_interval: ExpIncInterval, /// Interval at which to request addresses of authorities, refilling the pending lookups queue. - query_interval: Interval, + query_interval: ExpIncInterval, /// Interval on which to set the peerset priority group to a new random /// set of addresses. - priority_group_set_interval: Interval, + priority_group_set_interval: ExpIncInterval, /// Queue of throttled lookups pending to be passed to the network. pending_lookups: Vec, @@ -153,31 +150,26 @@ where prometheus_registry: Option, config: crate::WorkerConfig, ) -> Self { - // Kademlia's default time-to-live for Dht records is 36h, republishing - // records every 24h through libp2p-kad. - // Given that a node could restart at any point in time, one can not depend on the - // republishing process, thus publishing own external addresses should happen on an interval - // < 36h. - let publish_interval = interval_at( - Instant::now() + config.query_start_delay, - config.publish_interval, + // When a node starts up publishing and querying might fail due to various reasons, for + // example due to being not yet fully bootstrapped on the DHT. Thus one should retry rather + // sooner than later. On the other hand, a long running node is likely well connected and + // thus timely retries are not needed. For this reasoning use an exponentially increasing + // interval for `publish_interval`, `query_interval` and `priority_group_set_interval` + // instead of a constant interval. + let publish_interval = ExpIncInterval::new( + Duration::from_secs(2), + config.max_publish_interval, ); - - // External addresses of remote authorities can change at any given point in time. The - // interval on which to trigger new queries for the current authorities is a trade off - // between efficiency and performance. - let query_interval_start = Instant::now() + config.query_start_delay; - let query_interval_duration = config.query_interval; - let query_interval = interval_at(query_interval_start, query_interval_duration); - - // Querying 500 [`AuthorityId`]s takes ~1m on the Kusama DHT (10th of August 2020) when - // comparing `authority_discovery_authority_addresses_requested_total` and - // `authority_discovery_dht_event_received`. With that in mind set the peerset priority - // group on the same interval as the [`query_interval`] above, - // just delayed by 5 minutes by default. - let priority_group_set_interval = interval_at( - query_interval_start + config.priority_group_set_offset, - config.priority_group_set_interval, + let query_interval = ExpIncInterval::new( + Duration::from_secs(2), + config.max_query_interval, + ); + let priority_group_set_interval = ExpIncInterval::new( + Duration::from_secs(2), + // Trade-off between node connection churn and connectivity. Using half of + // [`crate::WorkerConfig::max_query_interval`] to update priority group once at the + // beginning and once in the middle of each query interval. + config.max_query_interval / 2, ); let addr_cache = AddrCache::new(); @@ -413,7 +405,7 @@ where } if log_enabled!(log::Level::Debug) { - let hashes = v.iter().map(|(hash, _value)| hash.clone()); + let hashes: Vec<_> = v.iter().map(|(hash, _value)| hash.clone()).collect(); debug!( target: LOG_TARGET, "Value for hash '{:?}' found on Dht.", hashes, @@ -449,6 +441,11 @@ where } }, DhtEvent::ValuePut(hash) => { + // Fast forward the exponentially increasing interval to the configured maximum. In + // case this was the first successful address publishing there is no need for a + // timely retry. + self.publish_interval.set_to_max(); + if let Some(metrics) = &self.metrics { metrics.dht_event_received.with_label_values(&["value_put"]).inc(); } @@ -661,16 +658,6 @@ fn hash_authority_id(id: &[u8]) -> libp2p::kad::record::Key { libp2p::kad::record::Key::new(&libp2p::multihash::Sha2_256::digest(id)) } -fn interval_at(start: Instant, duration: Duration) -> Interval { - let stream = futures::stream::unfold(start, move |next| { - let time_until_next = next.saturating_duration_since(Instant::now()); - - Delay::new(time_until_next).map(move |_| Some(((), next + duration))) - }); - - Box::new(stream) -} - /// Prometheus metrics for a [`Worker`]. #[derive(Clone)] pub(crate) struct Metrics { diff --git a/client/authority-discovery/src/worker/tests.rs b/client/authority-discovery/src/worker/tests.rs index 12adb8f2325..fee861dfeb0 100644 --- a/client/authority-discovery/src/worker/tests.rs +++ b/client/authority-discovery/src/worker/tests.rs @@ -37,66 +37,6 @@ use substrate_test_runtime_client::runtime::Block; use super::*; -#[test] -fn interval_at_with_start_now() { - let start = Instant::now(); - - let mut interval = interval_at( - std::time::Instant::now(), - std::time::Duration::from_secs(10), - ); - - futures::executor::block_on(async { - interval.next().await; - }); - - assert!( - Instant::now().saturating_duration_since(start) < Duration::from_secs(1), - "Expected low resolution instant interval to fire within less than a second.", - ); -} - -#[test] -fn interval_at_is_queuing_ticks() { - let start = Instant::now(); - - let interval = interval_at(start, std::time::Duration::from_millis(100)); - - // Let's wait for 200ms, thus 3 elements should be queued up (1st at 0ms, 2nd at 100ms, 3rd - // at 200ms). - std::thread::sleep(Duration::from_millis(200)); - - futures::executor::block_on(async { - interval.take(3).collect::>().await; - }); - - // Make sure we did not wait for more than 300 ms, which would imply that `at_interval` is - // not queuing ticks. - assert!( - Instant::now().saturating_duration_since(start) < Duration::from_millis(300), - "Expect interval to /queue/ events when not polled for a while.", - ); -} - -#[test] -fn interval_at_with_initial_delay() { - let start = Instant::now(); - - let mut interval = interval_at( - std::time::Instant::now() + Duration::from_millis(100), - std::time::Duration::from_secs(10), - ); - - futures::executor::block_on(async { - interval.next().await; - }); - - assert!( - Instant::now().saturating_duration_since(start) > Duration::from_millis(100), - "Expected interval with initial delay not to fire right away.", - ); -} - #[derive(Clone)] pub(crate) struct TestApi { pub(crate) authorities: Vec, diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 60d35dbdf1a..717aec01f75 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -693,7 +693,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { DiscoveryOut::ValueNotFound(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } Err(e) => { - warn!(target: "sub-libp2p", + debug!(target: "sub-libp2p", "Libp2p => Failed to get record: {:?}", e); DiscoveryOut::ValueNotFound(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } @@ -704,7 +704,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { let ev = match res { Ok(ok) => DiscoveryOut::ValuePut(ok.key, stats.duration().unwrap_or_else(Default::default)), Err(e) => { - warn!(target: "sub-libp2p", + debug!(target: "sub-libp2p", "Libp2p => Failed to put record: {:?}", e); DiscoveryOut::ValuePutFailed(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } @@ -716,7 +716,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { Ok(ok) => debug!(target: "sub-libp2p", "Libp2p => Record republished: {:?}", ok.key), - Err(e) => warn!(target: "sub-libp2p", + Err(e) => debug!(target: "sub-libp2p", "Libp2p => Republishing of record {:?} failed with: {:?}", e.key(), e) } -- GitLab From d021078200021b1fcae1aa8434282edd9e6a8f4b Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Tue, 24 Nov 2020 02:29:41 +0800 Subject: [PATCH 039/163] sc-network: update some dependencies (#7582) Signed-off-by: koushiro --- Cargo.lock | 48 ++++++------------- client/network/Cargo.toml | 8 ++-- .../src/protocol/generic_proto/handler.rs | 2 +- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70d60f0d9f3..2925ad64d3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -571,12 +571,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "bs58" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" - [[package]] name = "bs58" version = "0.4.0" @@ -2930,7 +2924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8186060d6bd415e4e928e6cb44c4fe7e7a7dd53437bd936ce7e5f421e45a51" dependencies = [ "asn1_der", - "bs58 0.4.0", + "bs58", "ed25519-dalek", "either", "fnv", @@ -2952,7 +2946,7 @@ dependencies = [ "sha2 0.9.2", "smallvec 1.5.0", "thiserror", - "unsigned-varint 0.5.1", + "unsigned-varint", "void", "zeroize", ] @@ -3029,7 +3023,7 @@ dependencies = [ "rand 0.7.3", "sha2 0.9.2", "smallvec 1.5.0", - "unsigned-varint 0.5.1", + "unsigned-varint", "wasm-timer", ] @@ -3071,7 +3065,7 @@ dependencies = [ "sha2 0.9.2", "smallvec 1.5.0", "uint", - "unsigned-varint 0.5.1", + "unsigned-varint", "void", "wasm-timer", ] @@ -3113,7 +3107,7 @@ dependencies = [ "parking_lot 0.11.1", "rand 0.7.3", "smallvec 1.5.0", - "unsigned-varint 0.5.1", + "unsigned-varint", ] [[package]] @@ -3166,7 +3160,7 @@ dependencies = [ "log", "prost", "prost-build", - "unsigned-varint 0.5.1", + "unsigned-varint", "void", ] @@ -3200,7 +3194,7 @@ dependencies = [ "minicbor", "rand 0.7.3", "smallvec 1.5.0", - "unsigned-varint 0.5.1", + "unsigned-varint", "wasm-timer", ] @@ -3665,7 +3659,7 @@ dependencies = [ "sha-1 0.9.2", "sha2 0.9.2", "sha3", - "unsigned-varint 0.5.1", + "unsigned-varint", ] [[package]] @@ -3685,7 +3679,7 @@ dependencies = [ "log", "pin-project 1.0.2", "smallvec 1.5.0", - "unsigned-varint 0.5.1", + "unsigned-varint", ] [[package]] @@ -5201,14 +5195,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43244a26dc1ddd3097216bb12eaa6cf8a07b060c72718d9ebd60fd297d6401df" dependencies = [ "arrayref", - "bs58 0.4.0", + "bs58", "byteorder", "data-encoding", "multihash", "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.5.1", + "unsigned-varint", "url 2.2.0", ] @@ -7091,7 +7085,7 @@ dependencies = [ "async-std", "async-trait", "bitflags", - "bs58 0.3.1", + "bs58", "bytes 0.5.6", "derive_more", "either", @@ -7110,7 +7104,7 @@ dependencies = [ "lru 0.6.1", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.10.2", + "parking_lot 0.11.1", "pin-project 0.4.27", "prost", "prost-build", @@ -7123,7 +7117,7 @@ dependencies = [ "serde_json", "slog", "slog_derive", - "smallvec 0.6.13", + "smallvec 1.5.0", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -7138,7 +7132,7 @@ dependencies = [ "substrate-test-runtime-client", "tempfile", "thiserror", - "unsigned-varint 0.4.0", + "unsigned-varint", "void", "wasm-timer", "zeroize", @@ -9815,18 +9809,6 @@ dependencies = [ "subtle 2.3.0", ] -[[package]] -name = "unsigned-varint" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "669d776983b692a906c881fcd0cfb34271a48e197e4d6cb8df32b05bfc3d3fa5" -dependencies = [ - "bytes 0.5.6", - "futures-io", - "futures-util", - "futures_codec", -] - [[package]] name = "unsigned-varint" version = "0.5.1" diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 80353183ec9..dac2cb22c4f 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -20,7 +20,7 @@ prost-build = "0.6.1" async-trait = "0.1" async-std = "1.6.5" bitflags = "1.2.0" -bs58 = "0.3.1" +bs58 = "0.4.0" bytes = "0.5.0" codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } derive_more = "0.99.2" @@ -38,7 +38,7 @@ linked_hash_set = "0.1.3" log = "0.4.8" lru = "0.6.1" nohash-hasher = "0.2.0" -parking_lot = "0.10.0" +parking_lot = "0.11.1" pin-project = "0.4.6" prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0", path = "../../utils/prometheus" } prost = "0.6.1" @@ -50,7 +50,7 @@ serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" -smallvec = "0.6.10" +smallvec = "1.5.0" sp-arithmetic = { version = "2.0.0", path = "../../primitives/arithmetic" } sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } sp-consensus = { version = "0.8.0", path = "../../primitives/consensus/common" } @@ -58,7 +58,7 @@ sp-core = { version = "2.0.0", path = "../../primitives/core" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0", path = "../../primitives/utils" } thiserror = "1" -unsigned-varint = { version = "0.4.0", features = ["futures", "futures-codec"] } +unsigned-varint = { version = "0.5.0", features = ["futures", "futures-codec"] } void = "1.0.2" wasm-timer = "0.2" zeroize = "1.0.0" diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index 0272261f67d..c8a76c1cc9a 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -715,7 +715,7 @@ impl ProtocolsHandler for NotifsHandler { }, NotifsHandlerIn::Close => { - for mut substream in self.legacy_substreams.drain() { + for mut substream in self.legacy_substreams.drain(..) { substream.shutdown(); self.legacy_shutdown.push(substream); } -- GitLab From 3558103e2e80259ab0e8c136ec23687647cb32f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 23 Nov 2020 19:43:54 +0100 Subject: [PATCH 040/163] Bump linregress and do some other cleanups (#7580) --- Cargo.lock | 76 +++++++++++++++++++---------------- Cargo.toml | 2 - frame/benchmarking/Cargo.toml | 3 +- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2925ad64d3c..42a26e50412 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,17 +109,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alga" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" -dependencies = [ - "approx", - "num-complex", - "num-traits", -] - [[package]] name = "ansi_term" version = "0.11.0" @@ -2032,6 +2021,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "generic-array" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -3345,11 +3343,10 @@ dependencies = [ [[package]] name = "linregress" -version = "0.1.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9290cf6f928576eeb9c096c6fad9d8d452a0a1a70a2bbffa6e36064eedc0aac9" +checksum = "0d0ad4b5cc8385a881c561fac3501353d63d2a2b7a357b5064d71815c9a92724" dependencies = [ - "failure", "nalgebra", "statrs", ] @@ -3684,18 +3681,19 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.18.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2" +checksum = "d6b6147c3d50b4f3cdabfe2ecc94a0191fd3d6ad58aefd9664cf396285883486" dependencies = [ - "alga", "approx", - "generic-array 0.12.3", + "generic-array 0.13.2", "matrixmultiply", "num-complex", "num-rational", "num-traits", - "rand 0.6.5", + "rand 0.7.3", + "rand_distr", + "simba", "typenum", ] @@ -5900,19 +5898,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -dependencies = [ - "cloudabi 0.0.3", - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "winapi 0.3.9", -] - [[package]] name = "rand" version = "0.6.5" @@ -5990,6 +5975,15 @@ dependencies = [ "getrandom 0.1.15", ] +[[package]] +name = "rand_distr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2" +dependencies = [ + "rand 0.7.3", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -7834,6 +7828,18 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +[[package]] +name = "simba" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb931b1367faadea6b1ab1c306a860ec17aaa5fa39f367d0c744e69d971a1fb2" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste 0.1.18", +] + [[package]] name = "slab" version = "0.4.2" @@ -8721,11 +8727,11 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "statrs" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10102ac8d55e35db2b3fafc26f81ba8647da2e15879ab686a67e6d19af2685e8" +checksum = "cce16f6de653e88beca7bd13780d08e09d4489dbca1f9210e041bc4852481382" dependencies = [ - "rand 0.5.6", + "rand 0.7.3", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 71bf56f9b0f..df66cab5414 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -218,8 +218,6 @@ crossbeam-queue = { opt-level = 3 } crypto-mac = { opt-level = 3 } curve25519-dalek = { opt-level = 3 } ed25519-dalek = { opt-level = 3 } -evm-core = { opt-level = 3 } -evm-runtime = { opt-level = 3 } flate2 = { opt-level = 3 } futures-channel = { opt-level = 3 } hashbrown = { opt-level = 3 } diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 924ffc8627a..acd29e46824 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -linregress = "0.1" +linregress = { version = "0.4.0", optional = true } paste = "0.1" codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } sp-api = { version = "2.0.0", path = "../../primitives/api", default-features = false } @@ -38,4 +38,5 @@ std = [ "sp-std/std", "frame-support/std", "frame-system/std", + "linregress", ] -- GitLab From 7e94f01af67c498605eb0206b7fca261f12a278c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 24 Nov 2020 10:18:36 +0100 Subject: [PATCH 041/163] Wasm-builder 3.0 (#7532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Build every wasm crate in its own project with wasm-builder Building all wasm crates in one workspace was a nice idea, however it just introduced problems: 1. We needed to prune old members, but this didn't worked for old git deps. 2. We locked the whole wasm workspace while building one crate. This could lead to infinitely locking the workspace on a crash. Now we just build every crate in its own project, this means we will build the dependencies multiple times. While building the dependencies multiple times, we still decrease the build time by around 30 seconds for Polkadot and Substrate because of the new parallelism ;) * Remove the requirement on wasm-builder-runner This removes the requirement on wasm-builder-runner by using the new `build_dep` feature of cargo. We use nightly anyway and that enables us to use this feature. This solves the problem of not mixing build/proc-macro deps with normal deps. By doing this we get rid off this complicated project structure and can depend directly on `wasm-builder`. This also removes all the code from wasm-builder-runner and mentions that it is deprecated. * Copy the `Cargo.lock` to the correct folder * Remove wasm-builder-runner * Update docs * Fix deterministic check Modified-by: Bastian Köcher * Try to make the ui test happy * Switch to `SKIP_WASM_BUILD` * Rename `SKIP_WASM_BINARY` to the correct name... * Update utils/wasm-builder/src/builder.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update utils/wasm-builder/src/builder.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- .gitlab-ci.yml | 12 +- Cargo.lock | 59 ++- Cargo.toml | 1 - bin/node-template/runtime/Cargo.toml | 2 +- bin/node-template/runtime/build.rs | 3 +- bin/node/runtime/Cargo.toml | 2 +- bin/node/runtime/build.rs | 3 +- bin/node/runtime/src/lib.rs | 4 +- client/executor/runtime-test/Cargo.toml | 2 +- client/executor/runtime-test/build.rs | 6 +- client/executor/runtime-test/src/lib.rs | 2 +- docs/README.adoc | 22 - .../test/tests/construct_runtime_ui.rs | 2 +- frame/support/test/tests/decl_module_ui.rs | 2 +- frame/support/test/tests/decl_storage_ui.rs | 2 +- .../support/test/tests/derive_no_bound_ui.rs | 2 +- frame/support/test/tests/reserved_keyword.rs | 2 +- primitives/api/test/tests/trybuild.rs | 2 +- .../test-wasm-deprecated/Cargo.toml | 2 +- .../test-wasm-deprecated/build.rs | 3 +- .../test-wasm-deprecated/src/lib.rs | 2 +- .../runtime-interface/test-wasm/Cargo.toml | 2 +- .../runtime-interface/test-wasm/build.rs | 3 +- .../runtime-interface/test-wasm/src/lib.rs | 2 +- primitives/runtime-interface/tests/ui.rs | 2 +- test-utils/runtime/Cargo.toml | 2 +- test-utils/runtime/build.rs | 3 +- test-utils/runtime/src/lib.rs | 2 +- utils/wasm-builder-runner/Cargo.toml | 15 - utils/wasm-builder-runner/README.md | 12 - utils/wasm-builder-runner/src/lib.rs | 498 ------------------ utils/wasm-builder/Cargo.toml | 6 +- utils/wasm-builder/README.md | 40 +- utils/wasm-builder/src/builder.rs | 245 +++++++++ utils/wasm-builder/src/lib.rs | 132 ++--- utils/wasm-builder/src/wasm_project.rs | 228 +++----- 36 files changed, 443 insertions(+), 886 deletions(-) delete mode 100644 utils/wasm-builder-runner/Cargo.toml delete mode 100644 utils/wasm-builder-runner/README.md delete mode 100644 utils/wasm-builder-runner/src/lib.rs create mode 100644 utils/wasm-builder/src/builder.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cbb56fcf726..b37d60a941d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -197,7 +197,7 @@ cargo-check-benches: <<: *docker-env <<: *test-refs script: - - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly check --benches --all + - SKIP_WASM_BUILD=1 time cargo +nightly check --benches --all - cargo run --release -p node-bench -- ::node::import::native::sr25519::transfer_keep_alive::paritydb::small - cargo run --release -p node-bench -- ::trie::read::small - sccache -s @@ -208,7 +208,7 @@ cargo-check-subkey: <<: *test-refs script: - cd ./bin/utils/subkey - - BUILD_DUMMY_WASM_BINARY=1 time cargo check --release + - SKIP_WASM_BUILD=1 time cargo check --release - sccache -s test-deterministic-wasm: @@ -222,7 +222,7 @@ test-deterministic-wasm: # build runtime - cargo build --verbose --release -p node-runtime # make checksum - - sha256sum target/release/wbuild/target/wasm32-unknown-unknown/release/node_runtime.wasm > checksum.sha256 + - sha256sum target/release/wbuild/node-runtime/target/wasm32-unknown-unknown/release/node_runtime.wasm > checksum.sha256 # clean up – FIXME: can we reuse some of the artifacts? - cargo clean # build again @@ -343,7 +343,7 @@ cargo-check-macos: <<: *docker-env <<: *test-refs script: - - BUILD_DUMMY_WASM_BINARY=1 time cargo check --release + - SKIP_WASM_BUILD=1 time cargo check --release - sccache -s tags: - osx @@ -451,7 +451,7 @@ build-linux-subkey: &build-subkey - mkdir -p ./artifacts/subkey script: - cd ./bin/utils/subkey - - BUILD_DUMMY_WASM_BINARY=1 time cargo build --release --verbose + - SKIP_WASM_BUILD=1 time cargo build --release --verbose - cd - - mv ./target/release/subkey ./artifacts/subkey/. - echo -n "Subkey version = " @@ -483,7 +483,7 @@ build-rust-doc: - ./crate-docs/ script: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/.maintain/rustdoc-header.html" + - SKIP_WASM_BUILD=1 RUSTDOCFLAGS="--html-in-header $(pwd)/.maintain/rustdoc-header.html" time cargo +nightly doc --no-deps --workspace --all-features --verbose - mv ./target/doc ./crate-docs - echo "" > ./crate-docs/index.html diff --git a/Cargo.lock b/Cargo.lock index 42a26e50412..57ab273804c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -636,13 +636,12 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" [[package]] name = "cargo_metadata" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8de60b887edf6d74370fc8eb177040da4847d971d6234c7b13a6da324ef0caf" +checksum = "d5a5f7b42f606b7f23674f6f4d877628350682bc40687d3fae65679a58d55345" dependencies = [ - "semver 0.9.0", + "semver 0.11.0", "serde", - "serde_derive", "serde_json", ] @@ -1783,16 +1782,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "fs_extra" version = "1.2.0" @@ -4043,7 +4032,7 @@ dependencies = [ "sp-transaction-pool", "sp-version", "static_assertions", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", ] [[package]] @@ -4114,7 +4103,7 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", ] [[package]] @@ -7321,7 +7310,7 @@ dependencies = [ "sp-sandbox", "sp-std", "sp-tasks", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", ] [[package]] @@ -7663,7 +7652,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", ] [[package]] @@ -7672,7 +7661,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.1", "serde", ] @@ -7682,6 +7680,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428" +dependencies = [ + "pest", +] + [[package]] name = "send_wrapper" version = "0.3.0" @@ -8496,7 +8503,7 @@ dependencies = [ "sp-io", "sp-runtime-interface", "sp-std", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", ] [[package]] @@ -8507,7 +8514,7 @@ dependencies = [ "sp-io", "sp-runtime-interface", "sp-std", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", ] [[package]] @@ -8993,7 +9000,7 @@ dependencies = [ "sp-trie", "sp-version", "substrate-test-runtime-client", - "substrate-wasm-builder-runner", + "substrate-wasm-builder", "trie-db", ] @@ -9063,24 +9070,18 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "2.0.1" +version = "3.0.0" dependencies = [ "ansi_term 0.12.1", "atty", "build-helper", "cargo_metadata", - "fs2", - "itertools 0.8.2", "tempfile", "toml", "walkdir", "wasm-gc-api", ] -[[package]] -name = "substrate-wasm-builder-runner" -version = "2.0.0" - [[package]] name = "subtle" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index df66cab5414..2e3cff821e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,6 @@ members = [ "client/transaction-pool", "client/transaction-pool/graph", "utils/prometheus", - "utils/wasm-builder-runner", "frame/assets", "frame/aura", "frame/atomic-swap", diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index ed5a114b813..f1b15070ddd 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -48,7 +48,7 @@ hex-literal = { version = "0.3.1", optional = true } template = { version = "2.0.0", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../../utils/wasm-builder" } [features] default = ["std"] diff --git a/bin/node-template/runtime/build.rs b/bin/node-template/runtime/build.rs index 9654139121f..9b53d2457df 100644 --- a/bin/node-template/runtime/build.rs +++ b/bin/node-template/runtime/build.rs @@ -1,9 +1,8 @@ -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates("2.0.1") .export_heap_base() .import_memory() .build() diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 2bad2db510b..eabc9f61c62 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -79,7 +79,7 @@ pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-featur pallet-vesting = { version = "2.0.0", default-features = false, path = "../../../frame/vesting" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../../utils/wasm-builder" } [dev-dependencies] sp-io = { version = "2.0.0", path = "../../../primitives/io" } diff --git a/bin/node/runtime/build.rs b/bin/node/runtime/build.rs index 4f111bc9930..8a0b4d7a0c1 100644 --- a/bin/node/runtime/build.rs +++ b/bin/node/runtime/build.rs @@ -15,12 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 3e08b2cf8a6..958d2fe19e0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -91,11 +91,11 @@ use sp_runtime::generic::Era; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] -/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect("Development wasm binary is not available. This means the client is \ - built with `BUILD_DUMMY_WASM_BINARY` flag and it is only usable for \ + built with `SKIP_WASM_BUILD` flag and it is only usable for \ production chains. Please rebuild with the flag disabled.") } diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index ba23e31febe..1a898b92ca9 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -22,7 +22,7 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../../primiti sp-tasks = { version = "2.0.0", default-features = false, path = "../../../primitives/tasks" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../../utils/wasm-builder" } [features] default = [ "std" ] diff --git a/client/executor/runtime-test/build.rs b/client/executor/runtime-test/build.rs index bc07db900c3..a83de21db7f 100644 --- a/client/executor/runtime-test/build.rs +++ b/client/executor/runtime-test/build.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { // regular build WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build(); @@ -28,10 +27,9 @@ fn main() { // and building with tracing activated WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .set_file_name("wasm_binary_with_tracing.rs") - .append_to_rust_flags("--cfg feature=\\\"with-tracing\\\"") + .append_to_rust_flags(r#"--cfg feature="with-tracing""#) .build(); } diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index 404530c1c3e..f4cef65b629 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -4,8 +4,8 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] -/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ supported with the flag disabled.") diff --git a/docs/README.adoc b/docs/README.adoc index 7f3d50faac7..71052420b1a 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -308,28 +308,6 @@ cargo run --release \-- \ Additional Substrate CLI usage options are available and may be shown by running `cargo run \-- --help`. -=== WASM binaries - -The WASM binaries are built during the normal `cargo build` process. To control the WASM binary building, -we support multiple environment variables: - -* `SKIP_WASM_BUILD` - Skips building any WASM binary. This is useful when only native should be recompiled. -* `BUILD_DUMMY_WASM_BINARY` - Builds dummy WASM binaries. These dummy binaries are empty and useful - for `cargo check` runs. -* `WASM_BUILD_TYPE` - Sets the build type for building WASM binaries. Supported values are `release` or `debug`. - By default the build type is equal to the build type used by the main build. -* `FORCE_WASM_BUILD` - Can be set to force a WASM build. On subsequent calls the value of the variable - needs to change. As WASM builder instructs `cargo` to watch for file changes - this environment variable should only be required in certain circumstances. -* `WASM_TARGET_DIRECTORY` - Will copy release build WASM binary to the given directory. The path needs - to be absolute. -* `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the wasm binary. -* `WASM_BUILD_NO_COLOR` - Disable color output of the wasm build. - -Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. -Where `PROJECT_NAME` needs to be replaced by the name of the cargo project, e.g. `node-runtime` will -be `NODE_RUNTIME`. - [[flaming-fir]] === Joining the Flaming Fir Testnet diff --git a/frame/support/test/tests/construct_runtime_ui.rs b/frame/support/test/tests/construct_runtime_ui.rs index e1624c76830..83a90c96dd6 100644 --- a/frame/support/test/tests/construct_runtime_ui.rs +++ b/frame/support/test/tests/construct_runtime_ui.rs @@ -21,7 +21,7 @@ use std::env; #[test] fn ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/construct_runtime_ui/*.rs"); diff --git a/frame/support/test/tests/decl_module_ui.rs b/frame/support/test/tests/decl_module_ui.rs index 7df64bc52f4..22237d904ae 100644 --- a/frame/support/test/tests/decl_module_ui.rs +++ b/frame/support/test/tests/decl_module_ui.rs @@ -19,7 +19,7 @@ #[test] fn decl_module_ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + std::env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/decl_module_ui/*.rs"); diff --git a/frame/support/test/tests/decl_storage_ui.rs b/frame/support/test/tests/decl_storage_ui.rs index 56529d62c28..4b082cb8172 100644 --- a/frame/support/test/tests/decl_storage_ui.rs +++ b/frame/support/test/tests/decl_storage_ui.rs @@ -19,7 +19,7 @@ #[test] fn decl_storage_ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + std::env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/decl_storage_ui/*.rs"); diff --git a/frame/support/test/tests/derive_no_bound_ui.rs b/frame/support/test/tests/derive_no_bound_ui.rs index da276018f7f..ba8fff1f3a5 100644 --- a/frame/support/test/tests/derive_no_bound_ui.rs +++ b/frame/support/test/tests/derive_no_bound_ui.rs @@ -19,7 +19,7 @@ #[test] fn derive_no_bound_ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + std::env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/derive_no_bound_ui/*.rs"); diff --git a/frame/support/test/tests/reserved_keyword.rs b/frame/support/test/tests/reserved_keyword.rs index 382b2e49874..8136d11824a 100644 --- a/frame/support/test/tests/reserved_keyword.rs +++ b/frame/support/test/tests/reserved_keyword.rs @@ -19,7 +19,7 @@ #[test] fn reserved_keyword() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + std::env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/reserved_keyword/*.rs"); diff --git a/primitives/api/test/tests/trybuild.rs b/primitives/api/test/tests/trybuild.rs index 2f7fd6d06bc..f23c7291e8e 100644 --- a/primitives/api/test/tests/trybuild.rs +++ b/primitives/api/test/tests/trybuild.rs @@ -21,7 +21,7 @@ use std::env; #[test] fn ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/*.rs"); diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index 59790eb172e..eba557de5db 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -19,7 +19,7 @@ sp-io = { version = "2.0.0", default-features = false, path = "../../io" } sp-core = { version = "2.0.0", default-features = false, path = "../../core" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../../utils/wasm-builder" } [features] default = [ "std" ] diff --git a/primitives/runtime-interface/test-wasm-deprecated/build.rs b/primitives/runtime-interface/test-wasm-deprecated/build.rs index 4f111bc9930..8a0b4d7a0c1 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/build.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/build.rs @@ -15,12 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs index 174cdb8cdf8..ae0697b2938 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs @@ -26,8 +26,8 @@ use sp_runtime_interface::runtime_interface; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] -/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ supported with the flag disabled.") diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index 39c8df976a5..3cf36f95145 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -19,7 +19,7 @@ sp-io = { version = "2.0.0", default-features = false, path = "../../io" } sp-core = { version = "2.0.0", default-features = false, path = "../../core" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../../utils/wasm-builder" } [features] default = [ "std" ] diff --git a/primitives/runtime-interface/test-wasm/build.rs b/primitives/runtime-interface/test-wasm/build.rs index 4f111bc9930..8a0b4d7a0c1 100644 --- a/primitives/runtime-interface/test-wasm/build.rs +++ b/primitives/runtime-interface/test-wasm/build.rs @@ -15,12 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 28895df2214..6cd37a6c1d1 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -30,8 +30,8 @@ use sp_core::{sr25519::Public, wasm_export_functions}; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] -/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ supported with the flag disabled.") diff --git a/primitives/runtime-interface/tests/ui.rs b/primitives/runtime-interface/tests/ui.rs index 2f7fd6d06bc..f23c7291e8e 100644 --- a/primitives/runtime-interface/tests/ui.rs +++ b/primitives/runtime-interface/tests/ui.rs @@ -21,7 +21,7 @@ use std::env; #[test] fn ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/ui/*.rs"); diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index cb6147adf25..cf1a4bcddd5 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -56,7 +56,7 @@ sc-executor = { version = "0.8.0", path = "../../client/executor" } substrate-test-runtime-client = { version = "2.0.0", path = "./client" } [build-dependencies] -wasm-builder-runner = { version = "2.0.0", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } +substrate-wasm-builder = { version = "3.0.0", path = "../../utils/wasm-builder" } [features] default = [ diff --git a/test-utils/runtime/build.rs b/test-utils/runtime/build.rs index 834551a7ba1..5c9af20528a 100644 --- a/test-utils/runtime/build.rs +++ b/test-utils/runtime/build.rs @@ -15,12 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use wasm_builder_runner::WasmBuilder; +use substrate_wasm_builder::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("2.0.1", "../../utils/wasm-builder") .export_heap_base() // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index e772a28ee33..20244677710 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -66,8 +66,8 @@ pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] -/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. pub fn wasm_binary_unwrap() -> &'static [u8] { WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ supported with the flag disabled.") diff --git a/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml deleted file mode 100644 index 2c54a5ec3a4..00000000000 --- a/utils/wasm-builder-runner/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "substrate-wasm-builder-runner" -version = "2.0.0" -authors = ["Parity Technologies "] -description = "Runner for substrate-wasm-builder" -edition = "2018" -readme = "README.md" -repository = "https://github.com/paritytech/substrate/" -license = "Apache-2.0" -homepage = "https://substrate.dev" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] diff --git a/utils/wasm-builder-runner/README.md b/utils/wasm-builder-runner/README.md deleted file mode 100644 index 1b9e2b08ca4..00000000000 --- a/utils/wasm-builder-runner/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## WASM builder runner - -Since cargo contains many bugs when it comes to correct dependency and feature -resolution, we need this little tool. See for -more information. - -It will create a project that will call `substrate-wasm-builder` to prevent any dependencies -from `substrate-wasm-builder` influencing the main project's dependencies. - -For more information see - -License: GPL-3.0 diff --git a/utils/wasm-builder-runner/src/lib.rs b/utils/wasm-builder-runner/src/lib.rs deleted file mode 100644 index 04e06495c69..00000000000 --- a/utils/wasm-builder-runner/src/lib.rs +++ /dev/null @@ -1,498 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 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. - -//! # WASM builder runner -//! -//! Since cargo contains many bugs when it comes to correct dependency and feature -//! resolution, we need this little tool. See for -//! more information. -//! -//! It will create a project that will call `substrate-wasm-builder` to prevent any dependencies -//! from `substrate-wasm-builder` influencing the main project's dependencies. -//! -//! For more information see - -use std::{ - env, process::{Command, self}, fs, path::{PathBuf, Path}, hash::{Hash, Hasher}, - collections::hash_map::DefaultHasher, -}; - -/// Environment variable that tells us to skip building the WASM binary. -const SKIP_BUILD_ENV: &str = "SKIP_WASM_BUILD"; - -/// Environment variable that tells us to create a dummy WASM binary. -/// -/// This is useful for `cargo check` to speed-up the compilation. -/// -/// # Caution -/// -/// Enabling this option will just provide `&[]` as WASM binary. -const DUMMY_WASM_BINARY_ENV: &str = "BUILD_DUMMY_WASM_BINARY"; - -/// Environment variable that makes sure the WASM build is triggered. -const FORCE_WASM_BUILD_ENV: &str = "FORCE_WASM_BUILD"; - -/// Replace all backslashes with slashes. -fn replace_back_slashes(path: T) -> String { - path.to_string().replace("\\", "/") -} - -/// Returns the manifest dir from the `CARGO_MANIFEST_DIR` env. -fn get_manifest_dir() -> PathBuf { - env::var("CARGO_MANIFEST_DIR") - .expect("`CARGO_MANIFEST_DIR` is always set for `build.rs` files; qed") - .into() -} - -/// First step of the [`WasmBuilder`] to select the project to build. -pub struct WasmBuilderSelectProject { - /// This parameter just exists to make it impossible to construct - /// this type outside of this crate. - _ignore: (), -} - -impl WasmBuilderSelectProject { - /// Use the current project as project for building the WASM binary. - /// - /// # Panics - /// - /// Panics if the `CARGO_MANIFEST_DIR` variable is not set. This variable - /// is always set by `Cargo` in `build.rs` files. - pub fn with_current_project(self) -> WasmBuilderSelectSource { - WasmBuilderSelectSource(get_manifest_dir().join("Cargo.toml")) - } - - /// Use the given `path` as project for building the WASM binary. - /// - /// Returns an error if the given `path` does not points to a `Cargo.toml`. - pub fn with_project( - self, - path: impl Into, - ) -> Result { - let path = path.into(); - - if path.ends_with("Cargo.toml") { - Ok(WasmBuilderSelectSource(path)) - } else { - Err("Project path must point to the `Cargo.toml` of the project") - } - } -} - -/// Second step of the [`WasmBuilder`] to set the source of the `wasm-builder`. -pub struct WasmBuilderSelectSource(PathBuf); - -impl WasmBuilderSelectSource { - /// Use the given `path` as source for `wasm-builder`. - /// - /// The `path` must be relative and point to the directory that contains the `Cargo.toml` for - /// `wasm-builder`. - pub fn with_wasm_builder_from_path(self, path: &'static str) -> WasmBuilder { - WasmBuilder { - source: WasmBuilderSource::Path(path), - rust_flags: Vec::new(), - file_name: None, - project_cargo_toml: self.0, - } - } - - /// Use the given `repo` and `rev` as source for `wasm-builder`. - pub fn with_wasm_builder_from_git(self, repo: &'static str, rev: &'static str) -> WasmBuilder { - WasmBuilder { - source: WasmBuilderSource::Git { repo, rev }, - rust_flags: Vec::new(), - file_name: None, - project_cargo_toml: self.0, - } - } - - /// Use the given `version` to fetch `wasm-builder` source from crates.io. - pub fn with_wasm_builder_from_crates(self, version: &'static str) -> WasmBuilder { - WasmBuilder { - source: WasmBuilderSource::Crates(version), - rust_flags: Vec::new(), - file_name: None, - project_cargo_toml: self.0, - } - } - - /// Use the given `version` to fetch `wasm-builder` source from crates.io or use - /// the given `path` as source. - /// - /// The `path` must be relative and point to the directory that contains the `Cargo.toml` for - /// `wasm-builder`. - pub fn with_wasm_builder_from_crates_or_path( - self, - version: &'static str, - path: &'static str, - ) -> WasmBuilder { - WasmBuilder { - source: WasmBuilderSource::CratesOrPath { version, path }, - rust_flags: Vec::new(), - file_name: None, - project_cargo_toml: self.0, - } - } - - /// Use the given `source` as source for `wasm-builder`. - pub fn with_wasm_builder_source(self, source: WasmBuilderSource) -> WasmBuilder { - WasmBuilder { - source, - rust_flags: Vec::new(), - file_name: None, - project_cargo_toml: self.0, - } - } -} - -/// The builder for building a wasm binary. -/// -/// The builder itself is seperated into multiple structs to make the setup type safe. -/// -/// Building a wasm binary: -/// -/// 1. Call [`WasmBuilder::new`] to create a new builder. -/// 2. Select the project to build using the methods of [`WasmBuilderSelectProject`]. -/// 3. Select the source of the `wasm-builder` crate using the methods of -/// [`WasmBuilderSelectSource`]. -/// 4. Set additional `RUST_FLAGS` or a different name for the file containing the WASM code -/// using methods of [`WasmBuilder`]. -/// 5. Build the WASM binary using [`Self::build`]. -pub struct WasmBuilder { - /// Where should we pull the `wasm-builder` crate from. - source: WasmBuilderSource, - /// Flags that should be appended to `RUST_FLAGS` env variable. - rust_flags: Vec, - /// The name of the file that is being generated in `OUT_DIR`. - /// - /// Defaults to `wasm_binary.rs`. - file_name: Option, - /// The path to the `Cargo.toml` of the project that should be build - /// for wasm. - project_cargo_toml: PathBuf, -} - -impl WasmBuilder { - /// Create a new instance of the builder. - pub fn new() -> WasmBuilderSelectProject { - WasmBuilderSelectProject { - _ignore: (), - } - } - - /// Enable exporting `__heap_base` as global variable in the WASM binary. - /// - /// This adds `-Clink-arg=--export=__heap_base` to `RUST_FLAGS`. - pub fn export_heap_base(mut self) -> Self { - self.rust_flags.push("-Clink-arg=--export=__heap_base".into()); - self - } - - /// Set the name of the file that will be generated in `OUT_DIR`. - /// - /// This file needs to be included to get access to the build WASM binary. - /// - /// If this function is not called, `file_name` defaults to `wasm_binary.rs` - pub fn set_file_name(mut self, file_name: impl Into) -> Self { - self.file_name = Some(file_name.into()); - self - } - - /// Instruct the linker to import the memory into the WASM binary. - /// - /// This adds `-C link-arg=--import-memory` to `RUST_FLAGS`. - pub fn import_memory(mut self) -> Self { - self.rust_flags.push("-C link-arg=--import-memory".into()); - self - } - - /// Append the given `flag` to `RUST_FLAGS`. - /// - /// `flag` is appended as is, so it needs to be a valid flag. - pub fn append_to_rust_flags(mut self, flag: impl Into) -> Self { - self.rust_flags.push(flag.into()); - self - } - - /// Build the WASM binary. - pub fn build(self) { - let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); - let file_path = out_dir.join(self.file_name.unwrap_or_else(|| "wasm_binary.rs".into())); - - if check_skip_build() { - // If we skip the build, we still want to make sure to be called when an env variable - // changes - generate_rerun_if_changed_instructions(); - - provide_dummy_wasm_binary(&file_path, true); - - return; - } - - // Hash the path to the project cargo toml. - let mut hasher = DefaultHasher::new(); - self.project_cargo_toml.hash(&mut hasher); - - let project_name = env::var("CARGO_PKG_NAME").expect("`CARGO_PKG_NAME` is set by cargo!"); - // Make sure the `wasm-builder-runner` path is unique by concatenating the name of the - // project that is compiling the WASM binary with the hash of the path to the project that - // should be compiled as WASM binary. - let project_folder = get_workspace_root() - .join(format!("{}{}", project_name, hasher.finish())); - - if check_provide_dummy_wasm_binary() { - provide_dummy_wasm_binary(&file_path, false); - } else { - create_project( - &project_folder, - &file_path, - self.source, - &self.project_cargo_toml, - &self.rust_flags.into_iter().map(|f| format!("{} ", f)).collect::(), - ); - run_project(&project_folder); - } - - // As last step we need to generate our `rerun-if-changed` stuff. If a build fails, we don't - // want to spam the output! - generate_rerun_if_changed_instructions(); - } -} - -/// The `wasm-builder` dependency source. -pub enum WasmBuilderSource { - /// The relative path to the source code from the current manifest dir. - Path(&'static str), - /// The git repository that contains the source code. - Git { - repo: &'static str, - rev: &'static str, - }, - /// Use the given version released on crates.io. - Crates(&'static str), - /// Use the given version released on crates.io or from the given path. - CratesOrPath { - version: &'static str, - path: &'static str, - } -} - -impl WasmBuilderSource { - /// Convert to a valid cargo source declaration. - /// - /// `absolute_path` - The manifest dir. - fn to_cargo_source(&self, manifest_dir: &Path) -> String { - match self { - WasmBuilderSource::Path(path) => { - replace_back_slashes(format!("path = \"{}\"", manifest_dir.join(path).display())) - } - WasmBuilderSource::Git { repo, rev } => { - format!("git = \"{}\", rev=\"{}\"", repo, rev) - } - WasmBuilderSource::Crates(version) => { - format!("version = \"{}\"", version) - } - WasmBuilderSource::CratesOrPath { version, path } => { - replace_back_slashes( - format!( - "path = \"{}\", version = \"{}\"", - manifest_dir.join(path).display(), - version - ) - ) - } - } - } -} - -/// Build the currently built project as WASM binary and extend `RUSTFLAGS` with the given rustflags. -/// -/// For more information, see [`build_current_project`]. -#[deprecated( - since = "1.0.5", - note = "Please switch to [`WasmBuilder`]", -)] -pub fn build_current_project_with_rustflags( - file_name: &str, - wasm_builder_source: WasmBuilderSource, - default_rust_flags: &str, -) { - WasmBuilder::new() - .with_current_project() - .with_wasm_builder_source(wasm_builder_source) - .append_to_rust_flags(default_rust_flags) - .set_file_name(file_name) - .build() -} - -/// Build the currently built project as WASM binary. -/// -/// The current project is determined using the `CARGO_MANIFEST_DIR` environment variable. -/// -/// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the -/// constant `WASM_BINARY` which contains the build wasm binary. -/// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. -#[deprecated( - since = "1.0.5", - note = "Please switch to [`WasmBuilder`]", -)] -pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { - #[allow(deprecated)] - build_current_project_with_rustflags(file_name, wasm_builder_source, ""); -} - -/// Returns the root path of the wasm-builder workspace. -/// -/// The wasm-builder workspace contains all wasm-builder's projects. -fn get_workspace_root() -> PathBuf { - let out_dir_env = env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!"); - let mut out_dir = PathBuf::from(&out_dir_env); - - loop { - match out_dir.parent() { - Some(parent) if out_dir.ends_with("build") => return parent.join("wbuild-runner"), - _ => if !out_dir.pop() { - break; - } - } - } - - panic!("Could not find target dir in: {}", out_dir_env) -} - -fn create_project( - project_folder: &Path, - file_path: &Path, - wasm_builder_source: WasmBuilderSource, - cargo_toml_path: &Path, - default_rustflags: &str, -) { - fs::create_dir_all(project_folder.join("src")) - .expect("WASM build runner dir create can not fail; qed"); - - write_file_if_changed( - project_folder.join("Cargo.toml"), - format!( - r#" - [package] - name = "wasm-build-runner-impl" - version = "1.0.0" - edition = "2018" - - [dependencies] - substrate-wasm-builder = {{ {wasm_builder_source} }} - - [workspace] - "#, - wasm_builder_source = wasm_builder_source.to_cargo_source(&get_manifest_dir()), - ), - ); - - write_file_if_changed( - project_folder.join("src/main.rs"), - format!( - r#" - //! This is automatically generated code by `substrate-wasm-builder`. - - use substrate_wasm_builder::build_project_with_default_rustflags; - - fn main() {{ - build_project_with_default_rustflags( - "{file_path}", - "{cargo_toml_path}", - "{default_rustflags}", - ) - }} - "#, - file_path = replace_back_slashes(file_path.display()), - cargo_toml_path = replace_back_slashes(cargo_toml_path.display()), - default_rustflags = default_rustflags, - ), - ); -} - -fn run_project(project_folder: &Path) { - let cargo = env::var("CARGO").expect("`CARGO` env variable is always set when executing `build.rs`."); - let mut cmd = Command::new(cargo); - cmd.arg("run").arg(format!("--manifest-path={}", project_folder.join("Cargo.toml").display())); - - if env::var("DEBUG") != Ok(String::from("true")) { - cmd.arg("--release"); - } - - // Make sure we always run the `wasm-builder` project for the `HOST` architecture. - let host_triple = env::var("HOST").expect("`HOST` is always set when executing `build.rs`."); - cmd.arg(&format!("--target={}", host_triple)); - - // Unset the `CARGO_TARGET_DIR` to prevent a cargo deadlock (cargo locks a target dir exclusive). - // The runner project is created in `CARGO_TARGET_DIR` and executing it will create a sub target - // directory inside of `CARGO_TARGET_DIR`. - cmd.env_remove("CARGO_TARGET_DIR"); - - if !cmd.status().map(|s| s.success()).unwrap_or(false) { - // Don't spam the output with backtraces when a build failed! - process::exit(1); - } -} - -/// Generate the name of the skip build environment variable for the current crate. -fn generate_crate_skip_build_env_name() -> String { - format!( - "SKIP_{}_WASM_BUILD", - env::var("CARGO_PKG_NAME").expect("Package name is set").to_uppercase().replace('-', "_"), - ) -} - -/// Checks if the build of the WASM binary should be skipped. -fn check_skip_build() -> bool { - env::var(SKIP_BUILD_ENV).is_ok() || env::var(generate_crate_skip_build_env_name()).is_ok() -} - -/// Check if we should provide a dummy WASM binary. -fn check_provide_dummy_wasm_binary() -> bool { - env::var(DUMMY_WASM_BINARY_ENV).is_ok() -} - -/// Provide the dummy WASM binary -/// -/// If `skip_build` is `true`, it will only generate the wasm binary if it doesn't exist. -fn provide_dummy_wasm_binary(file_path: &Path, skip_build: bool) { - if !skip_build || !file_path.exists() { - write_file_if_changed( - file_path.into(), - "pub const WASM_BINARY: Option<&[u8]> = None;\ - pub const WASM_BINARY_BLOATY: Option<&[u8]> = None;".into(), - ); - } -} - -/// Generate the `rerun-if-changed` instructions for cargo to make sure that the WASM binary is -/// rebuilt when needed. -fn generate_rerun_if_changed_instructions() { - // Make sure that the `build.rs` is called again if one of the following env variables changes. - println!("cargo:rerun-if-env-changed={}", SKIP_BUILD_ENV); - println!("cargo:rerun-if-env-changed={}", DUMMY_WASM_BINARY_ENV); - println!("cargo:rerun-if-env-changed={}", FORCE_WASM_BUILD_ENV); - println!("cargo:rerun-if-env-changed={}", generate_crate_skip_build_env_name()); -} - -/// Write to the given `file` if the `content` is different. -fn write_file_if_changed(file: PathBuf, content: String) { - if fs::read_to_string(&file).ok().as_ref() != Some(&content) { - fs::write(&file, content).unwrap_or_else(|_| panic!("Writing `{}` can not fail!", file.display())); - } -} diff --git a/utils/wasm-builder/Cargo.toml b/utils/wasm-builder/Cargo.toml index e9dd1a97b89..199e26b509e 100644 --- a/utils/wasm-builder/Cargo.toml +++ b/utils/wasm-builder/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder" -version = "2.0.1" +version = "3.0.0" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" @@ -14,12 +14,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] build-helper = "0.1.1" -cargo_metadata = "0.10.0" +cargo_metadata = "0.12.0" tempfile = "3.1.0" toml = "0.5.4" walkdir = "2.3.1" -fs2 = "0.4.3" wasm-gc-api = "0.1.11" atty = "0.2.13" -itertools = "0.8.2" ansi_term = "0.12.1" diff --git a/utils/wasm-builder/README.md b/utils/wasm-builder/README.md index 1e24d2cebab..3868faf1aca 100644 --- a/utils/wasm-builder/README.md +++ b/utils/wasm-builder/README.md @@ -8,20 +8,23 @@ The Wasm builder is a tool that integrates the process of building the WASM bina A project that should be compiled as a Wasm binary needs to: 1. Add a `build.rs` file. -2. Add `substrate-wasm-builder` as dependency into `build-dependencies`. +2. Add `wasm-builder` as dependency into `build-dependencies`. The `build.rs` file needs to contain the following code: ```rust -use wasm_builder_runner::{build_current_project, WasmBuilderSource}; +use substrate_wasm_builder::WasmBuilder; fn main() { - build_current_project( - // The name of the file being generated in out-dir. - "wasm_binary.rs", - // How to include wasm-builder, in this case from crates.io. - WasmBuilderSource::Crates("1.0.0"), - ); + WasmBuilder::new() + // Tell the builder to build the project (crate) this `build.rs` is part of. + .with_current_project() + // Make sure to export the `heap_base` global, this is required by Substrate + .export_heap_base() + // Build the Wasm file so that it imports the memory (need to be provided by at instantiation) + .import_memory() + // Build it. + .build() } ``` @@ -32,9 +35,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); ``` This will include the generated Wasm binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. -The former is a compact Wasm binary and the latter is not compacted. +The former is a compact Wasm binary and the latter is the Wasm binary as being generated by the compiler. +Both variables have `Option<&'static [u8]>` as type. -### Feature +### Features Wasm builder supports to enable cargo features while building the Wasm binary. By default it will enable all features in the wasm build that are enabled for the native build except the @@ -46,19 +50,19 @@ Wasm binary. If this feature is not present, it will not be enabled. By using environment variables, you can configure which Wasm binaries are built and how: -- `SKIP_WASM_BUILD` - Skips building any wasm binary. This is useful when only native should be recompiled. -- `BUILD_DUMMY_WASM_BINARY` - Builds dummy wasm binaries. These dummy binaries are empty and useful - for `cargo check` runs. -- `WASM_BUILD_TYPE` - Sets the build type for building wasm binaries. Supported values are `release` or `debug`. +- `SKIP_WASM_BUILD` - Skips building any Wasm binary. This is useful when only native should be recompiled. + If this is the first run and there doesn't exist a Wasm binary, this will set both + variables to `None`. +- `WASM_BUILD_TYPE` - Sets the build type for building Wasm binaries. Supported values are `release` or `debug`. By default the build type is equal to the build type used by the main build. -- `FORCE_WASM_BUILD` - Can be set to force a wasm build. On subsequent calls the value of the variable - needs to change. As wasm builder instructs `cargo` to watch for file changes +- `FORCE_WASM_BUILD` - Can be set to force a Wasm build. On subsequent calls the value of the variable + needs to change. As wasm-builder instructs `cargo` to watch for file changes this environment variable should only be required in certain circumstances. - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the wasm binary. - `WASM_BUILD_NO_COLOR` - Disable color output of the wasm build. -- `WASM_TARGET_DIRECTORY` - Will copy any build wasm binary to the given directory. The path needs +- `WASM_TARGET_DIRECTORY` - Will copy any build Wasm binary to the given directory. The path needs to be absolute. -- `WASM_BUILD_TOOLCHAIN` - The toolchain that should be used to build the wasm binaries. The +- `WASM_BUILD_TOOLCHAIN` - The toolchain that should be used to build the Wasm binaries. The format needs to be the same as used by cargo, e.g. `nightly-2020-02-20`. Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. diff --git a/utils/wasm-builder/src/builder.rs b/utils/wasm-builder/src/builder.rs new file mode 100644 index 00000000000..75e1d805720 --- /dev/null +++ b/utils/wasm-builder/src/builder.rs @@ -0,0 +1,245 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 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::{env, path::{PathBuf, Path}, process}; + +/// Returns the manifest dir from the `CARGO_MANIFEST_DIR` env. +fn get_manifest_dir() -> PathBuf { + env::var("CARGO_MANIFEST_DIR") + .expect("`CARGO_MANIFEST_DIR` is always set for `build.rs` files; qed") + .into() +} + +/// First step of the [`WasmBuilder`] to select the project to build. +pub struct WasmBuilderSelectProject { + /// This parameter just exists to make it impossible to construct + /// this type outside of this crate. + _ignore: (), +} + +impl WasmBuilderSelectProject { + /// Use the current project as project for building the WASM binary. + /// + /// # Panics + /// + /// Panics if the `CARGO_MANIFEST_DIR` variable is not set. This variable + /// is always set by `Cargo` in `build.rs` files. + pub fn with_current_project(self) -> WasmBuilder { + WasmBuilder { + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: get_manifest_dir().join("Cargo.toml"), + } + } + + /// Use the given `path` as project for building the WASM binary. + /// + /// Returns an error if the given `path` does not points to a `Cargo.toml`. + pub fn with_project( + self, + path: impl Into, + ) -> Result { + let path = path.into(); + + if path.ends_with("Cargo.toml") && path.exists() { + Ok(WasmBuilder { + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: path, + }) + } else { + Err("Project path must point to the `Cargo.toml` of the project") + } + } +} + +/// The builder for building a wasm binary. +/// +/// The builder itself is separated into multiple structs to make the setup type safe. +/// +/// Building a wasm binary: +/// +/// 1. Call [`WasmBuilder::new`] to create a new builder. +/// 2. Select the project to build using the methods of [`WasmBuilderSelectProject`]. +/// 3. Set additional `RUST_FLAGS` or a different name for the file containing the WASM code +/// using methods of [`WasmBuilder`]. +/// 4. Build the WASM binary using [`Self::build`]. +pub struct WasmBuilder { + /// Flags that should be appended to `RUST_FLAGS` env variable. + rust_flags: Vec, + /// The name of the file that is being generated in `OUT_DIR`. + /// + /// Defaults to `wasm_binary.rs`. + file_name: Option, + /// The path to the `Cargo.toml` of the project that should be built + /// for wasm. + project_cargo_toml: PathBuf, +} + +impl WasmBuilder { + /// Create a new instance of the builder. + pub fn new() -> WasmBuilderSelectProject { + WasmBuilderSelectProject { + _ignore: (), + } + } + + /// Enable exporting `__heap_base` as global variable in the WASM binary. + /// + /// This adds `-Clink-arg=--export=__heap_base` to `RUST_FLAGS`. + pub fn export_heap_base(mut self) -> Self { + self.rust_flags.push("-Clink-arg=--export=__heap_base".into()); + self + } + + /// Set the name of the file that will be generated in `OUT_DIR`. + /// + /// This file needs to be included to get access to the build WASM binary. + /// + /// If this function is not called, `file_name` defaults to `wasm_binary.rs` + pub fn set_file_name(mut self, file_name: impl Into) -> Self { + self.file_name = Some(file_name.into()); + self + } + + /// Instruct the linker to import the memory into the WASM binary. + /// + /// This adds `-C link-arg=--import-memory` to `RUST_FLAGS`. + pub fn import_memory(mut self) -> Self { + self.rust_flags.push("-C link-arg=--import-memory".into()); + self + } + + /// Append the given `flag` to `RUST_FLAGS`. + /// + /// `flag` is appended as is, so it needs to be a valid flag. + pub fn append_to_rust_flags(mut self, flag: impl Into) -> Self { + self.rust_flags.push(flag.into()); + self + } + + /// Build the WASM binary. + pub fn build(self) { + let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); + let file_path = out_dir.join(self.file_name.unwrap_or_else(|| "wasm_binary.rs".into())); + + if check_skip_build() { + // If we skip the build, we still want to make sure to be called when an env variable + // changes + generate_rerun_if_changed_instructions(); + + provide_dummy_wasm_binary_if_not_exist(&file_path); + + return; + } + + build_project( + file_path, + self.project_cargo_toml, + self.rust_flags.into_iter().map(|f| format!("{} ", f)).collect(), + ); + + // As last step we need to generate our `rerun-if-changed` stuff. If a build fails, we don't + // want to spam the output! + generate_rerun_if_changed_instructions(); + } +} + +/// Generate the name of the skip build environment variable for the current crate. +fn generate_crate_skip_build_env_name() -> String { + format!( + "SKIP_{}_WASM_BUILD", + env::var("CARGO_PKG_NAME").expect("Package name is set").to_uppercase().replace('-', "_"), + ) +} + +/// Checks if the build of the WASM binary should be skipped. +fn check_skip_build() -> bool { + env::var(crate::SKIP_BUILD_ENV).is_ok() || env::var(generate_crate_skip_build_env_name()).is_ok() +} + +/// Provide a dummy WASM binary if there doesn't exist one. +fn provide_dummy_wasm_binary_if_not_exist(file_path: &Path) { + if !file_path.exists() { + crate::write_file_if_changed( + file_path, + "pub const WASM_BINARY: Option<&[u8]> = None;\ + pub const WASM_BINARY_BLOATY: Option<&[u8]> = None;", + ); + } +} + +/// Generate the `rerun-if-changed` instructions for cargo to make sure that the WASM binary is +/// rebuilt when needed. +fn generate_rerun_if_changed_instructions() { + // Make sure that the `build.rs` is called again if one of the following env variables changes. + println!("cargo:rerun-if-env-changed={}", crate::SKIP_BUILD_ENV); + println!("cargo:rerun-if-env-changed={}", crate::FORCE_WASM_BUILD_ENV); + println!("cargo:rerun-if-env-changed={}", generate_crate_skip_build_env_name()); +} + +/// Build the currently built project as wasm binary. +/// +/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. +/// +/// `file_name` - The name + path of the file being generated. The file contains the +/// constant `WASM_BINARY`, which contains the built WASM binary. +/// `project_cargo_toml` - The path to the `Cargo.toml` of the project that should be built. +/// `default_rustflags` - Default `RUSTFLAGS` that will always be set for the build. +fn build_project( + file_name: PathBuf, + project_cargo_toml: PathBuf, + default_rustflags: String, +) { + let cargo_cmd = match crate::prerequisites::check() { + Ok(cmd) => cmd, + Err(err_msg) => { + eprintln!("{}", err_msg); + process::exit(1); + }, + }; + + let (wasm_binary, bloaty) = crate::wasm_project::create_and_compile( + &project_cargo_toml, + &default_rustflags, + cargo_cmd, + ); + + let (wasm_binary, wasm_binary_bloaty) = if let Some(wasm_binary) = wasm_binary { + ( + wasm_binary.wasm_binary_path_escaped(), + bloaty.wasm_binary_bloaty_path_escaped(), + ) + } else { + ( + bloaty.wasm_binary_bloaty_path_escaped(), + bloaty.wasm_binary_bloaty_path_escaped(), + ) + }; + + crate::write_file_if_changed( + file_name, + format!( + r#" + pub const WASM_BINARY: Option<&[u8]> = Some(include_bytes!("{wasm_binary}")); + pub const WASM_BINARY_BLOATY: Option<&[u8]> = Some(include_bytes!("{wasm_binary_bloaty}")); + "#, + wasm_binary = wasm_binary, + wasm_binary_bloaty = wasm_binary_bloaty, + ), + ); +} diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index aa63e9596e1..573afbfcb6d 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -25,20 +25,23 @@ //! A project that should be compiled as a Wasm binary needs to: //! //! 1. Add a `build.rs` file. -//! 2. Add `substrate-wasm-builder` as dependency into `build-dependencies`. +//! 2. Add `wasm-builder` as dependency into `build-dependencies`. //! //! The `build.rs` file needs to contain the following code: //! -//! ```ignore -//! use wasm_builder_runner::{build_current_project, WasmBuilderSource}; +//! ```no_run +//! use substrate_wasm_builder::WasmBuilder; //! //! fn main() { -//! build_current_project( -//! // The name of the file being generated in out-dir. -//! "wasm_binary.rs", -//! // How to include wasm-builder, in this case from crates.io. -//! WasmBuilderSource::Crates("1.0.0"), -//! ); +//! WasmBuilder::new() +//! // Tell the builder to build the project (crate) this `build.rs` is part of. +//! .with_current_project() +//! // Make sure to export the `heap_base` global, this is required by Substrate +//! .export_heap_base() +//! // Build the Wasm file so that it imports the memory (need to be provided by at instantiation) +//! .import_memory() +//! // Build it. +//! .build() //! } //! ``` //! @@ -49,7 +52,8 @@ //! ``` //! //! This will include the generated Wasm binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. -//! The former is a compact Wasm binary and the latter is not compacted. +//! The former is a compact Wasm binary and the latter is the Wasm binary as being generated by the compiler. +//! Both variables have `Option<&'static [u8]>` as type. //! //! ### Feature //! @@ -63,19 +67,19 @@ //! //! By using environment variables, you can configure which Wasm binaries are built and how: //! -//! - `SKIP_WASM_BUILD` - Skips building any wasm binary. This is useful when only native should be recompiled. -//! - `BUILD_DUMMY_WASM_BINARY` - Builds dummy wasm binaries. These dummy binaries are empty and useful -//! for `cargo check` runs. -//! - `WASM_BUILD_TYPE` - Sets the build type for building wasm binaries. Supported values are `release` or `debug`. +//! - `SKIP_WASM_BUILD` - Skips building any Wasm binary. This is useful when only native should be recompiled. +//! If this is the first run and there doesn't exist a Wasm binary, this will set both +//! variables to `None`. +//! - `WASM_BUILD_TYPE` - Sets the build type for building Wasm binaries. Supported values are `release` or `debug`. //! By default the build type is equal to the build type used by the main build. -//! - `FORCE_WASM_BUILD` - Can be set to force a wasm build. On subsequent calls the value of the variable -//! needs to change. As wasm builder instructs `cargo` to watch for file changes +//! - `FORCE_WASM_BUILD` - Can be set to force a Wasm build. On subsequent calls the value of the variable +//! needs to change. As wasm-builder instructs `cargo` to watch for file changes //! this environment variable should only be required in certain circumstances. //! - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the wasm binary. //! - `WASM_BUILD_NO_COLOR` - Disable color output of the wasm build. -//! - `WASM_TARGET_DIRECTORY` - Will copy any build wasm binary to the given directory. The path needs +//! - `WASM_TARGET_DIRECTORY` - Will copy any build Wasm binary to the given directory. The path needs //! to be absolute. -//! - `WASM_BUILD_TOOLCHAIN` - The toolchain that should be used to build the wasm binaries. The +//! - `WASM_BUILD_TOOLCHAIN` - The toolchain that should be used to build the Wasm binaries. The //! format needs to be the same as used by cargo, e.g. `nightly-2020-02-20`. //! //! Each project can be skipped individually by using the environment variable `SKIP_PROJECT_NAME_WASM_BUILD`. @@ -92,11 +96,14 @@ //! 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`. -use std::{env, fs, path::{PathBuf, Path}, process::{Command, self}, io::BufRead}; +use std::{env, fs, path::{PathBuf, Path}, process::Command, io::BufRead}; +mod builder; mod prerequisites; mod wasm_project; +pub use builder::{WasmBuilder, WasmBuilderSelectProject}; + /// Environment variable that tells us to skip building the wasm binary. const SKIP_BUILD_ENV: &str = "SKIP_WASM_BUILD"; @@ -120,87 +127,8 @@ const WASM_BUILD_NO_COLOR: &str = "WASM_BUILD_NO_COLOR"; /// Environment variable to set the toolchain used to compile the wasm binary. const WASM_BUILD_TOOLCHAIN: &str = "WASM_BUILD_TOOLCHAIN"; -/// Build the currently built project as wasm binary. -/// -/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. -/// -/// `file_name` - The name + path of the file being generated. The file contains the -/// constant `WASM_BINARY`, which contains the built WASM binary. -/// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. -pub fn build_project(file_name: &str, cargo_manifest: &str) { - build_project_with_default_rustflags(file_name, cargo_manifest, ""); -} - -/// Build the currently built project as wasm binary. -/// -/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable. -/// -/// `file_name` - The name + path of the file being generated. The file contains the -/// constant `WASM_BINARY`, which contains the built WASM binary. -/// `cargo_manifest` - The path to the `Cargo.toml` of the project that should be built. -/// `default_rustflags` - Default `RUSTFLAGS` that will always be set for the build. -pub fn build_project_with_default_rustflags( - file_name: &str, - cargo_manifest: &str, - default_rustflags: &str, -) { - if check_skip_build() { - return; - } - - let cargo_manifest = PathBuf::from(cargo_manifest); - - if !cargo_manifest.exists() { - panic!("'{}' does not exist!", cargo_manifest.display()); - } - - if !cargo_manifest.ends_with("Cargo.toml") { - panic!("'{}' no valid path to a `Cargo.toml`!", cargo_manifest.display()); - } - - let cargo_cmd = match prerequisites::check() { - Ok(cmd) => cmd, - Err(err_msg) => { - eprintln!("{}", err_msg); - process::exit(1); - }, - }; - - let (wasm_binary, bloaty) = wasm_project::create_and_compile( - &cargo_manifest, - default_rustflags, - cargo_cmd, - ); - - let (wasm_binary, wasm_binary_bloaty) = if let Some(wasm_binary) = wasm_binary { - ( - wasm_binary.wasm_binary_path_escaped(), - bloaty.wasm_binary_bloaty_path_escaped(), - ) - } else { - ( - bloaty.wasm_binary_bloaty_path_escaped(), - bloaty.wasm_binary_bloaty_path_escaped(), - ) - }; - - write_file_if_changed( - file_name, - format!( - r#" - pub const WASM_BINARY: Option<&[u8]> = Some(include_bytes!("{wasm_binary}")); - pub const WASM_BINARY_BLOATY: Option<&[u8]> = Some(include_bytes!("{wasm_binary_bloaty}")); - "#, - wasm_binary = wasm_binary, - wasm_binary_bloaty = wasm_binary_bloaty, - ), - ); -} - -/// Checks if the build of the WASM binary should be skipped. -fn check_skip_build() -> bool { - env::var(SKIP_BUILD_ENV).is_ok() -} +/// Environment variable that makes sure the WASM build is triggered. +const FORCE_WASM_BUILD_ENV: &str = "FORCE_WASM_BUILD"; /// Write to the given `file` if the `content` is different. fn write_file_if_changed(file: impl AsRef, content: impl AsRef) { @@ -217,7 +145,9 @@ fn copy_file_if_changed(src: PathBuf, dst: PathBuf) { if src_file != dst_file { fs::copy(&src, &dst) - .unwrap_or_else(|_| panic!("Copying `{}` to `{}` can not fail; qed", src.display(), dst.display())); + .unwrap_or_else( + |_| panic!("Copying `{}` to `{}` can not fail; qed", src.display(), dst.display()) + ); } } diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index c27af71988b..4c4c80e5a86 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -30,10 +30,6 @@ use cargo_metadata::{MetadataCommand, Metadata}; use walkdir::WalkDir; -use fs2::FileExt; - -use itertools::Itertools; - /// Colorize an info message. /// /// Returns the colorized message. @@ -70,31 +66,6 @@ impl WasmBinary { } } -/// A lock for the WASM workspace. -struct WorkspaceLock(fs::File); - -impl WorkspaceLock { - /// Create a new lock - fn new(wasm_workspace_root: &Path) -> Self { - let lock = fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .open(wasm_workspace_root.join("wasm_workspace.lock")) - .expect("Opening the lock file does not fail"); - - lock.lock_exclusive().expect("Locking `wasm_workspace.lock` failed"); - - WorkspaceLock(lock) - } -} - -impl Drop for WorkspaceLock { - fn drop(&mut self) { - let _ = self.0.unlock(); - } -} - fn crate_metadata(cargo_manifest: &Path) -> Metadata { let mut cargo_lock = cargo_manifest.to_path_buf(); cargo_lock.set_file_name("Cargo.lock"); @@ -120,35 +91,36 @@ fn crate_metadata(cargo_manifest: &Path) -> Metadata { /// Creates the WASM project, compiles the WASM binary and compacts the WASM binary. /// /// # Returns +/// /// The path to the compact WASM binary and the bloaty WASM binary. pub(crate) fn create_and_compile( - cargo_manifest: &Path, + project_cargo_toml: &Path, default_rustflags: &str, cargo_cmd: CargoCommandVersioned, ) -> (Option, WasmBinaryBloaty) { let wasm_workspace_root = get_wasm_workspace_root(); let wasm_workspace = wasm_workspace_root.join("wbuild"); - // Lock the workspace exclusively for us - let _lock = WorkspaceLock::new(&wasm_workspace_root); + let crate_metadata = crate_metadata(project_cargo_toml); - let crate_metadata = crate_metadata(cargo_manifest); - - let project = create_project(cargo_manifest, &wasm_workspace, &crate_metadata); - create_wasm_workspace_project(&wasm_workspace, &crate_metadata.workspace_root); + let project = create_project( + project_cargo_toml, + &wasm_workspace, + &crate_metadata, + &crate_metadata.workspace_root, + ); build_project(&project, default_rustflags, cargo_cmd); let (wasm_binary, bloaty) = compact_wasm_file( &project, - cargo_manifest, - &wasm_workspace, + project_cargo_toml, ); wasm_binary.as_ref().map(|wasm_binary| - copy_wasm_to_target_directory(cargo_manifest, wasm_binary) + copy_wasm_to_target_directory(project_cargo_toml, wasm_binary) ); - generate_rerun_if_changed_instructions(cargo_manifest, &project, &wasm_workspace); + generate_rerun_if_changed_instructions(project_cargo_toml, &project, &wasm_workspace); (wasm_binary, bloaty) } @@ -221,69 +193,14 @@ fn get_wasm_workspace_root() -> PathBuf { panic!("Could not find target dir in: {}", build_helper::out_dir().display()) } -/// Find all workspace members. -/// -/// Each folder in `wasm_workspace` is seen as a member of the workspace. Exceptions are -/// folders starting with "." and the "target" folder. -/// -/// Every workspace member that is not valid anymore is deleted (the folder of it). A -/// member is not valid anymore when the `wasm-project` dependency points to an non-existing -/// folder or the package name is not valid. -fn find_and_clear_workspace_members(wasm_workspace: &Path) -> Vec { - let mut members = WalkDir::new(wasm_workspace) - .min_depth(1) - .max_depth(1) - .into_iter() - .filter_map(|p| p.ok()) - .map(|d| d.into_path()) - .filter(|p| p.is_dir()) - .filter_map(|p| p.file_name().map(|f| f.to_owned()).and_then(|s| s.into_string().ok())) - .filter(|f| !f.starts_with('.') && f != "target") - .collect::>(); - - let mut i = 0; - while i != members.len() { - let path = wasm_workspace.join(&members[i]).join("Cargo.toml"); - - // Extract the `wasm-project` dependency. - // If the path can be extracted and is valid and the package name matches, - // the member is valid. - if let Some(mut wasm_project) = fs::read_to_string(path) - .ok() - .and_then(|s| toml::from_str::(&s).ok()) - .and_then(|mut t| t.remove("dependencies")) - .and_then(|p| p.try_into::
().ok()) - .and_then(|mut t| t.remove("wasm_project")) - .and_then(|p| p.try_into::
().ok()) - { - if let Some(path) = wasm_project.remove("path") - .and_then(|p| p.try_into::().ok()) - { - if let Some(name) = wasm_project.remove("package") - .and_then(|p| p.try_into::().ok()) - { - let path = PathBuf::from(path); - if path.exists() { - if name == get_crate_name(&path.join("Cargo.toml")) { - i += 1; - continue - } - } - } - } - } - - fs::remove_dir_all(wasm_workspace.join(&members[i])) - .expect("Removing invalid workspace member can not fail; qed"); - members.remove(i); - } - - members -} - -fn create_wasm_workspace_project(wasm_workspace: &Path, workspace_root_path: &Path) { - let members = find_and_clear_workspace_members(wasm_workspace); - +fn create_project_cargo_toml( + wasm_workspace: &Path, + workspace_root_path: &Path, + crate_name: &str, + crate_path: &Path, + wasm_binary: &str, + enabled_features: &[String], +) { let mut workspace_toml: Table = toml::from_str( &fs::read_to_string( workspace_root_path.join("Cargo.toml"), @@ -306,12 +223,6 @@ fn create_wasm_workspace_project(wasm_workspace: &Path, workspace_root_path: &Pa wasm_workspace_toml.insert("profile".into(), profile.into()); - // Add `workspace` with members - let mut workspace = Table::new(); - workspace.insert("members".into(), members.into()); - - wasm_workspace_toml.insert("workspace".into(), workspace.into()); - // Add patch section from the project root `Cargo.toml` if let Some(mut patch) = workspace_toml.remove("patch").and_then(|p| p.try_into::
().ok()) { // Iterate over all patches and make the patch path absolute from the workspace root path. @@ -335,6 +246,33 @@ fn create_wasm_workspace_project(wasm_workspace: &Path, workspace_root_path: &Pa wasm_workspace_toml.insert("patch".into(), patch.into()); } + let mut package = Table::new(); + package.insert("name".into(), format!("{}-wasm", crate_name).into()); + package.insert("version".into(), "1.0.0".into()); + package.insert("edition".into(), "2018".into()); + + wasm_workspace_toml.insert("package".into(), package.into()); + + let mut lib = Table::new(); + lib.insert("name".into(), wasm_binary.into()); + lib.insert("crate-type".into(), vec!["cdylib".to_string()].into()); + + wasm_workspace_toml.insert("lib".into(), lib.into()); + + let mut dependencies = Table::new(); + + let mut wasm_project = Table::new(); + wasm_project.insert("package".into(), crate_name.into()); + wasm_project.insert("path".into(), crate_path.display().to_string().into()); + wasm_project.insert("default-features".into(), false.into()); + wasm_project.insert("features".into(), enabled_features.to_vec().into()); + + dependencies.insert("wasm-project".into(), wasm_project.into()); + + wasm_workspace_toml.insert("dependencies".into(), dependencies.into()); + + wasm_workspace_toml.insert("workspace".into(), Table::new().into()); + write_file_if_changed( wasm_workspace.join("Cargo.toml"), toml::to_string_pretty(&wasm_workspace_toml).expect("Wasm workspace toml is valid; qed"), @@ -394,56 +332,48 @@ fn has_runtime_wasm_feature_declared( /// Create the project used to build the wasm binary. /// /// # Returns -/// The path to the created project. -fn create_project(cargo_manifest: &Path, wasm_workspace: &Path, crate_metadata: &Metadata) -> PathBuf { - let crate_name = get_crate_name(cargo_manifest); - let crate_path = cargo_manifest.parent().expect("Parent path exists; qed"); - let wasm_binary = get_wasm_binary_name(cargo_manifest); - let project_folder = wasm_workspace.join(&crate_name); - - fs::create_dir_all(project_folder.join("src")) +/// +/// The path to the created wasm project. +fn create_project( + project_cargo_toml: &Path, + wasm_workspace: &Path, + crate_metadata: &Metadata, + workspace_root_path: &Path, +) -> PathBuf { + let crate_name = get_crate_name(project_cargo_toml); + let crate_path = project_cargo_toml.parent().expect("Parent path exists; qed"); + let wasm_binary = get_wasm_binary_name(project_cargo_toml); + let wasm_project_folder = wasm_workspace.join(&crate_name); + + fs::create_dir_all(wasm_project_folder.join("src")) .expect("Wasm project dir create can not fail; qed"); - let mut enabled_features = project_enabled_features(&cargo_manifest, &crate_metadata); + let mut enabled_features = project_enabled_features(&project_cargo_toml, &crate_metadata); - if has_runtime_wasm_feature_declared(cargo_manifest, crate_metadata) { + if has_runtime_wasm_feature_declared(project_cargo_toml, crate_metadata) { enabled_features.push("runtime-wasm".into()); } - write_file_if_changed( - project_folder.join("Cargo.toml"), - format!( - r#" - [package] - name = "{crate_name}-wasm" - version = "1.0.0" - edition = "2018" - - [lib] - name = "{wasm_binary}" - crate-type = ["cdylib"] - - [dependencies] - wasm_project = {{ package = "{crate_name}", path = "{crate_path}", default-features = false, features = [ {features} ] }} - "#, - crate_name = crate_name, - crate_path = crate_path.display(), - wasm_binary = wasm_binary, - features = enabled_features.into_iter().map(|f| format!("\"{}\"", f)).join(","), - ) + create_project_cargo_toml( + &wasm_project_folder, + workspace_root_path, + &crate_name, + &crate_path, + &wasm_binary, + &enabled_features, ); write_file_if_changed( - project_folder.join("src/lib.rs"), + wasm_project_folder.join("src/lib.rs"), "#![no_std] pub use wasm_project::*;", ); - if let Some(crate_lock_file) = find_cargo_lock(cargo_manifest) { + if let Some(crate_lock_file) = find_cargo_lock(project_cargo_toml) { // Use the `Cargo.lock` of the main project. - crate::copy_file_if_changed(crate_lock_file, wasm_workspace.join("Cargo.lock")); + crate::copy_file_if_changed(crate_lock_file, wasm_project_folder.join("Cargo.lock")); } - project_folder + wasm_project_folder } /// Returns if the project should be built as a release. @@ -474,9 +404,13 @@ fn build_project(project: &Path, default_rustflags: &str, cargo_cmd: CargoComman env::var(crate::WASM_BUILD_RUSTFLAGS_ENV).unwrap_or_default(), ); - build_cmd.args(&["rustc", "--target=wasm32-unknown-unknown"]) + build_cmd.args(&["-Zfeatures=build_dep", "rustc", "--target=wasm32-unknown-unknown"]) .arg(format!("--manifest-path={}", manifest_path.display())) .env("RUSTFLAGS", rustflags) + // Unset the `CARGO_TARGET_DIR` to prevent a cargo deadlock (cargo locks a target dir exclusive). + // The runner project is created in `CARGO_TARGET_DIR` and executing it will create a sub target + // directory inside of `CARGO_TARGET_DIR`. + .env_remove("CARGO_TARGET_DIR") // We don't want to call ourselves recursively .env(crate::SKIP_BUILD_ENV, ""); @@ -503,14 +437,14 @@ fn build_project(project: &Path, default_rustflags: &str, cargo_cmd: CargoComman fn compact_wasm_file( project: &Path, cargo_manifest: &Path, - wasm_workspace: &Path, ) -> (Option, WasmBinaryBloaty) { let is_release_build = is_release_build(); let target = if is_release_build { "release" } else { "debug" }; let wasm_binary = get_wasm_binary_name(cargo_manifest); - let wasm_file = wasm_workspace.join("target/wasm32-unknown-unknown") + let wasm_file = project.join("target/wasm32-unknown-unknown") .join(target) .join(format!("{}.wasm", wasm_binary)); + let wasm_compact_file = if is_release_build { let wasm_compact_file = project.join(format!("{}.compact.wasm", wasm_binary)); wasm_gc::garbage_collect_file(&wasm_file, &wasm_compact_file) -- GitLab From 31733d5075bdba62df00975df0463a56fadbcaa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:44:01 +0000 Subject: [PATCH 042/163] Bump tracing from 0.1.21 to 0.1.22 (#7589) Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.21 to 0.1.22. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.21...tracing-0.1.22) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 24 ++++++++++++-------- bin/node/cli/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/executor/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/tracing/Cargo.toml | 2 +- primitives/io/Cargo.toml | 2 +- primitives/runtime-interface/test/Cargo.toml | 2 +- primitives/tracing/Cargo.toml | 2 +- 9 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57ab273804c..710e3519d95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,7 +301,7 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite", + "pin-project-lite 0.1.11", "pin-utils", "slab", "wasm-bindgen-futures", @@ -1902,7 +1902,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite", + "pin-project-lite 0.1.11", "waker-fn", ] @@ -5554,6 +5554,12 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" +[[package]] +name = "pin-project-lite" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" + [[package]] name = "pin-utils" version = "0.1.0" @@ -5846,7 +5852,7 @@ checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" dependencies = [ "futures-core", "futures-sink", - "pin-project-lite", + "pin-project-lite 0.1.11", ] [[package]] @@ -9315,7 +9321,7 @@ dependencies = [ "mio", "mio-uds", "num_cpus", - "pin-project-lite", + "pin-project-lite 0.1.11", "signal-hook-registry", "slab", "tokio-macros", @@ -9546,7 +9552,7 @@ dependencies = [ "futures-core", "futures-sink", "log", - "pin-project-lite", + "pin-project-lite 0.1.11", "tokio 0.2.23", ] @@ -9567,13 +9573,13 @@ checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "tracing" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27" +checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "log", - "pin-project-lite", + "pin-project-lite 0.2.0", "tracing-attributes", "tracing-core", ] diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 604f4132ee1..6574ccb733b 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ hex-literal = "0.3.1" log = "0.4.8" rand = "0.7.2" structopt = { version = "0.3.8", optional = true } -tracing = "0.1.19" +tracing = "0.1.22" parking_lot = "0.10.0" # primitives diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index b0662c5eddf..900dddf8701 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -45,7 +45,7 @@ structopt = "0.3.8" sc-tracing = { version = "2.0.0", path = "../tracing" } chrono = "0.4.10" serde = "1.0.111" -tracing = "0.1.10" +tracing = "0.1.22" tracing-log = "0.1.1" tracing-subscriber = "0.2.10" sc-cli-proc-macro = { version = "2.0.0", path = "./proc-macro" } diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index b88e8926be1..803a49d1dea 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -48,7 +48,7 @@ test-case = "0.3.3" sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" } sc-tracing = { version = "2.0.0", path = "../tracing" } -tracing = "0.1.19" +tracing = "0.1.22" tracing-subscriber = "0.2.10" [features] diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index b85ebde3c1d..3d0b00820fe 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -76,7 +76,7 @@ sc-offchain = { version = "2.0.0", path = "../offchain" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} sc-tracing = { version = "2.0.0", path = "../tracing" } sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" } -tracing = "0.1.19" +tracing = "0.1.22" tracing-futures = { version = "0.2.4" } parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 35db326c949..4964adafe64 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -20,7 +20,7 @@ rustc-hash = "1.1.0" serde = "1.0.101" serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } -tracing = "0.1.21" +tracing = "0.1.22" tracing-core = "0.1.17" tracing-subscriber = "0.2.13" sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index e8483b2ef68..e470461d60b 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -30,7 +30,7 @@ sp-tracing = { version = "2.0.0", default-features = false, path = "../tracing" log = { version = "0.4.8", optional = true } futures = { version = "0.3.1", features = ["thread-pool"], optional = true } parking_lot = { version = "0.10.0", optional = true } -tracing = { version = "0.1.19", default-features = false } +tracing = { version = "0.1.22", default-features = false } tracing-core = { version = "0.1.17", default-features = false} [features] diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index d802f9cb6b3..d6da3db4b69 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -20,5 +20,5 @@ sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machin sp-runtime = { version = "2.0.0", path = "../../runtime" } sp-core = { version = "2.0.0", path = "../../core" } sp-io = { version = "2.0.0", path = "../../io" } -tracing = "0.1.19" +tracing = "0.1.22" tracing-core = "0.1.17" diff --git a/primitives/tracing/Cargo.toml b/primitives/tracing/Cargo.toml index 1000952b39f..ba370f46b9b 100644 --- a/primitives/tracing/Cargo.toml +++ b/primitives/tracing/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] [dependencies] sp-std = { version = "2.0.0", path = "../std", default-features = false} codec = { version = "1.3.1", package = "parity-scale-codec", default-features = false, features = ["derive"]} -tracing = { version = "0.1.21", default-features = false } +tracing = { version = "0.1.22", default-features = false } tracing-core = { version = "0.1.17", default-features = false } log = { version = "0.4.8", optional = true } tracing-subscriber = { version = "0.2.10", optional = true, features = ["tracing-log"] } -- GitLab From 9a29852e4e4005a3050c4104a25ffe734ace3bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 24 Nov 2020 11:42:20 +0100 Subject: [PATCH 043/163] contracts: Add `salt` argument to contract instantiation (#7482) * pallet-contracts: Fix seal_restore_to to output proper module errors Those errors where part of the decl_error for some time but where never actually returned. This allows proper debugging of failed restorations. Previously, any error did return the misleading `ContractTrapped`. * Bind UncheckedFrom + AsRef<[u8]> everywhere This allows us to make assumptions about the AccoutId that are necessary for testing and in order to benchmark the module properly. This also groups free standing functions into inherent functions in order to minimize the places where the new bounds need to be specified. * Rework contract address determination * Do not allow override by runtime author * Instantiate gained a new parameter "salt" This change is done now in expecation of the upcoming code rent which needs to change the instantiation dispatchable and host function anyways. The situation in where we have only something that is like CREATE2 makes it impossible for UIs to help the user to create an arbitrary amount of instantiations from the same code. With this change we have the same functionality as ethereum with a CREATE and CREATE2 instantation semantic. * Remove TrieIdGenerator The new trait bounds allows us to remove this workaround from the configuration trait. * Remove default parameters for config trait It should be solely the responsiblity to determine proper values for these parameter. As a matter of fact most runtime weren't using these values anyways. * Fix tests for new account id type Because of the new bounds on the trait tests can't get away by using u64 as accound id. Replacing the 8 byte value by a 32 byte value creates out quite a bit of code churn. * Fix benchmarks The benchmarks need adaption to the new instantiate semantics. * Fix compile errors caused by adding new trait bounds * Fix compile errors caused by renaming storage and rent functions * Adapt host functions and dispatchables to the new salt * Add tests for instantiate host functions (was not possible before) * Add benchmark results * Adapt to the new WeightInfo The new benchmarks add a new parameter for salt "s" to the instantiate weights that needs to be applied. * Fix deploying_wasm_contract_should_work integration test This test is adapted to use the new instantiate signature. * Break overlong line * Break more long lines Co-authored-by: Parity Benchmarking Bot --- bin/node/executor/tests/basic.rs | 8 +- bin/node/runtime/src/lib.rs | 14 +- frame/contracts/fixtures/call_return_code.wat | 36 +- frame/contracts/fixtures/caller_contract.wat | 21 +- .../fixtures/destroy_and_transfer.wat | 42 +- frame/contracts/fixtures/drain.wat | 2 +- .../fixtures/instantiate_return_code.wat | 38 +- frame/contracts/fixtures/restoration.wat | 23 +- frame/contracts/fixtures/self_destruct.wat | 39 +- .../fixtures/self_destructing_constructor.wat | 2 +- frame/contracts/fixtures/set_rent.wat | 28 +- .../fixtures/transfer_return_code.wat | 21 +- frame/contracts/src/benchmarking/code.rs | 25 +- frame/contracts/src/benchmarking/mod.rs | 63 +- frame/contracts/src/benchmarking/sandbox.rs | 13 +- frame/contracts/src/exec.rs | 111 +- frame/contracts/src/lib.rs | 195 ++-- frame/contracts/src/rent.rs | 749 +++++++------- frame/contracts/src/schedule.rs | 8 +- frame/contracts/src/storage.rs | 342 ++++--- frame/contracts/src/tests.rs | 505 +++++---- frame/contracts/src/wasm/code_cache.rs | 7 +- frame/contracts/src/wasm/env_def/macros.rs | 14 +- frame/contracts/src/wasm/mod.rs | 194 ++-- frame/contracts/src/wasm/runtime.rs | 850 ++++++++------- frame/contracts/src/weights.rs | 965 +++++++----------- 26 files changed, 2170 insertions(+), 2145 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index a48efaea2d6..236e0a823ac 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -27,7 +27,6 @@ use sp_runtime::{ traits::Hash as HashT, transaction_validity::InvalidTransaction, }; -use pallet_contracts::ContractAddressFor; use frame_system::{self, EventRecord, Phase}; use node_runtime::{ @@ -583,10 +582,10 @@ fn deploying_wasm_contract_should_work() { let transfer_code = wat::parse_str(CODE_TRANSFER).unwrap(); let transfer_ch = ::Hashing::hash(&transfer_code); - let addr = ::DetermineContractAddress::contract_address_for( + let addr = pallet_contracts::Module::::contract_address( + &charlie(), &transfer_ch, &[], - &charlie(), ); let subsistence = pallet_contracts::Config::::subsistence_threshold_uncached(); @@ -613,7 +612,8 @@ fn deploying_wasm_contract_should_work() { 1 * DOLLARS + subsistence, 500_000_000, transfer_ch, - Vec::new() + Vec::new(), + Vec::new(), ) ), }, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 958d2fe19e0..4feff5d051a 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -675,6 +675,10 @@ parameter_types! { pub const RentByteFee: Balance = 4 * MILLICENTS; pub const RentDepositOffset: Balance = 1000 * MILLICENTS; pub const SurchargeReward: Balance = 150 * MILLICENTS; + pub const SignedClaimHandicap: u32 = 2; + pub const MaxDepth: u32 = 32; + pub const StorageSizeOffset: u32 = 8; + pub const MaxValueSize: u32 = 16 * 1024; } impl pallet_contracts::Trait for Runtime { @@ -682,17 +686,15 @@ impl pallet_contracts::Trait for Runtime { type Randomness = RandomnessCollectiveFlip; type Currency = Balances; type Event = Event; - type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer; - type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter; type RentPayment = (); - type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap; + type SignedClaimHandicap = SignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; - type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset; + type StorageSizeOffset = StorageSizeOffset; type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; - type MaxDepth = pallet_contracts::DefaultMaxDepth; - type MaxValueSize = pallet_contracts::DefaultMaxValueSize; + type MaxDepth = MaxDepth; + type MaxValueSize = MaxValueSize; type WeightPrice = pallet_transaction_payment::Module; type WeightInfo = pallet_contracts::weights::SubstrateWeight; } diff --git a/frame/contracts/fixtures/call_return_code.wat b/frame/contracts/fixtures/call_return_code.wat index f7a7ff20a49..4e9ab4dd77c 100644 --- a/frame/contracts/fixtures/call_return_code.wat +++ b/frame/contracts/fixtures/call_return_code.wat @@ -1,5 +1,5 @@ -;; This calls Django (4) and transfers 100 balance during this call and copies the return code -;; of this call to the output buffer. +;; This calls the supplied dest and transfers 100 balance during this call and copies +;; the return code of this call to the output buffer. ;; It also forwards its input to the callee. (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) @@ -7,38 +7,36 @@ (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) - ;; [0, 8) address of django - (data (i32.const 0) "\04\00\00\00\00\00\00\00") + ;; [0, 8) 100 balance + (data (i32.const 0) "\64\00\00\00\00\00\00\00") - ;; [8, 16) 100 balance - (data (i32.const 8) "\64\00\00\00\00\00\00\00") + ;; [8, 12) here we store the return code of the transfer - ;; [16, 20) here we store the return code of the transfer + ;; [12, 16) size of the input data + (data (i32.const 12) "\24") - ;; [20, 24) here we store the input data - - ;; [24, 28) size of the input data - (data (i32.const 24) "\04") + ;; [16, inf) here we store the input data + ;; 32 byte dest + 4 byte forward (func (export "deploy")) (func (export "call") - (call $seal_input (i32.const 20) (i32.const 24)) + (call $seal_input (i32.const 16) (i32.const 12)) (i32.store - (i32.const 16) + (i32.const 8) (call $seal_call - (i32.const 0) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 16) ;; Pointer to "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 20) ;; Pointer to input data buffer address - (i32.load (i32.const 24)) ;; Length of input data buffer + (i32.const 48) ;; Pointer to input data buffer address + (i32.const 4) ;; Length of input data buffer (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output (i32.const 0) ;; Ptr to output buffer len ) ) ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + (call $seal_return (i32.const 0) (i32.const 8) (i32.const 4)) ) ) diff --git a/frame/contracts/fixtures/caller_contract.wat b/frame/contracts/fixtures/caller_contract.wat index 408af92e182..d6564117b72 100644 --- a/frame/contracts/fixtures/caller_contract.wat +++ b/frame/contracts/fixtures/caller_contract.wat @@ -2,7 +2,9 @@ (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate + (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + )) (import "seal0" "seal_println" (func $seal_println (param i32 i32))) (import "env" "memory" (memory 1 1)) @@ -71,6 +73,8 @@ (i32.const 0) ;; Length is ignored in this case (i32.const 4294967295) ;; u32 max sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case + (i32.const 0) ;; salt_ptr + (i32.const 0) ;; salt_le ) ) @@ -98,6 +102,9 @@ (i32.const 0) ;; Length is ignored in this case (i32.const 4294967295) ;; u32 max sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case + (i32.const 0) ;; salt_ptr + (i32.const 0) ;; salt_le + ) ) @@ -114,7 +121,7 @@ ;; Length of the output buffer (i32.store (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 8) + (i32.const 256) ) ;; Deploy the contract successfully. @@ -131,6 +138,8 @@ (i32.sub (get_local $sp) (i32.const 4)) ;; Pointer to the address buffer length (i32.const 4294967295) ;; u32 max sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case + (i32.const 0) ;; salt_ptr + (i32.const 0) ;; salt_le ) ) @@ -142,7 +151,7 @@ ;; Check that address has the expected length (call $assert - (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 4))) (i32.const 8)) + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 4))) (i32.const 32)) ) ;; Check that balance has been deducted. @@ -169,7 +178,7 @@ (set_local $exit_code (call $seal_call (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. @@ -205,7 +214,7 @@ (set_local $exit_code (call $seal_call (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 1) ;; Supply too little gas (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. @@ -242,7 +251,7 @@ (set_local $exit_code (call $seal_call (i32.const 16) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. diff --git a/frame/contracts/fixtures/destroy_and_transfer.wat b/frame/contracts/fixtures/destroy_and_transfer.wat index 3220f4e612d..7e1d84f3cf9 100644 --- a/frame/contracts/fixtures/destroy_and_transfer.wat +++ b/frame/contracts/fixtures/destroy_and_transfer.wat @@ -4,7 +4,9 @@ (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate + (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + )) (import "env" "memory" (memory 1 1)) ;; [0, 8) Endowment to send when creating contract. @@ -16,14 +18,18 @@ ;; [48, 80) Buffer where to store the input to the contract - ;; [80, 88) Buffer where to store the address of the instantiated contract - ;; [88, 96) Size of the buffer - (data (i32.const 88) "\08") + (data (i32.const 88) "\FF") ;; [96, 100) Size of the input buffer (data (i32.const 96) "\20") + ;; [100, 132) Buffer where to store the address of the instantiated contract + + ;; [132, 134) Salt + (data (i32.const 132) "\47\11") + + (func $assert (param i32) (block $ok (br_if $ok @@ -54,10 +60,12 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer - (i32.const 80) ;; Buffer where to store address of new contract + (i32.const 100) ;; Buffer where to store address of new contract (i32.const 88) ;; Pointer to the length of the buffer (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this cas + (i32.const 0) ;; Length is ignored in this case + (i32.const 132) ;; salt_ptr + (i32.const 2) ;; salt_len ) (i32.const 0) ) @@ -67,15 +75,15 @@ (call $assert (i32.eq (i32.load (i32.const 88)) - (i32.const 8) + (i32.const 32) ) ) ;; Store the return address. (call $seal_set_storage (i32.const 16) ;; Pointer to the key - (i32.const 80) ;; Pointer to the value - (i32.const 8) ;; Length of the value + (i32.const 100) ;; Pointer to the value + (i32.const 32) ;; Length of the value ) ) @@ -85,7 +93,7 @@ (i32.eq (call $seal_get_storage (i32.const 16) ;; Pointer to the key - (i32.const 80) ;; Pointer to the value + (i32.const 100) ;; Pointer to the value (i32.const 88) ;; Pointer to the len of the value ) (i32.const 0) @@ -94,7 +102,7 @@ (call $assert (i32.eq (i32.load (i32.const 88)) - (i32.const 8) + (i32.const 32) ) ) @@ -102,8 +110,8 @@ (call $assert (i32.eq (call $seal_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address + (i32.const 100) ;; Pointer to destination address + (i32.const 32) ;; Length of destination address (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer @@ -121,8 +129,8 @@ (call $assert (i32.eq (call $seal_call - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address + (i32.const 100) ;; Pointer to destination address + (i32.const 32) ;; Length of destination address (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 8) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer @@ -141,8 +149,8 @@ (call $assert (i32.eq (call $seal_transfer - (i32.const 80) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address + (i32.const 100) ;; Pointer to destination address + (i32.const 32) ;; Length of destination address (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer ) diff --git a/frame/contracts/fixtures/drain.wat b/frame/contracts/fixtures/drain.wat index 9180047f5d0..546026ac959 100644 --- a/frame/contracts/fixtures/drain.wat +++ b/frame/contracts/fixtures/drain.wat @@ -38,7 +38,7 @@ (i32.eq (call $seal_transfer (i32.const 16) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address + (i32.const 32) ;; Length of destination address (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer ) diff --git a/frame/contracts/fixtures/instantiate_return_code.wat b/frame/contracts/fixtures/instantiate_return_code.wat index 20ab96d88ad..cead1f1c9fa 100644 --- a/frame/contracts/fixtures/instantiate_return_code.wat +++ b/frame/contracts/fixtures/instantiate_return_code.wat @@ -1,47 +1,49 @@ -;; This instantiats Charlie (3) and transfers 100 balance during this call and copies the return code +;; This instantiats a contract and transfers 100 balance during this call and copies the return code ;; of this call to the output buffer. ;; The first 32 byte of input is the code hash to instantiate ;; The rest of the input is forwarded to the constructor of the callee (module (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate + (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + )) (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) - ;; [0, 8) address of django - (data (i32.const 0) "\04\00\00\00\00\00\00\00") + ;; [0, 8) 100 balance + (data (i32.const 0) "\64\00\00\00\00\00\00\00") - ;; [8, 16) 100 balance - (data (i32.const 8) "\64\00\00\00\00\00\00\00") + ;; [8, 12) here we store the return code of the transfer - ;; [16, 20) here we store the return code of the transfer + ;; [12, 16) size of the input buffer + (data (i32.const 12) "\24") - ;; [20, 24) size of the input buffer - (data (i32.const 20) "\FF") - - ;; [24, inf) input buffer + ;; [16, inf) input buffer + ;; 32 bye code hash + 4 byte forward (func (export "deploy")) (func (export "call") - (call $seal_input (i32.const 24) (i32.const 20)) + (call $seal_input (i32.const 16) (i32.const 12)) (i32.store - (i32.const 16) + (i32.const 8) (call $seal_instantiate - (i32.const 24) ;; Pointer to the code hash. + (i32.const 16) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 56) ;; Pointer to input data buffer address - (i32.sub (i32.load (i32.const 20)) (i32.const 32)) ;; Length of input data buffer + (i32.const 48) ;; Pointer to input data buffer address + (i32.const 4) ;; Length of input data buffer (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy address (i32.const 0) ;; Length is ignored in this case (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case + (i32.const 0) ;; salt_ptr + (i32.const 0) ;; salt_len ) ) ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + (call $seal_return (i32.const 0) (i32.const 8) (i32.const 4)) ) ) diff --git a/frame/contracts/fixtures/restoration.wat b/frame/contracts/fixtures/restoration.wat index 3c15f7ae088..3462af28708 100644 --- a/frame/contracts/fixtures/restoration.wat +++ b/frame/contracts/fixtures/restoration.wat @@ -19,20 +19,19 @@ (func (export "call") ;; copy code hash to contract memory - (call $seal_input (i32.const 264) (i32.const 304)) + (call $seal_input (i32.const 308) (i32.const 304)) (call $assert (i32.eq (i32.load (i32.const 304)) - (i32.const 32) + (i32.const 64) ) ) - (call $seal_restore_to ;; Pointer and length of the encoded dest buffer. - (i32.const 256) - (i32.const 8) + (i32.const 340) + (i32.const 32) ;; Pointer and length of the encoded code hash buffer - (i32.const 264) + (i32.const 308) (i32.const 32) ;; Pointer and length of the encoded rent_allowance buffer (i32.const 296) @@ -65,14 +64,12 @@ ;; Buffer that has ACL storage keys. (data (i32.const 100) "\01") - ;; Address of bob - (data (i32.const 256) "\02\00\00\00\00\00\00\00") - - ;; [264, 296) Code hash of SET_RENT (copied here by seal_input) - ;; [296, 304) Rent allowance (data (i32.const 296) "\32\00\00\00\00\00\00\00") - ;; [304, 308) Size of SET_RENT buffer - (data (i32.const 304) "\20") + ;; [304, 308) Size of the buffer that holds code_hash + addr + (data (i32.const 304) "\40") + + ;; [308, 340) code hash of bob (copied by seal_input) + ;; [340, 372) addr of bob (copied by seal_input) ) diff --git a/frame/contracts/fixtures/self_destruct.wat b/frame/contracts/fixtures/self_destruct.wat index 6898e746b08..b8a37306e20 100644 --- a/frame/contracts/fixtures/self_destruct.wat +++ b/frame/contracts/fixtures/self_destruct.wat @@ -5,20 +5,23 @@ (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) (import "env" "memory" (memory 1 1)) - ;; [0, 8) reserved for $seal_address output + ;; [0, 32) reserved for $seal_address output - ;; [8, 16) length of the buffer - (data (i32.const 8) "\08") + ;; [32, 36) length of the buffer + (data (i32.const 32) "\20") - ;; [16, 24) Address of django - (data (i32.const 16) "\04\00\00\00\00\00\00\00") + ;; [36, 68) Address of django + (data (i32.const 36) + "\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04" + "\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04" + ) - ;; [24, 32) reserved for output of $seal_input + ;; [68, 72) reserved for output of $seal_input - ;; [32, 36) length of the buffer - (data (i32.const 32) "\04") + ;; [72, 76) length of the buffer + (data (i32.const 72) "\04") - ;; [36, inf) zero initialized + ;; [76, inf) zero initialized (func $assert (param i32) (block $ok @@ -36,16 +39,16 @@ ;; This should trap instead of self-destructing since a contract cannot be removed live in ;; the execution stack cannot be removed. If the recursive call traps, then trap here as ;; well. - (call $seal_input (i32.const 24) (i32.const 32)) - (if (i32.load (i32.const 32)) + (call $seal_input (i32.const 68) (i32.const 72)) + (if (i32.load (i32.const 72)) (then - (call $seal_address (i32.const 0) (i32.const 8)) + (call $seal_address (i32.const 0) (i32.const 32)) ;; Expect address to be 8 bytes. (call $assert (i32.eq - (i32.load (i32.const 8)) - (i32.const 8) + (i32.load (i32.const 32)) + (i32.const 32) ) ) @@ -54,9 +57,9 @@ (i32.eq (call $seal_call (i32.const 0) ;; Pointer to own address - (i32.const 8) ;; Length of own address + (i32.const 32) ;; Length of own address (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 36) ;; Pointer to the buffer with value to transfer + (i32.const 76) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer @@ -70,8 +73,8 @@ (else ;; Try to terminate and give balance to django. (call $seal_terminate - (i32.const 16) ;; Pointer to beneficiary address - (i32.const 8) ;; Length of beneficiary address + (i32.const 36) ;; Pointer to beneficiary address + (i32.const 32) ;; Length of beneficiary address ) (unreachable) ;; seal_terminate never returns ) diff --git a/frame/contracts/fixtures/self_destructing_constructor.wat b/frame/contracts/fixtures/self_destructing_constructor.wat index ab8c289f1b5..85fce511e21 100644 --- a/frame/contracts/fixtures/self_destructing_constructor.wat +++ b/frame/contracts/fixtures/self_destructing_constructor.wat @@ -15,7 +15,7 @@ ;; Self-destruct by sending full balance to the 0 address. (call $seal_terminate (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address + (i32.const 32) ;; Length of destination address ) ) diff --git a/frame/contracts/fixtures/set_rent.wat b/frame/contracts/fixtures/set_rent.wat index a09d3dc4bd4..1c6b512cc77 100644 --- a/frame/contracts/fixtures/set_rent.wat +++ b/frame/contracts/fixtures/set_rent.wat @@ -26,7 +26,7 @@ (func $call_2 (call $assert (i32.eq - (call $seal_transfer (i32.const 68) (i32.const 8) (i32.const 76) (i32.const 8)) + (call $seal_transfer (i32.const 136) (i32.const 32) (i32.const 100) (i32.const 8)) (i32.const 0) ) ) @@ -47,10 +47,11 @@ ;; Dispatch the call according to input size (func (export "call") (local $input_size i32) - (i32.store (i32.const 64) (i32.const 64)) - (call $seal_input (i32.const 1024) (i32.const 64)) + ;; 4 byte i32 for br_table followed by 32 byte destination for transfer + (i32.store (i32.const 128) (i32.const 36)) + (call $seal_input (i32.const 132) (i32.const 128)) (set_local $input_size - (i32.load (i32.const 64)) + (i32.load (i32.const 132)) ) (block $IF_ELSE (block $IF_2 @@ -81,25 +82,24 @@ (i32.const 0) (i32.const 4) ) + (i32.store (i32.const 128) (i32.const 64)) (call $seal_input - (i32.const 0) - (i32.const 64) + (i32.const 104) + (i32.const 100) ) (call $seal_set_rent_allowance - (i32.const 0) - (i32.load (i32.const 64)) + (i32.const 104) + (i32.load (i32.const 128)) ) ) ;; Encoding of 10 in balance (data (i32.const 0) "\28") - ;; Size of the buffer at address 0 - (data (i32.const 64) "\40") + ;; encoding of 50 balance + (data (i32.const 100) "\32") - ;; encoding of Charlies's account id - (data (i32.const 68) "\03") + ;; [128, 132) size of seal input buffer - ;; encoding of 50 balance - (data (i32.const 76) "\32") + ;; [132, inf) output buffer for seal input ) diff --git a/frame/contracts/fixtures/transfer_return_code.wat b/frame/contracts/fixtures/transfer_return_code.wat index 7a1bec9adf3..50098851dcf 100644 --- a/frame/contracts/fixtures/transfer_return_code.wat +++ b/frame/contracts/fixtures/transfer_return_code.wat @@ -5,27 +5,30 @@ (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) - ;; [0, 8) zero-adress - (data (i32.const 0) "\00\00\00\00\00\00\00\00") + ;; [0, 32) zero-adress + (data (i32.const 0) + "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" + "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" + ) - ;; [8, 16) 100 balance - (data (i32.const 8) "\64\00\00\00\00\00\00\00") + ;; [32, 40) 100 balance + (data (i32.const 32) "\64\00\00\00\00\00\00\00") - ;; [16, 20) here we store the return code of the transfer + ;; [40, 44) here we store the return code of the transfer (func (export "deploy")) (func (export "call") (i32.store - (i32.const 16) + (i32.const 40) (call $seal_transfer (i32.const 0) ;; ptr to destination address - (i32.const 8) ;; length of destination address - (i32.const 8) ;; ptr to value to transfer + (i32.const 32) ;; length of destination address + (i32.const 32) ;; ptr to value to transfer (i32.const 8) ;; length of value to transfer ) ) ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + (call $seal_return (i32.const 0) (i32.const 40) (i32.const 4)) ) ) diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index cb5052042aa..f879d2eed55 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -29,6 +29,7 @@ use crate::Module as Contracts; use parity_wasm::elements::{Instruction, Instructions, FuncBody, ValueType, BlockType}; use pwasm_utils::stack_height::inject_limiter; +use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::Hash; use sp_sandbox::{EnvironmentDefinitionBuilder, Memory}; use sp_std::{prelude::*, convert::TryFrom}; @@ -86,7 +87,11 @@ pub struct ImportedMemory { } impl ImportedMemory { - pub fn max() -> Self { + pub fn max() -> Self + where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, + { let pages = max_pages::(); Self { min_pages: pages, max_pages: pages } } @@ -106,7 +111,11 @@ pub struct WasmModule { memory: Option, } -impl From for WasmModule { +impl From for WasmModule +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ fn from(def: ModuleDefinition) -> Self { // internal functions start at that offset. let func_offset = u32::try_from(def.imported_functions.len()).unwrap(); @@ -216,7 +225,11 @@ impl From for WasmModule { } } -impl WasmModule { +impl WasmModule +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ /// Creates a wasm module with an empty `call` and `deploy` function and nothing else. pub fn dummy() -> Self { ModuleDefinition::default().into() @@ -470,6 +483,10 @@ pub mod body { } /// The maximum amount of pages any contract is allowed to have according to the current `Schedule`. -pub fn max_pages() -> u32 { +pub fn max_pages() -> u32 +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ Contracts::::current_schedule().limits.memory_pages } diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index dd9e89d6f35..2e15542368a 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -25,7 +25,9 @@ mod sandbox; use crate::{ *, Module as Contracts, exec::StorageKey, + rent::Rent, schedule::{API_BENCHMARK_BATCH_SIZE, INSTR_BENCHMARK_BATCH_SIZE}, + storage::Storage, }; use self::{ code::{ @@ -75,7 +77,11 @@ impl Endow { } } -impl Contract { +impl Contract +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ /// Create new contract and use a default account id as instantiator. fn new( module: WasmModule, @@ -123,7 +129,8 @@ impl Contract { Endow::Max => (0u32.into(), Endow::max::()), }; T::Currency::make_free_balance_be(&caller, caller_funding::()); - let addr = T::DetermineContractAddress::contract_address_for(&module.hash, &data, &caller); + let salt = vec![0xff]; + let addr = Contracts::::contract_address(&caller, &module.hash, &salt); // The default block number is zero. The benchmarking system bumps the block number // to one for the benchmarking closure when it is set to zero. In order to prevent this @@ -139,6 +146,7 @@ impl Contract { Weight::max_value(), module.hash, data, + salt, )?; let result = Contract { @@ -160,7 +168,7 @@ impl Contract { fn store(&self, items: &Vec<(StorageKey, Vec)>) -> Result<(), &'static str> { let info = self.alive_info()?; for item in items { - crate::storage::write_contract_storage::( + Storage::::write( &self.account_id, &info.trie_id, &item.0, @@ -192,7 +200,7 @@ impl Contract { /// Get the block number when this contract will be evicted. Returns an error when /// the rent collection won't happen because the contract has to much endowment. fn eviction_at(&self) -> Result { - let projection = crate::rent::compute_rent_projection::(&self.account_id) + let projection = Rent::::compute_projection(&self.account_id) .map_err(|_| "Invalid acc for rent")?; match projection { RentProjection::EvictionAt(at) => Ok(at), @@ -211,7 +219,11 @@ struct Tombstone { storage: Vec<(StorageKey, Vec)>, } -impl Tombstone { +impl Tombstone +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ /// Create and evict a new contract with the supplied storage item count and size each. fn new(stor_num: u32, stor_size: u32) -> Result { let contract = Contract::::new(WasmModule::dummy(), vec![], Endow::CollectRent)?; @@ -220,7 +232,7 @@ impl Tombstone { System::::set_block_number( contract.eviction_at()? + T::SignedClaimHandicap::get() + 5u32.into() ); - crate::rent::collect_rent::(&contract.account_id); + Rent::::collect(&contract.account_id); contract.ensure_tombstone()?; Ok(Tombstone { @@ -250,6 +262,11 @@ fn caller_funding() -> BalanceOf { } benchmarks! { + where_clause { where + T::AccountId: UncheckedFrom, + T::AccountId: AsRef<[u8]>, + } + _ { } @@ -276,17 +293,20 @@ benchmarks! { // The size of the input data influences the runtime because it is hashed in order to determine // the contract address. // `n`: Size of the data passed to constructor in kilobytes. + // `s`: Size of the salt in kilobytes. instantiate { let n in 0 .. code::max_pages::() * 64; + let s in 0 .. code::max_pages::() * 64; let data = vec![42u8; (n * 1024) as usize]; + let salt = vec![42u8; (s * 1024) as usize]; let endowment = Config::::subsistence_threshold_uncached(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let WasmModule { code, hash, .. } = WasmModule::::dummy_with_mem(); let origin = RawOrigin::Signed(caller.clone()); - let addr = T::DetermineContractAddress::contract_address_for(&hash, &data, &caller); + let addr = Contracts::::contract_address(&caller, &hash, &salt); Contracts::::put_code_raw(code)?; - }: _(origin, endowment, Weight::max_value(), hash, data) + }: _(origin, endowment, Weight::max_value(), hash, data, salt) verify { // endowment was removed from the caller assert_eq!(T::Currency::free_balance(&caller), caller_funding::() - endowment); @@ -1000,7 +1020,7 @@ benchmarks! { let instance = Contract::::new(code, vec![], Endow::Max)?; let trie_id = instance.alive_info()?.trie_id; for key in keys { - crate::storage::write_contract_storage::( + Storage::::write( &instance.account_id, &trie_id, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, @@ -1045,7 +1065,7 @@ benchmarks! { let instance = Contract::::new(code, vec![], Endow::Max)?; let trie_id = instance.alive_info()?.trie_id; for key in keys { - crate::storage::write_contract_storage::( + Storage::::write( &instance.account_id, &trie_id, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, @@ -1089,7 +1109,7 @@ benchmarks! { }); let instance = Contract::::new(code, vec![], Endow::Max)?; let trie_id = instance.alive_info()?.trie_id; - crate::storage::write_contract_storage::( + Storage::::write( &instance.account_id, &trie_id, key.as_slice().try_into().map_err(|e| "Key has wrong length")?, @@ -1341,7 +1361,9 @@ benchmarks! { ValueType::I32, ValueType::I32, ValueType::I32, - ValueType::I32 + ValueType::I32, + ValueType::I32, + ValueType::I32, ], return_type: Some(ValueType::I32), }], @@ -1371,6 +1393,8 @@ benchmarks! { Regular(Instruction::I32Const(addr_len_offset as i32)), // address_len_ptr Regular(Instruction::I32Const(u32::max_value() as i32)), // output_ptr Regular(Instruction::I32Const(0)), // output_len_ptr + Regular(Instruction::I32Const(0)), // salt_ptr + Regular(Instruction::I32Const(0)), // salt_ptr_len Regular(Instruction::Call(0)), Regular(Instruction::Drop), ])), @@ -1381,8 +1405,8 @@ benchmarks! { let callee = instance.addr.clone(); let addresses = hashes .iter() - .map(|hash| T::DetermineContractAddress::contract_address_for( - hash, &[], &instance.account_id + .map(|hash| Contracts::::contract_address( + &instance.account_id, hash, &[], )) .collect::>(); @@ -1398,9 +1422,10 @@ benchmarks! { } } - seal_instantiate_per_input_output_kb { + seal_instantiate_per_input_output_salt_kb { let i in 0 .. (code::max_pages::() - 1) * 64; let o in 0 .. (code::max_pages::() - 1) * 64; + let s in 0 .. (code::max_pages::() - 1) * 64; let callee_code = WasmModule::::from(ModuleDefinition { memory: Some(ImportedMemory::max::()), imported_functions: vec![ImportedFunction { @@ -1458,7 +1483,9 @@ benchmarks! { ValueType::I32, ValueType::I32, ValueType::I32, - ValueType::I32 + ValueType::I32, + ValueType::I32, + ValueType::I32, ], return_type: Some(ValueType::I32), }], @@ -1496,6 +1523,8 @@ benchmarks! { Regular(Instruction::I32Const(addr_len_offset as i32)), // address_len_ptr Regular(Instruction::I32Const(output_offset as i32)), // output_ptr Regular(Instruction::I32Const(output_len_offset as i32)), // output_len_ptr + Counter(input_offset as u32, input_len as u32), // salt_ptr + Regular(Instruction::I32Const((s * 1024).max(input_len as u32) as i32)), // salt_len Regular(Instruction::Call(0)), Regular(Instruction::I32Eqz), Regular(Instruction::If(BlockType::NoResult)), @@ -2401,6 +2430,8 @@ mod tests { create_test!(seal_transfer); create_test!(seal_call); create_test!(seal_call_per_transfer_input_output_kb); + create_test!(seal_instantiate); + create_test!(seal_instantiate_per_input_output_salt_kb); create_test!(seal_clear_storage); create_test!(seal_hash_sha2_256); create_test!(seal_hash_sha2_256_per_kb); diff --git a/frame/contracts/src/benchmarking/sandbox.rs b/frame/contracts/src/benchmarking/sandbox.rs index 1d93db19ee5..76cebfaf1ed 100644 --- a/frame/contracts/src/benchmarking/sandbox.rs +++ b/frame/contracts/src/benchmarking/sandbox.rs @@ -19,8 +19,11 @@ ///! sandbox to execute the wasm code. This is because we do not need the full ///! environment that provides the seal interface as imported functions. -use super::code::WasmModule; -use super::Trait; +use super::{ + Trait, + code::WasmModule, +}; +use sp_core::crypto::UncheckedFrom; use sp_sandbox::{EnvironmentDefinitionBuilder, Instance, Memory}; /// Minimal execution environment without any exported functions. @@ -36,7 +39,11 @@ impl Sandbox { } } -impl From<&WasmModule> for Sandbox { +impl From<&WasmModule> for Sandbox +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ /// Creates an instance from the supplied module and supplies as much memory /// to the instance as the module declares as imported. fn from(module: &WasmModule) -> Self { diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index f93f262d821..73e1f564498 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -15,10 +15,11 @@ // along with Substrate. If not, see . use crate::{ - CodeHash, Config, ContractAddressFor, Event, RawEvent, Trait, - TrieId, BalanceOf, ContractInfo, TrieIdGenerator, - gas::GasMeter, rent, storage, Error, ContractInfoOf + CodeHash, Config, Event, RawEvent, Trait, Module as Contracts, + TrieId, BalanceOf, ContractInfo, gas::GasMeter, rent::Rent, storage::{self, Storage}, + Error, ContractInfoOf }; +use sp_core::crypto::UncheckedFrom; use sp_std::prelude::*; use sp_runtime::traits::{Bounded, Zero, Convert, Saturating}; use frame_support::{ @@ -75,6 +76,7 @@ pub trait Ext { value: BalanceOf, gas_meter: &mut GasMeter, input_data: Vec, + salt: &[u8], ) -> Result<(AccountIdOf, ExecReturnValue), ExecError>; /// Transfer some amount of funds into the specified account. @@ -118,7 +120,7 @@ pub trait Ext { code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(), &'static str>; + ) -> Result<(), DispatchError>; /// Returns a reference to the account id of the caller. fn caller(&self) -> &AccountIdOf; @@ -215,6 +217,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { impl<'a, T, E, V, L> ExecutionContext<'a, T, V, L> where T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]>, L: Loader, V: Vm, { @@ -264,12 +267,12 @@ where Err(Error::::MaxCallDepthReached)? } - // Assumption: `collect_rent` doesn't collide with overlay because - // `collect_rent` will be done on first call and destination contract and balance + // Assumption: `collect` doesn't collide with overlay because + // `collect` will be done on first call and destination contract and balance // cannot be changed before the first call // We do not allow 'calling' plain accounts. For transfering value // `seal_transfer` must be used. - let contract = if let Some(ContractInfo::Alive(info)) = rent::collect_rent::(&dest) { + let contract = if let Some(ContractInfo::Alive(info)) = Rent::::collect(&dest) { info } else { Err(Error::::NotCallable)? @@ -308,6 +311,7 @@ where gas_meter: &mut GasMeter, code_hash: &CodeHash, input_data: Vec, + salt: &[u8], ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { if self.depth == self.config.max_depth as usize { Err(Error::::MaxCallDepthReached)? @@ -315,19 +319,15 @@ where let transactor_kind = self.transactor_kind(); let caller = self.self_account.clone(); - let dest = T::DetermineContractAddress::contract_address_for( - code_hash, - &input_data, - &caller, - ); + let dest = Contracts::::contract_address(&caller, code_hash, salt); // TrieId has not been generated yet and storage is empty since contract is new. // // Generate it now. - let dest_trie_id = ::TrieIdGenerator::trie_id(&dest); + let dest_trie_id = Storage::::generate_trie_id(&dest); let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { - storage::place_contract::( + Storage::::place_contract( &dest, nested .self_trie_id @@ -444,7 +444,10 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( dest: &T::AccountId, value: BalanceOf, ctx: &mut ExecutionContext<'a, T, V, L>, -) -> Result<(), DispatchError> { +) -> Result<(), DispatchError> +where + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ use self::TransferCause::*; use self::TransactorKind::*; @@ -491,6 +494,7 @@ struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { impl<'a, 'b: 'a, T, E, V, L> Ext for CallContext<'a, 'b, T, V, L> where T: Trait + 'b, + T::AccountId: UncheckedFrom + AsRef<[u8]>, V: Vm, L: Loader, { @@ -503,7 +507,7 @@ where expect can't fail;\ qed", ); - storage::read_contract_storage(trie_id, key) + Storage::::read(trie_id, key) } fn set_storage(&mut self, key: StorageKey, value: Option>) { @@ -514,12 +518,12 @@ where qed", ); if let Err(storage::ContractAbsentError) = - storage::write_contract_storage::(&self.ctx.self_account, trie_id, &key, value) + Storage::::write(&self.ctx.self_account, trie_id, &key, value) { panic!( "the contract must be in the alive state within the `CallContext`;\ the contract cannot be absent in storage; - write_contract_storage cannot return `None`; + write cannot return `None`; qed" ); } @@ -531,8 +535,9 @@ where endowment: BalanceOf, gas_meter: &mut GasMeter, input_data: Vec, + salt: &[u8], ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { - self.ctx.instantiate(endowment, gas_meter, code_hash, input_data) + self.ctx.instantiate(endowment, gas_meter, code_hash, input_data, salt) } fn transfer( @@ -558,9 +563,7 @@ where let value = T::Currency::free_balance(&self_id); if let Some(caller_ctx) = self.ctx.caller { if caller_ctx.is_live(&self_id) { - return Err(DispatchError::Other( - "Cannot terminate a contract that is present on the call stack", - )); + return Err(Error::::ReentranceDenied.into()); } } transfer( @@ -576,7 +579,7 @@ where a contract has a trie id;\ this can't be None; qed", ); - storage::destroy_contract::(&self_id, self_trie_id); + Storage::::destroy_contract(&self_id, self_trie_id); Ok(()) } @@ -596,16 +599,14 @@ where code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) -> Result<(), &'static str> { + ) -> Result<(), DispatchError> { if let Some(caller_ctx) = self.ctx.caller { if caller_ctx.is_live(&self.ctx.self_account) { - return Err( - "Cannot perform restoration of a contract that is present on the call stack", - ); + return Err(Error::::ReentranceDenied.into()); } } - let result = crate::rent::restore_to::( + let result = Rent::::restore_to( self.ctx.self_account.clone(), dest.clone(), code_hash.clone(), @@ -667,7 +668,7 @@ where fn set_rent_allowance(&mut self, rent_allowance: BalanceOf) { if let Err(storage::ContractAbsentError) = - storage::set_rent_allowance::(&self.ctx.self_account, rent_allowance) + Storage::::set_rent_allowance(&self.ctx.self_account, rent_allowance) { panic!( "`self_account` points to an alive contract within the `CallContext`; @@ -677,7 +678,7 @@ where } fn rent_allowance(&self) -> BalanceOf { - storage::rent_allowance::(&self.ctx.self_account) + Storage::::rent_allowance(&self.ctx.self_account) .unwrap_or_else(|_| >::max_value()) // Must never be triggered actually } @@ -711,23 +712,21 @@ fn deposit_event( mod tests { use super::{ BalanceOf, Event, ExecResult, ExecutionContext, Ext, Loader, - RawEvent, Vm, ReturnFlags, ExecError, ErrorOrigin + RawEvent, Vm, ReturnFlags, ExecError, ErrorOrigin, AccountIdOf, }; use crate::{ gas::GasMeter, tests::{ExtBuilder, Test, MetaEvent}, exec::ExecReturnValue, CodeHash, Config, gas::Gas, - storage, Error + storage::Storage, + tests::{ALICE, BOB, CHARLIE}, + Error, }; use crate::tests::test_utils::{place_contract, set_balance, get_balance}; use sp_runtime::DispatchError; use assert_matches::assert_matches; use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc}; - const ALICE: u64 = 1; - const BOB: u64 = 2; - const CHARLIE: u64 = 3; - const GAS_LIMIT: Gas = 10_000_000_000; fn events() -> Vec> { @@ -869,7 +868,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); set_balance(&origin, 100); set_balance(&dest, 0); @@ -902,13 +901,13 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); place_contract(&BOB, return_ch); set_balance(&origin, 100); set_balance(&dest, 0); let output = ctx.call( - dest, + dest.clone(), 55, &mut GasMeter::::new(GAS_LIMIT), vec![], @@ -932,7 +931,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); set_balance(&origin, 0); let result = super::transfer( @@ -1061,6 +1060,7 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &input_data_ch, vec![1, 2, 3, 4], + &[], ); assert_matches!(result, Ok(_)); }); @@ -1120,13 +1120,13 @@ mod tests { let vm = MockVm::new(); - let witnessed_caller_bob = RefCell::new(None::); - let witnessed_caller_charlie = RefCell::new(None::); + let witnessed_caller_bob = RefCell::new(None::>); + let witnessed_caller_charlie = RefCell::new(None::>); let mut loader = MockLoader::empty(); let bob_ch = loader.insert(|ctx| { // Record the caller for bob. - *witnessed_caller_bob.borrow_mut() = Some(*ctx.ext.caller()); + *witnessed_caller_bob.borrow_mut() = Some(ctx.ext.caller().clone()); // Call into CHARLIE contract. assert_matches!( @@ -1137,19 +1137,19 @@ mod tests { }); let charlie_ch = loader.insert(|ctx| { // Record the caller for charlie. - *witnessed_caller_charlie.borrow_mut() = Some(*ctx.ext.caller()); + *witnessed_caller_charlie.borrow_mut() = Some(ctx.ext.caller().clone()); exec_success() }); ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); - let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); place_contract(&dest, bob_ch); place_contract(&CHARLIE, charlie_ch); let result = ctx.call( - dest, + dest.clone(), 0, &mut GasMeter::::new(GAS_LIMIT), vec![], @@ -1217,6 +1217,7 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &dummy_ch, vec![], + &[], ), Err(_) ); @@ -1243,13 +1244,14 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &dummy_ch, vec![], + &[], ), Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address ); // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(storage::code_hash::(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(Storage::::code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&events(), &[ RawEvent::Instantiated(ALICE, instantiated_contract_address) ]); @@ -1276,12 +1278,13 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &dummy_ch, vec![], + &[], ), Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address ); // Check that the account has not been created. - assert!(storage::code_hash::(&instantiated_contract_address).is_err()); + assert!(Storage::::code_hash(&instantiated_contract_address).is_err()); assert!(events().is_empty()); }); } @@ -1292,7 +1295,7 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert(|_| exec_success()); - let instantiated_contract_address = Rc::new(RefCell::new(None::)); + let instantiated_contract_address = Rc::new(RefCell::new(None::>)); let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); let instantiated_contract_address = Rc::clone(&instantiated_contract_address); @@ -1302,7 +1305,8 @@ mod tests { &dummy_ch, Config::::subsistence_threshold_uncached(), ctx.gas_meter, - vec![] + vec![], + &[48, 49, 50], ).unwrap(); *instantiated_contract_address.borrow_mut() = address.into(); @@ -1326,7 +1330,7 @@ mod tests { // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(storage::code_hash::(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(Storage::::code_hash(&instantiated_contract_address).unwrap(), dummy_ch); assert_eq!(&events(), &[ RawEvent::Instantiated(BOB, instantiated_contract_address) ]); @@ -1350,7 +1354,8 @@ mod tests { &dummy_ch, 15u64, ctx.gas_meter, - vec![] + vec![], + &[], ), Err(ExecError { error: DispatchError::Other("It's a trap!"), @@ -1405,6 +1410,7 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &terminate_ch, vec![], + &[], ), Err(Error::::NewContractNotFunded.into()) ); @@ -1437,6 +1443,7 @@ mod tests { &mut GasMeter::::new(GAS_LIMIT), &rent_allowance_ch, vec![], + &[], ); assert_matches!(result, Ok(_)); }); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index f43bfd0ebdb..65995afb73d 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -93,14 +93,18 @@ pub mod weights; #[cfg(test)] mod tests; -use crate::exec::ExecutionContext; -use crate::wasm::{WasmLoader, WasmVm}; -use crate::weights::WeightInfo; - -pub use crate::gas::{Gas, GasMeter}; -pub use crate::wasm::ReturnCode as RuntimeReturnCode; -pub use crate::schedule::{Schedule, HostFnWeights, InstructionWeights, Limits}; - +pub use crate::{ + gas::{Gas, GasMeter}, + wasm::ReturnCode as RuntimeReturnCode, + weights::WeightInfo, + schedule::{Schedule, HostFnWeights, InstructionWeights, Limits}, +}; +use crate::{ + exec::ExecutionContext, + wasm::{WasmLoader, WasmVm}, + rent::Rent, + storage::Storage, +}; use sp_core::crypto::UncheckedFrom; use sp_std::{prelude::*, marker::PhantomData, fmt::Debug}; use codec::{Codec, Encode, Decode}; @@ -112,7 +116,7 @@ use sp_runtime::{ }; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, - parameter_types, storage::child::ChildInfo, + storage::child::ChildInfo, dispatch::{DispatchResult, DispatchResultWithPostInfo}, traits::{OnUnbalanced, Currency, Get, Time, Randomness}, }; @@ -125,11 +129,6 @@ use frame_support::weights::Weight; pub type CodeHash = ::Hash; pub type TrieId = Vec; -/// A function that generates an `AccountId` for a contract upon instantiation. -pub trait ContractAddressFor { - fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &AccountId) -> AccountId; -} - /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account #[derive(Encode, Decode, RuntimeDebug)] @@ -257,66 +256,11 @@ impl From> for ContractInfo { } } -/// Get a trie id (trie id must be unique and collision resistant depending upon its context). -/// Note that it is different than encode because trie id should be collision resistant -/// (being a proper unique identifier). -pub trait TrieIdGenerator { - /// Get a trie id for an account, using reference to parent account trie id to ensure - /// uniqueness of trie id. - /// - /// The implementation must ensure every new trie id is unique: two consecutive calls with the - /// same parameter needs to return different trie id values. - fn trie_id(account_id: &AccountId) -> TrieId; -} - -/// Get trie id from `account_id`. -pub struct TrieIdFromParentCounter(PhantomData); - -/// This generator uses inner counter for account id and applies the hash over `AccountId + -/// accountid_counter`. -impl TrieIdGenerator for TrieIdFromParentCounter -where - T::AccountId: AsRef<[u8]> -{ - fn trie_id(account_id: &T::AccountId) -> TrieId { - // Note that skipping a value due to error is not an issue here. - // We only need uniqueness, not sequence. - let new_seed = AccountCounter::mutate(|v| { - *v = v.wrapping_add(1); - *v - }); - - let mut buf = Vec::new(); - buf.extend_from_slice(account_id.as_ref()); - buf.extend_from_slice(&new_seed.to_le_bytes()[..]); - T::Hashing::hash(&buf[..]).as_ref().into() - } -} - pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -parameter_types! { - /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. - pub const DefaultSignedClaimHandicap: u32 = 2; - /// A reasonable default value for [`Trait::TombstoneDeposit`]. - pub const DefaultTombstoneDeposit: u32 = 16; - /// A reasonable default value for [`Trait::StorageSizeOffset`]. - pub const DefaultStorageSizeOffset: u32 = 8; - /// A reasonable default value for [`Trait::RentByteFee`]. - pub const DefaultRentByteFee: u32 = 4; - /// A reasonable default value for [`Trait::RentDepositOffset`]. - pub const DefaultRentDepositOffset: u32 = 1000; - /// A reasonable default value for [`Trait::SurchargeReward`]. - pub const DefaultSurchargeReward: u32 = 150; - /// A reasonable default value for [`Trait::MaxDepth`]. - pub const DefaultMaxDepth: u32 = 32; - /// A reasonable default value for [`Trait::MaxValueSize`]. - pub const DefaultMaxValueSize: u32 = 16_384; -} - pub trait Trait: frame_system::Trait { type Time: Time; type Randomness: Randomness; @@ -327,12 +271,6 @@ pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From> + Into<::Event>; - /// A function type to get the contract address given the instantiator. - type DetermineContractAddress: ContractAddressFor, Self::AccountId>; - - /// trie id generator - type TrieIdGenerator: TrieIdGenerator; - /// Handler for rent payments. type RentPayment: OnUnbalanced>; @@ -383,32 +321,13 @@ pub trait Trait: frame_system::Trait { type WeightInfo: WeightInfo; } -/// Simple contract address determiner. -/// -/// Address calculated from the code (of the constructor), input data to the constructor, -/// and the account id that requested the account creation. -/// -/// Formula: `blake2_256(blake2_256(code) + blake2_256(data) + origin)` -pub struct SimpleAddressDeterminer(PhantomData); -impl ContractAddressFor, T::AccountId> for SimpleAddressDeterminer -where - T::AccountId: UncheckedFrom + AsRef<[u8]> -{ - fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &T::AccountId) -> T::AccountId { - let data_hash = T::Hashing::hash(data); - - let mut buf = Vec::new(); - buf.extend_from_slice(code_hash.as_ref()); - buf.extend_from_slice(data_hash.as_ref()); - buf.extend_from_slice(origin.as_ref()); - - UncheckedFrom::unchecked_from(T::Hashing::hash(&buf[..])) - } -} - decl_error! { /// Error for the contracts module. - pub enum Error for Module { + pub enum Error for Module + where + T::AccountId: UncheckedFrom, + T::AccountId: AsRef<[u8]>, + { /// A new schedule must have a greater version than the current one. InvalidScheduleVersion, /// An origin must be signed or inherent and auxiliary sender only provided on inherent. @@ -455,12 +374,21 @@ decl_error! { ContractTrapped, /// The size defined in `T::MaxValueSize` was exceeded. ValueTooLarge, + /// The action performed is not allowed while the contract performing it is already + /// on the call stack. Those actions are contract self destruction and restoration + /// of a tombstone. + ReentranceDenied, } } decl_module! { /// Contracts module. - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call + where + origin: T::Origin, + T::AccountId: UncheckedFrom, + T::AccountId: AsRef<[u8]>, + { type Error = Error; /// Number of block delay an extrinsic claim surcharge has. @@ -563,29 +491,38 @@ decl_module! { gas_meter.into_dispatch_result(result) } - /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. + /// Instantiates a new contract from the `code_hash` generated by `put_code`, + /// optionally transferring some balance. + /// + /// The supplied `salt` is used for contract address deriviation. See `fn contract_address`. /// /// Instantiation is executed as follows: /// - /// - The destination address is computed based on the sender and hash of the code. + /// - The destination address is computed based on the sender, code_hash and the salt. /// - The smart-contract account is created at the computed address. /// - The `ctor_code` is executed in the context of the newly-created account. Buffer returned /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - #[weight = T::WeightInfo::instantiate(data.len() as u32 / 1024).saturating_add(*gas_limit)] + #[weight = + T::WeightInfo::instantiate( + data.len() as u32 / 1024, + salt.len() as u32 / 1024, + ).saturating_add(*gas_limit) + ] pub fn instantiate( origin, #[compact] endowment: BalanceOf, #[compact] gas_limit: Gas, code_hash: CodeHash, - data: Vec + data: Vec, + salt: Vec, ) -> DispatchResultWithPostInfo { let origin = ensure_signed(origin)?; let mut gas_meter = GasMeter::new(gas_limit); let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.instantiate(endowment, gas_meter, &code_hash, data) + ctx.instantiate(endowment, gas_meter, &code_hash, data, &salt) .map(|(_address, output)| output) }); gas_meter.into_dispatch_result(result) @@ -619,7 +556,7 @@ decl_module! { }; // If poking the contract has lead to eviction of the contract, give out the rewards. - if rent::snitch_contract_should_be_evicted::(&dest, handicap) { + if Rent::::snitch_contract_should_be_evicted(&dest, handicap) { T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; } } @@ -627,7 +564,10 @@ decl_module! { } /// Public APIs provided by the contracts module. -impl Module { +impl Module +where + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ /// Perform a call to a specified contract. /// /// This function is similar to `Self::call`, but doesn't perform any address lookups and better @@ -659,12 +599,12 @@ impl Module { .get_alive() .ok_or(ContractAccessError::IsTombstone)?; - let maybe_value = storage::read_contract_storage(&contract_info.trie_id, &key); + let maybe_value = Storage::::read(&contract_info.trie_id, &key); Ok(maybe_value) } pub fn rent_projection(address: T::AccountId) -> RentProjectionResult { - rent::compute_rent_projection::(&address) + Rent::::compute_projection(&address) } /// Put code for benchmarks which does not check or instrument the code. @@ -674,9 +614,34 @@ impl Module { let result = wasm::save_code_raw::(code, &schedule); result.map(|_| ()).map_err(Into::into) } + + /// Determine the address of a contract, + /// + /// This is the address generation function used by contract instantation. Its result + /// is only dependend on its inputs. It can therefore be used to reliably predict the + /// address of a contract. This is akin to the formular of eth's CRATE2 opcode. There + /// is no CREATE equivalent because CREATE2 is strictly more powerful. + /// + /// Formula: `hash(deploying_address ++ code_hash ++ salt)` + pub fn contract_address( + deploying_address: &T::AccountId, + code_hash: &CodeHash, + salt: &[u8], + ) -> T::AccountId + { + let buf: Vec<_> = deploying_address.as_ref().iter() + .chain(code_hash.as_ref()) + .chain(salt) + .cloned() + .collect(); + UncheckedFrom::unchecked_from(T::Hashing::hash(&buf)) + } } -impl Module { +impl Module +where + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ fn execute_wasm( origin: T::AccountId, gas_meter: &mut GasMeter, @@ -734,7 +699,10 @@ decl_event! { } decl_storage! { - trait Store for Module as Contracts { + trait Store for Module as Contracts + where + T::AccountId: UncheckedFrom + AsRef<[u8]> + { /// Current cost schedule for contracts. CurrentSchedule get(fn current_schedule) config(): Schedule = Default::default(); /// A mapping from an original code hash to the original code, untouched by instrumentation. @@ -762,7 +730,10 @@ pub struct Config { pub max_value_size: u32, } -impl Config { +impl Config +where + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ fn preload() -> Config { Config { schedule: >::current_schedule(), diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 3dc47336319..a8886b990a9 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -18,15 +18,19 @@ use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, - TombstoneContractInfo, Trait, CodeHash, Config + TombstoneContractInfo, Trait, CodeHash, Config, Error, }; use sp_std::prelude::*; use sp_io::hashing::blake2_256; +use sp_core::crypto::UncheckedFrom; use frame_support::storage::child; use frame_support::traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReasons}; use frame_support::StorageMap; use pallet_contracts_primitives::{ContractAccessError, RentProjection, RentProjectionResult}; -use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}; +use sp_runtime::{ + DispatchError, + traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}, +}; /// The amount to charge. /// @@ -82,405 +86,412 @@ enum Verdict { Charge { amount: OutstandingAmount }, } -/// Returns a fee charged per block from the contract. -/// -/// This function accounts for the storage rent deposit. I.e. if the contract possesses enough funds -/// then the fee can drop to zero. -fn compute_fee_per_block( - free_balance: &BalanceOf, - contract: &AliveContractInfo, -) -> BalanceOf { - let free_storage = free_balance - .checked_div(&T::RentDepositOffset::get()) - .unwrap_or_else(Zero::zero); - - // For now, we treat every empty KV pair as if it was one byte long. - let empty_pairs_equivalent = contract.empty_pair_count; - - let effective_storage_size = >::from( - contract.storage_size + T::StorageSizeOffset::get() + empty_pairs_equivalent, - ) - .saturating_sub(free_storage); - - effective_storage_size - .checked_mul(&T::RentByteFee::get()) - .unwrap_or_else(|| >::max_value()) -} +pub struct Rent(sp_std::marker::PhantomData); -/// Returns amount of funds available to consume by rent mechanism. -/// -/// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make -/// the balance lower than [`subsistence_threshold`]. -/// -/// In case the toal_balance is below the subsistence threshold, this function returns `None`. -fn rent_budget( - total_balance: &BalanceOf, - free_balance: &BalanceOf, - contract: &AliveContractInfo, -) -> Option> { - let subsistence_threshold = Config::::subsistence_threshold_uncached(); - // Reserved balance contributes towards the subsistence threshold to stay consistent - // with the existential deposit where the reserved balance is also counted. - if *total_balance < subsistence_threshold { - return None; +impl Rent +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ + /// Returns a fee charged per block from the contract. + /// + /// This function accounts for the storage rent deposit. I.e. if the contract possesses enough funds + /// then the fee can drop to zero. + fn compute_fee_per_block( + free_balance: &BalanceOf, + contract: &AliveContractInfo + ) -> BalanceOf { + let free_storage = free_balance + .checked_div(&T::RentDepositOffset::get()) + .unwrap_or_else(Zero::zero); + + // For now, we treat every empty KV pair as if it was one byte long. + let empty_pairs_equivalent = contract.empty_pair_count; + + let effective_storage_size = >::from( + contract.storage_size + T::StorageSizeOffset::get() + empty_pairs_equivalent, + ) + .saturating_sub(free_storage); + + effective_storage_size + .checked_mul(&T::RentByteFee::get()) + .unwrap_or_else(|| >::max_value()) } - // However, reserved balance cannot be charged so we need to use the free balance - // to calculate the actual budget (which can be 0). - let rent_allowed_to_charge = free_balance.saturating_sub(subsistence_threshold); - Some(>::min( - contract.rent_allowance, - rent_allowed_to_charge, - )) -} + /// Returns amount of funds available to consume by rent mechanism. + /// + /// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make + /// the balance lower than [`subsistence_threshold`]. + /// + /// In case the toal_balance is below the subsistence threshold, this function returns `None`. + fn rent_budget( + total_balance: &BalanceOf, + free_balance: &BalanceOf, + contract: &AliveContractInfo, + ) -> Option> { + let subsistence_threshold = Config::::subsistence_threshold_uncached(); + // Reserved balance contributes towards the subsistence threshold to stay consistent + // with the existential deposit where the reserved balance is also counted. + if *total_balance < subsistence_threshold { + return None; + } -/// Consider the case for rent payment of the given account and returns a `Verdict`. -/// -/// Use `handicap` in case you want to change the reference block number. (To get more details see -/// `snitch_contract_should_be_evicted` ). -fn consider_case( - account: &T::AccountId, - current_block_number: T::BlockNumber, - handicap: T::BlockNumber, - contract: &AliveContractInfo, -) -> Verdict { - // How much block has passed since the last deduction for the contract. - let blocks_passed = { - // Calculate an effective block number, i.e. after adjusting for handicap. - let effective_block_number = current_block_number.saturating_sub(handicap); - effective_block_number.saturating_sub(contract.deduct_block) - }; - if blocks_passed.is_zero() { - // Rent has already been paid - return Verdict::Exempt; + // However, reserved balance cannot be charged so we need to use the free balance + // to calculate the actual budget (which can be 0). + let rent_allowed_to_charge = free_balance.saturating_sub(subsistence_threshold); + Some(>::min( + contract.rent_allowance, + rent_allowed_to_charge, + )) } - let total_balance = T::Currency::total_balance(account); - let free_balance = T::Currency::free_balance(account); + /// Consider the case for rent payment of the given account and returns a `Verdict`. + /// + /// Use `handicap` in case you want to change the reference block number. (To get more details see + /// `snitch_contract_should_be_evicted` ). + fn consider_case( + account: &T::AccountId, + current_block_number: T::BlockNumber, + handicap: T::BlockNumber, + contract: &AliveContractInfo, + ) -> Verdict { + // How much block has passed since the last deduction for the contract. + let blocks_passed = { + // Calculate an effective block number, i.e. after adjusting for handicap. + let effective_block_number = current_block_number.saturating_sub(handicap); + effective_block_number.saturating_sub(contract.deduct_block) + }; + if blocks_passed.is_zero() { + // Rent has already been paid + return Verdict::Exempt; + } - // An amount of funds to charge per block for storage taken up by the contract. - let fee_per_block = compute_fee_per_block::(&free_balance, contract); - if fee_per_block.is_zero() { - // The rent deposit offset reduced the fee to 0. This means that the contract - // gets the rent for free. - return Verdict::Exempt; - } + let total_balance = T::Currency::total_balance(account); + let free_balance = T::Currency::free_balance(account); - let rent_budget = match rent_budget::(&total_balance, &free_balance, contract) { - Some(rent_budget) => rent_budget, - None => { - // The contract's total balance is already below subsistence threshold. That - // indicates that the contract cannot afford to leave a tombstone. - // - // So cleanly wipe the contract. - return Verdict::Kill; + // An amount of funds to charge per block for storage taken up by the contract. + let fee_per_block = Self::compute_fee_per_block(&free_balance, contract); + if fee_per_block.is_zero() { + // The rent deposit offset reduced the fee to 0. This means that the contract + // gets the rent for free. + return Verdict::Exempt; } - }; - - let dues = fee_per_block - .checked_mul(&blocks_passed.saturated_into::().into()) - .unwrap_or_else(|| >::max_value()); - let insufficient_rent = rent_budget < dues; - - // If the rent payment cannot be withdrawn due to locks on the account balance, then evict the - // account. - // - // NOTE: This seems problematic because it provides a way to tombstone an account while - // avoiding the last rent payment. In effect, someone could retroactively set rent_allowance - // for their contract to 0. - let dues_limited = dues.min(rent_budget); - let can_withdraw_rent = T::Currency::ensure_can_withdraw( - account, - dues_limited, - WithdrawReasons::FEE, - free_balance.saturating_sub(dues_limited), - ) - .is_ok(); - - if insufficient_rent || !can_withdraw_rent { - // The contract cannot afford the rent payment and has a balance above the subsistence - // threshold, so it leaves a tombstone. - let amount = if can_withdraw_rent { - Some(OutstandingAmount::new(dues_limited)) - } else { - None + + let rent_budget = match Self::rent_budget(&total_balance, &free_balance, contract) { + Some(rent_budget) => rent_budget, + None => { + // The contract's total balance is already below subsistence threshold. That + // indicates that the contract cannot afford to leave a tombstone. + // + // So cleanly wipe the contract. + return Verdict::Kill; + } + }; + + let dues = fee_per_block + .checked_mul(&blocks_passed.saturated_into::().into()) + .unwrap_or_else(|| >::max_value()); + let insufficient_rent = rent_budget < dues; + + // If the rent payment cannot be withdrawn due to locks on the account balance, then evict the + // account. + // + // NOTE: This seems problematic because it provides a way to tombstone an account while + // avoiding the last rent payment. In effect, someone could retroactively set rent_allowance + // for their contract to 0. + let dues_limited = dues.min(rent_budget); + let can_withdraw_rent = T::Currency::ensure_can_withdraw( + account, + dues_limited, + WithdrawReasons::FEE, + free_balance.saturating_sub(dues_limited), + ) + .is_ok(); + + if insufficient_rent || !can_withdraw_rent { + // The contract cannot afford the rent payment and has a balance above the subsistence + // threshold, so it leaves a tombstone. + let amount = if can_withdraw_rent { + Some(OutstandingAmount::new(dues_limited)) + } else { + None + }; + return Verdict::Evict { amount }; + } + + return Verdict::Charge { + // We choose to use `dues_limited` here instead of `dues` just to err on the safer side. + amount: OutstandingAmount::new(dues_limited), }; - return Verdict::Evict { amount }; } - return Verdict::Charge { - // We choose to use `dues_limited` here instead of `dues` just to err on the safer side. - amount: OutstandingAmount::new(dues_limited), - }; -} + /// Enacts the given verdict and returns the updated `ContractInfo`. + /// + /// `alive_contract_info` should be from the same address as `account`. + fn enact_verdict( + account: &T::AccountId, + alive_contract_info: AliveContractInfo, + current_block_number: T::BlockNumber, + verdict: Verdict, + ) -> Option> { + match verdict { + Verdict::Exempt => return Some(ContractInfo::Alive(alive_contract_info)), + Verdict::Kill => { + >::remove(account); + child::kill_storage( + &alive_contract_info.child_trie_info(), + ); + >::deposit_event(RawEvent::Evicted(account.clone(), false)); + None + } + Verdict::Evict { amount } => { + if let Some(amount) = amount { + amount.withdraw(account); + } + + // Note: this operation is heavy. + let child_storage_root = child::root( + &alive_contract_info.child_trie_info(), + ); + + let tombstone = >::new( + &child_storage_root[..], + alive_contract_info.code_hash, + ); + let tombstone_info = ContractInfo::Tombstone(tombstone); + >::insert(account, &tombstone_info); + + child::kill_storage( + &alive_contract_info.child_trie_info(), + ); + + >::deposit_event(RawEvent::Evicted(account.clone(), true)); + Some(tombstone_info) + } + Verdict::Charge { amount } => { + let contract_info = ContractInfo::Alive(AliveContractInfo:: { + rent_allowance: alive_contract_info.rent_allowance - amount.peek(), + deduct_block: current_block_number, + ..alive_contract_info + }); + >::insert(account, &contract_info); -/// Enacts the given verdict and returns the updated `ContractInfo`. -/// -/// `alive_contract_info` should be from the same address as `account`. -fn enact_verdict( - account: &T::AccountId, - alive_contract_info: AliveContractInfo, - current_block_number: T::BlockNumber, - verdict: Verdict, -) -> Option> { - match verdict { - Verdict::Exempt => return Some(ContractInfo::Alive(alive_contract_info)), - Verdict::Kill => { - >::remove(account); - child::kill_storage( - &alive_contract_info.child_trie_info(), - ); - >::deposit_event(RawEvent::Evicted(account.clone(), false)); - None - } - Verdict::Evict { amount } => { - if let Some(amount) = amount { amount.withdraw(account); + Some(contract_info) } + } + } - // Note: this operation is heavy. - let child_storage_root = child::root( - &alive_contract_info.child_trie_info(), - ); - - let tombstone = >::new( - &child_storage_root[..], - alive_contract_info.code_hash, - ); - let tombstone_info = ContractInfo::Tombstone(tombstone); - >::insert(account, &tombstone_info); + /// Make account paying the rent for the current block number + /// + /// NOTE this function performs eviction eagerly. All changes are read and written directly to + /// storage. + pub fn collect(account: &T::AccountId) -> Option> { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return contract_info, + Some(ContractInfo::Alive(contract)) => contract, + }; - child::kill_storage( - &alive_contract_info.child_trie_info(), - ); + let current_block_number = >::block_number(); + let verdict = Self::consider_case( + account, + current_block_number, + Zero::zero(), + &alive_contract_info, + ); + Self::enact_verdict(account, alive_contract_info, current_block_number, verdict) + } - >::deposit_event(RawEvent::Evicted(account.clone(), true)); - Some(tombstone_info) - } - Verdict::Charge { amount } => { - let contract_info = ContractInfo::Alive(AliveContractInfo:: { - rent_allowance: alive_contract_info.rent_allowance - amount.peek(), - deduct_block: current_block_number, - ..alive_contract_info - }); - >::insert(account, &contract_info); - - amount.withdraw(account); - Some(contract_info) + /// Process a report that a contract under the given address should be evicted. + /// + /// Enact the eviction right away if the contract should be evicted and return true. + /// Otherwise, **do nothing** and return false. + /// + /// The `handicap` parameter gives a way to check the rent to a moment in the past instead + /// of current block. E.g. if the contract is going to be evicted at the current block, + /// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain snitchers + /// relative to others. + /// + /// NOTE this function performs eviction eagerly. All changes are read and written directly to + /// storage. + pub fn snitch_contract_should_be_evicted( + account: &T::AccountId, + handicap: T::BlockNumber, + ) -> bool { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return false, + Some(ContractInfo::Alive(contract)) => contract, + }; + let current_block_number = >::block_number(); + let verdict = Self::consider_case( + account, + current_block_number, + handicap, + &alive_contract_info, + ); + + // Enact the verdict only if the contract gets removed. + match verdict { + Verdict::Kill | Verdict::Evict { .. } => { + Self::enact_verdict(account, alive_contract_info, current_block_number, verdict); + true + } + _ => false, } } -} -/// Make account paying the rent for the current block number -/// -/// NOTE this function performs eviction eagerly. All changes are read and written directly to -/// storage. -pub fn collect_rent(account: &T::AccountId) -> Option> { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return contract_info, - Some(ContractInfo::Alive(contract)) => contract, - }; - - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - Zero::zero(), - &alive_contract_info, - ); - enact_verdict(account, alive_contract_info, current_block_number, verdict) -} + /// Returns the projected time a given contract will be able to sustain paying its rent. The + /// returned projection is relevant for the current block, i.e. it is as if the contract was + /// accessed at the beginning of the current block. Returns `None` in case if the contract was + /// evicted before or as a result of the rent collection. + /// + /// The returned value is only an estimation. It doesn't take into account any top ups, changing the + /// rent allowance, or any problems coming from withdrawing the dues. + /// + /// NOTE that this is not a side-effect free function! It will actually collect rent and then + /// compute the projection. This function is only used for implementation of an RPC method through + /// `RuntimeApi` meaning that the changes will be discarded anyway. + pub fn compute_projection( + account: &T::AccountId, + ) -> RentProjectionResult { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + Some(ContractInfo::Alive(contract)) => contract, + }; + let current_block_number = >::block_number(); + let verdict = Self::consider_case( + account, + current_block_number, + Zero::zero(), + &alive_contract_info, + ); + let new_contract_info = + Self::enact_verdict(account, alive_contract_info, current_block_number, verdict); + + // Check what happened after enaction of the verdict. + let alive_contract_info = match new_contract_info { + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + Some(ContractInfo::Alive(contract)) => contract, + }; -/// Process a report that a contract under the given address should be evicted. -/// -/// Enact the eviction right away if the contract should be evicted and return true. -/// Otherwise, **do nothing** and return false. -/// -/// The `handicap` parameter gives a way to check the rent to a moment in the past instead -/// of current block. E.g. if the contract is going to be evicted at the current block, -/// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain snitchers -/// relative to others. -/// -/// NOTE this function performs eviction eagerly. All changes are read and written directly to -/// storage. -pub fn snitch_contract_should_be_evicted( - account: &T::AccountId, - handicap: T::BlockNumber, -) -> bool { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return false, - Some(ContractInfo::Alive(contract)) => contract, - }; - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - handicap, - &alive_contract_info, - ); - - // Enact the verdict only if the contract gets removed. - match verdict { - Verdict::Kill | Verdict::Evict { .. } => { - enact_verdict(account, alive_contract_info, current_block_number, verdict); - true + // Compute how much would the fee per block be with the *updated* balance. + let total_balance = T::Currency::total_balance(account); + let free_balance = T::Currency::free_balance(account); + let fee_per_block = Self::compute_fee_per_block(&free_balance, &alive_contract_info); + if fee_per_block.is_zero() { + return Ok(RentProjection::NoEviction); } - _ => false, - } -} -/// Returns the projected time a given contract will be able to sustain paying its rent. The -/// returned projection is relevant for the current block, i.e. it is as if the contract was -/// accessed at the beginning of the current block. Returns `None` in case if the contract was -/// evicted before or as a result of the rent collection. -/// -/// The returned value is only an estimation. It doesn't take into account any top ups, changing the -/// rent allowance, or any problems coming from withdrawing the dues. -/// -/// NOTE that this is not a side-effect free function! It will actually collect rent and then -/// compute the projection. This function is only used for implementation of an RPC method through -/// `RuntimeApi` meaning that the changes will be discarded anyway. -pub fn compute_rent_projection( - account: &T::AccountId, -) -> RentProjectionResult { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), - Some(ContractInfo::Alive(contract)) => contract, - }; - let current_block_number = >::block_number(); - let verdict = consider_case::( - account, - current_block_number, - Zero::zero(), - &alive_contract_info, - ); - let new_contract_info = - enact_verdict(account, alive_contract_info, current_block_number, verdict); - - // Check what happened after enaction of the verdict. - let alive_contract_info = match new_contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), - Some(ContractInfo::Alive(contract)) => contract, - }; - - // Compute how much would the fee per block be with the *updated* balance. - let total_balance = T::Currency::total_balance(account); - let free_balance = T::Currency::free_balance(account); - let fee_per_block = compute_fee_per_block::(&free_balance, &alive_contract_info); - if fee_per_block.is_zero() { - return Ok(RentProjection::NoEviction); + // Then compute how much the contract will sustain under these circumstances. + let rent_budget = Self::rent_budget(&total_balance, &free_balance, &alive_contract_info).expect( + "the contract exists and in the alive state; + the updated balance must be greater than subsistence deposit; + this function doesn't return `None`; + qed + ", + ); + let blocks_left = match rent_budget.checked_div(&fee_per_block) { + Some(blocks_left) => blocks_left, + None => { + // `fee_per_block` is not zero here, so `checked_div` can return `None` if + // there is an overflow. This cannot happen with integers though. Return + // `NoEviction` here just in case. + return Ok(RentProjection::NoEviction); + } + }; + + let blocks_left = blocks_left.saturated_into::().into(); + Ok(RentProjection::EvictionAt( + current_block_number + blocks_left, + )) } - // Then compute how much the contract will sustain under these circumstances. - let rent_budget = rent_budget::(&total_balance, &free_balance, &alive_contract_info).expect( - "the contract exists and in the alive state; - the updated balance must be greater than subsistence deposit; - this function doesn't return `None`; - qed - ", - ); - let blocks_left = match rent_budget.checked_div(&fee_per_block) { - Some(blocks_left) => blocks_left, - None => { - // `fee_per_block` is not zero here, so `checked_div` can return `None` if - // there is an overflow. This cannot happen with integers though. Return - // `NoEviction` here just in case. - return Ok(RentProjection::NoEviction); + /// Restores the destination account using the origin as prototype. + /// + /// The restoration will be performed iff: + /// - origin exists and is alive, + /// - the origin's storage is not written in the current block + /// - the restored account has tombstone + /// - the tombstone matches the hash of the origin storage root, and code hash. + /// + /// Upon succesful restoration, `origin` will be destroyed, all its funds are transferred to + /// the restored account. The restored account will inherit the last write block and its last + /// deduct block will be set to the current block. + pub fn restore_to( + origin: T::AccountId, + dest: T::AccountId, + code_hash: CodeHash, + rent_allowance: BalanceOf, + delta: Vec, + ) -> Result<(), DispatchError> { + let mut origin_contract = >::get(&origin) + .and_then(|c| c.get_alive()) + .ok_or(Error::::InvalidSourceContract)?; + + let child_trie_info = origin_contract.child_trie_info(); + + let current_block = >::block_number(); + + if origin_contract.last_write == Some(current_block) { + return Err(Error::::InvalidContractOrigin.into()); } - }; - let blocks_left = blocks_left.saturated_into::().into(); - Ok(RentProjection::EvictionAt( - current_block_number + blocks_left, - )) -} + let dest_tombstone = >::get(&dest) + .and_then(|c| c.get_tombstone()) + .ok_or(Error::::InvalidDestinationContract)?; -/// Restores the destination account using the origin as prototype. -/// -/// The restoration will be performed iff: -/// - origin exists and is alive, -/// - the origin's storage is not written in the current block -/// - the restored account has tombstone -/// - the tombstone matches the hash of the origin storage root, and code hash. -/// -/// Upon succesful restoration, `origin` will be destroyed, all its funds are transferred to -/// the restored account. The restored account will inherit the last write block and its last -/// deduct block will be set to the current block. -pub fn restore_to( - origin: T::AccountId, - dest: T::AccountId, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec, -) -> Result<(), &'static str> { - let mut origin_contract = >::get(&origin) - .and_then(|c| c.get_alive()) - .ok_or("Cannot restore from inexisting or tombstone contract")?; - - let child_trie_info = origin_contract.child_trie_info(); - - let current_block = >::block_number(); - - if origin_contract.last_write == Some(current_block) { - return Err("Origin TrieId written in the current block"); - } + let last_write = if !delta.is_empty() { + Some(current_block) + } else { + origin_contract.last_write + }; - let dest_tombstone = >::get(&dest) - .and_then(|c| c.get_tombstone()) - .ok_or("Cannot restore to inexisting or alive contract")?; - - let last_write = if !delta.is_empty() { - Some(current_block) - } else { - origin_contract.last_write - }; - - let key_values_taken = delta.iter() - .filter_map(|key| { - child::get_raw(&child_trie_info, &blake2_256(key)).map(|value| { - child::kill(&child_trie_info, &blake2_256(key)); - (key, value) + let key_values_taken = delta.iter() + .filter_map(|key| { + child::get_raw(&child_trie_info, &blake2_256(key)).map(|value| { + child::kill(&child_trie_info, &blake2_256(key)); + (key, value) + }) }) - }) - .collect::>(); - - let tombstone = >::new( - // This operation is cheap enough because last_write (delta not included) - // is not this block as it has been checked earlier. - &child::root(&child_trie_info)[..], - code_hash, - ); - - if tombstone != dest_tombstone { - for (key, value) in key_values_taken { - child::put_raw(&child_trie_info, &blake2_256(key), &value); + .collect::>(); + + let tombstone = >::new( + // This operation is cheap enough because last_write (delta not included) + // is not this block as it has been checked earlier. + &child::root(&child_trie_info)[..], + code_hash, + ); + + if tombstone != dest_tombstone { + for (key, value) in key_values_taken { + child::put_raw(&child_trie_info, &blake2_256(key), &value); + } + return Err(Error::::InvalidTombstone.into()); } - return Err("Tombstones don't match"); + origin_contract.storage_size -= key_values_taken.iter() + .map(|(_, value)| value.len() as u32) + .sum::(); + + >::remove(&origin); + >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { + trie_id: origin_contract.trie_id, + storage_size: origin_contract.storage_size, + empty_pair_count: origin_contract.empty_pair_count, + total_pair_count: origin_contract.total_pair_count, + code_hash, + rent_allowance, + deduct_block: current_block, + last_write, + })); + + let origin_free_balance = T::Currency::free_balance(&origin); + T::Currency::make_free_balance_be(&origin, >::zero()); + T::Currency::deposit_creating(&dest, origin_free_balance); + + Ok(()) } - - origin_contract.storage_size -= key_values_taken.iter() - .map(|(_, value)| value.len() as u32) - .sum::(); - - >::remove(&origin); - >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { - trie_id: origin_contract.trie_id, - storage_size: origin_contract.storage_size, - empty_pair_count: origin_contract.empty_pair_count, - total_pair_count: origin_contract.total_pair_count, - code_hash, - rent_allowance, - deduct_block: current_block, - last_write, - })); - - let origin_free_balance = T::Currency::free_balance(&origin); - T::Currency::make_free_balance_be(&origin, >::zero()); - T::Currency::deposit_creating(&dest, origin_free_balance); - - Ok(()) } diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index ff2cde22971..197cc654c59 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -302,6 +302,9 @@ pub struct HostFnWeights { /// Weight per output byte received through `seal_instantiate`. pub instantiate_per_output_byte: Weight, + /// Weight per salt byte supplied to `seal_instantiate`. + pub instantiate_per_salt_byte: Weight, + /// Weight of calling `seal_hash_sha_256`. pub hash_sha2_256: Weight, @@ -535,8 +538,9 @@ impl Default for HostFnWeights { call_per_input_byte: cost_byte_batched_args!(seal_call_per_transfer_input_output_kb, 0, 1, 0), call_per_output_byte: cost_byte_batched_args!(seal_call_per_transfer_input_output_kb, 0, 0, 1), instantiate: cost_batched!(seal_instantiate), - instantiate_per_input_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_kb, 1, 0), - instantiate_per_output_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_kb, 0, 1), + instantiate_per_input_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 1, 0, 0), + instantiate_per_output_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 0, 1, 0), + instantiate_per_salt_byte: cost_byte_batched_args!(seal_instantiate_per_input_output_salt_kb, 0, 0, 1), hash_sha2_256: cost_batched!(seal_hash_sha2_256), hash_sha2_256_per_byte: cost_byte_batched!(seal_hash_sha2_256_per_kb), hash_keccak_256: cost_batched!(seal_hash_keccak_256), diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index 3740952778f..acd78879615 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -19,10 +19,13 @@ use crate::{ exec::{AccountIdOf, StorageKey}, AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Trait, TrieId, + AccountCounter, }; use sp_std::prelude::*; +use sp_std::marker::PhantomData; use sp_io::hashing::blake2_256; use sp_runtime::traits::Bounded; +use sp_core::crypto::UncheckedFrom; use frame_support::{storage::child, StorageMap}; /// An error that means that the account requested either doesn't exist or represents a tombstone @@ -30,167 +33,196 @@ use frame_support::{storage::child, StorageMap}; #[cfg_attr(test, derive(PartialEq, Eq, Debug))] pub struct ContractAbsentError; -/// Reads a storage kv pair of a contract. -/// -/// The read is performed from the `trie_id` only. The `address` is not necessary. If the contract -/// doesn't store under the given `key` `None` is returned. -pub fn read_contract_storage(trie_id: &TrieId, key: &StorageKey) -> Option> { - child::get_raw(&crate::child_trie_info(&trie_id), &blake2_256(key)) -} - -/// Update a storage entry into a contract's kv storage. -/// -/// If the `opt_new_value` is `None` then the kv pair is removed. -/// -/// This function also updates the bookkeeping info such as: number of total non-empty pairs a -/// contract owns, the last block the storage was written to, etc. That's why, in contrast to -/// `read_contract_storage`, this function also requires the `account` ID. -/// -/// If the contract specified by the id `account` doesn't exist `Err` is returned.` -pub fn write_contract_storage( - account: &AccountIdOf, - trie_id: &TrieId, - key: &StorageKey, - opt_new_value: Option>, -) -> Result<(), ContractAbsentError> { - let mut new_info = match >::get(account) { - Some(ContractInfo::Alive(alive)) => alive, - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAbsentError), - }; - - let hashed_key = blake2_256(key); - let child_trie_info = &crate::child_trie_info(&trie_id); - - // In order to correctly update the book keeping we need to fetch the previous - // value of the key-value pair. - // - // It might be a bit more clean if we had an API that supported getting the size - // of the value without going through the loading of it. But at the moment of - // writing, there is no such API. - // - // That's not a show stopper in any case, since the performance cost is - // dominated by the trie traversal anyway. - let opt_prev_value = child::get_raw(&child_trie_info, &hashed_key); - - // Update the total number of KV pairs and the number of empty pairs. - match (&opt_prev_value, &opt_new_value) { - (Some(prev_value), None) => { - new_info.total_pair_count -= 1; - if prev_value.is_empty() { - new_info.empty_pair_count -= 1; - } - }, - (None, Some(new_value)) => { - new_info.total_pair_count += 1; - if new_value.is_empty() { - new_info.empty_pair_count += 1; - } - }, - (Some(prev_value), Some(new_value)) => { - if prev_value.is_empty() { - new_info.empty_pair_count -= 1; - } - if new_value.is_empty() { - new_info.empty_pair_count += 1; +pub struct Storage(PhantomData); + +impl Storage +where + T: Trait, + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ + /// Reads a storage kv pair of a contract. + /// + /// The read is performed from the `trie_id` only. The `address` is not necessary. If the contract + /// doesn't store under the given `key` `None` is returned. + pub fn read(trie_id: &TrieId, key: &StorageKey) -> Option> { + child::get_raw(&crate::child_trie_info(&trie_id), &blake2_256(key)) + } + + /// Update a storage entry into a contract's kv storage. + /// + /// If the `opt_new_value` is `None` then the kv pair is removed. + /// + /// This function also updates the bookkeeping info such as: number of total non-empty pairs a + /// contract owns, the last block the storage was written to, etc. That's why, in contrast to + /// `read`, this function also requires the `account` ID. + /// + /// If the contract specified by the id `account` doesn't exist `Err` is returned.` + pub fn write( + account: &AccountIdOf, + trie_id: &TrieId, + key: &StorageKey, + opt_new_value: Option>, + ) -> Result<(), ContractAbsentError> { + let mut new_info = match >::get(account) { + Some(ContractInfo::Alive(alive)) => alive, + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAbsentError), + }; + + let hashed_key = blake2_256(key); + let child_trie_info = &crate::child_trie_info(&trie_id); + + // In order to correctly update the book keeping we need to fetch the previous + // value of the key-value pair. + // + // It might be a bit more clean if we had an API that supported getting the size + // of the value without going through the loading of it. But at the moment of + // writing, there is no such API. + // + // That's not a show stopper in any case, since the performance cost is + // dominated by the trie traversal anyway. + let opt_prev_value = child::get_raw(&child_trie_info, &hashed_key); + + // Update the total number of KV pairs and the number of empty pairs. + match (&opt_prev_value, &opt_new_value) { + (Some(prev_value), None) => { + new_info.total_pair_count -= 1; + if prev_value.is_empty() { + new_info.empty_pair_count -= 1; + } + }, + (None, Some(new_value)) => { + new_info.total_pair_count += 1; + if new_value.is_empty() { + new_info.empty_pair_count += 1; + } + }, + (Some(prev_value), Some(new_value)) => { + if prev_value.is_empty() { + new_info.empty_pair_count -= 1; + } + if new_value.is_empty() { + new_info.empty_pair_count += 1; + } } + (None, None) => {} + } + + // Update the total storage size. + let prev_value_len = opt_prev_value + .as_ref() + .map(|old_value| old_value.len() as u32) + .unwrap_or(0); + let new_value_len = opt_new_value + .as_ref() + .map(|new_value| new_value.len() as u32) + .unwrap_or(0); + new_info.storage_size = new_info + .storage_size + .saturating_add(new_value_len) + .saturating_sub(prev_value_len); + + new_info.last_write = Some(>::block_number()); + >::insert(&account, ContractInfo::Alive(new_info)); + + // Finally, perform the change on the storage. + match opt_new_value { + Some(new_value) => child::put_raw(&child_trie_info, &hashed_key, &new_value[..]), + None => child::kill(&child_trie_info, &hashed_key), } - (None, None) => {} + + Ok(()) } - // Update the total storage size. - let prev_value_len = opt_prev_value - .as_ref() - .map(|old_value| old_value.len() as u32) - .unwrap_or(0); - let new_value_len = opt_new_value - .as_ref() - .map(|new_value| new_value.len() as u32) - .unwrap_or(0); - new_info.storage_size = new_info - .storage_size - .saturating_add(new_value_len) - .saturating_sub(prev_value_len); - - new_info.last_write = Some(>::block_number()); - >::insert(&account, ContractInfo::Alive(new_info)); - - // Finally, perform the change on the storage. - match opt_new_value { - Some(new_value) => child::put_raw(&child_trie_info, &hashed_key, &new_value[..]), - None => child::kill(&child_trie_info, &hashed_key), + /// Returns the rent allowance set for the contract give by the account id. + pub fn rent_allowance( + account: &AccountIdOf, + ) -> Result, ContractAbsentError> + { + >::get(account) + .and_then(|i| i.as_alive().map(|i| i.rent_allowance)) + .ok_or(ContractAbsentError) } - Ok(()) -} - -/// Returns the rent allowance set for the contract give by the account id. -pub fn rent_allowance( - account: &AccountIdOf, -) -> Result, ContractAbsentError> { - >::get(account) - .and_then(|i| i.as_alive().map(|i| i.rent_allowance)) - .ok_or(ContractAbsentError) -} - -/// Set the rent allowance for the contract given by the account id. -/// -/// Returns `Err` if the contract doesn't exist or is a tombstone. -pub fn set_rent_allowance( - account: &AccountIdOf, - rent_allowance: BalanceOf, -) -> Result<(), ContractAbsentError> { - >::mutate(account, |maybe_contract_info| match maybe_contract_info { - Some(ContractInfo::Alive(ref mut alive_info)) => { - alive_info.rent_allowance = rent_allowance; - Ok(()) - } - _ => Err(ContractAbsentError), - }) -} - -/// Returns the code hash of the contract specified by `account` ID. -#[cfg(test)] -pub fn code_hash(account: &AccountIdOf) -> Result, ContractAbsentError> { - >::get(account) - .and_then(|i| i.as_alive().map(|i| i.code_hash)) - .ok_or(ContractAbsentError) -} - -/// Creates a new contract descriptor in the storage with the given code hash at the given address. -/// -/// Returns `Err` if there is already a contract (or a tombstone) exists at the given address. -pub fn place_contract( - account: &AccountIdOf, - trie_id: TrieId, - ch: CodeHash, -) -> Result<(), &'static str> { - >::mutate(account, |maybe_contract_info| { - if maybe_contract_info.is_some() { - return Err("Alive contract or tombstone already exists"); - } + /// Set the rent allowance for the contract given by the account id. + /// + /// Returns `Err` if the contract doesn't exist or is a tombstone. + pub fn set_rent_allowance( + account: &AccountIdOf, + rent_allowance: BalanceOf, + ) -> Result<(), ContractAbsentError> { + >::mutate(account, |maybe_contract_info| match maybe_contract_info { + Some(ContractInfo::Alive(ref mut alive_info)) => { + alive_info.rent_allowance = rent_allowance; + Ok(()) + } + _ => Err(ContractAbsentError), + }) + } - *maybe_contract_info = Some( - AliveContractInfo:: { - code_hash: ch, - storage_size: 0, - trie_id, - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - empty_pair_count: 0, - total_pair_count: 0, - last_write: None, + /// Creates a new contract descriptor in the storage with the given code hash at the given address. + /// + /// Returns `Err` if there is already a contract (or a tombstone) exists at the given address. + pub fn place_contract( + account: &AccountIdOf, + trie_id: TrieId, + ch: CodeHash, + ) -> Result<(), &'static str> { + >::mutate(account, |maybe_contract_info| { + if maybe_contract_info.is_some() { + return Err("Alive contract or tombstone already exists"); } - .into(), - ); - Ok(()) - }) -} - -/// Removes the contract and all the storage associated with it. -/// -/// This function doesn't affect the account. -pub fn destroy_contract(address: &AccountIdOf, trie_id: &TrieId) { - >::remove(address); - child::kill_storage(&crate::child_trie_info(&trie_id)); -} + *maybe_contract_info = Some( + AliveContractInfo:: { + code_hash: ch, + storage_size: 0, + trie_id, + deduct_block: >::block_number(), + rent_allowance: >::max_value(), + empty_pair_count: 0, + total_pair_count: 0, + last_write: None, + } + .into(), + ); + + Ok(()) + }) + } + + /// Removes the contract and all the storage associated with it. + /// + /// This function doesn't affect the account. + pub fn destroy_contract(address: &AccountIdOf, trie_id: &TrieId) { + >::remove(address); + child::kill_storage(&crate::child_trie_info(&trie_id)); + } + + /// This generator uses inner counter for account id and applies the hash over `AccountId + + /// accountid_counter`. + pub fn generate_trie_id(account_id: &AccountIdOf) -> TrieId { + use frame_support::StorageValue; + use sp_runtime::traits::Hash; + // Note that skipping a value due to error is not an issue here. + // We only need uniqueness, not sequence. + let new_seed = AccountCounter::mutate(|v| { + *v = v.wrapping_add(1); + *v + }); + + let buf: Vec<_> = account_id.as_ref().iter() + .chain(&new_seed.to_le_bytes()) + .cloned() + .collect(); + T::Hashing::hash(&buf).as_ref().into() + } + + /// Returns the code hash of the contract specified by `account` ID. + #[cfg(test)] + pub fn code_hash(account: &AccountIdOf) -> Result, ContractAbsentError> + { + >::get(account) + .and_then(|i| i.as_alive().map(|i| i.code_hash)) + .ok_or(ContractAbsentError) + } +} \ No newline at end of file diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 05e46a3ab15..6a0476096c8 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -15,21 +15,22 @@ // along with Substrate. If not, see . use crate::{ - BalanceOf, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, Module, - RawAliveContractInfo, RawEvent, Trait, TrieId, Schedule, TrieIdGenerator, gas::Gas, - Error, Config, RuntimeReturnCode, + BalanceOf, ContractInfo, ContractInfoOf, GenesisConfig, Module, + RawAliveContractInfo, RawEvent, Trait, Schedule, gas::Gas, + Error, Config, RuntimeReturnCode, storage::Storage, + exec::AccountIdOf, }; use assert_matches::assert_matches; -use hex_literal::*; use codec::Encode; use sp_runtime::{ Perbill, traits::{BlakeTwo256, Hash, IdentityLookup, Convert}, testing::{Header, H256}, + AccountId32, }; use frame_support::{ assert_ok, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, - impl_outer_origin, parameter_types, StorageMap, StorageValue, + impl_outer_origin, parameter_types, StorageMap, traits::{Currency, ReservableCurrency}, weights::{Weight, PostDispatchInfo}, dispatch::DispatchErrorWithPostInfo, @@ -66,28 +67,30 @@ impl_outer_dispatch! { #[macro_use] pub mod test_utils { use super::{Test, Balances}; - use crate::{ContractInfoOf, TrieIdGenerator, CodeHash}; - use crate::storage::{write_contract_storage, read_contract_storage}; - use crate::exec::StorageKey; + use crate::{ + ContractInfoOf, CodeHash, + storage::Storage, + exec::{StorageKey, AccountIdOf}, + }; use frame_support::{StorageMap, traits::Currency}; - pub fn set_storage(addr: &u64, key: &StorageKey, value: Option>) { + pub fn set_storage(addr: &AccountIdOf, key: &StorageKey, value: Option>) { let contract_info = >::get(&addr).unwrap().get_alive().unwrap(); - write_contract_storage::(&1, &contract_info.trie_id, key, value).unwrap(); + Storage::::write(addr, &contract_info.trie_id, key, value).unwrap(); } - pub fn get_storage(addr: &u64, key: &StorageKey) -> Option> { + pub fn get_storage(addr: &AccountIdOf, key: &StorageKey) -> Option> { let contract_info = >::get(&addr).unwrap().get_alive().unwrap(); - read_contract_storage(&contract_info.trie_id, key) + Storage::::read(&contract_info.trie_id, key) } - pub fn place_contract(address: &u64, code_hash: CodeHash) { - let trie_id = ::TrieIdGenerator::trie_id(address); - crate::storage::place_contract::(&address, trie_id, code_hash).unwrap() + pub fn place_contract(address: &AccountIdOf, code_hash: CodeHash) { + let trie_id = Storage::::generate_trie_id(address); + Storage::::place_contract(&address, trie_id, code_hash).unwrap() } - pub fn set_balance(who: &u64, amount: u64) { + pub fn set_balance(who: &AccountIdOf, amount: u64) { let imbalance = Balances::deposit_creating(who, amount); drop(imbalance); } - pub fn get_balance(who: &u64) -> u64 { + pub fn get_balance(who: &AccountIdOf) -> u64 { Balances::free_balance(who) } macro_rules! assert_return_code { @@ -115,7 +118,7 @@ impl frame_system::Trait for Test { type Hash = H256; type Call = Call; type Hashing = BlakeTwo256; - type AccountId = u64; + type AccountId = AccountId32; type Lookup = IdentityLookup; type Header = Header; type Event = MetaEvent; @@ -177,9 +180,7 @@ impl Trait for Test { type Time = Timestamp; type Randomness = Randomness; type Currency = Balances; - type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; - type TrieIdGenerator = DummyTrieIdGenerator; type RentPayment = (); type SignedClaimHandicap = SignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; @@ -199,32 +200,10 @@ type Contracts = Module; type System = frame_system::Module; type Randomness = pallet_randomness_collective_flip::Module; -pub struct DummyContractAddressFor; -impl ContractAddressFor for DummyContractAddressFor { - fn contract_address_for(_code_hash: &H256, _data: &[u8], origin: &u64) -> u64 { - *origin + 1 - } -} - -pub struct DummyTrieIdGenerator; -impl TrieIdGenerator for DummyTrieIdGenerator { - fn trie_id(account_id: &u64) -> TrieId { - let new_seed = super::AccountCounter::mutate(|v| { - *v = v.wrapping_add(1); - *v - }); - - let mut res = vec![]; - res.extend_from_slice(&new_seed.to_le_bytes()); - res.extend_from_slice(&account_id.to_le_bytes()); - res - } -} - -const ALICE: u64 = 1; -const BOB: u64 = 2; -const CHARLIE: u64 = 3; -const DJANGO: u64 = 4; +pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); +pub const BOB: AccountId32 = AccountId32::new([2u8; 32]); +pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]); +pub const DJANGO: AccountId32 = AccountId32::new([4u8; 32]); const GAS_LIMIT: Gas = 10_000_000_000; @@ -309,8 +288,8 @@ fn account_removal_does_not_remove_storage() { use self::test_utils::{set_storage, get_storage}; ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - let trie_id1 = ::TrieIdGenerator::trie_id(&1); - let trie_id2 = ::TrieIdGenerator::trie_id(&2); + let trie_id1 = Storage::::generate_trie_id(&ALICE); + let trie_id2 = Storage::::generate_trie_id(&BOB); let key1 = &[1; 32]; let key2 = &[2; 32]; @@ -399,17 +378,21 @@ fn instantiate_and_call_and_deposit_event() { GAS_LIMIT, code_hash.into(), vec![], + vec![], ); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); pretty_assertions::assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE.clone())), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + event: MetaEvent::balances( + pallet_balances::RawEvent::Endowed(ALICE, 1_000_000) + ), topics: vec![], }, EventRecord { @@ -419,37 +402,39 @@ fn instantiate_and_call_and_deposit_event() { }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(addr.clone())), topics: vec![], }, EventRecord { phase: Phase::Initialization, event: MetaEvent::balances( - pallet_balances::RawEvent::Endowed(BOB, subsistence) + pallet_balances::RawEvent::Endowed(addr.clone(), subsistence) ), topics: vec![], }, EventRecord { phase: Phase::Initialization, event: MetaEvent::balances( - pallet_balances::RawEvent::Transfer(ALICE, BOB, subsistence) + pallet_balances::RawEvent::Transfer(ALICE, addr.clone(), subsistence) ), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), + event: MetaEvent::contracts( + RawEvent::ContractExecution(addr.clone(), vec![1, 2, 3, 4]) + ), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), + event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, addr.clone())), topics: vec![], } ]); assert_ok!(creation); - assert!(ContractInfoOf::::contains_key(BOB)); + assert!(ContractInfoOf::::contains_key(&addr)); }); } @@ -470,16 +455,21 @@ fn deposit_event_max_value_limit() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(addr.clone()) + .unwrap() + .get_alive() + .unwrap(); assert_eq!(bob_contract.rent_allowance, >::max_value()); // Call contract with allowed storage value. assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer, ::MaxValueSize::get().encode(), @@ -489,7 +479,7 @@ fn deposit_event_max_value_limit() { assert_err_ignore_postinfo!( Contracts::call( Origin::signed(ALICE), - BOB, + addr, 0, GAS_LIMIT, (::MaxValueSize::get() + 1).encode(), @@ -517,14 +507,16 @@ fn run_out_of_gas() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Call the contract with a fixed gas limit. It must run out of gas because it just // loops forever. assert_err_ignore_postinfo!( Contracts::call( Origin::signed(ALICE), - BOB, // newly created account + addr, // newly created account 0, 67_500_000, vec![], @@ -536,21 +528,19 @@ fn run_out_of_gas() { /// Input data for each call in set_rent code mod call { - pub fn set_storage_4_byte() -> Vec { vec![] } - pub fn remove_storage_4_byte() -> Vec { vec![0] } - pub fn transfer() -> Vec { vec![0, 0] } - pub fn null() -> Vec { vec![0, 0, 0] } + use super::{AccountIdOf, Test}; + pub fn set_storage_4_byte() -> Vec { 0u32.to_le_bytes().to_vec() } + pub fn remove_storage_4_byte() -> Vec { 1u32.to_le_bytes().to_vec() } + pub fn transfer(to: &AccountIdOf) -> Vec { + 2u32.to_le_bytes().iter().chain(AsRef::<[u8]>::as_ref(to)).cloned().collect() + } + pub fn null() -> Vec { 3u32.to_le_bytes().to_vec() } } /// Test correspondence of set_rent code and its hash. /// Also test that encoded extrinsic in code correspond to the correct transfer #[test] fn test_set_rent_code_and_hash() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - let (wasm, code_hash) = compile_module::("set_rent").unwrap(); ExtBuilder::default() @@ -565,12 +555,14 @@ fn test_set_rent_code_and_hash() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE)), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed( + ALICE, 1_000_000 + )), topics: vec![], }, EventRecord { @@ -599,9 +591,11 @@ fn storage_size() { 30_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); - let bob_contract = ContractInfoOf::::get(BOB) + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + let bob_contract = ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap(); @@ -620,12 +614,12 @@ fn storage_size() { assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT, call::set_storage_4_byte() )); - let bob_contract = ContractInfoOf::::get(BOB) + let bob_contract = ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap(); @@ -644,12 +638,12 @@ fn storage_size() { assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT, call::remove_storage_4_byte() )); - let bob_contract = ContractInfoOf::::get(BOB) + let bob_contract = ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap(); @@ -683,8 +677,10 @@ fn empty_kv_pairs() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); - let bob_contract = ContractInfoOf::::get(BOB) + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); + let bob_contract = ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap(); @@ -729,90 +725,98 @@ fn deduct_blocks() { Origin::signed(ALICE), 30_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000); // Advance 4 blocks initialize_block(5); // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + assert_ok!( + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()) + ); // Check result let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset * 4 // rent byte price * 4; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000 - rent); assert_eq!(bob_contract.deduct_block, 5); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent); + assert_eq!(Balances::free_balance(&addr), 30_000 - rent); // Advance 7 blocks more initialize_block(12); // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + assert_ok!( + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()) + ); // Check result let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset * 4 // rent byte price * 7; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + assert_eq!(Balances::free_balance(&addr), 30_000 - rent - rent_2); // Second call on same block should have no effect on rent - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + assert_ok!( + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()) + ); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + assert_eq!(Balances::free_balance(&addr), 30_000 - rent - rent_2); }); } #[test] fn call_contract_removals() { - removals(|| { + removals(|addr| { // Call on already-removed account might fail, and this is fine. - let _ = Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()); + let _ = Contracts::call(Origin::signed(ALICE), addr, 0, GAS_LIMIT, call::null()); true }); } #[test] fn inherent_claim_surcharge_contract_removals() { - removals(|| Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok()); + removals(|addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok()); } #[test] fn signed_claim_surcharge_contract_removals() { - removals(|| Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok()); + removals(|addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok()); } #[test] fn claim_surcharge_malus() { // Test surcharge malus for inherent - claim_surcharge(4, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(3, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(2, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(1, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), false); + claim_surcharge(4, |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), true); + claim_surcharge(3, |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), true); + claim_surcharge(2, |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), true); + claim_surcharge(1, |addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok(), false); // Test surcharge malus for signed - claim_surcharge(4, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), true); - claim_surcharge(3, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); - claim_surcharge(2, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); - claim_surcharge(1, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); + claim_surcharge(4, |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), true); + claim_surcharge(3, |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), false); + claim_surcharge(2, |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), false); + claim_surcharge(1, |addr| Contracts::claim_surcharge(Origin::signed(ALICE), addr, None).is_ok(), false); } /// Claim surcharge with the given trigger_call at the given blocks. /// If `removes` is true then assert that the contract is a tombstone. -fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { +fn claim_surcharge(blocks: u64, trigger_call: impl Fn(AccountIdOf) -> bool, removes: bool) { let (wasm, code_hash) = compile_module::("set_rent").unwrap(); ExtBuilder::default() @@ -826,19 +830,21 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Advance blocks initialize_block(blocks); // Trigger rent through call - assert!(trigger_call()); + assert!(trigger_call(addr.clone())); if removes { - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); } else { - assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); + assert!(ContractInfoOf::::get(&addr).unwrap().get_alive().is_some()); } }); } @@ -848,7 +854,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) /// * if allowance is exceeded /// * if balance is reached and balance < subsistence threshold /// * this case cannot be triggered by a contract: we check whether a tombstone is left -fn removals(trigger_call: impl Fn() -> bool) { +fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { let (wasm, code_hash) = compile_module::("set_rent").unwrap(); // Balance reached and superior to subsistence threshold @@ -863,31 +869,33 @@ fn removals(trigger_call: impl Fn() -> bool) { Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(BOB), 100); + assert!(trigger_call(addr.clone())); + assert_eq!(ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(&addr), 100); // Advance blocks initialize_block(10); // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + assert!(trigger_call(addr.clone())); + assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&addr), subsistence_threshold); // Advance blocks initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + assert!(trigger_call(addr.clone())); + assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(&addr), subsistence_threshold); }); // Allowance exceeded @@ -903,43 +911,45 @@ fn removals(trigger_call: impl Fn() -> bool) { 1_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance + ::Balance::from(100u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Trigger rent must have no effect - assert!(trigger_call()); + assert!(trigger_call(addr.clone())); assert_eq!( - ContractInfoOf::::get(BOB) + ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap() .rent_allowance, 100 ); - assert_eq!(Balances::free_balance(BOB), 1_000); + assert_eq!(Balances::free_balance(&addr), 1_000); // Advance blocks initialize_block(10); // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) + assert!(trigger_call(addr.clone())); + assert!(ContractInfoOf::::get(&addr) .unwrap() .get_tombstone() .is_some()); // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(BOB), 900); + assert_eq!(Balances::free_balance(&addr), 900); // Advance blocks initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB) + assert!(trigger_call(addr.clone())); + assert!(ContractInfoOf::::get(&addr) .unwrap() .get_tombstone() .is_some()); - assert_eq!(Balances::free_balance(BOB), 900); + assert_eq!(Balances::free_balance(&addr), 900); }); // Balance reached and inferior to subsistence threshold @@ -957,13 +967,15 @@ fn removals(trigger_call: impl Fn() -> bool) { 50 + subsistence_threshold, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Trigger rent must have no effect - assert!(trigger_call()); + assert!(trigger_call(addr.clone())); assert_eq!( - ContractInfoOf::::get(BOB) + ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap() @@ -971,43 +983,43 @@ fn removals(trigger_call: impl Fn() -> bool) { 1_000 ); assert_eq!( - Balances::free_balance(BOB), + Balances::free_balance(&addr), 50 + subsistence_threshold, ); // Transfer funds assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT, - call::transfer() + call::transfer(&BOB), )); assert_eq!( - ContractInfoOf::::get(BOB) + ContractInfoOf::::get(&addr) .unwrap() .get_alive() .unwrap() .rent_allowance, 1_000 ); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + assert_eq!(Balances::free_balance(&addr), subsistence_threshold); // Advance blocks initialize_block(10); // Trigger rent through call - assert!(trigger_call()); - assert_matches!(ContractInfoOf::::get(BOB), Some(ContractInfo::Tombstone(_))); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + assert!(trigger_call(addr.clone())); + assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Tombstone(_))); + assert_eq!(Balances::free_balance(&addr), subsistence_threshold); // Advance blocks initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call()); - assert_matches!(ContractInfoOf::::get(BOB), Some(ContractInfo::Tombstone(_))); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + assert!(trigger_call(addr.clone())); + assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Tombstone(_))); + assert_eq!(Balances::free_balance(&addr), subsistence_threshold); }); } @@ -1027,32 +1039,36 @@ fn call_removed_contract() { Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Calling contract should succeed. - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + assert_ok!( + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()) + ); // Advance blocks initialize_block(10); // Calling contract should remove contract and fail. assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()), Error::::NotCallable ); // Calling a contract that is about to evict shall emit an event. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), + event: MetaEvent::contracts(RawEvent::Evicted(addr.clone(), true)), topics: vec![], }, ]); // Subsequent contract calls should also fail. assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Contracts::call(Origin::signed(ALICE), addr, 0, GAS_LIMIT, call::null()), Error::::NotCallable ); }) @@ -1075,20 +1091,24 @@ fn default_rent_allowance_on_instantiate() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, >::max_value()); // Advance blocks initialize_block(5); // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + assert_ok!( + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()) + ); // Check contract is still alive - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive(); assert!(bob_contract.is_some()) }); } @@ -1130,12 +1150,12 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE)), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(ALICE, 1_000_000)), topics: vec![], }, EventRecord { @@ -1157,18 +1177,20 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, GAS_LIMIT, set_rent_code_hash.into(), - ::Balance::from(0u32).encode() + ::Balance::from(0u32).encode(), + vec![], )); + let addr_bob = Contracts::contract_address(&ALICE, &set_rent_code_hash, &[]); // Check if `BOB` was created successfully and that the rent allowance is // set to 0. - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr_bob).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 0); if test_different_storage { assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, 0, GAS_LIMIT, + addr_bob.clone(), 0, GAS_LIMIT, call::set_storage_4_byte()) ); } @@ -1179,15 +1201,17 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 // we expect that it will get removed leaving tombstone. assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Contracts::call( + Origin::signed(ALICE), addr_bob.clone(), 0, GAS_LIMIT, call::null() + ), Error::::NotCallable ); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_tombstone().is_some()); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, event: MetaEvent::contracts( - RawEvent::Evicted(BOB.clone(), true) + RawEvent::Evicted(addr_bob.clone(), true) ), topics: vec![], }, @@ -1203,13 +1227,16 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, GAS_LIMIT, restoration_code_hash.into(), - ::Balance::from(0u32).encode() + ::Balance::from(0u32).encode(), + vec![], )); + let addr_django = Contracts::contract_address(&CHARLIE, &restoration_code_hash, &[]); // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() + let django_trie_id = ContractInfoOf::::get(&addr_django).unwrap() .get_alive().unwrap().trie_id; + // The trie is regarded as 'dirty' when it was written to in the current block. if !test_restore_to_with_dirty_storage { // Advance 1 block, to the 6th. initialize_block(6); @@ -1220,37 +1247,43 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: let perform_the_restoration = || { Contracts::call( Origin::signed(ALICE), - DJANGO, + addr_django.clone(), 0, GAS_LIMIT, - set_rent_code_hash.as_ref().to_vec(), + set_rent_code_hash + .as_ref() + .iter() + .chain(AsRef::<[u8]>::as_ref(&addr_bob)) + .cloned() + .collect(), ) }; if test_different_storage || test_restore_to_with_dirty_storage { // Parametrization of the test imply restoration failure. Check that `DJANGO` aka // restoration contract is still in place and also that `BOB` doesn't exist. - - assert_err_ignore_postinfo!( - perform_the_restoration(), - Error::::ContractTrapped, - ); - - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - let django_contract = ContractInfoOf::::get(DJANGO).unwrap() + let result = perform_the_restoration(); + assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_tombstone().is_some()); + let django_contract = ContractInfoOf::::get(&addr_django).unwrap() .get_alive().unwrap(); assert_eq!(django_contract.storage_size, 8); assert_eq!(django_contract.trie_id, django_trie_id); assert_eq!(django_contract.deduct_block, System::block_number()); match (test_different_storage, test_restore_to_with_dirty_storage) { (true, false) => { + assert_err_ignore_postinfo!( + result, Error::::InvalidTombstone, + ); assert_eq!(System::events(), vec![]); } (_, true) => { + assert_err_ignore_postinfo!( + result, Error::::InvalidContractOrigin, + ); pretty_assertions::assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), + event: MetaEvent::contracts(RawEvent::Evicted(addr_bob, true)), topics: vec![], }, EventRecord { @@ -1265,24 +1298,24 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(DJANGO)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(addr_django.clone())), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(DJANGO, 30_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(addr_django.clone(), 30_000)), topics: vec![], }, EventRecord { phase: Phase::Initialization, event: MetaEvent::balances( - pallet_balances::RawEvent::Transfer(CHARLIE, DJANGO, 30_000) + pallet_balances::RawEvent::Transfer(CHARLIE, addr_django.clone(), 30_000) ), topics: vec![], }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, DJANGO)), + event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, addr_django.clone())), topics: vec![], }, ]); @@ -1294,24 +1327,24 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Here we expect that the restoration is succeeded. Check that the restoration // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(BOB)); - let bob_contract = ContractInfoOf::::get(BOB).unwrap() + println!("{:?}", ContractInfoOf::::get(&addr_bob)); + let bob_contract = ContractInfoOf::::get(&addr_bob).unwrap() .get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 50); assert_eq!(bob_contract.storage_size, 4); assert_eq!(bob_contract.trie_id, django_trie_id); assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(DJANGO).is_none()); + assert!(ContractInfoOf::::get(&addr_django).is_none()); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(system::RawEvent::KilledAccount(DJANGO)), + event: MetaEvent::system(system::RawEvent::KilledAccount(addr_django.clone())), topics: vec![], }, EventRecord { phase: Phase::Initialization, event: MetaEvent::contracts( - RawEvent::Restored(DJANGO, BOB, bob_contract.code_hash, 50) + RawEvent::Restored(addr_django, addr_bob, bob_contract.code_hash, 50) ), topics: vec![], }, @@ -1337,16 +1370,18 @@ fn storage_max_value_limit() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + let bob_contract = ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, >::max_value()); // Call contract with allowed storage value. assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer ::MaxValueSize::get().encode(), @@ -1356,7 +1391,7 @@ fn storage_max_value_limit() { assert_err_ignore_postinfo!( Contracts::call( Origin::signed(ALICE), - BOB, + addr, 0, GAS_LIMIT, (::MaxValueSize::get() + 1).encode(), @@ -1386,13 +1421,15 @@ fn deploy_and_call_other_contract() { GAS_LIMIT, caller_code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &caller_code_hash, &[]); // Call BOB contract, which attempts to instantiate and call the callee contract and // makes various assertions on the results from those calls. assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr, 0, GAS_LIMIT, callee_code_hash.as_ref().to_vec(), @@ -1417,11 +1454,13 @@ fn cannot_self_destruct_through_draning() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. assert_matches!( - ContractInfoOf::::get(BOB), + ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_)) ); @@ -1430,7 +1469,7 @@ fn cannot_self_destruct_through_draning() { assert_ok!( Contracts::call( Origin::signed(ALICE), - BOB, + addr, 0, GAS_LIMIT, vec![], @@ -1456,11 +1495,13 @@ fn cannot_self_destruct_while_live() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. assert_matches!( - ContractInfoOf::::get(BOB), + ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_)) ); @@ -1469,7 +1510,7 @@ fn cannot_self_destruct_while_live() { assert_err_ignore_postinfo!( Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT, vec![0], @@ -1479,7 +1520,7 @@ fn cannot_self_destruct_while_live() { // Check that BOB is still alive. assert_matches!( - ContractInfoOf::::get(BOB), + ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_)) ); }); @@ -1502,11 +1543,13 @@ fn self_destruct_works() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Check that the BOB contract has been instantiated. assert_matches!( - ContractInfoOf::::get(BOB), + ContractInfoOf::::get(&addr), Some(ContractInfo::Alive(_)) ); @@ -1514,7 +1557,7 @@ fn self_destruct_works() { assert_matches!( Contracts::call( Origin::signed(ALICE), - BOB, + addr.clone(), 0, GAS_LIMIT, vec![], @@ -1523,7 +1566,7 @@ fn self_destruct_works() { ); // Check that account is gone - assert!(ContractInfoOf::::get(BOB).is_none()); + assert!(ContractInfoOf::::get(&addr).is_none()); // check that the beneficiary (django) got remaining balance assert_eq!(Balances::free_balance(DJANGO), 100_000); @@ -1554,25 +1597,30 @@ fn destroy_contract_and_transfer_funds() { GAS_LIMIT, caller_code_hash.into(), callee_code_hash.as_ref().to_vec(), + vec![], )); + let addr_bob = Contracts::contract_address(&ALICE, &caller_code_hash, &[]); + let addr_charlie = Contracts::contract_address( + &addr_bob, &callee_code_hash, &[0x47, 0x11] + ); // Check that the CHARLIE contract has been instantiated. assert_matches!( - ContractInfoOf::::get(CHARLIE), + ContractInfoOf::::get(&addr_charlie), Some(ContractInfo::Alive(_)) ); // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. assert_ok!(Contracts::call( Origin::signed(ALICE), - BOB, + addr_bob, 0, GAS_LIMIT, - CHARLIE.encode(), + addr_charlie.encode(), )); // Check that CHARLIE has moved on to the great beyond (ie. died). - assert!(ContractInfoOf::::get(CHARLIE).is_none()); + assert!(ContractInfoOf::::get(&addr_charlie).is_none()); }); } @@ -1594,6 +1642,7 @@ fn cannot_self_destruct_in_constructor() { GAS_LIMIT, code_hash.into(), vec![], + vec![], ), Error::::NewContractNotFunded, ); @@ -1618,7 +1667,9 @@ fn crypto_hashes() { GAS_LIMIT, code_hash.into(), vec![], + vec![], )); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Perform the call. let input = b"_DEAD_BEEF"; use sp_io::hashing::*; @@ -1642,7 +1693,7 @@ fn crypto_hashes() { params.extend_from_slice(input); let result = >::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, params, @@ -1669,13 +1720,15 @@ fn transfer_return_code() { GAS_LIMIT, code_hash.into(), vec![], + vec![], ), ); + let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Contract has only the minimal balance so any transfer will return BelowSubsistence. let result = Contracts::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, vec![], @@ -1685,11 +1738,11 @@ fn transfer_return_code() { // Contract has enough total balance in order to not go below the subsistence // threshold when transfering 100 balance but this balance is reserved so // the transfer still fails but with another return code. - Balances::make_free_balance_be(&BOB, subsistence + 100); - Balances::reserve(&BOB, subsistence + 100).unwrap(); + Balances::make_free_balance_be(&addr, subsistence + 100); + Balances::reserve(&addr, subsistence + 100).unwrap(); let result = Contracts::bare_call( ALICE, - BOB, + addr, 0, GAS_LIMIT, vec![], @@ -1716,16 +1769,18 @@ fn call_return_code() { GAS_LIMIT, caller_hash.into(), vec![0], + vec![], ), ); + let addr_bob = Contracts::contract_address(&ALICE, &caller_hash, &[]); // Contract calls into Django which is no valid contract let result = Contracts::bare_call( ALICE, - BOB, + addr_bob.clone(), 0, GAS_LIMIT, - vec![0], + AsRef::<[u8]>::as_ref(&DJANGO).to_vec(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::NotCallable); @@ -1736,51 +1791,53 @@ fn call_return_code() { GAS_LIMIT, callee_hash.into(), vec![0], + vec![], ), ); + let addr_django = Contracts::contract_address(&CHARLIE, &callee_hash, &[]); // Contract has only the minimal balance so any transfer will return BelowSubsistence. let result = Contracts::bare_call( ALICE, - BOB, + addr_bob.clone(), 0, GAS_LIMIT, - vec![0], + AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); // Contract has enough total balance in order to not go below the subsistence // threshold when transfering 100 balance but this balance is reserved so // the transfer still fails but with another return code. - Balances::make_free_balance_be(&BOB, subsistence + 100); - Balances::reserve(&BOB, subsistence + 100).unwrap(); + Balances::make_free_balance_be(&addr_bob, subsistence + 100); + Balances::reserve(&addr_bob, subsistence + 100).unwrap(); let result = Contracts::bare_call( ALICE, - BOB, + addr_bob.clone(), 0, GAS_LIMIT, - vec![0], + AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&0u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::TransferFailed); // Contract has enough balance but callee reverts because "1" is passed. - Balances::make_free_balance_be(&BOB, subsistence + 1000); + Balances::make_free_balance_be(&addr_bob, subsistence + 1000); let result = Contracts::bare_call( ALICE, - BOB, + addr_bob.clone(), 0, GAS_LIMIT, - vec![1], + AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&1u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeReverted); // Contract has enough balance but callee traps because "2" is passed. let result = Contracts::bare_call( ALICE, - BOB, + addr_bob, 0, GAS_LIMIT, - vec![2], + AsRef::<[u8]>::as_ref(&addr_django).iter().chain(&2u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); @@ -1806,13 +1863,15 @@ fn instantiate_return_code() { GAS_LIMIT, caller_hash.into(), vec![], + vec![], ), ); + let addr = Contracts::contract_address(&ALICE, &caller_hash, &[]); // Contract has only the minimal balance so any transfer will return BelowSubsistence. let result = Contracts::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, vec![0; 33], @@ -1822,11 +1881,11 @@ fn instantiate_return_code() { // Contract has enough total balance in order to not go below the subsistence // threshold when transfering 100 balance but this balance is reserved so // the transfer still fails but with another return code. - Balances::make_free_balance_be(&BOB, subsistence + 100); - Balances::reserve(&BOB, subsistence + 100).unwrap(); + Balances::make_free_balance_be(&addr, subsistence + 100); + Balances::reserve(&addr, subsistence + 100).unwrap(); let result = Contracts::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, vec![0; 33], @@ -1834,10 +1893,10 @@ fn instantiate_return_code() { assert_return_code!(result, RuntimeReturnCode::TransferFailed); // Contract has enough balance but the passed code hash is invalid - Balances::make_free_balance_be(&BOB, subsistence + 1000); + Balances::make_free_balance_be(&addr, subsistence + 1000); let result = Contracts::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, vec![0; 33], @@ -1847,20 +1906,20 @@ fn instantiate_return_code() { // Contract has enough balance but callee reverts because "1" is passed. let result = Contracts::bare_call( ALICE, - BOB, + addr.clone(), 0, GAS_LIMIT, - callee_hash.iter().cloned().chain(sp_std::iter::once(1)).collect(), + callee_hash.iter().chain(&1u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeReverted); // Contract has enough balance but callee traps because "2" is passed. let result = Contracts::bare_call( ALICE, - BOB, + addr, 0, GAS_LIMIT, - callee_hash.iter().cloned().chain(sp_std::iter::once(2)).collect(), + callee_hash.iter().chain(&2u32.to_le_bytes()).cloned().collect(), ).exec_result.unwrap(); assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index 34b8ea74435..a64f387097e 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -30,6 +30,7 @@ use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; use sp_std::prelude::*; use sp_runtime::traits::Hash; +use sp_core::crypto::UncheckedFrom; use frame_support::StorageMap; /// Put code in the storage. The hash of code is used as a key and is returned @@ -39,7 +40,7 @@ use frame_support::StorageMap; pub fn save( original_code: Vec, schedule: &Schedule, -) -> Result, &'static str> { +) -> Result, &'static str> where T::AccountId: UncheckedFrom + AsRef<[u8]> { let prefab_module = prepare::prepare_contract::(&original_code, schedule)?; let code_hash = T::Hashing::hash(&original_code); @@ -57,7 +58,7 @@ pub fn save( pub fn save_raw( original_code: Vec, schedule: &Schedule, -) -> Result, &'static str> { +) -> Result, &'static str> where T::AccountId: UncheckedFrom + AsRef<[u8]> { let prefab_module = prepare::benchmarking::prepare_contract::(&original_code, schedule)?; let code_hash = T::Hashing::hash(&original_code); @@ -75,7 +76,7 @@ pub fn save_raw( pub fn load( code_hash: &CodeHash, schedule: &Schedule, -) -> Result { +) -> Result where T::AccountId: UncheckedFrom + AsRef<[u8]> { let mut prefab_module = >::get(code_hash).ok_or_else(|| "code is not found")?; diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index 2538f85fb73..6741896102d 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -127,7 +127,12 @@ macro_rules! define_func { fn $name< E: $seal_ty >( $ctx: &mut $crate::wasm::Runtime, args: &[sp_sandbox::Value], - ) -> Result { + ) -> Result + where + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + + AsRef<[u8]> + { #[allow(unused)] let mut args = args.iter(); @@ -183,7 +188,12 @@ macro_rules! define_env { } } - impl $crate::wasm::env_def::FunctionImplProvider for $init_name { + impl $crate::wasm::env_def::FunctionImplProvider for $init_name + where + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + + AsRef<[u8]> + { fn impls)>(f: &mut F) { register_func!(f, < E: $seal_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* ); } diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index f90f3af688d..baa75ad4972 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -23,6 +23,7 @@ use crate::exec::Ext; use crate::gas::GasMeter; use sp_std::prelude::*; +use sp_core::crypto::UncheckedFrom; use codec::{Encode, Decode}; use sp_sandbox; @@ -32,7 +33,7 @@ mod code_cache; mod prepare; mod runtime; -use self::runtime::{to_execution_result, Runtime}; +use self::runtime::Runtime; use self::code_cache::load as load_code; use pallet_contracts_primitives::ExecResult; @@ -71,13 +72,16 @@ pub struct WasmLoader<'a, T: Trait> { schedule: &'a Schedule, } -impl<'a, T: Trait> WasmLoader<'a, T> { +impl<'a, T: Trait> WasmLoader<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { pub fn new(schedule: &'a Schedule) -> Self { WasmLoader { schedule } } } -impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> { +impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> +where + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ type Executable = WasmExecutable; fn load_init(&self, code_hash: &CodeHash) -> Result { @@ -97,17 +101,20 @@ impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> { } /// Implementation of `Vm` that takes `WasmExecutable` and executes it. -pub struct WasmVm<'a, T: Trait> { +pub struct WasmVm<'a, T: Trait> where T::AccountId: UncheckedFrom + AsRef<[u8]> { schedule: &'a Schedule, } -impl<'a, T: Trait> WasmVm<'a, T> { +impl<'a, T: Trait> WasmVm<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { pub fn new(schedule: &'a Schedule) -> Self { WasmVm { schedule } } } -impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a, T> { +impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a, T> +where + T::AccountId: UncheckedFrom + AsRef<[u8]> +{ type Executable = WasmExecutable; fn execute>( @@ -147,20 +154,22 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a, T> { // entrypoint. let result = sp_sandbox::Instance::new(&exec.prefab_module.code, &imports, &mut runtime) .and_then(|mut instance| instance.invoke(exec.entrypoint_name, &[], &mut runtime)); - to_execution_result(runtime, result) + runtime.to_execution_result(result) } } #[cfg(test)] mod tests { use super::*; + use crate::{ + CodeHash, BalanceOf, Error, Module as Contracts, + exec::{Ext, StorageKey, AccountIdOf}, + gas::{Gas, GasMeter}, + tests::{Test, Call, ALICE, BOB}, + wasm::prepare::prepare_contract, + }; use std::collections::HashMap; use sp_core::H256; - use crate::exec::{Ext, StorageKey}; - use crate::gas::{Gas, GasMeter}; - use crate::tests::{Test, Call}; - use crate::wasm::prepare::prepare_contract; - use crate::{CodeHash, BalanceOf, Error}; use hex_literal::hex; use sp_runtime::DispatchError; use frame_support::weights::Weight; @@ -174,7 +183,7 @@ mod tests { #[derive(Debug, PartialEq, Eq)] struct RestoreEntry { - dest: u64, + dest: AccountIdOf, code_hash: H256, rent_allowance: u64, delta: Vec, @@ -186,16 +195,17 @@ mod tests { endowment: u64, data: Vec, gas_left: u64, + salt: Vec, } #[derive(Debug, PartialEq, Eq)] struct TerminationEntry { - beneficiary: u64, + beneficiary: AccountIdOf, } #[derive(Debug, PartialEq, Eq)] struct TransferEntry { - to: u64, + to: AccountIdOf, value: u64, data: Vec, } @@ -210,7 +220,6 @@ mod tests { restores: Vec, // (topics, data) events: Vec<(Vec, Vec)>, - next_account_id: u64, } impl Ext for MockExt { @@ -228,18 +237,17 @@ mod tests { endowment: u64, gas_meter: &mut GasMeter, data: Vec, - ) -> Result<(u64, ExecReturnValue), ExecError> { + salt: &[u8], + ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { self.instantiates.push(InstantiateEntry { code_hash: code_hash.clone(), endowment, data: data.to_vec(), gas_left: gas_meter.gas_left(), + salt: salt.to_vec(), }); - let address = self.next_account_id; - self.next_account_id += 1; - Ok(( - address, + Contracts::::contract_address(&ALICE, code_hash, salt), ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new(), @@ -248,11 +256,11 @@ mod tests { } fn transfer( &mut self, - to: &u64, + to: &AccountIdOf, value: u64, ) -> Result<(), DispatchError> { self.transfers.push(TransferEntry { - to: *to, + to: to.clone(), value, data: Vec::new(), }); @@ -260,13 +268,13 @@ mod tests { } fn call( &mut self, - to: &u64, + to: &AccountIdOf, value: u64, _gas_meter: &mut GasMeter, data: Vec, ) -> ExecResult { self.transfers.push(TransferEntry { - to: *to, + to: to.clone(), value, data: data, }); @@ -276,20 +284,20 @@ mod tests { } fn terminate( &mut self, - beneficiary: &u64, + beneficiary: &AccountIdOf, ) -> Result<(), DispatchError> { self.terminations.push(TerminationEntry { - beneficiary: *beneficiary, + beneficiary: beneficiary.clone(), }); Ok(()) } fn restore_to( &mut self, - dest: u64, + dest: AccountIdOf, code_hash: H256, rent_allowance: u64, delta: Vec, - ) -> Result<(), &'static str> { + ) -> Result<(), DispatchError> { self.restores.push(RestoreEntry { dest, code_hash, @@ -298,11 +306,11 @@ mod tests { }); Ok(()) } - fn caller(&self) -> &u64 { - &42 + fn caller(&self) -> &AccountIdOf { + &ALICE } - fn address(&self) -> &u64 { - &69 + fn address(&self) -> &AccountIdOf { + &BOB } fn balance(&self) -> u64 { 228 @@ -363,25 +371,26 @@ mod tests { value: u64, gas_meter: &mut GasMeter, input_data: Vec, - ) -> Result<(u64, ExecReturnValue), ExecError> { - (**self).instantiate(code, value, gas_meter, input_data) + salt: &[u8], + ) -> Result<(AccountIdOf, ExecReturnValue), ExecError> { + (**self).instantiate(code, value, gas_meter, input_data, salt) } fn transfer( &mut self, - to: &u64, + to: &AccountIdOf, value: u64, ) -> Result<(), DispatchError> { (**self).transfer(to, value) } fn terminate( &mut self, - beneficiary: &u64, + beneficiary: &AccountIdOf, ) -> Result<(), DispatchError> { (**self).terminate(beneficiary) } fn call( &mut self, - to: &u64, + to: &AccountIdOf, value: u64, gas_meter: &mut GasMeter, input_data: Vec, @@ -390,11 +399,11 @@ mod tests { } fn restore_to( &mut self, - dest: u64, + dest: AccountIdOf, code_hash: H256, rent_allowance: u64, delta: Vec, - ) -> Result<(), &'static str> { + ) -> Result<(), DispatchError> { (**self).restore_to( dest, code_hash, @@ -402,10 +411,10 @@ mod tests { delta, ) } - fn caller(&self) -> &u64 { + fn caller(&self) -> &AccountIdOf { (**self).caller() } - fn address(&self) -> &u64 { + fn address(&self) -> &AccountIdOf { (**self).address() } fn balance(&self) -> u64 { @@ -451,7 +460,11 @@ mod tests { input_data: Vec, ext: E, gas_meter: &mut GasMeter, - ) -> ExecResult { + ) -> ExecResult + where + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> + { use crate::exec::Vm; let wasm = wat::parse_str(wat).unwrap(); @@ -485,21 +498,23 @@ mod tests { (drop (call $seal_transfer (i32.const 4) ;; Pointer to "account" address. - (i32.const 8) ;; Length of "account" address. - (i32.const 12) ;; Pointer to the buffer with value to transfer + (i32.const 32) ;; Length of "account" address. + (i32.const 36) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. ) ) ) (func (export "deploy")) - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\07\00\00\00\00\00\00\00") + ;; Destination AccountId (ALICE) + (data (i32.const 4) + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + ) ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\99\00\00\00\00\00\00\00") + (data (i32.const 36) "\99\00\00\00\00\00\00\00") ) "#; @@ -516,7 +531,7 @@ mod tests { assert_eq!( &mock_ext.transfers, &[TransferEntry { - to: 7, + to: ALICE, value: 153, data: Vec::new(), }] @@ -542,11 +557,11 @@ mod tests { (drop (call $seal_call (i32.const 4) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 12) ;; Pointer to the buffer with value to transfer + (i32.const 36) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 20) ;; Pointer to input data buffer address + (i32.const 44) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case @@ -555,14 +570,17 @@ mod tests { ) (func (export "deploy")) - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") + ;; Destination AccountId (ALICE) + (data (i32.const 4) + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + ) + ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") + (data (i32.const 36) "\06\00\00\00\00\00\00\00") - (data (i32.const 20) "\01\02\03\04") + (data (i32.const 44) "\01\02\03\04") ) "#; @@ -579,7 +597,7 @@ mod tests { assert_eq!( &mock_ext.transfers, &[TransferEntry { - to: 9, + to: ALICE, value: 6, data: vec![1, 2, 3, 4], }] @@ -602,7 +620,9 @@ mod tests { ;; output_ptr: u32, ;; output_len_ptr: u32 ;; ) -> u32 - (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate + (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) + )) (import "env" "memory" (memory 1 1)) (func (export "call") (drop @@ -618,11 +638,15 @@ mod tests { (i32.const 0) ;; Length is ignored in this case (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this case + (i32.const 0) ;; salt_ptr + (i32.const 4) ;; salt_len ) ) ) (func (export "deploy")) + ;; Salt + (data (i32.const 0) "\42\43\44\45") ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. (data (i32.const 4) "\03\00\00\00\00\00\00\00") @@ -653,7 +677,11 @@ mod tests { endowment: 3, data, gas_left: _, - }] if code_hash == &[0x11; 32].into() && data == &vec![1, 2, 3, 4] + salt, + }] if + code_hash == &[0x11; 32].into() && + data == &vec![1, 2, 3, 4] && + salt == &vec![0x42, 0x43, 0x44, 0x45] ); } @@ -668,14 +696,16 @@ mod tests { (func (export "call") (call $seal_terminate (i32.const 4) ;; Pointer to "beneficiary" address. - (i32.const 8) ;; Length of "beneficiary" address. + (i32.const 32) ;; Length of "beneficiary" address. ) ) (func (export "deploy")) ;; Beneficiary AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") + (data (i32.const 4) + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + ) ) "#; @@ -692,7 +722,7 @@ mod tests { assert_eq!( &mock_ext.terminations, &[TerminationEntry { - beneficiary: 0x09, + beneficiary: ALICE, }] ); } @@ -716,11 +746,11 @@ mod tests { (drop (call $seal_call (i32.const 4) ;; Pointer to "callee" address. - (i32.const 8) ;; Length of "callee" address. + (i32.const 32) ;; Length of "callee" address. (i64.const 228) ;; How much gas to devote for the execution. - (i32.const 12) ;; Pointer to the buffer with value to transfer + (i32.const 36) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 20) ;; Pointer to input data buffer address + (i32.const 44) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output (i32.const 0) ;; Length is ignored in this cas @@ -730,13 +760,15 @@ mod tests { (func (export "deploy")) ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") + (data (i32.const 4) + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" + ) ;; Amount of value to transfer. ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") + (data (i32.const 36) "\06\00\00\00\00\00\00\00") - (data (i32.const 20) "\01\02\03\04") + (data (i32.const 44) "\01\02\03\04") ) "#; @@ -753,7 +785,7 @@ mod tests { assert_eq!( &mock_ext.transfers, &[TransferEntry { - to: 9, + to: ALICE, value: 6, data: vec![1, 2, 3, 4], }] @@ -863,19 +895,19 @@ mod tests { ;; fill the buffer with the caller. (call $seal_caller (i32.const 0) (i32.const 32)) - ;; assert len == 8 + ;; assert len == 32 (call $assert (i32.eq (i32.load (i32.const 32)) - (i32.const 8) + (i32.const 32) ) ) - ;; assert that contents of the buffer is equal to the i64 value of 42. + ;; assert that the first 64 byte are the beginning of "ALICE" (call $assert (i64.eq (i64.load (i32.const 0)) - (i64.const 42) + (i64.const 0x0101010101010101) ) ) ) @@ -916,19 +948,19 @@ mod tests { ;; fill the buffer with the self address. (call $seal_address (i32.const 0) (i32.const 32)) - ;; assert size == 8 + ;; assert size == 32 (call $assert (i32.eq (i32.load (i32.const 32)) - (i32.const 8) + (i32.const 32) ) ) - ;; assert that contents of the buffer is equal to the i64 value of 69. + ;; assert that the first 64 byte are the beginning of "BOB" (call $assert (i64.eq (i64.load (i32.const 0)) - (i64.const 69) + (i64.const 0x0202020202020202) ) ) ) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index c7de93ece70..90ea86f9cec 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -29,6 +29,7 @@ use frame_support::dispatch::DispatchError; use sp_std::prelude::*; use codec::{Decode, Encode}; use sp_runtime::traits::SaturatedConversion; +use sp_core::crypto::UncheckedFrom; use sp_io::hashing::{ keccak_256, blake2_256, @@ -116,92 +117,6 @@ enum TrapReason { Restoration, } -/// Can only be used for one call. -pub(crate) struct Runtime<'a, E: Ext + 'a> { - ext: &'a mut E, - input_data: Option>, - schedule: &'a Schedule, - memory: sp_sandbox::Memory, - gas_meter: &'a mut GasMeter, - trap_reason: Option, -} -impl<'a, E: Ext + 'a> Runtime<'a, E> { - pub(crate) fn new( - ext: &'a mut E, - input_data: Vec, - schedule: &'a Schedule, - memory: sp_sandbox::Memory, - gas_meter: &'a mut GasMeter, - ) -> Self { - Runtime { - ext, - input_data: Some(input_data), - schedule, - memory, - gas_meter, - trap_reason: None, - } - } -} - -/// Converts the sandbox result and the runtime state into the execution outcome. -/// -/// It evaluates information stored in the `trap_reason` variable of the runtime and -/// bases the outcome on the value if this variable. Only if `trap_reason` is `None` -/// the result of the sandbox is evaluated. -pub(crate) fn to_execution_result( - runtime: Runtime, - sandbox_result: Result, -) -> ExecResult { - // If a trap reason is set we base our decision solely on that. - if let Some(trap_reason) = runtime.trap_reason { - return match trap_reason { - // The trap was the result of the execution `return` host function. - TrapReason::Return(ReturnData{ flags, data }) => { - let flags = ReturnFlags::from_bits(flags).ok_or_else(|| - "used reserved bit in return flags" - )?; - Ok(ExecReturnValue { - flags, - data, - }) - }, - TrapReason::Termination => { - Ok(ExecReturnValue { - flags: ReturnFlags::empty(), - data: Vec::new(), - }) - }, - TrapReason::Restoration => { - Ok(ExecReturnValue { - flags: ReturnFlags::empty(), - data: Vec::new(), - }) - }, - TrapReason::SupervisorError(error) => Err(error)?, - } - } - - // Check the exact type of the error. - match sandbox_result { - // No traps were generated. Proceed normally. - Ok(_) => { - Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) - } - // `Error::Module` is returned only if instantiation or linking failed (i.e. - // wasm binary tried to import a function that is not provided by the host). - // This shouldn't happen because validation process ought to reject such binaries. - // - // Because panics are really undesirable in the runtime code, we treat this as - // a trap for now. Eventually, we might want to revisit this. - Err(sp_sandbox::Error::Module) => - Err("validation error")?, - // Any other kind of a trap should result in a failure. - Err(sp_sandbox::Error::Execution) | Err(sp_sandbox::Error::OutOfBounds) => - Err(Error::::ContractTrapped)? - } -} - #[cfg_attr(test, derive(Debug, PartialEq, Eq))] #[derive(Copy, Clone)] pub enum RuntimeToken { @@ -262,10 +177,10 @@ pub enum RuntimeToken { CallSurchargeTransfer, /// Weight of output received through `seal_call` for the given size. CallCopyOut(u32), - /// Weight of calling `seal_instantiate` for the given input size without output weight. + /// Weight of calling `seal_instantiate` for the given input and salt without output weight. /// This includes the transfer as an instantiate without a value will always be below /// the existential deposit and is disregarded as corner case. - InstantiateBase(u32), + InstantiateBase{input_data_len: u32, salt_len: u32}, /// Weight of output received through `seal_instantiate` for the given size. InstantiateCopyOut(u32), /// Weight of calling `seal_hash_sha_256` for the given input size. @@ -278,7 +193,10 @@ pub enum RuntimeToken { HashBlake128(u32), } -impl Token for RuntimeToken { +impl Token for RuntimeToken +where + T::AccountId: UncheckedFrom, T::AccountId: AsRef<[u8]> +{ type Metadata = HostFnWeights; fn calculate_amount(&self, s: &Self::Metadata) -> Gas { @@ -318,8 +236,9 @@ impl Token for RuntimeToken { .saturating_add(s.call_per_input_byte.saturating_mul(len.into())), CallSurchargeTransfer => s.call_transfer_surcharge, CallCopyOut(len) => s.call_per_output_byte.saturating_mul(len.into()), - InstantiateBase(len) => s.instantiate - .saturating_add(s.instantiate_per_input_byte.saturating_mul(len.into())), + InstantiateBase{input_data_len, salt_len} => s.instantiate + .saturating_add(s.instantiate_per_input_byte.saturating_mul(input_data_len.into())) + .saturating_add(s.instantiate_per_salt_byte.saturating_mul(salt_len.into())), InstantiateCopyOut(len) => s.instantiate_per_output_byte .saturating_mul(len.into()), HashSha256(len) => s.hash_sha2_256 @@ -334,215 +253,345 @@ impl Token for RuntimeToken { } } -/// Charge the gas meter with the specified token. -/// -/// Returns `Err(HostError)` if there is not enough gas. -fn charge_gas(ctx: &mut Runtime, token: Tok) -> Result<(), sp_sandbox::HostError> -where - E: Ext, - Tok: Token>, -{ - match ctx.gas_meter.charge(&ctx.schedule.host_fn_weights, token) { - GasMeterResult::Proceed => Ok(()), - GasMeterResult::OutOfGas => { - ctx.trap_reason = Some(TrapReason::SupervisorError(Error::::OutOfGas.into())); - Err(sp_sandbox::HostError) - }, - } +/// This is only appropriate when writing out data of constant size that does not depend on user +/// input. In this case the costs for this copy was already charged as part of the token at +/// the beginning of the API entry point. +fn already_charged(_: u32) -> Option { + None } -/// Read designated chunk from the sandbox memory. -/// -/// Returns `Err` if one of the following conditions occurs: +/// Finds duplicates in a given vector. /// -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result, sp_sandbox::HostError> { - let mut buf = vec![0u8; len as usize]; - ctx.memory.get(ptr, buf.as_mut_slice()) - .map_err(|_| store_err(ctx, Error::::OutOfBounds))?; - Ok(buf) +/// This function has complexity of O(n log n) and no additional memory is required, although +/// the order of items is not preserved. +fn has_duplicates>(items: &mut Vec) -> bool { + // Sort the vector + items.sort_by(|a, b| { + Ord::cmp(a.as_ref(), b.as_ref()) + }); + // And then find any two consecutive equal elements. + items.windows(2).any(|w| { + match w { + &[ref a, ref b] => a == b, + _ => false, + } + }) } -/// Read designated chunk from the sandbox memory into the supplied buffer. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory_into_buf( - ctx: &mut Runtime, - ptr: u32, - buf: &mut [u8], -) -> Result<(), sp_sandbox::HostError> { - ctx.memory.get(ptr, buf).map_err(|_| store_err(ctx, Error::::OutOfBounds)) +/// Can only be used for one call. +pub struct Runtime<'a, E: Ext + 'a> { + ext: &'a mut E, + input_data: Option>, + schedule: &'a Schedule, + memory: sp_sandbox::Memory, + gas_meter: &'a mut GasMeter, + trap_reason: Option, } -/// Read designated chunk from the sandbox memory and attempt to decode into the specified type. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - requested buffer is not within the bounds of the sandbox memory. -/// - the buffer contents cannot be decoded as the required type. -fn read_sandbox_memory_as( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result { - let buf = read_sandbox_memory(ctx, ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| store_err(ctx, Error::::DecodingFailed)) -} +impl<'a, E> Runtime<'a, E> +where + E: Ext + 'a, + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> +{ + pub fn new( + ext: &'a mut E, + input_data: Vec, + schedule: &'a Schedule, + memory: sp_sandbox::Memory, + gas_meter: &'a mut GasMeter, + ) -> Self { + Runtime { + ext, + input_data: Some(input_data), + schedule, + memory, + gas_meter, + trap_reason: None, + } + } -/// Write the given buffer to the designated location in the sandbox memory. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - designated area is not within the bounds of the sandbox memory. -fn write_sandbox_memory( - ctx: &mut Runtime, - ptr: u32, - buf: &[u8], -) -> Result<(), sp_sandbox::HostError> { - ctx.memory.set(ptr, buf).map_err(|_| store_err(ctx, Error::::OutOfBounds)) -} + /// Converts the sandbox result and the runtime state into the execution outcome. + /// + /// It evaluates information stored in the `trap_reason` variable of the runtime and + /// bases the outcome on the value if this variable. Only if `trap_reason` is `None` + /// the result of the sandbox is evaluated. + pub fn to_execution_result( + self, + sandbox_result: Result, + ) -> ExecResult { + // If a trap reason is set we base our decision solely on that. + if let Some(trap_reason) = self.trap_reason { + return match trap_reason { + // The trap was the result of the execution `return` host function. + TrapReason::Return(ReturnData{ flags, data }) => { + let flags = ReturnFlags::from_bits(flags).ok_or_else(|| + "used reserved bit in return flags" + )?; + Ok(ExecReturnValue { + flags, + data, + }) + }, + TrapReason::Termination => { + Ok(ExecReturnValue { + flags: ReturnFlags::empty(), + data: Vec::new(), + }) + }, + TrapReason::Restoration => { + Ok(ExecReturnValue { + flags: ReturnFlags::empty(), + data: Vec::new(), + }) + }, + TrapReason::SupervisorError(error) => Err(error)?, + } + } -/// Write the given buffer and its length to the designated locations in sandbox memory and -/// charge gas according to the token returned by `create_token`. -// -/// `out_ptr` is the location in sandbox memory where `buf` should be written to. -/// `out_len_ptr` is an in-out location in sandbox memory. It is read to determine the -/// length of the buffer located at `out_ptr`. If that buffer is large enough the actual -/// `buf.len()` is written to this location. -/// -/// If `out_ptr` is set to the sentinel value of `u32::max_value()` and `allow_skip` is true the -/// operation is skipped and `Ok` is returned. This is supposed to help callers to make copying -/// output optional. For example to skip copying back the output buffer of an `seal_call` -/// when the caller is not interested in the result. -/// -/// `create_token` can optionally instruct this function to charge the gas meter with the token -/// it returns. `create_token` receives the variable amount of bytes that are about to be copied by -/// this function. -/// -/// In addition to the error conditions of `write_sandbox_memory` this functions returns -/// `Err` if the size of the buffer located at `out_ptr` is too small to fit `buf`. -fn write_sandbox_output( - ctx: &mut Runtime, - out_ptr: u32, - out_len_ptr: u32, - buf: &[u8], - allow_skip: bool, - create_token: impl FnOnce(u32) -> Option, -) -> Result<(), sp_sandbox::HostError> { - if allow_skip && out_ptr == u32::max_value() { - return Ok(()); + // Check the exact type of the error. + match sandbox_result { + // No traps were generated. Proceed normally. + Ok(_) => { + Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) + } + // `Error::Module` is returned only if instantiation or linking failed (i.e. + // wasm binary tried to import a function that is not provided by the host). + // This shouldn't happen because validation process ought to reject such binaries. + // + // Because panics are really undesirable in the runtime code, we treat this as + // a trap for now. Eventually, we might want to revisit this. + Err(sp_sandbox::Error::Module) => + Err("validation error")?, + // Any other kind of a trap should result in a failure. + Err(sp_sandbox::Error::Execution) | Err(sp_sandbox::Error::OutOfBounds) => + Err(Error::::ContractTrapped)? + } } - let buf_len = buf.len() as u32; - let len: u32 = read_sandbox_memory_as(ctx, out_len_ptr, 4)?; + /// Charge the gas meter with the specified token. + /// + /// Returns `Err(HostError)` if there is not enough gas. + fn charge_gas(&mut self, token: Tok) -> Result<(), sp_sandbox::HostError> + where + Tok: Token>, + { + match self.gas_meter.charge(&self.schedule.host_fn_weights, token) { + GasMeterResult::Proceed => Ok(()), + GasMeterResult::OutOfGas => { + self.trap_reason = Some( + TrapReason::SupervisorError(Error::::OutOfGas.into()) + ); + Err(sp_sandbox::HostError) + }, + } + } - if len < buf_len { - Err(store_err(ctx, Error::::OutputBufferTooSmall))? + /// Read designated chunk from the sandbox memory. + /// + /// Returns `Err` if one of the following conditions occurs: + /// + /// - requested buffer is not within the bounds of the sandbox memory. + fn read_sandbox_memory(&mut self, ptr: u32, len: u32) + -> Result, sp_sandbox::HostError> + { + let mut buf = vec![0u8; len as usize]; + self.memory.get(ptr, buf.as_mut_slice()) + .map_err(|_| self.store_err(Error::::OutOfBounds))?; + Ok(buf) } - if let Some(token) = create_token(buf_len) { - charge_gas(ctx, token)?; + /// Read designated chunk from the sandbox memory into the supplied buffer. + /// + /// Returns `Err` if one of the following conditions occurs: + /// + /// - requested buffer is not within the bounds of the sandbox memory. + fn read_sandbox_memory_into_buf(&mut self, ptr: u32, buf: &mut [u8]) + -> Result<(), sp_sandbox::HostError> + { + self.memory.get(ptr, buf).map_err(|_| self.store_err(Error::::OutOfBounds)) } - ctx.memory.set(out_ptr, buf).and_then(|_| { - ctx.memory.set(out_len_ptr, &buf_len.encode()) - }) - .map_err(|_| store_err(ctx, Error::::OutOfBounds))?; + /// Read designated chunk from the sandbox memory and attempt to decode into the specified type. + /// + /// Returns `Err` if one of the following conditions occurs: + /// + /// - requested buffer is not within the bounds of the sandbox memory. + /// - the buffer contents cannot be decoded as the required type. + fn read_sandbox_memory_as(&mut self, ptr: u32, len: u32) + -> Result + { + let buf = self.read_sandbox_memory(ptr, len)?; + D::decode(&mut &buf[..]).map_err(|_| self.store_err(Error::::DecodingFailed)) + } - Ok(()) -} + /// Write the given buffer to the designated location in the sandbox memory. + /// + /// Returns `Err` if one of the following conditions occurs: + /// + /// - designated area is not within the bounds of the sandbox memory. + fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<(), sp_sandbox::HostError> { + self.memory.set(ptr, buf).map_err(|_| self.store_err(Error::::OutOfBounds)) + } -/// Supply to `write_sandbox_output` to indicate that the gas meter should not be charged. -/// -/// This is only appropriate when writing out data of constant size that does not depend on user -/// input. In this case the costs for this copy was already charged as part of the token at -/// the beginning of the API entry point. -fn already_charged(_: u32) -> Option { - None -} + /// Write the given buffer and its length to the designated locations in sandbox memory and + /// charge gas according to the token returned by `create_token`. + // + /// `out_ptr` is the location in sandbox memory where `buf` should be written to. + /// `out_len_ptr` is an in-out location in sandbox memory. It is read to determine the + /// length of the buffer located at `out_ptr`. If that buffer is large enough the actual + /// `buf.len()` is written to this location. + /// + /// If `out_ptr` is set to the sentinel value of `u32::max_value()` and `allow_skip` is true the + /// operation is skipped and `Ok` is returned. This is supposed to help callers to make copying + /// output optional. For example to skip copying back the output buffer of an `seal_call` + /// when the caller is not interested in the result. + /// + /// `create_token` can optionally instruct this function to charge the gas meter with the token + /// it returns. `create_token` receives the variable amount of bytes that are about to be copied by + /// this function. + /// + /// In addition to the error conditions of `write_sandbox_memory` this functions returns + /// `Err` if the size of the buffer located at `out_ptr` is too small to fit `buf`. + fn write_sandbox_output( + &mut self, + out_ptr: u32, + out_len_ptr: u32, + buf: &[u8], + allow_skip: bool, + create_token: impl FnOnce(u32) -> Option, + ) -> Result<(), sp_sandbox::HostError> + { + if allow_skip && out_ptr == u32::max_value() { + return Ok(()); + } -/// Stores a DispatchError returned from an Ext function into the trap_reason. -/// -/// This allows through supervisor generated errors to the caller. -fn store_err(ctx: &mut Runtime, err: Error) -> sp_sandbox::HostError where - E: Ext, - Error: Into, -{ - ctx.trap_reason = Some(TrapReason::SupervisorError(err.into())); - sp_sandbox::HostError -} + let buf_len = buf.len() as u32; + let len: u32 = self.read_sandbox_memory_as(out_len_ptr, 4)?; -/// Fallible conversion of `DispatchError` to `ReturnCode`. -fn err_into_return_code(from: DispatchError) -> Result { - use ReturnCode::*; - - let below_sub = Error::::BelowSubsistenceThreshold.into(); - let transfer_failed = Error::::TransferFailed.into(); - let not_funded = Error::::NewContractNotFunded.into(); - let no_code = Error::::CodeNotFound.into(); - let invalid_contract = Error::::NotCallable.into(); - - match from { - x if x == below_sub => Ok(BelowSubsistenceThreshold), - x if x == transfer_failed => Ok(TransferFailed), - x if x == not_funded => Ok(NewContractNotFunded), - x if x == no_code => Ok(CodeNotFound), - x if x == invalid_contract => Ok(NotCallable), - err => Err(err) + if len < buf_len { + Err(self.store_err(Error::::OutputBufferTooSmall))? + } + + if let Some(token) = create_token(buf_len) { + self.charge_gas(token)?; + } + + self.memory.set(out_ptr, buf).and_then(|_| { + self.memory.set(out_len_ptr, &buf_len.encode()) + }) + .map_err(|_| self.store_err(Error::::OutOfBounds))?; + + Ok(()) } -} -/// Fallible conversion of a `ExecResult` to `ReturnCode`. -fn exec_into_return_code(from: ExecResult) -> Result { - use pallet_contracts_primitives::ErrorOrigin::Callee; + /// Computes the given hash function on the supplied input. + /// + /// Reads from the sandboxed input buffer into an intermediate buffer. + /// Returns the result directly to the output buffer of the sandboxed memory. + /// + /// It is the callers responsibility to provide an output buffer that + /// is large enough to hold the expected amount of bytes returned by the + /// chosen hash function. + /// + /// # Note + /// + /// The `input` and `output` buffers may overlap. + fn compute_hash_on_intermediate_buffer( + &mut self, + hash_fn: F, + input_ptr: u32, + input_len: u32, + output_ptr: u32, + ) -> Result<(), sp_sandbox::HostError> + where + F: FnOnce(&[u8]) -> R, + R: AsRef<[u8]>, + { + // Copy input into supervisor memory. + let input = self.read_sandbox_memory(input_ptr, input_len)?; + // Compute the hash on the input buffer using the given hash function. + let hash = hash_fn(&input); + // Write the resulting hash back into the sandboxed output buffer. + self.write_sandbox_memory(output_ptr, hash.as_ref())?; + Ok(()) + } - let ExecError { error, origin } = match from { - Ok(retval) => return Ok(retval.into()), - Err(err) => err, - }; + /// Stores a DispatchError returned from an Ext function into the trap_reason. + /// + /// This allows through supervisor generated errors to the caller. + fn store_err(&mut self, err: Error) -> sp_sandbox::HostError + where + Error: Into, + { + self.trap_reason = Some(TrapReason::SupervisorError(err.into())); + sp_sandbox::HostError + } - match (error, origin) { - (_, Callee) => Ok(ReturnCode::CalleeTrapped), - (err, _) => err_into_return_code::(err) + /// Used by Runtime API that calls into other contracts. + /// + /// Those need to transform the the `ExecResult` returned from the execution into + /// a `ReturnCode`. If this conversion fails because the `ExecResult` constitutes a + /// a fatal error then this error is stored in the `ExecutionContext` so it can be + /// extracted for display in the UI. + fn map_exec_result(&mut self, result: ExecResult) -> Result { + match Self::exec_into_return_code(result) { + Ok(code) => Ok(code), + Err(err) => Err(self.store_err(err)), + } } -} -/// Used by Runtime API that calls into other contracts. -/// -/// Those need to transform the the `ExecResult` returned from the execution into -/// a `ReturnCode`. If this conversion fails because the `ExecResult` constitutes a -/// a fatal error then this error is stored in the `ExecutionContext` so it can be -/// extracted for display in the UI. -fn map_exec_result(ctx: &mut Runtime, result: ExecResult) + /// Try to convert an error into a `ReturnCode`. + /// + /// Used to decide between fatal and non-fatal errors. + fn map_dispatch_result(&mut self, result: Result) -> Result -{ - match exec_into_return_code::(result) { - Ok(code) => Ok(code), - Err(err) => Err(store_err(ctx, err)), + { + let err = if let Err(err) = result { + err + } else { + return Ok(ReturnCode::Success) + }; + + match Self::err_into_return_code(err) { + Ok(code) => Ok(code), + Err(err) => Err(self.store_err(err)), + } } -} -/// Try to convert an error into a `ReturnCode`. -/// -/// Used to decide between fatal and non-fatal errors. -fn map_dispatch_result(ctx: &mut Runtime, result: Result) - -> Result -{ - let err = if let Err(err) = result { - err - } else { - return Ok(ReturnCode::Success) - }; - - match err_into_return_code::(err) { - Ok(code) => Ok(code), - Err(err) => Err(store_err(ctx, err)), + /// Fallible conversion of `DispatchError` to `ReturnCode`. + fn err_into_return_code(from: DispatchError) -> Result { + use ReturnCode::*; + + let below_sub = Error::::BelowSubsistenceThreshold.into(); + let transfer_failed = Error::::TransferFailed.into(); + let not_funded = Error::::NewContractNotFunded.into(); + let no_code = Error::::CodeNotFound.into(); + let invalid_contract = Error::::NotCallable.into(); + + match from { + x if x == below_sub => Ok(BelowSubsistenceThreshold), + x if x == transfer_failed => Ok(TransferFailed), + x if x == not_funded => Ok(NewContractNotFunded), + x if x == no_code => Ok(CodeNotFound), + x if x == invalid_contract => Ok(NotCallable), + err => Err(err) + } + } + + /// Fallible conversion of a `ExecResult` to `ReturnCode`. + fn exec_into_return_code(from: ExecResult) -> Result { + use pallet_contracts_primitives::ErrorOrigin::Callee; + + let ExecError { error, origin } = match from { + Ok(retval) => return Ok(retval.into()), + Err(err) => err, + }; + + match (error, origin) { + (_, Callee) => Ok(ReturnCode::CalleeTrapped), + (err, _) => Self::err_into_return_code(err) + } } } @@ -567,7 +616,7 @@ define_env!(Env, , // // - amount: How much gas is used. gas(ctx, amount: u32) => { - charge_gas(ctx, RuntimeToken::MeteringBlock(amount))?; + ctx.charge_gas(RuntimeToken::MeteringBlock(amount))?; Ok(()) }, @@ -587,13 +636,13 @@ define_env!(Env, , // - If value length exceeds the configured maximum value length of a storage entry. // - Upon trying to set an empty storage entry (value length is 0). seal_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => { - charge_gas(ctx, RuntimeToken::SetStorage(value_len))?; + ctx.charge_gas(RuntimeToken::SetStorage(value_len))?; if value_len > ctx.ext.max_value_size() { - Err(store_err(ctx, Error::::ValueTooLarge))?; + Err(ctx.store_err(Error::::ValueTooLarge))?; } let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; - let value = Some(read_sandbox_memory(ctx, value_ptr, value_len)?); + ctx.read_sandbox_memory_into_buf(key_ptr, &mut key)?; + let value = Some(ctx.read_sandbox_memory(value_ptr, value_len)?); ctx.ext.set_storage(key, value); Ok(()) }, @@ -604,9 +653,9 @@ define_env!(Env, , // // - `key_ptr`: pointer into the linear memory where the location to clear the value is placed. seal_clear_storage(ctx, key_ptr: u32) => { - charge_gas(ctx, RuntimeToken::ClearStorage)?; + ctx.charge_gas(RuntimeToken::ClearStorage)?; let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; + ctx.read_sandbox_memory_into_buf(key_ptr, &mut key)?; ctx.ext.set_storage(key, None); Ok(()) }, @@ -624,11 +673,11 @@ define_env!(Env, , // // `ReturnCode::KeyNotFound` seal_get_storage(ctx, key_ptr: u32, out_ptr: u32, out_len_ptr: u32) -> ReturnCode => { - charge_gas(ctx, RuntimeToken::GetStorageBase)?; + ctx.charge_gas(RuntimeToken::GetStorageBase)?; let mut key: StorageKey = [0; 32]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; + ctx.read_sandbox_memory_into_buf(key_ptr, &mut key)?; if let Some(value) = ctx.ext.get_storage(&key) { - write_sandbox_output(ctx, out_ptr, out_len_ptr, &value, false, |len| { + ctx.write_sandbox_output(out_ptr, out_len_ptr, &value, false, |len| { Some(RuntimeToken::GetStorageCopyOut(len)) })?; Ok(ReturnCode::Success) @@ -659,14 +708,14 @@ define_env!(Env, , value_ptr: u32, value_len: u32 ) -> ReturnCode => { - charge_gas(ctx, RuntimeToken::Transfer)?; + ctx.charge_gas(RuntimeToken::Transfer)?; let callee: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, account_ptr, account_len)?; + ctx.read_sandbox_memory_as(account_ptr, account_len)?; let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; + ctx.read_sandbox_memory_as(value_ptr, value_len)?; let result = ctx.ext.transfer(&callee, value); - map_dispatch_result(ctx, result) + ctx.map_dispatch_result(result) }, // Make a call to another contract. @@ -712,14 +761,14 @@ define_env!(Env, , output_ptr: u32, output_len_ptr: u32 ) -> ReturnCode => { - charge_gas(ctx, RuntimeToken::CallBase(input_data_len))?; + ctx.charge_gas(RuntimeToken::CallBase(input_data_len))?; let callee: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, callee_ptr, callee_len)?; - let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; - let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; + ctx.read_sandbox_memory_as(callee_ptr, callee_len)?; + let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; + let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; if value > 0u32.into() { - charge_gas(ctx, RuntimeToken::CallSurchargeTransfer)?; + ctx.charge_gas(RuntimeToken::CallSurchargeTransfer)?; } let nested_gas_limit = if gas == 0 { @@ -744,11 +793,11 @@ define_env!(Env, , }); if let Ok(output) = &call_outcome { - write_sandbox_output(ctx, output_ptr, output_len_ptr, &output.data, true, |len| { + ctx.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { Some(RuntimeToken::CallCopyOut(len)) })?; } - map_exec_result(ctx, call_outcome) + ctx.map_exec_result(call_outcome) }, // Instantiate a contract with the specified code hash. @@ -779,6 +828,8 @@ define_env!(Env, , // - output_ptr: a pointer where the output buffer is copied to. // - output_len_ptr: in-out pointer to where the length of the buffer is read from // and the actual length is written to. + // - salt_ptr: Pointer to raw bytes used for address deriviation. See `fn contract_address`. + // - salt_len: length in bytes of the supplied salt. // // # Errors // @@ -806,13 +857,16 @@ define_env!(Env, , address_ptr: u32, address_len_ptr: u32, output_ptr: u32, - output_len_ptr: u32 + output_len_ptr: u32, + salt_ptr: u32, + salt_len: u32 ) -> ReturnCode => { - charge_gas(ctx, RuntimeToken::InstantiateBase(input_data_len))?; + ctx.charge_gas(RuntimeToken::InstantiateBase {input_data_len, salt_len})?; let code_hash: CodeHash<::T> = - read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; - let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; - let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; + ctx.read_sandbox_memory_as(code_hash_ptr, code_hash_len)?; + let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; + let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; + let salt = ctx.read_sandbox_memory(salt_ptr, salt_len)?; let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() @@ -827,7 +881,8 @@ define_env!(Env, , &code_hash, value, nested_meter, - input_data + input_data, + &salt, ) } // there is not enough gas to allocate for the nested call. @@ -836,15 +891,15 @@ define_env!(Env, , }); if let Ok((address, output)) = &instantiate_outcome { if !output.flags.contains(ReturnFlags::REVERT) { - write_sandbox_output( - ctx, address_ptr, address_len_ptr, &address.encode(), true, already_charged, + ctx.write_sandbox_output( + address_ptr, address_len_ptr, &address.encode(), true, already_charged, )?; } - write_sandbox_output(ctx, output_ptr, output_len_ptr, &output.data, true, |len| { + ctx.write_sandbox_output(output_ptr, output_len_ptr, &output.data, true, |len| { Some(RuntimeToken::InstantiateCopyOut(len)) })?; } - map_exec_result(ctx, instantiate_outcome.map(|(_id, retval)| retval)) + ctx.map_exec_result(instantiate_outcome.map(|(_id, retval)| retval)) }, // Remove the calling account and transfer remaining balance. @@ -866,20 +921,20 @@ define_env!(Env, , beneficiary_ptr: u32, beneficiary_len: u32 ) => { - charge_gas(ctx, RuntimeToken::Terminate)?; + ctx.charge_gas(RuntimeToken::Terminate)?; let beneficiary: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?; + ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; - if let Ok(_) = ctx.ext.terminate(&beneficiary) { + if let Ok(_) = ctx.ext.terminate(&beneficiary).map_err(|e| ctx.store_err(e)) { ctx.trap_reason = Some(TrapReason::Termination); } Err(sp_sandbox::HostError) }, seal_input(ctx, buf_ptr: u32, buf_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::InputBase)?; + ctx.charge_gas(RuntimeToken::InputBase)?; if let Some(input) = ctx.input_data.take() { - write_sandbox_output(ctx, buf_ptr, buf_len_ptr, &input, false, |len| { + ctx.write_sandbox_output(buf_ptr, buf_len_ptr, &input, false, |len| { Some(RuntimeToken::InputCopyOut(len)) }) } else { @@ -905,10 +960,10 @@ define_env!(Env, , // // Using a reserved bit triggers a trap. seal_return(ctx, flags: u32, data_ptr: u32, data_len: u32) => { - charge_gas(ctx, RuntimeToken::Return(data_len))?; + ctx.charge_gas(RuntimeToken::Return(data_len))?; ctx.trap_reason = Some(TrapReason::Return(ReturnData { flags, - data: read_sandbox_memory(ctx, data_ptr, data_len)?, + data: ctx.read_sandbox_memory(data_ptr, data_len)?, })); // The trap mechanism is used to immediately terminate the execution. @@ -928,9 +983,9 @@ define_env!(Env, , // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the // address of the contract will be returned. The value is encoded as T::AccountId. seal_caller(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::Caller)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.caller().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::Caller)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.caller().encode(), false, already_charged ) }, @@ -941,9 +996,9 @@ define_env!(Env, , // `out_ptr`. This call overwrites it with the size of the value. If the available // space at `out_ptr` is less than the size of the value a trap is triggered. seal_address(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::Address)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.address().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::Address)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.address().encode(), false, already_charged ) }, @@ -961,10 +1016,9 @@ define_env!(Env, , // It is recommended to avoid specifying very small values for `gas` as the prices for a single // gas can be smaller than one. seal_weight_to_fee(ctx, gas: u64, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::WeightToFee)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.get_weight_price(gas).encode(), false, - already_charged + ctx.charge_gas(RuntimeToken::WeightToFee)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.get_weight_price(gas).encode(), false, already_charged ) }, @@ -977,9 +1031,9 @@ define_env!(Env, , // // The data is encoded as Gas. seal_gas_left(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::GasLeft)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.gas_meter.gas_left().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::GasLeft)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.gas_meter.gas_left().encode(), false, already_charged ) }, @@ -992,9 +1046,9 @@ define_env!(Env, , // // The data is encoded as T::Balance. seal_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::Balance)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.balance().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::Balance)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.balance().encode(), false, already_charged ) }, @@ -1007,10 +1061,9 @@ define_env!(Env, , // // The data is encoded as T::Balance. seal_value_transferred(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::ValueTransferred)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.value_transferred().encode(), false, - already_charged + ctx.charge_gas(RuntimeToken::ValueTransferred)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.value_transferred().encode(), false, already_charged ) }, @@ -1023,14 +1076,13 @@ define_env!(Env, , // // The data is encoded as T::Hash. seal_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::Random)?; + ctx.charge_gas(RuntimeToken::Random)?; if subject_len > ctx.schedule.limits.subject_len { return Err(sp_sandbox::HostError); } - let subject_buf = read_sandbox_memory(ctx, subject_ptr, subject_len)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.random(&subject_buf).encode(), false, - already_charged + let subject_buf = ctx.read_sandbox_memory(subject_ptr, subject_len)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.random(&subject_buf).encode(), false, already_charged ) }, @@ -1041,9 +1093,9 @@ define_env!(Env, , // `out_ptr`. This call overwrites it with the size of the value. If the available // space at `out_ptr` is less than the size of the value a trap is triggered. seal_now(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::Now)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.now().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::Now)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.now().encode(), false, already_charged ) }, @@ -1051,9 +1103,9 @@ define_env!(Env, , // // The data is encoded as T::Balance. seal_minimum_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::MinimumBalance)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.minimum_balance().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::MinimumBalance)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.minimum_balance().encode(), false, already_charged ) }, @@ -1073,10 +1125,9 @@ define_env!(Env, , // below the sum of existential deposit and the tombstone deposit. The sum // is commonly referred as subsistence threshold in code. seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::TombstoneDeposit)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false, - already_charged + ctx.charge_gas(RuntimeToken::TombstoneDeposit)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false, already_charged ) }, @@ -1117,13 +1168,13 @@ define_env!(Env, , delta_ptr: u32, delta_count: u32 ) => { - charge_gas(ctx, RuntimeToken::RestoreTo(delta_count))?; + ctx.charge_gas(RuntimeToken::RestoreTo(delta_count))?; let dest: <::T as frame_system::Trait>::AccountId = - read_sandbox_memory_as(ctx, dest_ptr, dest_len)?; + ctx.read_sandbox_memory_as(dest_ptr, dest_len)?; let code_hash: CodeHash<::T> = - read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; + ctx.read_sandbox_memory_as(code_hash_ptr, code_hash_len)?; let rent_allowance: BalanceOf<::T> = - read_sandbox_memory_as(ctx, rent_allowance_ptr, rent_allowance_len)?; + ctx.read_sandbox_memory_as(rent_allowance_ptr, rent_allowance_len)?; let delta = { // We can eagerly allocate because we charged for the complete delta count already let mut delta = Vec::with_capacity(delta_count as usize); @@ -1134,7 +1185,7 @@ define_env!(Env, , // Read the delta into the provided buffer and collect it into the buffer. let mut delta_key: StorageKey = [0; KEY_SIZE]; - read_sandbox_memory_into_buf(ctx, key_ptr, &mut delta_key)?; + ctx.read_sandbox_memory_into_buf(key_ptr, &mut delta_key)?; delta.push(delta_key); // Offset key_ptr to the next element. @@ -1149,7 +1200,7 @@ define_env!(Env, , code_hash, rent_allowance, delta, - ) { + ).map_err(|e| ctx.store_err(e)) { ctx.trap_reason = Some(TrapReason::Restoration); } Err(sp_sandbox::HostError) @@ -1166,18 +1217,18 @@ define_env!(Env, , seal_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => { let num_topic = topics_len .checked_div(sp_std::mem::size_of::>() as u32) - .ok_or_else(|| store_err(ctx, "Zero sized topics are not allowed"))?; - charge_gas(ctx, RuntimeToken::DepositEvent { + .ok_or_else(|| ctx.store_err("Zero sized topics are not allowed"))?; + ctx.charge_gas(RuntimeToken::DepositEvent { num_topic, len: data_len, })?; if data_len > ctx.ext.max_value_size() { - Err(store_err(ctx, Error::::ValueTooLarge))?; + Err(ctx.store_err(Error::::ValueTooLarge))?; } let mut topics: Vec::::T>> = match topics_len { 0 => Vec::new(), - _ => read_sandbox_memory_as(ctx, topics_ptr, topics_len)?, + _ => ctx.read_sandbox_memory_as(topics_ptr, topics_len)?, }; // If there are more than `event_topics`, then trap. @@ -1190,7 +1241,7 @@ define_env!(Env, , return Err(sp_sandbox::HostError); } - let event_data = read_sandbox_memory(ctx, data_ptr, data_len)?; + let event_data = ctx.read_sandbox_memory(data_ptr, data_len)?; ctx.ext.deposit_event(topics, event_data); @@ -1203,9 +1254,9 @@ define_env!(Env, , // Should be decodable as a `T::Balance`. Traps otherwise. // - value_len: length of the value buffer. seal_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => { - charge_gas(ctx, RuntimeToken::SetRentAllowance)?; + ctx.charge_gas(RuntimeToken::SetRentAllowance)?; let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; + ctx.read_sandbox_memory_as(value_ptr, value_len)?; ctx.ext.set_rent_allowance(value); Ok(()) @@ -1220,9 +1271,9 @@ define_env!(Env, , // // The data is encoded as T::Balance. seal_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::RentAllowance)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.rent_allowance().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::RentAllowance)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.rent_allowance().encode(), false, already_charged ) }, @@ -1230,7 +1281,7 @@ define_env!(Env, , // Only available on `--dev` chains. // This function may be removed at any time, superseded by a more general contract debugging feature. seal_println(ctx, str_ptr: u32, str_len: u32) => { - let data = read_sandbox_memory(ctx, str_ptr, str_len)?; + let data = ctx.read_sandbox_memory(str_ptr, str_len)?; if let Ok(utf8) = core::str::from_utf8(&data) { sp_runtime::print(utf8); } @@ -1244,9 +1295,9 @@ define_env!(Env, , // `out_ptr`. This call overwrites it with the size of the value. If the available // space at `out_ptr` is less than the size of the value a trap is triggered. seal_block_number(ctx, out_ptr: u32, out_len_ptr: u32) => { - charge_gas(ctx, RuntimeToken::BlockNumber)?; - write_sandbox_output( - ctx, out_ptr, out_len_ptr, &ctx.ext.block_number().encode(), false, already_charged + ctx.charge_gas(RuntimeToken::BlockNumber)?; + ctx.write_sandbox_output( + out_ptr, out_len_ptr, &ctx.ext.block_number().encode(), false, already_charged ) }, @@ -1271,8 +1322,8 @@ define_env!(Env, , // data is placed. The function will write the result // directly into this buffer. seal_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - charge_gas(ctx, RuntimeToken::HashSha256(input_len))?; - compute_hash_on_intermediate_buffer(ctx, sha2_256, input_ptr, input_len, output_ptr) + ctx.charge_gas(RuntimeToken::HashSha256(input_len))?; + ctx.compute_hash_on_intermediate_buffer(sha2_256, input_ptr, input_len, output_ptr) }, // Computes the KECCAK 256-bit hash on the given input buffer. @@ -1296,8 +1347,8 @@ define_env!(Env, , // data is placed. The function will write the result // directly into this buffer. seal_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - charge_gas(ctx, RuntimeToken::HashKeccak256(input_len))?; - compute_hash_on_intermediate_buffer(ctx, keccak_256, input_ptr, input_len, output_ptr) + ctx.charge_gas(RuntimeToken::HashKeccak256(input_len))?; + ctx.compute_hash_on_intermediate_buffer(keccak_256, input_ptr, input_len, output_ptr) }, // Computes the BLAKE2 256-bit hash on the given input buffer. @@ -1321,8 +1372,8 @@ define_env!(Env, , // data is placed. The function will write the result // directly into this buffer. seal_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - charge_gas(ctx, RuntimeToken::HashBlake256(input_len))?; - compute_hash_on_intermediate_buffer(ctx, blake2_256, input_ptr, input_len, output_ptr) + ctx.charge_gas(RuntimeToken::HashBlake256(input_len))?; + ctx.compute_hash_on_intermediate_buffer(blake2_256, input_ptr, input_len, output_ptr) }, // Computes the BLAKE2 128-bit hash on the given input buffer. @@ -1346,62 +1397,7 @@ define_env!(Env, , // data is placed. The function will write the result // directly into this buffer. seal_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { - charge_gas(ctx, RuntimeToken::HashBlake128(input_len))?; - compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr) + ctx.charge_gas(RuntimeToken::HashBlake128(input_len))?; + ctx.compute_hash_on_intermediate_buffer(blake2_128, input_ptr, input_len, output_ptr) }, ); - -/// Computes the given hash function on the supplied input. -/// -/// Reads from the sandboxed input buffer into an intermediate buffer. -/// Returns the result directly to the output buffer of the sandboxed memory. -/// -/// It is the callers responsibility to provide an output buffer that -/// is large enough to hold the expected amount of bytes returned by the -/// chosen hash function. -/// -/// # Note -/// -/// The `input` and `output` buffers may overlap. -fn compute_hash_on_intermediate_buffer( - ctx: &mut Runtime, - hash_fn: F, - input_ptr: u32, - input_len: u32, - output_ptr: u32, -) -> Result<(), sp_sandbox::HostError> -where - E: Ext, - F: FnOnce(&[u8]) -> R, - R: AsRef<[u8]>, -{ - // Copy input into supervisor memory. - let input = read_sandbox_memory(ctx, input_ptr, input_len)?; - // Compute the hash on the input buffer using the given hash function. - let hash = hash_fn(&input); - // Write the resulting hash back into the sandboxed output buffer. - write_sandbox_memory( - ctx, - output_ptr, - hash.as_ref(), - )?; - Ok(()) -} - -/// Finds duplicates in a given vector. -/// -/// This function has complexity of O(n log n) and no additional memory is required, although -/// the order of items is not preserved. -fn has_duplicates>(items: &mut Vec) -> bool { - // Sort the vector - items.sort_by(|a, b| { - Ord::cmp(a.as_ref(), b.as_ref()) - }); - // And then find any two consecutive equal elements. - items.windows(2).any(|w| { - match w { - &[ref a, ref b] => a == b, - _ => false, - } - }) -} diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index a84acbfd79a..77bb83cf4d4 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -17,7 +17,7 @@ //! Weights for pallet_contracts //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-10-27, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2020-11-10, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -45,7 +45,7 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn update_schedule() -> Weight; fn put_code(n: u32, ) -> Weight; - fn instantiate(n: u32, ) -> Weight; + fn instantiate(n: u32, s: u32, ) -> Weight; fn call() -> Weight; fn claim_surcharge() -> Weight; fn seal_caller(r: u32, ) -> Weight; @@ -80,7 +80,7 @@ pub trait WeightInfo { fn seal_call(r: u32, ) -> Weight; fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight; fn seal_instantiate(r: u32, ) -> Weight; - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight; + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight; fn seal_hash_sha2_256(r: u32, ) -> Weight; fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight; fn seal_hash_keccak_256(r: u32, ) -> Weight; @@ -140,228 +140,201 @@ pub trait WeightInfo { fn instr_i64shru(r: u32, ) -> Weight; fn instr_i64rotl(r: u32, ) -> Weight; fn instr_i64rotr(r: u32, ) -> Weight; - } /// Weights for pallet_contracts using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn update_schedule() -> Weight { - (33_160_000 as Weight) + (35_214_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } fn put_code(n: u32, ) -> Weight { - (5_975_000 as Weight) - .saturating_add((108_953_000 as Weight).saturating_mul(n as Weight)) + (0 as Weight) + .saturating_add((109_242_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn instantiate(n: u32, ) -> Weight { - (218_223_000 as Weight) - .saturating_add((1_007_000 as Weight).saturating_mul(n as Weight)) + fn instantiate(n: u32, s: u32, ) -> Weight { + (195_276_000 as Weight) + .saturating_add((35_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((2_244_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } fn call() -> Weight { - (201_492_000 as Weight) + (207_142_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } fn claim_surcharge() -> Weight { - (449_203_000 as Weight) + (489_633_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } fn seal_caller(r: u32, ) -> Weight { - (136_650_000 as Weight) - .saturating_add((364_640_000 as Weight).saturating_mul(r as Weight)) + (136_550_000 as Weight) + .saturating_add((373_182_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_address(r: u32, ) -> Weight { - (144_167_000 as Weight) - .saturating_add((365_328_000 as Weight).saturating_mul(r as Weight)) + (136_329_000 as Weight) + .saturating_add((373_392_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_gas_left(r: u32, ) -> Weight { - (138_458_000 as Weight) - .saturating_add((361_076_000 as Weight).saturating_mul(r as Weight)) + (111_577_000 as Weight) + .saturating_add((373_536_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_balance(r: u32, ) -> Weight { - (147_909_000 as Weight) - .saturating_add((792_169_000 as Weight).saturating_mul(r as Weight)) + (157_531_000 as Weight) + .saturating_add((810_382_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } fn seal_value_transferred(r: u32, ) -> Weight { - (148_524_000 as Weight) - .saturating_add((361_842_000 as Weight).saturating_mul(r as Weight)) + (143_801_000 as Weight) + .saturating_add((369_769_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_minimum_balance(r: u32, ) -> Weight { - (139_795_000 as Weight) - .saturating_add((366_013_000 as Weight).saturating_mul(r as Weight)) + (133_546_000 as Weight) + .saturating_add((370_036_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (140_557_000 as Weight) - .saturating_add((362_687_000 as Weight).saturating_mul(r as Weight)) + (138_568_000 as Weight) + .saturating_add((370_322_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_rent_allowance(r: u32, ) -> Weight { - (152_989_000 as Weight) - .saturating_add((836_876_000 as Weight).saturating_mul(r as Weight)) + (144_431_000 as Weight) + .saturating_add((851_810_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_block_number(r: u32, ) -> Weight { - (140_228_000 as Weight) - .saturating_add((360_561_000 as Weight).saturating_mul(r as Weight)) + (133_237_000 as Weight) + .saturating_add((369_156_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_now(r: u32, ) -> Weight { - (148_776_000 as Weight) - .saturating_add((361_712_000 as Weight).saturating_mul(r as Weight)) + (139_700_000 as Weight) + .saturating_add((368_961_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_weight_to_fee(r: u32, ) -> Weight { - (126_903_000 as Weight) - .saturating_add((603_100_000 as Weight).saturating_mul(r as Weight)) + (149_395_000 as Weight) + .saturating_add((625_812_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } fn seal_gas(r: u32, ) -> Weight { - (125_712_000 as Weight) - .saturating_add((184_450_000 as Weight).saturating_mul(r as Weight)) + (125_777_000 as Weight) + .saturating_add((187_585_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_input(r: u32, ) -> Weight { - (136_175_000 as Weight) - .saturating_add((7_489_000 as Weight).saturating_mul(r as Weight)) + (132_584_000 as Weight) + .saturating_add((7_661_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_input_per_kb(n: u32, ) -> Weight { - (145_434_000 as Weight) - .saturating_add((276_000 as Weight).saturating_mul(n as Weight)) + (143_408_000 as Weight) + .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_return(r: u32, ) -> Weight { - (124_788_000 as Weight) - .saturating_add((5_696_000 as Weight).saturating_mul(r as Weight)) + (126_257_000 as Weight) + .saturating_add((5_455_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_return_per_kb(n: u32, ) -> Weight { - (133_483_000 as Weight) - .saturating_add((675_000 as Weight).saturating_mul(n as Weight)) + (133_286_000 as Weight) + .saturating_add((698_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_terminate(r: u32, ) -> Weight { - (135_387_000 as Weight) - .saturating_add((338_395_000 as Weight).saturating_mul(r as Weight)) + (130_607_000 as Weight) + .saturating_add((358_370_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to(r: u32, ) -> Weight { - (227_617_000 as Weight) - .saturating_add((132_493_000 as Weight).saturating_mul(r as Weight)) + (233_645_000 as Weight) + .saturating_add((135_355_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (15_263_000 as Weight) - .saturating_add((3_732_219_000 as Weight).saturating_mul(d as Weight)) + (74_573_000 as Weight) + .saturating_add((3_768_682_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(5 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (236_391_000 as Weight) - .saturating_add((913_452_000 as Weight).saturating_mul(r as Weight)) + (140_286_000 as Weight) + .saturating_add((950_890_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } fn seal_deposit_event(r: u32, ) -> Weight { - (140_845_000 as Weight) - .saturating_add((1_322_796_000 as Weight).saturating_mul(r as Weight)) + (167_735_000 as Weight) + .saturating_add((1_375_429_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_651_556_000 as Weight) - .saturating_add((737_421_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((244_183_000 as Weight).saturating_mul(n as Weight)) + (1_715_857_000 as Weight) + .saturating_add((760_777_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((241_853_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (151_091_000 as Weight) - .saturating_add((983_375_000 as Weight).saturating_mul(r as Weight)) + (156_911_000 as Weight) + .saturating_add((1_006_139_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } fn seal_set_storage(r: u32, ) -> Weight { - (460_478_000 as Weight) - .saturating_add((14_824_033_000 as Weight).saturating_mul(r as Weight)) + (0 as Weight) + .saturating_add((14_938_793_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (2_255_458_000 as Weight) - .saturating_add((204_470_000 as Weight).saturating_mul(n as Weight)) + (2_300_169_000 as Weight) + .saturating_add((204_543_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((5_052_125_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((5_140_241_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (95_473_000 as Weight) - .saturating_add((1_044_784_000 as Weight).saturating_mul(r as Weight)) + (45_212_000 as Weight) + .saturating_add((1_131_504_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (860_080_000 as Weight) - .saturating_add((146_913_000 as Weight).saturating_mul(n as Weight)) + (885_531_000 as Weight) + .saturating_add((148_986_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) - } fn seal_transfer(r: u32, ) -> Weight { - (107_119_000 as Weight) - .saturating_add((5_993_434_000 as Weight).saturating_mul(r as Weight)) + (92_276_000 as Weight) + .saturating_add((6_216_852_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -369,560 +342,473 @@ impl WeightInfo for SubstrateWeight { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((10_533_320_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((10_734_719_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (9_839_633_000 as Weight) - .saturating_add((5_580_035_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((53_716_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((73_668_000 as Weight).saturating_mul(o as Weight)) + (12_735_614_000 as Weight) + .saturating_add((2_870_730_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((52_569_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((73_956_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(105 as Weight)) .saturating_add(T::DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((21_856_497_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((22_365_908_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { - (18_796_671_000 as Weight) - .saturating_add((156_269_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((74_645_000 as Weight).saturating_mul(o as Weight)) + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { + (18_899_296_000 as Weight) + .saturating_add((53_289_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((76_026_000 as Weight).saturating_mul(o as Weight)) + .saturating_add((281_097_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(207 as Weight)) .saturating_add(T::DbWeight::get().writes(202 as Weight)) - } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (132_190_000 as Weight) - .saturating_add((319_943_000 as Weight).saturating_mul(r as Weight)) + (136_601_000 as Weight) + .saturating_add((323_373_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (747_208_000 as Weight) - .saturating_add((421_808_000 as Weight).saturating_mul(n as Weight)) + (777_563_000 as Weight) + .saturating_add((423_353_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (139_235_000 as Weight) - .saturating_add((333_792_000 as Weight).saturating_mul(r as Weight)) + (136_771_000 as Weight) + .saturating_add((337_881_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (543_256_000 as Weight) - .saturating_add((334_383_000 as Weight).saturating_mul(n as Weight)) + (337_906_000 as Weight) + .saturating_add((336_778_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (142_704_000 as Weight) - .saturating_add((305_513_000 as Weight).saturating_mul(r as Weight)) + (131_040_000 as Weight) + .saturating_add((312_992_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (592_813_000 as Weight) - .saturating_add((151_270_000 as Weight).saturating_mul(n as Weight)) + (693_415_000 as Weight) + .saturating_add((152_745_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (139_921_000 as Weight) - .saturating_add((304_746_000 as Weight).saturating_mul(r as Weight)) + (135_654_000 as Weight) + .saturating_add((311_271_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (544_524_000 as Weight) - .saturating_add((151_549_000 as Weight).saturating_mul(n as Weight)) + (839_521_000 as Weight) + .saturating_add((153_146_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - } fn instr_i64const(r: u32, ) -> Weight { - (24_652_000 as Weight) - .saturating_add((3_306_000 as Weight).saturating_mul(r as Weight)) - + (26_679_000 as Weight) + .saturating_add((3_155_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (27_131_000 as Weight) - .saturating_add((162_220_000 as Weight).saturating_mul(r as Weight)) - + (28_920_000 as Weight) + .saturating_add((159_343_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (27_086_000 as Weight) - .saturating_add((230_977_000 as Weight).saturating_mul(r as Weight)) - + (28_928_000 as Weight) + .saturating_add((227_286_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (24_656_000 as Weight) - .saturating_add((12_570_000 as Weight).saturating_mul(r as Weight)) - + (26_591_000 as Weight) + .saturating_add((12_591_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((12_442_000 as Weight).saturating_mul(r as Weight)) - + (26_597_000 as Weight) + .saturating_add((12_258_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (24_589_000 as Weight) - .saturating_add((6_237_000 as Weight).saturating_mul(r as Weight)) - + (26_586_000 as Weight) + .saturating_add((5_811_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (24_650_000 as Weight) - .saturating_add((14_393_000 as Weight).saturating_mul(r as Weight)) - + (26_581_000 as Weight) + .saturating_add((14_058_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (24_689_000 as Weight) - .saturating_add((15_706_000 as Weight).saturating_mul(r as Weight)) - + (26_615_000 as Weight) + .saturating_add((15_687_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (40_129_000 as Weight) - .saturating_add((83_000 as Weight).saturating_mul(e as Weight)) - + (40_963_000 as Weight) + .saturating_add((92_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (24_904_000 as Weight) - .saturating_add((96_429_000 as Weight).saturating_mul(r as Weight)) - + (26_880_000 as Weight) + .saturating_add((97_523_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (32_540_000 as Weight) - .saturating_add((201_773_000 as Weight).saturating_mul(r as Weight)) - + (34_628_000 as Weight) + .saturating_add((201_913_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (248_700_000 as Weight) - .saturating_add((3_705_000 as Weight).saturating_mul(p as Weight)) - + (255_763_000 as Weight) + .saturating_add((3_612_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (42_081_000 as Weight) - .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) - + (45_954_000 as Weight) + .saturating_add((3_439_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (42_128_000 as Weight) - .saturating_add((3_678_000 as Weight).saturating_mul(r as Weight)) - + (45_952_000 as Weight) + .saturating_add((3_601_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (42_073_000 as Weight) - .saturating_add((5_212_000 as Weight).saturating_mul(r as Weight)) - + (45_883_000 as Weight) + .saturating_add((5_203_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (28_182_000 as Weight) - .saturating_add((8_180_000 as Weight).saturating_mul(r as Weight)) - + (29_895_000 as Weight) + .saturating_add((8_221_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (28_060_000 as Weight) - .saturating_add((12_081_000 as Weight).saturating_mul(r as Weight)) - + (29_916_000 as Weight) + .saturating_add((12_036_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (27_113_000 as Weight) - .saturating_add((3_802_000 as Weight).saturating_mul(r as Weight)) - + (28_878_000 as Weight) + .saturating_add((3_794_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_521_000 as Weight) - .saturating_add((2_288_295_000 as Weight).saturating_mul(r as Weight)) - + (27_351_000 as Weight) + .saturating_add((2_302_301_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (24_662_000 as Weight) - .saturating_add((5_497_000 as Weight).saturating_mul(r as Weight)) - + (26_535_000 as Weight) + .saturating_add((5_450_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (24_647_000 as Weight) - .saturating_add((5_556_000 as Weight).saturating_mul(r as Weight)) - + (26_489_000 as Weight) + .saturating_add((5_410_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (24_646_000 as Weight) - .saturating_add((6_138_000 as Weight).saturating_mul(r as Weight)) - + (26_576_000 as Weight) + .saturating_add((5_976_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (24_649_000 as Weight) - .saturating_add((5_477_000 as Weight).saturating_mul(r as Weight)) - + (26_521_000 as Weight) + .saturating_add((5_465_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (24_655_000 as Weight) - .saturating_add((5_414_000 as Weight).saturating_mul(r as Weight)) - + (26_534_000 as Weight) + .saturating_add((5_375_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (24_619_000 as Weight) - .saturating_add((5_434_000 as Weight).saturating_mul(r as Weight)) - + (26_560_000 as Weight) + .saturating_add((5_284_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (24_654_000 as Weight) - .saturating_add((5_483_000 as Weight).saturating_mul(r as Weight)) - + (26_554_000 as Weight) + .saturating_add((5_358_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (24_690_000 as Weight) - .saturating_add((7_485_000 as Weight).saturating_mul(r as Weight)) - + (26_549_000 as Weight) + .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (24_652_000 as Weight) - .saturating_add((7_468_000 as Weight).saturating_mul(r as Weight)) - + (26_582_000 as Weight) + .saturating_add((7_266_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (24_667_000 as Weight) - .saturating_add((7_426_000 as Weight).saturating_mul(r as Weight)) - + (26_558_000 as Weight) + .saturating_add((7_293_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (24_693_000 as Weight) - .saturating_add((7_393_000 as Weight).saturating_mul(r as Weight)) - + (26_569_000 as Weight) + .saturating_add((7_278_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (24_675_000 as Weight) - .saturating_add((7_407_000 as Weight).saturating_mul(r as Weight)) - + (26_516_000 as Weight) + .saturating_add((7_334_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (24_697_000 as Weight) - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) - + (26_561_000 as Weight) + .saturating_add((7_283_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (24_646_000 as Weight) - .saturating_add((7_420_000 as Weight).saturating_mul(r as Weight)) - + (26_589_000 as Weight) + .saturating_add((7_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (24_683_000 as Weight) - .saturating_add((7_404_000 as Weight).saturating_mul(r as Weight)) - + (26_593_000 as Weight) + .saturating_add((7_318_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (24_685_000 as Weight) - .saturating_add((7_461_000 as Weight).saturating_mul(r as Weight)) - + (26_626_000 as Weight) + .saturating_add((7_348_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (25_147_000 as Weight) - .saturating_add((7_003_000 as Weight).saturating_mul(r as Weight)) - + (26_595_000 as Weight) + .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (24_705_000 as Weight) - .saturating_add((7_483_000 as Weight).saturating_mul(r as Weight)) - + (26_568_000 as Weight) + .saturating_add((8_657_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (24_675_000 as Weight) - .saturating_add((7_377_000 as Weight).saturating_mul(r as Weight)) - + (27_393_000 as Weight) + .saturating_add((6_743_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (24_680_000 as Weight) - .saturating_add((7_376_000 as Weight).saturating_mul(r as Weight)) - + (26_571_000 as Weight) + .saturating_add((7_329_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (24_660_000 as Weight) - .saturating_add((13_091_000 as Weight).saturating_mul(r as Weight)) - + (26_585_000 as Weight) + .saturating_add((12_977_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((12_109_000 as Weight).saturating_mul(r as Weight)) - + (26_554_000 as Weight) + .saturating_add((11_955_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (24_615_000 as Weight) - .saturating_add((13_049_000 as Weight).saturating_mul(r as Weight)) - + (26_570_000 as Weight) + .saturating_add((12_903_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (24_696_000 as Weight) - .saturating_add((12_039_000 as Weight).saturating_mul(r as Weight)) - + (26_561_000 as Weight) + .saturating_add((12_112_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (24_683_000 as Weight) - .saturating_add((7_314_000 as Weight).saturating_mul(r as Weight)) - + (26_587_000 as Weight) + .saturating_add((7_411_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (24_657_000 as Weight) - .saturating_add((7_401_000 as Weight).saturating_mul(r as Weight)) - + (26_588_000 as Weight) + .saturating_add((7_479_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (24_661_000 as Weight) - .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) - + (26_541_000 as Weight) + .saturating_add((7_386_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (24_644_000 as Weight) - .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) - + (26_562_000 as Weight) + .saturating_add((7_263_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) - + (26_569_000 as Weight) + .saturating_add((7_353_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (24_634_000 as Weight) - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) - + (26_533_000 as Weight) + .saturating_add((7_342_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (24_618_000 as Weight) - .saturating_add((7_452_000 as Weight).saturating_mul(r as Weight)) - + (26_545_000 as Weight) + .saturating_add((7_362_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (24_618_000 as Weight) - .saturating_add((7_447_000 as Weight).saturating_mul(r as Weight)) - + (26_535_000 as Weight) + .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) } - } // For backwards compatibility and tests impl WeightInfo for () { fn update_schedule() -> Weight { - (33_160_000 as Weight) + (35_214_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } fn put_code(n: u32, ) -> Weight { - (5_975_000 as Weight) - .saturating_add((108_953_000 as Weight).saturating_mul(n as Weight)) + (0 as Weight) + .saturating_add((109_242_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } - fn instantiate(n: u32, ) -> Weight { - (218_223_000 as Weight) - .saturating_add((1_007_000 as Weight).saturating_mul(n as Weight)) + fn instantiate(n: u32, s: u32, ) -> Weight { + (195_276_000 as Weight) + .saturating_add((35_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((2_244_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } fn call() -> Weight { - (201_492_000 as Weight) + (207_142_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } fn claim_surcharge() -> Weight { - (449_203_000 as Weight) + (489_633_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } fn seal_caller(r: u32, ) -> Weight { - (136_650_000 as Weight) - .saturating_add((364_640_000 as Weight).saturating_mul(r as Weight)) + (136_550_000 as Weight) + .saturating_add((373_182_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_address(r: u32, ) -> Weight { - (144_167_000 as Weight) - .saturating_add((365_328_000 as Weight).saturating_mul(r as Weight)) + (136_329_000 as Weight) + .saturating_add((373_392_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_gas_left(r: u32, ) -> Weight { - (138_458_000 as Weight) - .saturating_add((361_076_000 as Weight).saturating_mul(r as Weight)) + (111_577_000 as Weight) + .saturating_add((373_536_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_balance(r: u32, ) -> Weight { - (147_909_000 as Weight) - .saturating_add((792_169_000 as Weight).saturating_mul(r as Weight)) + (157_531_000 as Weight) + .saturating_add((810_382_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - } fn seal_value_transferred(r: u32, ) -> Weight { - (148_524_000 as Weight) - .saturating_add((361_842_000 as Weight).saturating_mul(r as Weight)) + (143_801_000 as Weight) + .saturating_add((369_769_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_minimum_balance(r: u32, ) -> Weight { - (139_795_000 as Weight) - .saturating_add((366_013_000 as Weight).saturating_mul(r as Weight)) + (133_546_000 as Weight) + .saturating_add((370_036_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (140_557_000 as Weight) - .saturating_add((362_687_000 as Weight).saturating_mul(r as Weight)) + (138_568_000 as Weight) + .saturating_add((370_322_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_rent_allowance(r: u32, ) -> Weight { - (152_989_000 as Weight) - .saturating_add((836_876_000 as Weight).saturating_mul(r as Weight)) + (144_431_000 as Weight) + .saturating_add((851_810_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_block_number(r: u32, ) -> Weight { - (140_228_000 as Weight) - .saturating_add((360_561_000 as Weight).saturating_mul(r as Weight)) + (133_237_000 as Weight) + .saturating_add((369_156_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_now(r: u32, ) -> Weight { - (148_776_000 as Weight) - .saturating_add((361_712_000 as Weight).saturating_mul(r as Weight)) + (139_700_000 as Weight) + .saturating_add((368_961_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_weight_to_fee(r: u32, ) -> Weight { - (126_903_000 as Weight) - .saturating_add((603_100_000 as Weight).saturating_mul(r as Weight)) + (149_395_000 as Weight) + .saturating_add((625_812_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - } fn seal_gas(r: u32, ) -> Weight { - (125_712_000 as Weight) - .saturating_add((184_450_000 as Weight).saturating_mul(r as Weight)) + (125_777_000 as Weight) + .saturating_add((187_585_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_input(r: u32, ) -> Weight { - (136_175_000 as Weight) - .saturating_add((7_489_000 as Weight).saturating_mul(r as Weight)) + (132_584_000 as Weight) + .saturating_add((7_661_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_input_per_kb(n: u32, ) -> Weight { - (145_434_000 as Weight) - .saturating_add((276_000 as Weight).saturating_mul(n as Weight)) + (143_408_000 as Weight) + .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_return(r: u32, ) -> Weight { - (124_788_000 as Weight) - .saturating_add((5_696_000 as Weight).saturating_mul(r as Weight)) + (126_257_000 as Weight) + .saturating_add((5_455_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_return_per_kb(n: u32, ) -> Weight { - (133_483_000 as Weight) - .saturating_add((675_000 as Weight).saturating_mul(n as Weight)) + (133_286_000 as Weight) + .saturating_add((698_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_terminate(r: u32, ) -> Weight { - (135_387_000 as Weight) - .saturating_add((338_395_000 as Weight).saturating_mul(r as Weight)) + (130_607_000 as Weight) + .saturating_add((358_370_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to(r: u32, ) -> Weight { - (227_617_000 as Weight) - .saturating_add((132_493_000 as Weight).saturating_mul(r as Weight)) + (233_645_000 as Weight) + .saturating_add((135_355_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (15_263_000 as Weight) - .saturating_add((3_732_219_000 as Weight).saturating_mul(d as Weight)) + (74_573_000 as Weight) + .saturating_add((3_768_682_000 as Weight).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (236_391_000 as Weight) - .saturating_add((913_452_000 as Weight).saturating_mul(r as Weight)) + (140_286_000 as Weight) + .saturating_add((950_890_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - } fn seal_deposit_event(r: u32, ) -> Weight { - (140_845_000 as Weight) - .saturating_add((1_322_796_000 as Weight).saturating_mul(r as Weight)) + (167_735_000 as Weight) + .saturating_add((1_375_429_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_651_556_000 as Weight) - .saturating_add((737_421_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((244_183_000 as Weight).saturating_mul(n as Weight)) + (1_715_857_000 as Weight) + .saturating_add((760_777_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((241_853_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (151_091_000 as Weight) - .saturating_add((983_375_000 as Weight).saturating_mul(r as Weight)) + (156_911_000 as Weight) + .saturating_add((1_006_139_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } fn seal_set_storage(r: u32, ) -> Weight { - (460_478_000 as Weight) - .saturating_add((14_824_033_000 as Weight).saturating_mul(r as Weight)) + (0 as Weight) + .saturating_add((14_938_793_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (2_255_458_000 as Weight) - .saturating_add((204_470_000 as Weight).saturating_mul(n as Weight)) + (2_300_169_000 as Weight) + .saturating_add((204_543_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((5_052_125_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((5_140_241_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (95_473_000 as Weight) - .saturating_add((1_044_784_000 as Weight).saturating_mul(r as Weight)) + (45_212_000 as Weight) + .saturating_add((1_131_504_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (860_080_000 as Weight) - .saturating_add((146_913_000 as Weight).saturating_mul(n as Weight)) + (885_531_000 as Weight) + .saturating_add((148_986_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - } fn seal_transfer(r: u32, ) -> Weight { - (107_119_000 as Weight) - .saturating_add((5_993_434_000 as Weight).saturating_mul(r as Weight)) + (92_276_000 as Weight) + .saturating_add((6_216_852_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) @@ -930,338 +816,277 @@ impl WeightInfo for () { } fn seal_call(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((10_533_320_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((10_734_719_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) - } fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (9_839_633_000 as Weight) - .saturating_add((5_580_035_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((53_716_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((73_668_000 as Weight).saturating_mul(o as Weight)) + (12_735_614_000 as Weight) + .saturating_add((2_870_730_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((52_569_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((73_956_000 as Weight).saturating_mul(o as Weight)) .saturating_add(RocksDbWeight::get().reads(105 as Weight)) .saturating_add(RocksDbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((21_856_497_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((22_365_908_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) .saturating_add(RocksDbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) } - fn seal_instantiate_per_input_output_kb(i: u32, o: u32, ) -> Weight { - (18_796_671_000 as Weight) - .saturating_add((156_269_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((74_645_000 as Weight).saturating_mul(o as Weight)) + fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { + (18_899_296_000 as Weight) + .saturating_add((53_289_000 as Weight).saturating_mul(i as Weight)) + .saturating_add((76_026_000 as Weight).saturating_mul(o as Weight)) + .saturating_add((281_097_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(207 as Weight)) .saturating_add(RocksDbWeight::get().writes(202 as Weight)) - } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (132_190_000 as Weight) - .saturating_add((319_943_000 as Weight).saturating_mul(r as Weight)) + (136_601_000 as Weight) + .saturating_add((323_373_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (747_208_000 as Weight) - .saturating_add((421_808_000 as Weight).saturating_mul(n as Weight)) + (777_563_000 as Weight) + .saturating_add((423_353_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (139_235_000 as Weight) - .saturating_add((333_792_000 as Weight).saturating_mul(r as Weight)) + (136_771_000 as Weight) + .saturating_add((337_881_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (543_256_000 as Weight) - .saturating_add((334_383_000 as Weight).saturating_mul(n as Weight)) + (337_906_000 as Weight) + .saturating_add((336_778_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (142_704_000 as Weight) - .saturating_add((305_513_000 as Weight).saturating_mul(r as Weight)) + (131_040_000 as Weight) + .saturating_add((312_992_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (592_813_000 as Weight) - .saturating_add((151_270_000 as Weight).saturating_mul(n as Weight)) + (693_415_000 as Weight) + .saturating_add((152_745_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (139_921_000 as Weight) - .saturating_add((304_746_000 as Weight).saturating_mul(r as Weight)) + (135_654_000 as Weight) + .saturating_add((311_271_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (544_524_000 as Weight) - .saturating_add((151_549_000 as Weight).saturating_mul(n as Weight)) + (839_521_000 as Weight) + .saturating_add((153_146_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - } fn instr_i64const(r: u32, ) -> Weight { - (24_652_000 as Weight) - .saturating_add((3_306_000 as Weight).saturating_mul(r as Weight)) - + (26_679_000 as Weight) + .saturating_add((3_155_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (27_131_000 as Weight) - .saturating_add((162_220_000 as Weight).saturating_mul(r as Weight)) - + (28_920_000 as Weight) + .saturating_add((159_343_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (27_086_000 as Weight) - .saturating_add((230_977_000 as Weight).saturating_mul(r as Weight)) - + (28_928_000 as Weight) + .saturating_add((227_286_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (24_656_000 as Weight) - .saturating_add((12_570_000 as Weight).saturating_mul(r as Weight)) - + (26_591_000 as Weight) + .saturating_add((12_591_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((12_442_000 as Weight).saturating_mul(r as Weight)) - + (26_597_000 as Weight) + .saturating_add((12_258_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (24_589_000 as Weight) - .saturating_add((6_237_000 as Weight).saturating_mul(r as Weight)) - + (26_586_000 as Weight) + .saturating_add((5_811_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (24_650_000 as Weight) - .saturating_add((14_393_000 as Weight).saturating_mul(r as Weight)) - + (26_581_000 as Weight) + .saturating_add((14_058_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (24_689_000 as Weight) - .saturating_add((15_706_000 as Weight).saturating_mul(r as Weight)) - + (26_615_000 as Weight) + .saturating_add((15_687_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (40_129_000 as Weight) - .saturating_add((83_000 as Weight).saturating_mul(e as Weight)) - + (40_963_000 as Weight) + .saturating_add((92_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (24_904_000 as Weight) - .saturating_add((96_429_000 as Weight).saturating_mul(r as Weight)) - + (26_880_000 as Weight) + .saturating_add((97_523_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (32_540_000 as Weight) - .saturating_add((201_773_000 as Weight).saturating_mul(r as Weight)) - + (34_628_000 as Weight) + .saturating_add((201_913_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (248_700_000 as Weight) - .saturating_add((3_705_000 as Weight).saturating_mul(p as Weight)) - + (255_763_000 as Weight) + .saturating_add((3_612_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (42_081_000 as Weight) - .saturating_add((3_548_000 as Weight).saturating_mul(r as Weight)) - + (45_954_000 as Weight) + .saturating_add((3_439_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (42_128_000 as Weight) - .saturating_add((3_678_000 as Weight).saturating_mul(r as Weight)) - + (45_952_000 as Weight) + .saturating_add((3_601_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (42_073_000 as Weight) - .saturating_add((5_212_000 as Weight).saturating_mul(r as Weight)) - + (45_883_000 as Weight) + .saturating_add((5_203_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (28_182_000 as Weight) - .saturating_add((8_180_000 as Weight).saturating_mul(r as Weight)) - + (29_895_000 as Weight) + .saturating_add((8_221_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (28_060_000 as Weight) - .saturating_add((12_081_000 as Weight).saturating_mul(r as Weight)) - + (29_916_000 as Weight) + .saturating_add((12_036_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (27_113_000 as Weight) - .saturating_add((3_802_000 as Weight).saturating_mul(r as Weight)) - + (28_878_000 as Weight) + .saturating_add((3_794_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (25_521_000 as Weight) - .saturating_add((2_288_295_000 as Weight).saturating_mul(r as Weight)) - + (27_351_000 as Weight) + .saturating_add((2_302_301_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (24_662_000 as Weight) - .saturating_add((5_497_000 as Weight).saturating_mul(r as Weight)) - + (26_535_000 as Weight) + .saturating_add((5_450_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (24_647_000 as Weight) - .saturating_add((5_556_000 as Weight).saturating_mul(r as Weight)) - + (26_489_000 as Weight) + .saturating_add((5_410_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (24_646_000 as Weight) - .saturating_add((6_138_000 as Weight).saturating_mul(r as Weight)) - + (26_576_000 as Weight) + .saturating_add((5_976_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (24_649_000 as Weight) - .saturating_add((5_477_000 as Weight).saturating_mul(r as Weight)) - + (26_521_000 as Weight) + .saturating_add((5_465_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (24_655_000 as Weight) - .saturating_add((5_414_000 as Weight).saturating_mul(r as Weight)) - + (26_534_000 as Weight) + .saturating_add((5_375_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (24_619_000 as Weight) - .saturating_add((5_434_000 as Weight).saturating_mul(r as Weight)) - + (26_560_000 as Weight) + .saturating_add((5_284_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (24_654_000 as Weight) - .saturating_add((5_483_000 as Weight).saturating_mul(r as Weight)) - + (26_554_000 as Weight) + .saturating_add((5_358_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (24_690_000 as Weight) - .saturating_add((7_485_000 as Weight).saturating_mul(r as Weight)) - + (26_549_000 as Weight) + .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (24_652_000 as Weight) - .saturating_add((7_468_000 as Weight).saturating_mul(r as Weight)) - + (26_582_000 as Weight) + .saturating_add((7_266_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (24_667_000 as Weight) - .saturating_add((7_426_000 as Weight).saturating_mul(r as Weight)) - + (26_558_000 as Weight) + .saturating_add((7_293_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (24_693_000 as Weight) - .saturating_add((7_393_000 as Weight).saturating_mul(r as Weight)) - + (26_569_000 as Weight) + .saturating_add((7_278_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (24_675_000 as Weight) - .saturating_add((7_407_000 as Weight).saturating_mul(r as Weight)) - + (26_516_000 as Weight) + .saturating_add((7_334_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (24_697_000 as Weight) - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) - + (26_561_000 as Weight) + .saturating_add((7_283_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (24_646_000 as Weight) - .saturating_add((7_420_000 as Weight).saturating_mul(r as Weight)) - + (26_589_000 as Weight) + .saturating_add((7_244_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (24_683_000 as Weight) - .saturating_add((7_404_000 as Weight).saturating_mul(r as Weight)) - + (26_593_000 as Weight) + .saturating_add((7_318_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (24_685_000 as Weight) - .saturating_add((7_461_000 as Weight).saturating_mul(r as Weight)) - + (26_626_000 as Weight) + .saturating_add((7_348_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (25_147_000 as Weight) - .saturating_add((7_003_000 as Weight).saturating_mul(r as Weight)) - + (26_595_000 as Weight) + .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (24_705_000 as Weight) - .saturating_add((7_483_000 as Weight).saturating_mul(r as Weight)) - + (26_568_000 as Weight) + .saturating_add((8_657_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (24_675_000 as Weight) - .saturating_add((7_377_000 as Weight).saturating_mul(r as Weight)) - + (27_393_000 as Weight) + .saturating_add((6_743_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (24_680_000 as Weight) - .saturating_add((7_376_000 as Weight).saturating_mul(r as Weight)) - + (26_571_000 as Weight) + .saturating_add((7_329_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (24_660_000 as Weight) - .saturating_add((13_091_000 as Weight).saturating_mul(r as Weight)) - + (26_585_000 as Weight) + .saturating_add((12_977_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((12_109_000 as Weight).saturating_mul(r as Weight)) - + (26_554_000 as Weight) + .saturating_add((11_955_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (24_615_000 as Weight) - .saturating_add((13_049_000 as Weight).saturating_mul(r as Weight)) - + (26_570_000 as Weight) + .saturating_add((12_903_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (24_696_000 as Weight) - .saturating_add((12_039_000 as Weight).saturating_mul(r as Weight)) - + (26_561_000 as Weight) + .saturating_add((12_112_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (24_683_000 as Weight) - .saturating_add((7_314_000 as Weight).saturating_mul(r as Weight)) - + (26_587_000 as Weight) + .saturating_add((7_411_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (24_657_000 as Weight) - .saturating_add((7_401_000 as Weight).saturating_mul(r as Weight)) - + (26_588_000 as Weight) + .saturating_add((7_479_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (24_661_000 as Weight) - .saturating_add((7_347_000 as Weight).saturating_mul(r as Weight)) - + (26_541_000 as Weight) + .saturating_add((7_386_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (24_644_000 as Weight) - .saturating_add((7_389_000 as Weight).saturating_mul(r as Weight)) - + (26_562_000 as Weight) + .saturating_add((7_263_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (24_643_000 as Weight) - .saturating_add((7_416_000 as Weight).saturating_mul(r as Weight)) - + (26_569_000 as Weight) + .saturating_add((7_353_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (24_634_000 as Weight) - .saturating_add((7_392_000 as Weight).saturating_mul(r as Weight)) - + (26_533_000 as Weight) + .saturating_add((7_342_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (24_618_000 as Weight) - .saturating_add((7_452_000 as Weight).saturating_mul(r as Weight)) - + (26_545_000 as Weight) + .saturating_add((7_362_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (24_618_000 as Weight) - .saturating_add((7_447_000 as Weight).saturating_mul(r as Weight)) - + (26_535_000 as Weight) + .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) } - } -- GitLab From 24809aad065365506fd6e279c926c0497034576d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 24 Nov 2020 19:56:21 +0100 Subject: [PATCH 044/163] */Cargo.toml: Remove unused dependencies (#7590) * */Cargo.toml: Remove unused dependencies Using cargo-udeps to detect unused dependencies. * client/network/Cargo: Revert dependency removal * Cargo.lock: Update --- Cargo.lock | 8 -------- client/api/Cargo.toml | 3 --- client/authority-discovery/Cargo.toml | 2 -- primitives/blockchain/Cargo.toml | 1 - primitives/panic-handler/Cargo.toml | 1 - primitives/runtime/Cargo.toml | 2 -- 6 files changed, 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 710e3519d95..827bf3b9985 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6377,7 +6377,6 @@ name = "sc-authority-discovery" version = "0.8.0" dependencies = [ "async-trait", - "bytes 0.5.6", "derive_more", "either", "futures 0.3.8", @@ -6390,7 +6389,6 @@ dependencies = [ "quickcheck", "rand 0.7.3", "sc-client-api", - "sc-keystore", "sc-network", "sc-peerset", "serde_json", @@ -6541,7 +6539,6 @@ dependencies = [ "fnv", "futures 0.3.8", "hash-db", - "hex-literal", "kvdb", "kvdb-memorydb", "lazy_static", @@ -6549,7 +6546,6 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.2", "sc-executor", - "sc-telemetry", "sp-api", "sp-blockchain", "sp-consensus", @@ -6557,7 +6553,6 @@ dependencies = [ "sp-database", "sp-externalities", "sp-inherents", - "sp-keyring", "sp-keystore", "sp-runtime", "sp-state-machine", @@ -8110,7 +8105,6 @@ dependencies = [ "lru 0.6.1", "parity-scale-codec", "parking_lot 0.10.2", - "sp-block-builder", "sp-consensus", "sp-database", "sp-runtime", @@ -8418,7 +8412,6 @@ name = "sp-panic-handler" version = "2.0.0" dependencies = [ "backtrace", - "log", ] [[package]] @@ -8447,7 +8440,6 @@ dependencies = [ "sp-application-crypto", "sp-arithmetic", "sp-core", - "sp-inherents", "sp-io", "sp-state-machine", "sp-std", diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index d0fb5fc3ee0..7d770912f27 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -23,9 +23,7 @@ fnv = "1.0.6" futures = "0.3.1" hash-db = { version = "0.15.2", default-features = false } sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } -hex-literal = "0.3.1" sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } kvdb = "0.7.0" log = "0.4.8" parking_lot = "0.10.0" @@ -39,7 +37,6 @@ sp-api = { version = "2.0.0", path = "../../primitives/api" } sp-utils = { version = "2.0.0", path = "../../primitives/utils" } sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } sp-state-machine = { version = "0.8.0", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0", path = "../telemetry" } sp-trie = { version = "2.0.0", path = "../../primitives/trie" } sp-storage = { version = "2.0.0", path = "../../primitives/storage" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 40b929fc8a0..fc948de53eb 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -18,7 +18,6 @@ prost-build = "0.6.1" [dependencies] async-trait = "0.1" -bytes = "0.5.0" codec = { package = "parity-scale-codec", default-features = false, version = "1.3.4" } derive_more = "0.99.2" either = "1.5.3" @@ -30,7 +29,6 @@ prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../.. prost = "0.6.1" rand = "0.7.2" sc-client-api = { version = "2.0.0", path = "../api" } -sc-keystore = { version = "2.0.0", path = "../keystore" } sc-network = { version = "0.8.0", path = "../network" } serde_json = "1.0.41" sp-authority-discovery = { version = "2.0.0", path = "../../primitives/authority-discovery" } diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index 7b7c0f3446e..eac1e032e3e 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -21,6 +21,5 @@ thiserror = "1.0.21" codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } sp-consensus = { version = "0.8.0", path = "../consensus/common" } sp-runtime = { version = "2.0.0", path = "../runtime" } -sp-block-builder = { version = "2.0.0", path = "../block-builder" } sp-state-machine = { version = "0.8.0", path = "../state-machine" } sp-database = { version = "2.0.0", path = "../database" } diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index acf454b960a..0baba8ee7ab 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -15,4 +15,3 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] backtrace = "0.3.38" -log = "0.4.8" diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 6579a17c77f..9c3286cd475 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -26,7 +26,6 @@ log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } either = { version = "1.5", default-features = false } @@ -50,7 +49,6 @@ std = [ "sp-std/std", "sp-io/std", "serde", - "sp-inherents/std", "parity-util-mem/std", "hash256-std-hasher/std", "either/use_std", -- GitLab From 94d27efce02b454f0ee22f33f1204f39439a021b Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Wed, 25 Nov 2020 09:48:10 +0100 Subject: [PATCH 045/163] CI: build docs after test; publish docs after build (#7591) docs time test/build success on master pub --- .gitlab-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b37d60a941d..215157061bb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -471,7 +471,9 @@ build-rust-doc: stage: build <<: *docker-env <<: *test-refs - allow_failure: true + needs: + - job: test-linux-stable + artifacts: false variables: <<: *default-vars RUSTFLAGS: -Dwarnings @@ -677,6 +679,8 @@ publish-s3-doc: needs: - job: build-rust-doc artifacts: true + - job: build-linux-substrate + artifacts: false <<: *build-refs <<: *kubernetes-build variables: -- GitLab From 45a0ea7e7b7c374642e3249324de11c56dbf2c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Wed, 25 Nov 2020 08:50:13 +0000 Subject: [PATCH 046/163] node-template: add aura to light block import pipeline (#7595) added aura to block import pipeline --- bin/node-template/node/src/service.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 83481f8c152..e32ba740504 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -239,9 +239,14 @@ pub fn new_light(config: Configuration) -> Result { select_chain.clone(), )?; + let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( + grandpa_block_import.clone(), + client.clone(), + ); + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( sc_consensus_aura::slot_duration(&*client)?, - grandpa_block_import.clone(), + aura_block_import, Some(Box::new(grandpa_block_import)), client.clone(), InherentDataProviders::new(), -- GitLab From bce646d0ed5e177a7c5862e061395d7bc1666384 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 25 Nov 2020 10:15:37 +0100 Subject: [PATCH 047/163] Fix notifications sometimes not being sent (#7594) * Fix notifications sometimes not being sent * Add comment --- client/network/src/protocol/generic_proto/handler.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index c8a76c1cc9a..42cf02f1b77 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -971,6 +971,16 @@ impl ProtocolsHandler for NotifsHandler { if let Some(pos) = self.out_protocols.iter().position(|(n, _)| *n == protocol_name) { if let Some(substream) = out_substreams[pos].as_mut() { let _ = substream.start_send_unpin(message); + // Calling `start_send_unpin` only queues the message. Actually + // emitting the message is done with `poll_flush`. In order to + // not introduce too much complexity, this flushing is done earlier + // in the body of this `poll()` method. As such, we schedule a task + // wake-up now in order to guarantee that `poll()` will be called + // again and the flush happening. + // At the time of the writing of this comment, a rewrite of this + // code is being planned. If you find this comment in the wild and + // the rewrite didn't happen, please consider a refactor. + cx.waker().wake_by_ref(); continue 'poll_notifs_sink; } -- GitLab From 1ec8a7f57ba5faac74c09296eab9977fb331c386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Nov 2020 10:59:13 +0100 Subject: [PATCH 048/163] Bump rpassword from 4.0.5 to 5.0.0 (#7597) Bumps [rpassword](https://github.com/conradkleinespel/rpassword) from 4.0.5 to 5.0.0. - [Release notes](https://github.com/conradkleinespel/rpassword/releases) - [Commits](https://github.com/conradkleinespel/rpassword/compare/v4.0.5...v5.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- client/cli/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 827bf3b9985..8d44eec2623 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6250,9 +6250,9 @@ dependencies = [ [[package]] name = "rpassword" -version = "4.0.5" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" +checksum = "d755237fc0f99d98641540e66abac8bc46a0652f19148ac9e21de2da06b326c9" dependencies = [ "libc", "winapi 0.3.9", diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 900dddf8701..651b0a7286b 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -52,7 +52,7 @@ sc-cli-proc-macro = { version = "2.0.0", path = "./proc-macro" } thiserror = "1.0.21" [target.'cfg(not(target_os = "unknown"))'.dependencies] -rpassword = "4.0.1" +rpassword = "5.0.0" [dev-dependencies] tempfile = "3.1.0" -- GitLab From fee109326e092879b981232fac5eba0b6fdb7287 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Wed, 25 Nov 2020 23:48:47 +0100 Subject: [PATCH 049/163] remove std feature flags for assert macros (#7600) * remove std feature flags for assert macros * re-add note about availability in no_std envs --- frame/support/src/lib.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 5dd452dbbe7..3c191ed6ae4 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -102,9 +102,8 @@ pub enum Never {} /// /// - Using `static` to create a static parameter type. Its value is /// being provided by a static variable with the equivalent name in `UPPER_SNAKE_CASE`. An -/// additional `set` function is provided in this case to alter the static variable. -/// -/// **This is intended for testing ONLY and is ONLY available when `std` is enabled** +/// additional `set` function is provided in this case to alter the static variable. +/// **This is intended for testing ONLY and is ONLY available when `std` is enabled.** /// /// # Examples /// @@ -488,7 +487,6 @@ macro_rules! ensure { /// /// Used as `assert_noop(expression_to_assert, expected_error_expression)`. #[macro_export] -#[cfg(feature = "std")] macro_rules! assert_noop { ( $x:expr, @@ -504,7 +502,6 @@ macro_rules! assert_noop { /// /// Used as `assert_err!(expression_to_assert, expected_error_expression)` #[macro_export] -#[cfg(feature = "std")] macro_rules! assert_err { ( $x:expr , $y:expr $(,)? ) => { assert_eq!($x, Err($y.into())); @@ -516,7 +513,6 @@ macro_rules! assert_err { /// This can be used on`DispatchResultWithPostInfo` when the post info should /// be ignored. #[macro_export] -#[cfg(feature = "std")] macro_rules! assert_err_ignore_postinfo { ( $x:expr , $y:expr $(,)? ) => { $crate::assert_err!($x.map(|_| ()).map_err(|e| e.error), $y); @@ -525,7 +521,6 @@ macro_rules! assert_err_ignore_postinfo { /// Assert an expression returns error with the given weight. #[macro_export] -#[cfg(feature = "std")] macro_rules! assert_err_with_weight { ($call:expr, $err:expr, $weight:expr $(,)? ) => { if let Err(dispatch_err_with_post) = $call { @@ -542,7 +537,6 @@ macro_rules! assert_err_with_weight { /// Used as `assert_ok!(expression_to_assert, expected_ok_expression)`, /// or `assert_ok!(expression_to_assert)` which would assert against `Ok(())`. #[macro_export] -#[cfg(feature = "std")] macro_rules! assert_ok { ( $x:expr $(,)? ) => { let is = $x; -- GitLab From cff25fbc37c9fc564f8816eefdcd8dce15e1606b Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 26 Nov 2020 00:07:51 +0100 Subject: [PATCH 050/163] Add small header cache (#7516) * Remove header query * Header cache * Fix potential race issue * Simplify status query --- client/db/src/lib.rs | 59 ++++++++++++++++++++-------- client/service/src/client/client.rs | 4 +- primitives/blockchain/src/backend.rs | 2 +- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 8196a750557..983459cfebe 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -49,6 +49,9 @@ use std::sync::Arc; use std::path::{Path, PathBuf}; use std::io; use std::collections::{HashMap, HashSet}; +use parking_lot::{Mutex, RwLock}; +use linked_hash_map::LinkedHashMap; +use log::{trace, debug, warn}; use sc_client_api::{ UsageInfo, MemoryInfo, IoInfo, MemorySize, @@ -63,7 +66,6 @@ use codec::{Decode, Encode}; use hash_db::Prefix; use sp_trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; use sp_database::Transaction; -use parking_lot::RwLock; use sp_core::ChangesTrieConfiguration; use sp_core::offchain::storage::{OffchainOverlayedChange, OffchainOverlayedChanges}; use sp_core::storage::{well_known_keys, ChildInfo}; @@ -83,7 +85,6 @@ use sc_state_db::StateDb; use sp_blockchain::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::storage_cache::{CachingState, SyncingCachingState, SharedCache, new_shared_cache}; use crate::stats::StateUsageStats; -use log::{trace, debug, warn}; // Re-export the Database trait so that one can pass an implementation of it. pub use sp_database::Database; @@ -93,6 +94,7 @@ pub use sc_state_db::PruningMode; pub use bench::BenchmarkingState; const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u32 = 32768; +const CACHE_HEADERS: usize = 8; /// Default value for storage cache child ratio. const DEFAULT_CHILD_RATIO: (usize, usize) = (1, 10); @@ -352,12 +354,24 @@ impl<'a> sc_state_db::MetaDb for StateMetaDb<'a> { } } +fn cache_header( + cache: &mut LinkedHashMap>, + hash: Hash, + header: Option
, +) { + cache.insert(hash, header); + while cache.len() > CACHE_HEADERS { + cache.pop_front(); + } +} + /// Block database pub struct BlockchainDb { db: Arc>, meta: Arc, Block::Hash>>>, leaves: RwLock>>, header_metadata_cache: Arc>, + header_cache: Mutex>>, } impl BlockchainDb { @@ -369,6 +383,7 @@ impl BlockchainDb { leaves: RwLock::new(leaves), meta: Arc::new(RwLock::new(meta)), header_metadata_cache: Arc::new(HeaderMetadataCache::default()), + header_cache: Default::default(), }) } @@ -407,7 +422,20 @@ impl BlockchainDb { impl sc_client_api::blockchain::HeaderBackend for BlockchainDb { fn header(&self, id: BlockId) -> ClientResult> { - utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) + match &id { + BlockId::Hash(h) => { + let mut cache = self.header_cache.lock(); + if let Some(result) = cache.get_refresh(h) { + return Ok(result.clone()); + } + let header = utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id)?; + cache_header(&mut cache, h.clone(), header.clone()); + Ok(header) + } + BlockId::Number(_) => { + utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) + } + } } fn info(&self) -> sc_client_api::blockchain::Info { @@ -424,12 +452,7 @@ impl sc_client_api::blockchain::HeaderBackend for Blockcha fn status(&self, id: BlockId) -> ClientResult { let exists = match id { - BlockId::Hash(_) => read_db( - &*self.db, - columns::KEY_LOOKUP, - columns::HEADER, - id - )?.is_some(), + BlockId::Hash(_) => self.header(id)?.is_some(), BlockId::Number(n) => n <= self.meta.read().best_number, }; match exists { @@ -1117,12 +1140,6 @@ impl Backend { hash, )?; - let header_metadata = CachedHeaderMetadata::from(&pending_block.header); - self.blockchain.insert_header_metadata( - header_metadata.hash, - header_metadata, - ); - transaction.set_from_vec(columns::HEADER, &lookup_key, pending_block.header.encode()); if let Some(body) = &pending_block.body { transaction.set_from_vec(columns::BODY, &lookup_key, body.encode()); @@ -1271,7 +1288,7 @@ impl Backend { meta_updates.push((hash, number, pending_block.leaf_state.is_best(), finalized)); - Some((number, hash, enacted, retracted, displaced_leaf, is_best, cache)) + Some((pending_block.header, number, hash, enacted, retracted, displaced_leaf, is_best, cache)) } else { None }; @@ -1297,7 +1314,11 @@ impl Backend { self.storage.db.commit(transaction)?; + // Apply all in-memory state shanges. + // Code beyond this point can't fail. + if let Some(( + header, number, hash, enacted, @@ -1306,6 +1327,12 @@ impl Backend { is_best, mut cache, )) = imported { + let header_metadata = CachedHeaderMetadata::from(&header); + self.blockchain.insert_header_metadata( + header_metadata.hash, + header_metadata, + ); + cache_header(&mut self.blockchain.header_cache.lock(), hash, Some(header)); cache.sync_cache( &enacted, &retracted, diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index d423fdee39b..e8d748011bc 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -1159,12 +1159,12 @@ impl Client where /// Prepare in-memory header that is used in execution environment. fn prepare_environment_block(&self, parent: &BlockId) -> sp_blockchain::Result { - let parent_header = self.backend.blockchain().expect_header(*parent)?; + let parent_hash = self.backend.blockchain().expect_block_hash_from_id(parent)?; Ok(<::Header as HeaderT>::new( self.backend.blockchain().expect_block_number_from_id(parent)? + One::one(), Default::default(), Default::default(), - parent_header.hash(), + parent_hash, Default::default(), )) } diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 1328dfb5752..326acd6b9bd 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -53,7 +53,7 @@ pub trait HeaderBackend: Send + Sync { /// Convert an arbitrary block ID into a block hash. fn block_number_from_id(&self, id: &BlockId) -> Result>> { match *id { - BlockId::Hash(_) => Ok(self.header(*id)?.map(|h| h.number().clone())), + BlockId::Hash(h) => self.number(h), BlockId::Number(n) => Ok(Some(n)), } } -- GitLab From ac4366bcf9b6f6063d0edfdb6ac0625093142238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 26 Nov 2020 17:33:17 +0100 Subject: [PATCH 051/163] Inform sync explicitly about new best block (#7604) * Inform sync explicitly about new best block Instead of "fishing" the new best block out of the processed blocks, we now tell sync directly that there is a new best block. It also makes sure that we update the corresponding sync handshake to the new best block. This is required for parachains as they first import blocks and declare the new best block after being made aware of it by the relay chain. * Adds test * Make sure async stuff had time to run --- client/network/src/protocol.rs | 24 ++---------- client/network/src/service.rs | 33 +++++----------- client/network/test/src/lib.rs | 38 ++++++++++++++++--- client/network/test/src/sync.rs | 35 +++++++++++++++++ client/service/src/lib.rs | 4 +- client/service/test/src/lib.rs | 3 +- .../consensus/common/src/import_queue.rs | 2 +- 7 files changed, 84 insertions(+), 55 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 597031b9018..f794b106da2 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -528,10 +528,9 @@ impl Protocol { self.sync.num_sync_requests() } - /// Sync local state with the blockchain state. - pub fn update_chain(&mut self) { - let info = self.context_data.chain.info(); - self.sync.update_chain_info(&info.best_hash, info.best_number); + /// Inform sync about new best imported block. + pub fn new_best_block_imported(&mut self, hash: B::Hash, number: NumberFor) { + self.sync.update_chain_info(&hash, number); self.behaviour.set_legacy_handshake_message( build_status_message(&self.config, &self.context_data.chain), ); @@ -541,11 +540,6 @@ impl Protocol { ); } - /// Inform sync about an own imported block. - pub fn own_block_imported(&mut self, hash: B::Hash, number: NumberFor) { - self.sync.update_chain_info(&hash, number); - } - fn update_peer_info(&mut self, who: &PeerId) { if let Some(info) = self.sync.peer_info(who) { if let Some(ref mut peer) = self.context_data.peers.get_mut(who) { @@ -1258,18 +1252,6 @@ impl Protocol { count: usize, results: Vec<(Result>, BlockImportError>, B::Hash)> ) { - let new_best = results.iter().rev().find_map(|r| match r { - (Ok(BlockImportResult::ImportedUnknown(n, aux, _)), hash) if aux.is_new_best => Some((*n, hash.clone())), - _ => None, - }); - if let Some((best_num, best_hash)) = new_best { - self.sync.update_chain_info(&best_hash, best_num); - self.behaviour.set_legacy_handshake_message(build_status_message(&self.config, &self.context_data.chain)); - self.behaviour.set_notif_protocol_handshake( - &self.block_announces_protocol, - BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() - ); - } let results = self.sync.on_blocks_processed( imported, count, diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 8ef76d48506..0a87c37703d 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -484,11 +484,9 @@ impl NetworkWorker { self.network_service.user_protocol_mut().on_block_finalized(hash, &header); } - /// This should be called when blocks are added to the - /// chain by something other than the import queue. - /// Currently this is only useful for tests. - pub fn update_chain(&mut self) { - self.network_service.user_protocol_mut().update_chain(); + /// Inform the network service about new best imported block. + pub fn new_best_block_imported(&mut self, hash: B::Hash, number: NumberFor) { + self.network_service.user_protocol_mut().new_best_block_imported(hash, number); } /// Returns the local `PeerId`. @@ -1012,21 +1010,11 @@ impl NetworkService { self.num_connected.load(Ordering::Relaxed) } - /// This function should be called when blocks are added to the chain by something other - /// than the import queue. - /// - /// > **Important**: This function is a hack and can be removed at any time. Do **not** use it. - pub fn update_chain(&self) { - let _ = self - .to_worker - .unbounded_send(ServiceToWorkerMsg::UpdateChain); - } - - /// Inform the network service about an own imported block. - pub fn own_block_imported(&self, hash: B::Hash, number: NumberFor) { + /// Inform the network service about new best imported block. + pub fn new_best_block_imported(&self, hash: B::Hash, number: NumberFor) { let _ = self .to_worker - .unbounded_send(ServiceToWorkerMsg::OwnBlockImported(hash, number)); + .unbounded_send(ServiceToWorkerMsg::NewBestBlockImported(hash, number)); } /// Utility function to extract `PeerId` from each `Multiaddr` for priority group updates. @@ -1181,8 +1169,7 @@ enum ServiceToWorkerMsg { protocol_name: Cow<'static, str>, }, DisconnectPeer(PeerId), - UpdateChain, - OwnBlockImported(B::Hash, NumberFor), + NewBestBlockImported(B::Hash, NumberFor), } /// Main network worker. Must be polled in order for the network to advance. @@ -1319,10 +1306,8 @@ impl Future for NetworkWorker { this.network_service.register_notifications_protocol(protocol_name), ServiceToWorkerMsg::DisconnectPeer(who) => this.network_service.user_protocol_mut().disconnect_peer(&who), - ServiceToWorkerMsg::UpdateChain => - this.network_service.user_protocol_mut().update_chain(), - ServiceToWorkerMsg::OwnBlockImported(hash, number) => - this.network_service.user_protocol_mut().own_block_imported(hash, number), + ServiceToWorkerMsg::NewBestBlockImported(hash, number) => + this.network_service.user_protocol_mut().new_best_block_imported(hash, number), } } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 6950ada4f84..a70ecb4fb04 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -279,7 +279,7 @@ impl Peer { where F: FnMut(BlockBuilder) -> Block { let best_hash = self.client.info().best_hash; - self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block, false) + self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block, false, true) } /// Add blocks to the peer -- edit the block before adding. The chain will @@ -291,6 +291,7 @@ impl Peer { origin: BlockOrigin, mut edit_block: F, headers_only: bool, + inform_sync_about_new_best_block: bool, ) -> H256 where F: FnMut(BlockBuilder) -> Block { let full_client = self.client.as_full() .expect("blocks could only be generated by full clients"); @@ -328,7 +329,12 @@ impl Peer { at = hash; } - self.network.update_chain(); + if inform_sync_about_new_best_block { + self.network.new_best_block_imported( + at, + full_client.header(&BlockId::Hash(at)).ok().flatten().unwrap().number().clone(), + ); + } self.network.service().announce_block(at.clone(), Vec::new()); at } @@ -342,18 +348,36 @@ impl Peer { /// Push blocks to the peer (simplified: with or without a TX) pub fn push_headers(&mut self, count: usize) -> H256 { let best_hash = self.client.info().best_hash; - self.generate_tx_blocks_at(BlockId::Hash(best_hash), count, false, true) + self.generate_tx_blocks_at(BlockId::Hash(best_hash), count, false, true, true) } /// Push blocks to the peer (simplified: with or without a TX) starting from /// given hash. pub fn push_blocks_at(&mut self, at: BlockId, count: usize, with_tx: bool) -> H256 { - self.generate_tx_blocks_at(at, count, with_tx, false) + self.generate_tx_blocks_at(at, count, with_tx, false, true) + } + + /// Push blocks to the peer (simplified: with or without a TX) starting from + /// given hash without informing the sync protocol about the new best block. + pub fn push_blocks_at_without_informing_sync( + &mut self, + at: BlockId, + count: usize, + with_tx: bool, + ) -> H256 { + self.generate_tx_blocks_at(at, count, with_tx, false, false) } /// Push blocks/headers to the peer (simplified: with or without a TX) starting from /// given hash. - fn generate_tx_blocks_at(&mut self, at: BlockId, count: usize, with_tx: bool, headers_only:bool) -> H256 { + fn generate_tx_blocks_at( + &mut self, + at: BlockId, + count: usize, + with_tx: bool, + headers_only: bool, + inform_sync_about_new_best_block: bool, + ) -> H256 { let mut nonce = 0; if with_tx { self.generate_blocks_at( @@ -370,7 +394,8 @@ impl Peer { nonce = nonce + 1; builder.build().unwrap().block }, - headers_only + headers_only, + inform_sync_about_new_best_block, ) } else { self.generate_blocks_at( @@ -379,6 +404,7 @@ impl Peer { BlockOrigin::File, |builder| builder.build().unwrap().block, headers_only, + inform_sync_about_new_best_block, ) } } diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 64985871d85..9a488ae4fa4 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -779,3 +779,38 @@ fn wait_until_deferred_block_announce_validation_is_ready() { net.block_until_idle(); } } + +/// When we don't inform the sync protocol about the best block, a node will not sync from us as the +/// handshake is not does not contain our best block. +#[test] +fn sync_to_tip_requires_that_sync_protocol_is_informed_about_best_block() { + sp_tracing::try_init_simple(); + log::trace!(target: "sync", "Test"); + let mut net = TestNet::new(1); + + // Produce some blocks + let block_hash = net.peer(0).push_blocks_at_without_informing_sync(BlockId::Number(0), 3, true); + + // Add a node and wait until they are connected + net.add_full_peer_with_config(Default::default()); + net.block_until_connected(); + net.block_until_idle(); + + // The peer should not have synced the block. + assert!(!net.peer(1).has_block(&block_hash)); + + // Make sync protocol aware of the best block + net.peer(0).network_service().new_best_block_imported(block_hash, 3); + net.block_until_idle(); + + // Connect another node that should now sync to the tip + net.add_full_peer_with_config(Default::default()); + net.block_until_connected(); + + while !net.peer(2).has_block(&block_hash) { + net.block_until_idle(); + } + + // However peer 1 should still not have the block. + assert!(!net.peer(1).has_block(&block_hash)); +} diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index fd5ad9ebac9..fdccbde6a02 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -250,8 +250,8 @@ async fn build_network_future< network.service().announce_block(notification.hash, Vec::new()); } - if let sp_consensus::BlockOrigin::Own = notification.origin { - network.service().own_block_imported( + if notification.is_new_best { + network.service().new_best_block_imported( notification.hash, notification.header.number().clone(), ); diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 8a9f0ace171..28930473f0a 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -542,7 +542,8 @@ pub fn sync( make_block_and_import(&first_service, first_user_data); } - network.full_nodes[0].1.network().update_chain(); + let info = network.full_nodes[0].1.client().info(); + network.full_nodes[0].1.network().new_best_block_imported(info.best_hash, info.best_number); network.full_nodes[0].3.clone() }; diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index 3ad8c7c92e0..b32ca0133d9 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -136,7 +136,7 @@ pub trait Link: Send { /// Block import successful result. #[derive(Debug, PartialEq)] -pub enum BlockImportResult { +pub enum BlockImportResult { /// Imported known block. ImportedKnown(N), /// Imported unknown block. -- GitLab From 021da1f333bae97967365ec4ca5c24209e0cbb70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Nov 2020 09:40:11 +0100 Subject: [PATCH 052/163] Bump directories from 2.0.2 to 3.0.1 (#7609) Bumps [directories](https://github.com/soc/directories-rs) from 2.0.2 to 3.0.1. - [Release notes](https://github.com/soc/directories-rs/releases) - [Commits](https://github.com/soc/directories-rs/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 +++++++++++-- client/service/Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d44eec2623..b4443dd4384 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,6 +1250,15 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "directories" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-sys" version = "0.3.5" @@ -7320,7 +7329,7 @@ version = "0.8.0" dependencies = [ "async-std", "derive_more", - "directories", + "directories 3.0.1", "exit-future", "futures 0.1.30", "futures 0.3.8", @@ -10153,7 +10162,7 @@ dependencies = [ "cranelift-entity", "cranelift-frontend", "cranelift-wasm", - "directories", + "directories 2.0.2", "errno", "file-per-thread-logger", "indexmap", diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 3d0b00820fe..23af49d38b1 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -82,7 +82,7 @@ parity-util-mem = { version = "0.7.0", default-features = false, features = ["pr [target.'cfg(not(target_os = "unknown"))'.dependencies] tempfile = "3.1.0" -directories = "2.0.2" +directories = "3.0.1" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } -- GitLab From 07a87405e04ae7ccfc4e5d3c22230fd9efa5529e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Nov 2020 10:24:34 +0100 Subject: [PATCH 053/163] Remove `RpcMetrics` weirdness (#7608) * Remove `RpcMetrics` weirdness The metrics was returning an error when prometheus was not given. This was a really weird setup, especially when compared to all other metrics that just do nothing if there is no registry. * Fix browser build --- client/rpc-servers/src/middleware.rs | 41 ++++++++++++++++------------ client/service/src/builder.rs | 6 ++-- client/service/src/lib.rs | 10 +++---- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/client/rpc-servers/src/middleware.rs b/client/rpc-servers/src/middleware.rs index 74139714c8c..233ceab3cf8 100644 --- a/client/rpc-servers/src/middleware.rs +++ b/client/rpc-servers/src/middleware.rs @@ -32,36 +32,41 @@ use futures::{future::Either, Future}; /// Metrics for RPC middleware #[derive(Debug, Clone)] pub struct RpcMetrics { - rpc_calls: CounterVec, + rpc_calls: Option>, } impl RpcMetrics { /// Create an instance of metrics pub fn new(metrics_registry: Option<&Registry>) -> Result { - metrics_registry.and_then(|r| { - Some(RpcMetrics { - rpc_calls: register(CounterVec::new( - Opts::new( - "rpc_calls_total", - "Number of rpc calls received", - ), - &["protocol"] - ).ok()?, r).ok()?, - }) - }).ok_or(PrometheusError::Msg("Cannot register metric".to_string())) + Ok(Self { + rpc_calls: metrics_registry.map(|r| + register( + CounterVec::new( + Opts::new( + "rpc_calls_total", + "Number of rpc calls received", + ), + &["protocol"] + )?, + r, + ) + ).transpose()?, + }) } } /// Middleware for RPC calls pub struct RpcMiddleware { - metrics: Option, + metrics: RpcMetrics, transport_label: String, } impl RpcMiddleware { - /// Create an instance of middleware with provided metrics - /// transport_label is used as a label for Prometheus collector - pub fn new(metrics: Option, transport_label: &str) -> Self { + /// Create an instance of middleware. + /// + /// - `metrics`: Will be used to report statistics. + /// - `transport_label`: The label that is used when reporting the statistics. + pub fn new(metrics: RpcMetrics, transport_label: &str) -> Self { RpcMiddleware { metrics, transport_label: String::from(transport_label), @@ -78,8 +83,8 @@ impl RequestMiddleware for RpcMiddleware { F: Fn(Request, M) -> X + Send + Sync, X: Future, Error = ()> + Send + 'static, { - if let Some(ref metrics) = self.metrics { - metrics.rpc_calls.with_label_values(&[self.transport_label.as_str()]).inc(); + if let Some(ref rpc_calls) = self.metrics.rpc_calls { + rpc_calls.with_label_values(&[self.transport_label.as_str()]).inc(); } Either::B(next(request, meta)) diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index d9dc0d1c6ba..52c1121d504 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -603,12 +603,12 @@ pub fn spawn_tasks( on_demand.clone(), remote_blockchain.clone(), &*rpc_extensions_builder, backend.offchain_storage(), system_rpc_tx.clone() ); - let rpc_metrics = sc_rpc_server::RpcMetrics::new(config.prometheus_registry()).ok(); - let rpc = start_rpc_servers(&config, gen_handler, rpc_metrics.as_ref())?; + let rpc_metrics = sc_rpc_server::RpcMetrics::new(config.prometheus_registry())?; + let rpc = start_rpc_servers(&config, gen_handler, rpc_metrics.clone())?; // This is used internally, so don't restrict access to unsafe RPC let rpc_handlers = RpcHandlers(Arc::new(gen_handler( sc_rpc::DenyUnsafe::No, - sc_rpc_server::RpcMiddleware::new(rpc_metrics.as_ref().cloned(), "inbrowser") + sc_rpc_server::RpcMiddleware::new(rpc_metrics, "inbrowser") ).into())); // Telemetry diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index fdccbde6a02..cd129de3260 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -401,7 +401,7 @@ fn start_rpc_servers< >( config: &Configuration, mut gen_handler: H, - rpc_metrics: Option<&sc_rpc_server::RpcMetrics> + rpc_metrics: sc_rpc_server::RpcMetrics, ) -> Result, error::Error> { fn maybe_start_server(address: Option, mut start: F) -> Result, io::Error> where F: FnMut(&SocketAddr) -> Result, @@ -434,7 +434,7 @@ fn start_rpc_servers< config.rpc_ipc.as_ref().map(|path| sc_rpc_server::start_ipc( &*path, gen_handler( sc_rpc::DenyUnsafe::No, - sc_rpc_server::RpcMiddleware::new(rpc_metrics.cloned(), "ipc") + sc_rpc_server::RpcMiddleware::new(rpc_metrics.clone(), "ipc") ) )), maybe_start_server( @@ -444,7 +444,7 @@ fn start_rpc_servers< config.rpc_cors.as_ref(), gen_handler( deny_unsafe(&address, &config.rpc_methods), - sc_rpc_server::RpcMiddleware::new(rpc_metrics.cloned(), "http") + sc_rpc_server::RpcMiddleware::new(rpc_metrics.clone(), "http") ), ), )?.map(|s| waiting::HttpServer(Some(s))), @@ -456,7 +456,7 @@ fn start_rpc_servers< config.rpc_cors.as_ref(), gen_handler( deny_unsafe(&address, &config.rpc_methods), - sc_rpc_server::RpcMiddleware::new(rpc_metrics.cloned(), "ws") + sc_rpc_server::RpcMiddleware::new(rpc_metrics.clone(), "ws") ), ), )?.map(|s| waiting::WsServer(Some(s))), @@ -471,7 +471,7 @@ fn start_rpc_servers< >( _: &Configuration, _: H, - _: Option<&sc_rpc_server::RpcMetrics> + _: sc_rpc_server::RpcMetrics, ) -> Result, error::Error> { Ok(Box::new(())) } -- GitLab From 6c0cd2a35b86957cf5fbe01d7f7b94f58d191781 Mon Sep 17 00:00:00 2001 From: Roman Borschel Date: Fri, 27 Nov 2020 15:29:18 +0100 Subject: [PATCH 054/163] Upgrade to libp2p-0.31. (#7606) * Upgrade to libp2p-0.31. * Address line width. * Add generous incoming connection limit. * Remove old noise configuration. --- Cargo.lock | 145 ++++++++++-------- bin/node/browser-testing/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/authority-discovery/src/error.rs | 2 +- client/authority-discovery/src/worker.rs | 2 +- .../src/worker/addr_cache.rs | 4 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 +- client/network/src/discovery.rs | 8 +- client/network/src/lib.rs | 3 + client/network/src/light_client_handler.rs | 3 +- client/network/src/peer_info.rs | 8 +- client/network/src/protocol.rs | 4 +- client/network/src/request_responses.rs | 4 +- client/network/src/service.rs | 61 ++++++-- client/network/src/transport.rs | 26 +--- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- frame/support/procedural/tools/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 23 files changed, 167 insertions(+), 127 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4443dd4384..7444178d73b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,7 +323,7 @@ dependencies = [ "futures-io", "rustls", "webpki", - "webpki-roots", + "webpki-roots 0.20.0", ] [[package]] @@ -489,17 +489,6 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake2s_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - [[package]] name = "block-buffer" version = "0.7.3" @@ -2876,9 +2865,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.30.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c2b4c99f8798be90746fc226acf95d3e6cff0655883634cc30dab1f64f438b" +checksum = "24966e73cc5624a6cf14b025365f67cb6da436b4d6337ed84d198063ba74451d" dependencies = [ "atomic", "bytes 0.5.6", @@ -2905,7 +2894,6 @@ dependencies = [ "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", - "multihash", "parity-multiaddr", "parking_lot 0.11.1", "pin-project 1.0.2", @@ -2915,12 +2903,13 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.24.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8186060d6bd415e4e928e6cb44c4fe7e7a7dd53437bd936ce7e5f421e45a51" +checksum = "28d92fab5df60c9705e05750d9ecee6a5af15aed1e3fa86e09fd3dd07ec5dc8e" dependencies = [ "asn1_der", "bs58", + "bytes 0.5.6", "ed25519-dalek", "either", "fnv", @@ -2949,9 +2938,9 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213" +checksum = "f4bc40943156e42138d22ed3c57ff0e1a147237742715937622a99b10fbe0156" dependencies = [ "quote", "syn", @@ -2959,9 +2948,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aea69349e70a58ef9ecd21ac12c5eaa36255ac6986828079d26393f9e618cb" +checksum = "5a579d7dd506d0620ba88ccc1754436b7de35ed6c884234f9a226bbfce382640" dependencies = [ "flate2", "futures 0.3.8", @@ -2970,9 +2959,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0baeff71fb5cb1fe1604f74a712a44b66a8c5900f4022411a1d550f09d6bb776" +checksum = "15dea5933f570844d7b5222b12b58f7bd52e9ca38cd65a1bd4f35341f053f012" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -2981,9 +2970,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0f925a45f310b678e70faf71a10023b829d02eb9cc2628a63de928936f3ade" +checksum = "23070a0838bd9a8adb27e6eba477eeb650c498f9d139383dd0135d20a8170253" dependencies = [ "cuckoofilter", "fnv", @@ -2999,9 +2988,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efeb65567174974f551a91f9f5719445b6695cad56f6a7a47a27111f37efb6b8" +checksum = "65e8f3aa0906fbad435dac23c177eef3cdfaaf62609791bd7f54f8553edcfdf9" dependencies = [ "base64 0.13.0", "byteorder", @@ -3025,9 +3014,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e074124669840484de564901d47f2d0892e73f6d8ee7c37e9c2644af1b217bf4" +checksum = "802fb973a7e0dde3fb9a2113a62bad90338ebe01983b706e1d576d0c2af93cda" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -3041,9 +3030,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a2653b2e3254a3bbeb66bfc3f0dca7d6cba6aa2a96791db114003dec1b5394" +checksum = "6506b7b7982f7626fc96a91bc61be4b1fe7ae9ac23824f0ecefcce21cb39238c" dependencies = [ "arrayvec 0.5.2", "bytes 0.5.6", @@ -3054,7 +3043,6 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "multihash", "prost", "prost-build", "rand 0.7.3", @@ -3068,9 +3056,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786b068098794322239f8f04df88a52daeb7863b2e77501c4d85d32e0a8f2d26" +checksum = "4458ec36b5ab2662fb4d5c8bb9b6e1591da0ab6efe8881c7a7670ef033bc8937" dependencies = [ "async-std", "data-encoding", @@ -3090,9 +3078,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed764eab613a8fb6b7dcf6c796f55a06fef2270e528329903e25cd3311b99663" +checksum = "ae2132b14045009b0f8e577a06e1459592ef0a89dedc58f3d4baf4eac956837b" dependencies = [ "bytes 0.5.6", "futures 0.3.8", @@ -3108,9 +3096,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb441fb015ec16690099c5d910fcba271d357763b3dcb784db7b27bbb0b68372" +checksum = "b9610a524bef4db383cd96b4ec3ec4722eafa72c7242fa89990b74166760583d" dependencies = [ "bytes 0.5.6", "curve25519-dalek 3.0.0", @@ -3130,9 +3118,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e5c50936cfdbe96a514e8992f304fa44cd3a681b6f779505f1ae62b3474705" +checksum = "659adf89356e04f65398bb74ee791b269e63da9e41b37f8dc19eaacd12487bfe" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -3145,9 +3133,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21026557c335d3639591f247b19b7536195772034ec7e9c463137227f95eaaa1" +checksum = "96dfe26270c91d4ff095030d1fcadd602f3fd84968ebd592829916d0715798a6" dependencies = [ "bytes 0.5.6", "futures 0.3.8", @@ -3176,9 +3164,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd9a1e0e6563dec1c9e702f7e68bdaa43da62a84536aa06372d3fed3e25d4ca" +checksum = "1e952dcc9d2d7e7e45ae8bfcff255723091bd43e3e9a7741a0af8a17fe55b3ed" dependencies = [ "async-trait", "bytes 0.5.6", @@ -3196,9 +3184,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "565f0e06674b4033c978471e4083d5aaa8e03cef0719a0ec0905aaeaad39a919" +checksum = "de333c483f27d02ecf7b6cef814a36f5e1876f15139eefb00225c405350e1c22" dependencies = [ "either", "futures 0.3.8", @@ -3212,9 +3200,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.24.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33f3dce259c0d3127af5167f45c275b6c047320efdd0e40fde947482487af0a3" +checksum = "bc28c9ad6dc43f4c3950411cf808639d90307a076330e7996e5e94e70279bde0" dependencies = [ "async-std", "futures 0.3.8", @@ -3228,9 +3216,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0aba04370a00d8d0236e350bc862926c1b42542a169aa6a481e660e5b990fe" +checksum = "9d821208d4b9af4b293a56dde470edd9f9fac8bb94a51f4f5327cc29a471b3f3" dependencies = [ "async-std", "futures 0.3.8", @@ -3240,9 +3228,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c703816f4170477a375b49c56d349e535ce68388f81ba1d9a3c8e2517effa82" +checksum = "1e6ef400b231ba78e866b860445480ca21ee447e03034138c6d57cf2969d6bf4" dependencies = [ "futures 0.3.8", "js-sys", @@ -3254,9 +3242,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5e7268a959748040a0cf7456ad655be55b87f0ceda03bdb5b53674726b28f7" +checksum = "a5736e2fccdcea6e728bbaf903bddc113be223313ce2c756ad9fe43b5a2b0f06" dependencies = [ "async-tls", "either", @@ -3269,14 +3257,14 @@ dependencies = [ "soketto", "url 2.2.0", "webpki", - "webpki-roots", + "webpki-roots 0.21.0", ] [[package]] name = "libp2p-yamux" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0798cbb58535162c40858493d09af06eac42a26e4966e58de0df701f559348" +checksum = "3be7ac000fa3e42ac09a6e658e48de34ac8ef9fff64a4e6e6b08dcc8f4b0e5f6" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -3644,19 +3632,31 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multihash" -version = "0.11.4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6" +checksum = "fb63389ee5fcd4df3f8727600f4a0c3df53c541f0ed4e8b50a9ae51a80fc1efe" dependencies = [ - "blake2b_simd", - "blake2s_simd", "digest 0.9.0", - "sha-1 0.9.2", + "generic-array 0.14.4", + "multihash-derive", "sha2 0.9.2", - "sha3", "unsigned-varint", ] +[[package]] +name = "multihash-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5653449cd45d502a53480ee08d7a599e8f4893d2bacb33c63d65bc20af6c1a" +dependencies = [ + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "multimap" version = "0.8.2" @@ -3665,9 +3665,9 @@ checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" [[package]] name = "multistream-select" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93faf2e41f9ee62fb01680ed48f3cc26652352327aa2e59869070358f6b7dd75" +checksum = "46e19fd46149acdd3600780ebaa09f6ae4e7f2ddbafec64aab54cf75aafd1746" dependencies = [ "bytes 0.5.6", "futures 0.3.8", @@ -5186,9 +5186,9 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.9.6" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43244a26dc1ddd3097216bb12eaa6cf8a07b060c72718d9ebd60fd297d6401df" +checksum = "2f51a30667591b14f96068b2d12f1306d07a41ebd98239d194356d4d9707ac16" dependencies = [ "arrayref", "bs58", @@ -9740,7 +9740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ "cfg-if 0.1.10", - "rand 0.7.3", + "rand 0.3.23", "static_assertions", ] @@ -10309,6 +10309,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82015b7e0b8bad8185994674a13a93306bea76cf5a16c5a181382fd3a5ec2376" +dependencies = [ + "webpki", +] + [[package]] name = "wepoll-sys" version = "3.0.1" diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index e072607a7b6..f1cad30aede 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index fc948de53eb..0d2a254c6b1 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -23,7 +23,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.30.1", default-features = false, features = ["kad"] } +libp2p = { version = "0.31.1", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index 48bcdf33114..82e4a6dd6f3 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -31,7 +31,7 @@ pub enum Error { /// Failed to verify a dht payload with the given signature. VerifyingDhtPayload, /// Failed to hash the authority id to be used as a dht key. - HashingAuthorityId(libp2p::core::multiaddr::multihash::EncodeError), + HashingAuthorityId(libp2p::core::multiaddr::multihash::Error), /// Failed calling into the Substrate runtime. CallingRuntime(sp_blockchain::Error), /// Received a dht record with a key that does not match any in-flight awaited keys. diff --git a/client/authority-discovery/src/worker.rs b/client/authority-discovery/src/worker.rs index c8e7a9f7aee..45b55f76673 100644 --- a/client/authority-discovery/src/worker.rs +++ b/client/authority-discovery/src/worker.rs @@ -28,7 +28,7 @@ use futures::{FutureExt, Stream, StreamExt, stream::Fuse}; use addr_cache::AddrCache; use async_trait::async_trait; use codec::Decode; -use libp2p::{core::multiaddr, multihash::Multihash}; +use libp2p::{core::multiaddr, multihash::{Multihash, Hasher}}; use log::{debug, error, log_enabled}; use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register}; use prost::Message; diff --git a/client/authority-discovery/src/worker/addr_cache.rs b/client/authority-discovery/src/worker/addr_cache.rs index a2cd3f33e92..75fcaa84017 100644 --- a/client/authority-discovery/src/worker/addr_cache.rs +++ b/client/authority-discovery/src/worker/addr_cache.rs @@ -139,7 +139,7 @@ fn peer_id_from_multiaddr(addr: &Multiaddr) -> Option { mod tests { use super::*; - use libp2p::multihash; + use libp2p::multihash::{self, Multihash}; use quickcheck::{Arbitrary, Gen, QuickCheck, TestResult}; use rand::Rng; @@ -163,7 +163,7 @@ mod tests { fn arbitrary(g: &mut G) -> Self { let seed: [u8; 32] = g.gen(); let peer_id = PeerId::from_multihash( - multihash::wrap(multihash::Code::Sha2_256, &seed) + Multihash::wrap(multihash::Code::Sha2_256.into(), &seed).unwrap() ).unwrap(); let multiaddr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse::() .unwrap() diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 651b0a7286b..45312202e86 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -21,7 +21,7 @@ ansi_term = "0.12.1" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.30.1" +libp2p = "0.31.1" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 02d93453239..edd993ce505 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } log = "0.4.8" lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index dac2cb22c4f..123ef6ddbc7 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -64,13 +64,13 @@ wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.30.1" +version = "0.31.1" default-features = false features = ["identify", "kad", "mdns-async-std", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 717aec01f75..e65d557a7bd 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -736,8 +736,8 @@ impl NetworkBehaviour for DiscoveryBehaviour { handler, event: (pid.clone(), event) }), - NetworkBehaviourAction::ReportObservedAddr { address } => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + NetworkBehaviourAction::ReportObservedAddr { address, score } => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }), } } } @@ -767,8 +767,8 @@ impl NetworkBehaviour for DiscoveryBehaviour { return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), NetworkBehaviourAction::NotifyHandler { event, .. } => match event {}, // `event` is an enum with no variant - NetworkBehaviourAction::ReportObservedAddr { address } => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + NetworkBehaviourAction::ReportObservedAddr { address, score } => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }), } } diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index b050db8785a..91ea49bce76 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -283,6 +283,9 @@ use sp_runtime::traits::{Block as BlockT, NumberFor}; /// two peers, the per-peer connection limit is not set to 1 but 2. const MAX_CONNECTIONS_PER_PEER: usize = 2; +/// The maximum number of concurrent established connections that were incoming. +const MAX_CONNECTIONS_ESTABLISHED_INCOMING: u32 = 10_000; + /// Minimum Requirements for a Hash within Networking pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index b72362fdfc3..27f1a9deea4 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -44,6 +44,7 @@ use libp2p::{ upgrade::{OutboundUpgrade, read_one, write_one} }, swarm::{ + AddressRecord, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, @@ -1463,7 +1464,7 @@ mod tests { impl PollParameters for EmptyPollParams { type SupportedProtocolsIter = iter::Empty>; type ListenedAddressesIter = iter::Empty; - type ExternalAddressesIter = iter::Empty; + type ExternalAddressesIter = iter::Empty; fn supported_protocols(&self) -> Self::SupportedProtocolsIter { iter::empty() diff --git a/client/network/src/peer_info.rs b/client/network/src/peer_info.rs index e69ad2b17e5..0bf2fe59fa2 100644 --- a/client/network/src/peer_info.rs +++ b/client/network/src/peer_info.rs @@ -304,8 +304,8 @@ impl NetworkBehaviour for PeerInfoBehaviour { handler, event: EitherOutput::First(event) }), - Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }) => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }), } } @@ -334,8 +334,8 @@ impl NetworkBehaviour for PeerInfoBehaviour { handler, event: EitherOutput::Second(event) }), - Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }) => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }), } } diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index f794b106da2..9a8cfe7e1ff 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1489,8 +1489,8 @@ impl NetworkBehaviour for Protocol { return Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }), Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }) => return Poll::Ready(NetworkBehaviourAction::NotifyHandler { peer_id, handler, event }), - Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }) => - return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address }), + Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }) => + return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { address, score }), }; let outcome = match event { diff --git a/client/network/src/request_responses.rs b/client/network/src/request_responses.rs index a3a68f719d6..69a2ffda1c8 100644 --- a/client/network/src/request_responses.rs +++ b/client/network/src/request_responses.rs @@ -398,9 +398,9 @@ impl NetworkBehaviour for RequestResponsesBehaviour { event: ((*protocol).to_string(), event), }) } - NetworkBehaviourAction::ReportObservedAddr { address } => { + NetworkBehaviourAction::ReportObservedAddr { address, score } => { return Poll::Ready(NetworkBehaviourAction::ReportObservedAddr { - address, + address, score, }) } }; diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 0a87c37703d..c722c3e32d7 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -39,15 +39,40 @@ use crate::{ }, on_demand_layer::AlwaysBadChecker, light_client_handler, block_requests, - protocol::{self, event::Event, NotifsHandlerError, NotificationsSink, Ready, sync::SyncState, PeerInfo, Protocol}, + protocol::{ + self, + NotifsHandlerError, + NotificationsSink, + PeerInfo, + Protocol, + Ready, + event::Event, + sync::SyncState, + }, transport, ReputationChange, }; use futures::{channel::oneshot, prelude::*}; use libp2p::{PeerId, multiaddr, Multiaddr}; -use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}, either::EitherError}; +use libp2p::core::{ + ConnectedPoint, + Executor, + connection::{ + ConnectionLimits, + ConnectionError, + PendingConnectionError + }, + either::EitherError, + upgrade +}; use libp2p::kad::record; use libp2p::ping::handler::PingFailure; -use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handler::NodeHandlerWrapperError}; +use libp2p::swarm::{ + AddressScore, + NetworkBehaviour, + SwarmBuilder, + SwarmEvent, + protocols_handler::NodeHandlerWrapperError +}; use log::{error, info, trace, warn}; use metrics::{Metrics, MetricSources, Histogram, HistogramVec}; use parking_lot::Mutex; @@ -332,7 +357,11 @@ impl NetworkWorker { transport::build_transport(local_identity, config_mem, config_wasm) }; let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()) - .peer_connection_limit(crate::MAX_CONNECTIONS_PER_PEER) + .connection_limits(ConnectionLimits::default() + .with_max_established_per_peer(Some(crate::MAX_CONNECTIONS_PER_PEER as u32)) + .with_max_established_incoming(Some(crate::MAX_CONNECTIONS_ESTABLISHED_INCOMING)) + ) + .substream_upgrade_protocol_override(upgrade::Version::V1Lazy) .notify_handler_buffer_size(NonZeroUsize::new(32).expect("32 != 0; qed")) .connection_event_buffer_size(1024); if let Some(spawner) = params.executor { @@ -368,7 +397,7 @@ impl NetworkWorker { // Add external addresses. for addr in ¶ms.network_config.public_addresses { - Swarm::::add_external_address(&mut swarm, addr.clone()); + Swarm::::add_external_address(&mut swarm, addr.clone(), AddressScore::Infinite); } let external_addresses = Arc::new(Mutex::new(Vec::new())); @@ -551,10 +580,17 @@ impl NetworkWorker { .collect() }; + let peer_id = Swarm::::local_peer_id(&swarm).to_base58(); + let listened_addresses = Swarm::::listeners(&swarm).cloned().collect(); + let external_addresses = Swarm::::external_addresses(&swarm) + .map(|r| &r.addr) + .cloned() + .collect(); + NetworkState { - peer_id: Swarm::::local_peer_id(&swarm).to_base58(), - listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), - external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), + peer_id, + listened_addresses, + external_addresses, connected_peers, not_connected_peers, peerset: swarm.user_protocol_mut().peerset_debug_info(), @@ -1660,7 +1696,10 @@ impl Future for NetworkWorker { // Update the variables shared with the `NetworkService`. this.num_connected.store(num_connected_peers, Ordering::Relaxed); { - let external_addresses = Swarm::::external_addresses(&this.network_service).cloned().collect(); + let external_addresses = Swarm::::external_addresses(&this.network_service) + .map(|r| &r.addr) + .cloned() + .collect(); *this.external_addresses.lock() = external_addresses; } @@ -1687,7 +1726,9 @@ impl Future for NetworkWorker { } metrics.peerset_num_discovered.set(this.network_service.user_protocol().num_discovered_peers() as u64); metrics.peerset_num_requested.set(this.network_service.user_protocol().requested_peers().count() as u64); - metrics.pending_connections.set(Swarm::network_info(&this.network_service).num_connections_pending as u64); + metrics.pending_connections.set( + Swarm::network_info(&this.network_service).connection_counters().num_pending() as u64 + ); } Poll::Pending diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index 035b3a9716a..4bf252d5797 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -17,9 +17,9 @@ // along with this program. If not, see . use libp2p::{ - InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, + PeerId, Transport, core::{ - self, either::{EitherOutput, EitherTransport}, muxing::StreamMuxerBox, + self, either::EitherTransport, muxing::StreamMuxerBox, transport::{Boxed, OptionalTransport}, upgrade }, mplex, identity, bandwidth, wasm_ext, noise @@ -74,11 +74,7 @@ pub fn build_transport( // For more information about these two panics, see in "On the Importance of // Checking Cryptographic Protocols for Faults" by Dan Boneh, Richard A. DeMillo, // and Richard J. Lipton. - let noise_keypair_legacy = noise::Keypair::::new().into_authentic(&keypair) - .expect("can only fail in case of a hardware bug; since this signing is performed only \ - once and at initialization, we're taking the bet that the inconvenience of a very \ - rare panic here is basically zero"); - let noise_keypair_spec = noise::Keypair::::new().into_authentic(&keypair) + let noise_keypair = noise::Keypair::::new().into_authentic(&keypair) .expect("can only fail in case of a hardware bug; since this signing is performed only \ once and at initialization, we're taking the bet that the inconvenience of a very \ rare panic here is basically zero"); @@ -87,19 +83,9 @@ pub fn build_transport( let mut noise_legacy = noise::LegacyConfig::default(); noise_legacy.recv_legacy_handshake = true; - let mut xx_config = noise::NoiseConfig::xx(noise_keypair_spec); + let mut xx_config = noise::NoiseConfig::xx(noise_keypair); xx_config.set_legacy_config(noise_legacy.clone()); - let mut ix_config = noise::NoiseConfig::ix(noise_keypair_legacy); - ix_config.set_legacy_config(noise_legacy); - - let extract_peer_id = |result| match result { - EitherOutput::First((peer_id, o)) => (peer_id, EitherOutput::First(o)), - EitherOutput::Second((peer_id, o)) => (peer_id, EitherOutput::Second(o)), - }; - - core::upgrade::SelectUpgrade::new(xx_config.into_authenticated(), ix_config.into_authenticated()) - .map_inbound(extract_peer_id) - .map_outbound(extract_peer_id) + xx_config.into_authenticated() }; let multiplexing_config = { @@ -115,7 +101,7 @@ pub fn build_transport( core::upgrade::SelectUpgrade::new(yamux_config, mplex_config) }; - let transport = transport.upgrade(upgrade::Version::V1) + let transport = transport.upgrade(upgrade::Version::V1Lazy) .authenticate(authentication_config) .multiplex(multiplexing_config) .timeout(Duration::from_secs(20)) diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index a74aa90d4f4..84fc5e2ef78 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index efca00a24de..8ec83b6fd64 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index fab0fe00869..a91d55e0c06 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.5" -libp2p = { version = "0.30.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.31.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index 2cff2473b85..b9a9cc7adb0 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -16,4 +16,4 @@ frame-support-procedural-tools-derive = { version = "2.0.0", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } -proc-macro-crate = "0.1.4" +proc-macro-crate = "0.1.5" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 938745048c1..a76abfcea36 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.30.1", default-features = false } +libp2p = { version = "0.31.1", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 4f35cd98803..e56fea11a38 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] futures = { version = "0.3", features = ["compat"] } futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.24", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.25", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From c116342f207d9e59f6489b7f55218c650f978200 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 27 Nov 2020 16:54:45 +0100 Subject: [PATCH 055/163] Add Key Subcommand to node-template (#7615) --- bin/node-template/node/src/cli.rs | 2 ++ bin/node-template/node/src/command.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/bin/node-template/node/src/cli.rs b/bin/node-template/node/src/cli.rs index f2faf17e4dd..947123a6bbf 100644 --- a/bin/node-template/node/src/cli.rs +++ b/bin/node-template/node/src/cli.rs @@ -12,6 +12,8 @@ pub struct Cli { #[derive(Debug, StructOpt)] pub enum Subcommand { + /// Key management cli utilities + Key(sc_cli::KeySubcommand), /// Build a chain specification. BuildSpec(sc_cli::BuildSpecCmd), diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index ac950b50483..5c41643a293 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -66,6 +66,7 @@ pub fn run() -> sc_cli::Result<()> { let cli = Cli::from_args(); match &cli.subcommand { + Some(Subcommand::Key(cmd)) => cmd.run(), Some(Subcommand::BuildSpec(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) -- GitLab From de44c00109ea19de13ef9219f8888f968d484b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 27 Nov 2020 17:36:58 +0100 Subject: [PATCH 056/163] Forward storage changes in manual seal (#7614) This prevents nodes from executing the same block 2 times. --- client/consensus/manual-seal/src/lib.rs | 10 +++++----- client/consensus/manual-seal/src/seal_block.rs | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 5a1cd0f79b4..9c4465f82fd 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -163,10 +163,10 @@ pub async fn run_manual_seal( C: HeaderBackend + Finalizer + ProvideRuntimeApi + 'static, CB: ClientBackend + 'static, E: Environment + 'static, - E::Error: std::fmt::Display, - >::Error: std::fmt::Display, + E::Proposer: Proposer>, CS: Stream::Hash>> + Unpin + 'static, SC: SelectChain + 'static, + TransactionFor: 'static, { while let Some(command) = commands_stream.next().await { match command { @@ -230,9 +230,9 @@ pub async fn run_instant_seal( C: HeaderBackend + Finalizer + ProvideRuntimeApi + 'static, CB: ClientBackend + 'static, E: Environment + 'static, - E::Error: std::fmt::Display, - >::Error: std::fmt::Display, - SC: SelectChain + 'static + E::Proposer: Proposer>, + SC: SelectChain + 'static, + TransactionFor: 'static, { // instant-seal creates blocks as soon as transactions are imported // into the transaction pool. diff --git a/client/consensus/manual-seal/src/seal_block.rs b/client/consensus/manual-seal/src/seal_block.rs index 58f017f2d41..a4afaa343e9 100644 --- a/client/consensus/manual-seal/src/seal_block.rs +++ b/client/consensus/manual-seal/src/seal_block.rs @@ -87,10 +87,10 @@ pub async fn seal_block( + Send + Sync + 'static, C: HeaderBackend + ProvideRuntimeApi, E: Environment, - >::Error: std::fmt::Display, - >::Error: std::fmt::Display, + E::Proposer: Proposer>, P: txpool::ChainApi, SC: SelectChain, + TransactionFor: 'static, { let future = async { if pool.validated_pool().status().ready == 0 && !create_empty { @@ -111,7 +111,7 @@ pub async fn seal_block( }; let proposer = env.init(&parent) - .map_err(|err| Error::StringError(format!("{}", err))).await?; + .map_err(|err| Error::StringError(format!("{:?}", err))).await?; let id = inherent_data_provider.create_inherent_data()?; let inherents_len = id.len(); @@ -122,7 +122,7 @@ pub async fn seal_block( }; let proposal = proposer.propose(id.clone(), digest, Duration::from_secs(MAX_PROPOSAL_DURATION), false.into()) - .map_err(|err| Error::StringError(format!("{}", err))).await?; + .map_err(|err| Error::StringError(format!("{:?}", err))).await?; if proposal.block.extrinsics().len() == inherents_len && !create_empty { return Err(Error::EmptyTransactionPool) @@ -133,6 +133,7 @@ pub async fn seal_block( params.body = Some(body); params.finalized = finalize; params.fork_choice = Some(ForkChoiceStrategy::LongestChain); + params.storage_changes = Some(proposal.storage_changes); if let Some(digest_provider) = digest_provider { digest_provider.append_block_import(&parent, &mut params, &id)?; -- GitLab From d428fc79a52fce1255442ed84ec42415aea487bf Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Fri, 27 Nov 2020 19:37:53 +0100 Subject: [PATCH 057/163] =?UTF-8?q?chore/error:=20remove=20from=20str=20co?= =?UTF-8?q?nversion=20and=20add=20deprecation=20notificat=E2=80=A6=20(#747?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore/error: remove from str conversion and add deprecation notifications * fixup changes * fix test looking for gone ::Msg variant * another test fix * one is duplicate, the other is not, so duplicates reported are n-1 * darn spaces Co-authored-by: Andronik Ordian * remove pointless doc comments of error variants without any value * low hanging fruits (for a tall person) * moar error type variants * avoid the storage modules for now They are in need of a refactor, and the pain is rather large removing all String error and DefaultError occurences. * chore remove pointless error generic * fix test for mocks, add a bunch of non_exhaustive * max line width * test fixes due to error changes * fin * error outputs... again * undo stderr adjustments * Update client/consensus/slots/src/lib.rs Co-authored-by: Bastian Köcher * remove closure clutter Co-authored-by: Bastian Köcher * more error types * introduce ApiError * extract Mock error * ApiError refactor * even more error types * the last for now * chore unused deps * another extraction * reduce should panic, due to extended error messages * error test happiness * shift error lines by one * doc tests * white space Co-authored-by: Bastian Köcher * Into -> From Co-authored-by: Bastian Köcher * remove pointless codec Co-authored-by: Bastian Köcher * avoid pointless self import Co-authored-by: Bastian Köcher Co-authored-by: Bernhard Schuster Co-authored-by: Andronik Ordian Co-authored-by: Bastian Köcher --- Cargo.lock | 16 ++- client/api/Cargo.toml | 1 + client/api/src/light.rs | 16 ++- .../basic-authorship/src/basic_authorship.rs | 5 +- client/block-builder/src/lib.rs | 2 +- client/cli/src/error.rs | 45 +++--- client/consensus/slots/Cargo.toml | 3 +- client/consensus/slots/src/lib.rs | 22 ++- client/db/src/lib.rs | 12 +- client/executor/common/Cargo.toml | 3 +- client/executor/common/src/error.rs | 89 ++++++------ client/executor/common/src/lib.rs | 1 + client/executor/common/src/util.rs | 16 +-- client/executor/src/integration_tests/mod.rs | 2 +- client/light/src/call_executor.rs | 3 +- client/light/src/fetcher.rs | 14 +- client/network/src/light_client_handler.rs | 2 +- client/network/src/on_demand_layer.rs | 23 ++- client/rpc/src/state/state_full.rs | 6 +- client/service/Cargo.toml | 4 +- client/service/src/client/call_executor.rs | 22 ++- client/service/src/client/client.rs | 5 +- client/service/src/client/wasm_override.rs | 53 ++++--- client/service/src/error.rs | 64 ++++----- client/state-db/Cargo.toml | 3 +- client/sync-state-rpc/Cargo.toml | 1 + client/sync-state-rpc/src/lib.rs | 52 ++++--- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 1 + client/transaction-pool/graph/src/error.rs | 24 ++-- client/transaction-pool/src/error.rs | 30 ++-- primitives/api/Cargo.toml | 2 + .../api/proc-macro/src/decl_runtime_apis.rs | 8 +- .../proc-macro/src/mock_impl_runtime_apis.rs | 4 +- primitives/api/src/lib.rs | 44 +++++- primitives/api/test/tests/decl_and_impl.rs | 22 ++- .../ui/mock_advanced_block_id_by_value.rs | 3 +- .../ui/mock_advanced_block_id_by_value.stderr | 14 +- .../tests/ui/mock_advanced_missing_blockid.rs | 3 +- .../ui/mock_advanced_missing_blockid.stderr | 4 +- .../tests/ui/mock_only_one_error_type.stderr | 8 +- primitives/blockchain/Cargo.toml | 2 + primitives/blockchain/src/backend.rs | 4 +- primitives/blockchain/src/error.rs | 131 +++++++++++------- primitives/consensus/common/src/error.rs | 1 + primitives/state-machine/src/error.rs | 8 +- primitives/transaction-pool/Cargo.toml | 4 +- primitives/transaction-pool/src/error.rs | 42 +++--- 48 files changed, 498 insertions(+), 348 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7444178d73b..b34d5f76c22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6574,6 +6574,7 @@ dependencies = [ "sp-version", "substrate-prometheus-endpoint", "substrate-test-runtime", + "thiserror", ] [[package]] @@ -6837,6 +6838,7 @@ dependencies = [ "sp-state-machine", "sp-trie", "substrate-test-runtime-client", + "thiserror", ] [[package]] @@ -6897,14 +6899,13 @@ name = "sc-executor-common" version = "0.8.0" dependencies = [ "derive_more", - "log", "parity-scale-codec", "parity-wasm 0.41.0", "sp-allocator", "sp-core", - "sp-runtime-interface", "sp-serializer", "sp-wasm-interface", + "thiserror", "wasmi", ] @@ -7328,7 +7329,6 @@ name = "sc-service" version = "0.8.0" dependencies = [ "async-std", - "derive_more", "directories 3.0.1", "exit-future", "futures 0.1.30", @@ -7387,6 +7387,7 @@ dependencies = [ "substrate-test-runtime", "substrate-test-runtime-client", "tempfile", + "thiserror", "tokio 0.2.23", "tracing", "tracing-futures", @@ -7440,6 +7441,7 @@ dependencies = [ "parking_lot 0.10.2", "sc-client-api", "sp-core", + "thiserror", ] [[package]] @@ -7458,6 +7460,7 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-runtime", + "thiserror", ] [[package]] @@ -7519,6 +7522,7 @@ dependencies = [ "sp-transaction-pool", "sp-utils", "substrate-test-runtime", + "thiserror", "wasm-timer", ] @@ -7527,7 +7531,6 @@ name = "sc-transaction-pool" version = "2.0.0" dependencies = [ "assert_matches", - "derive_more", "futures 0.3.8", "futures-diagnose", "hex", @@ -7551,6 +7554,7 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", + "thiserror", "wasm-timer", ] @@ -7992,6 +7996,7 @@ dependencies = [ "sp-std", "sp-test-primitives", "sp-version", + "thiserror", ] [[package]] @@ -8110,10 +8115,12 @@ dependencies = [ name = "sp-blockchain" version = "2.0.0" dependencies = [ + "futures 0.3.8", "log", "lru 0.6.1", "parity-scale-codec", "parking_lot 0.10.2", + "sp-api", "sp-consensus", "sp-database", "sp-runtime", @@ -8669,6 +8676,7 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-runtime", + "thiserror", ] [[package]] diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 7d770912f27..07036bfb414 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -46,3 +46,4 @@ prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0. kvdb-memorydb = "0.7.0" sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime" } +thiserror = "1.0.21" diff --git a/client/api/src/light.rs b/client/api/src/light.rs index 144851dac00..f9ba64544a8 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -312,13 +312,21 @@ pub mod tests { use sp_test_primitives::{Block, Header, Extrinsic}; use super::*; + #[derive(Debug, thiserror::Error)] + #[error("Not implemented on test node")] + struct MockError; + + impl Into for MockError { + fn into(self) -> ClientError { + ClientError::Application(Box::new(self)) + } + } + pub type OkCallFetcher = Mutex>; - fn not_implemented_in_tests() -> Ready> - where - E: std::convert::From<&'static str>, + fn not_implemented_in_tests() -> Ready> { - futures::future::ready(Err("Not implemented on test node".into())) + futures::future::ready(Err(MockError.into())) } impl Fetcher for OkCallFetcher { diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 2fe7ba72ec7..8c022ef3a97 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -208,10 +208,7 @@ impl sp_consensus::Proposer for })); async move { - match rx.await { - Ok(x) => x, - Err(err) => Err(sp_blockchain::Error::Msg(err.to_string())) - } + rx.await? }.boxed() } } diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index 8a38bb84780..cc1431ea349 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -212,7 +212,7 @@ where &state, changes_trie_state.as_ref(), parent_hash, - )?; + ).map_err(|e| sp_blockchain::Error::StorageChanges(e))?; Ok(BuiltBlock { block: ::new(header, self.extrinsics), diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index 36c963f3e8c..5190cae2c2f 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -25,35 +25,32 @@ pub type Result = std::result::Result; /// Error type for the CLI. #[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] pub enum Error { - /// Io error #[error(transparent)] Io(#[from] std::io::Error), - /// Cli error + #[error(transparent)] Cli(#[from] structopt::clap::Error), - /// Service error + #[error(transparent)] Service(#[from] sc_service::Error), - /// Client error + #[error(transparent)] Client(#[from] sp_blockchain::Error), - /// scale codec error + #[error(transparent)] Codec(#[from] parity_scale_codec::Error), - /// Input error + #[error("Invalid input: {0}")] Input(String), - /// Invalid listen multiaddress + #[error("Invalid listen multiaddress")] InvalidListenMultiaddress, - /// Application specific error chain sequence forwarder. - #[error(transparent)] - Application(#[from] Box), - /// URI error. + #[error("Invalid URI; expecting either a secret URI or a public URI.")] InvalidUri(crypto::PublicError), - /// Signature length mismatch. + #[error("Signature has an invalid length. Read {read} bytes, expected {expected} bytes")] SignatureInvalidLength { /// Amount of signature bytes read. @@ -61,28 +58,28 @@ pub enum Error { /// Expected number of signature bytes. expected: usize, }, - /// Missing base path argument. + #[error("The base path is missing, please provide one")] MissingBasePath, - /// Unknown key type specifier or missing key type specifier. + #[error("Unknown key type, must be a known 4-character sequence")] KeyTypeInvalid, - /// Signature verification failed. + #[error("Signature verification failed")] SignatureInvalid, - /// Storing a given key failed. + #[error("Key store operation failed")] KeyStoreOperation, - /// An issue with the underlying key storage was encountered. + #[error("Key storage issue encountered")] KeyStorage(#[from] sc_keystore::Error), - /// Bytes are not decodable when interpreted as hexadecimal string. - #[error("Invalid hex base data")] + + #[error("Invalid hexadecimal string data")] HexDataConversion(#[from] hex::FromHexError), - /// Shortcut type to specify types on the fly, discouraged. - #[deprecated = "Use `Forwarded` with an error type instead."] - #[error("Other: {0}")] - Other(String), + + /// Application specific error chain sequence forwarder. + #[error(transparent)] + Application(#[from] Box), } impl std::convert::From<&str> for Error { @@ -93,7 +90,7 @@ impl std::convert::From<&str> for Error { impl std::convert::From for Error { fn from(s: String) -> Error { - Error::Input(s.to_string()) + Error::Input(s) } } diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index d07ef49835b..e8bd1f33631 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -31,7 +31,8 @@ sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" -log = "0.4.8" +log = "0.4.11" +thiserror = "1.0.21" [dev-dependencies] substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index d8601a7c12c..ab8fc16007c 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -20,7 +20,8 @@ //! time during which certain events can and/or must occur. This crate //! provides generic functionality for slots. -#![forbid(unsafe_code, missing_docs)] +#![forbid(unsafe_code)] +#![deny(missing_docs)] mod slots; mod aux_schema; @@ -470,6 +471,15 @@ pub enum CheckedHeader { Checked(H, S), } + + +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error where T: SlotData + Clone + Debug + Send + Sync + 'static { + #[error("Slot duration is invalid: {0:?}")] + SlotDurationInvalid(SlotDuration), +} + /// A slot duration. Create with `get_or_compute`. // The internal member should stay private here to maintain invariants of // `get_or_compute`. @@ -494,7 +504,7 @@ impl SlotData for SlotDuration { const SLOT_KEY: &'static [u8] = T::SLOT_KEY; } -impl SlotDuration { +impl SlotDuration { /// Either fetch the slot duration from disk or compute it from the /// genesis state. /// @@ -532,10 +542,8 @@ impl SlotDuration { } }?; - if slot_duration.slot_duration() == 0 { - return Err(sp_blockchain::Error::Msg( - "Invalid value for slot_duration: the value must be greater than 0.".into(), - )) + if slot_duration.slot_duration() == 0u64 { + return Err(sp_blockchain::Error::Application(Box::new(Error::SlotDurationInvalid(slot_duration)))) } Ok(slot_duration) @@ -939,7 +947,7 @@ mod test { true, true, true, true, ]; - assert_eq!(backoff, expected); + assert_eq!(backoff.as_slice(), &expected[..]); } #[test] diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 983459cfebe..8254e652f68 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -891,9 +891,7 @@ impl Backend { let is_archive_pruning = config.pruning.is_archive(); let blockchain = BlockchainDb::new(db.clone())?; let meta = blockchain.meta.clone(); - let map_e = |e: sc_state_db::Error| sp_blockchain::Error::from( - format!("State database error: {:?}", e) - ); + let map_e = |e: sc_state_db::Error| sp_blockchain::Error::from_state_db(e); let state_db: StateDb<_, _> = StateDb::new( config.pruning.clone(), !config.source.supports_ref_counting(), @@ -1082,7 +1080,7 @@ impl Backend { trace!(target: "db", "Canonicalize block #{} ({:?})", new_canonical, hash); let commit = self.storage.state_db.canonicalize_block(&hash) - .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; + .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from_state_db(e))?; apply_state_commit(transaction, commit); }; @@ -1212,9 +1210,7 @@ impl Backend { number_u64, &pending_block.header.parent_hash(), changeset, - ).map_err(|e: sc_state_db::Error| - sp_blockchain::Error::from(format!("State database error: {:?}", e)) - )?; + ).map_err(|e: sc_state_db::Error| sp_blockchain::Error::from_state_db(e))?; apply_state_commit(&mut transaction, commit); // Check if need to finalize. Genesis is always finalized instantly. @@ -1379,7 +1375,7 @@ impl Backend { transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, lookup_key); let commit = self.storage.state_db.canonicalize_block(&f_hash) - .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; + .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from_state_db(e))?; apply_state_commit(transaction, commit); if !f_num.is_zero() { diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index 64ed23598f4..8501144a9a9 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -14,7 +14,6 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -log = "0.4.8" derive_more = "0.99.2" parity-wasm = "0.41.0" codec = { package = "parity-scale-codec", version = "1.3.4" } @@ -22,8 +21,8 @@ wasmi = "0.6.2" sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" } sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" } sp-serializer = { version = "2.0.0", path = "../../../primitives/serializer" } +thiserror = "1.0.21" [features] default = [] diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index caed63c183e..caf6159da07 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -25,92 +25,95 @@ use wasmi; pub type Result = std::result::Result; /// Error type. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] pub enum Error { /// Unserializable Data - InvalidData(sp_serializer::Error), + #[error("Unserializable data encountered")] + InvalidData(#[from] sp_serializer::Error), /// Trap occurred during execution - Trap(wasmi::Trap), + #[error(transparent)] + Trap(#[from] wasmi::Trap), /// Wasmi loading/instantiating error - Wasmi(wasmi::Error), + #[error(transparent)] + Wasmi(#[from] wasmi::Error), /// Error in the API. Parameter is an error message. - #[from(ignore)] + #[error("API Error: {0}")] ApiError(String), /// Method is not found - #[display(fmt="Method not found: '{}'", _0)] - #[from(ignore)] + #[error("Method not found: '{0}'")] MethodNotFound(String), /// Code is invalid (expected single byte) - #[display(fmt="Invalid Code: {}", _0)] - #[from(ignore)] + #[error("Invalid Code: '{0}'")] InvalidCode(String), /// Could not get runtime version. - #[display(fmt="On-chain runtime does not specify version")] + #[error("On-chain runtime does not specify version")] VersionInvalid, /// Externalities have failed. - #[display(fmt="Externalities error")] + #[error("Externalities error")] Externalities, /// Invalid index. - #[display(fmt="Invalid index provided")] + #[error("Invalid index provided")] InvalidIndex, /// Invalid return type. - #[display(fmt="Invalid type returned (should be u64)")] + #[error("Invalid type returned (should be u64)")] InvalidReturn, /// Runtime failed. - #[display(fmt="Runtime error")] + #[error("Runtime error")] Runtime, /// Runtime panicked. - #[display(fmt="Runtime panicked: {}", _0)] - #[from(ignore)] + #[error("Runtime panicked: {0}")] RuntimePanicked(String), /// Invalid memory reference. - #[display(fmt="Invalid memory reference")] + #[error("Invalid memory reference")] InvalidMemoryReference, /// The runtime must provide a global named `__heap_base` of type i32 for specifying where the /// allocator is allowed to place its data. - #[display(fmt="The runtime doesn't provide a global named `__heap_base`")] + #[error("The runtime doesn't provide a global named `__heap_base`")] HeapBaseNotFoundOrInvalid, /// The runtime WebAssembly module is not allowed to have the `start` function. - #[display(fmt="The runtime has the `start` function")] + #[error("The runtime has the `start` function")] RuntimeHasStartFn, /// Some other error occurred + #[error("Other: {0}")] Other(String), /// Some error occurred in the allocator - #[display(fmt="Error in allocator: {}", _0)] - Allocator(sp_allocator::Error), + #[error("Allocation Error")] + Allocator(#[from] sp_allocator::Error), /// Execution of a host function failed. - #[display(fmt="Host function {} execution failed with: {}", _0, _1)] + #[error("Host function {0} execution failed with: {1}")] FunctionExecution(String, String), /// No table is present. /// /// Call was requested that requires table but none was present in the instance. - #[display(fmt="No table exported by wasm blob")] + #[error("No table exported by wasm blob")] NoTable, /// No table entry is present. /// /// Call was requested that requires specific entry in the table to be present. - #[display(fmt="No table entry with index {} in wasm blob exported table", _0)] - #[from(ignore)] + #[error("No table entry with index {0} in wasm blob exported table")] NoTableEntryWithIndex(u32), /// Table entry is not a function. - #[display(fmt="Table element with index {} is not a function in wasm blob exported table", _0)] - #[from(ignore)] + #[error("Table element with index {0} is not a function in wasm blob exported table")] TableElementIsNotAFunction(u32), /// Function in table is null and thus cannot be called. - #[display(fmt="Table entry with index {} in wasm blob is null", _0)] - #[from(ignore)] + #[error("Table entry with index {0} in wasm blob is null")] FunctionRefIsNull(u32), -} -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Error::InvalidData(ref err) => Some(err), - Error::Trap(ref err) => Some(err), - Error::Wasmi(ref err) => Some(err), - _ => None, - } - } + #[error(transparent)] + RuntimeConstruction(#[from] WasmError), + + #[error("Shared memory is not supported")] + SharedMemUnsupported, + + #[error("Imported globals are not supported yet")] + ImportedGlobalsUnsupported, + + #[error("initializer expression can have only up to 2 expressions in wasm 1.0")] + InitializerHasTooManyExpressions, + + #[error("Invalid initializer expression provided {0}")] + InvalidInitializerExpression(String), } impl wasmi::HostError for Error {} @@ -121,9 +124,9 @@ impl From<&'static str> for Error { } } -impl From for Error { - fn from(err: WasmError) -> Error { - Error::Other(err.to_string()) +impl From for Error { + fn from(err: String) -> Error { + Error::Other(err) } } @@ -151,3 +154,5 @@ pub enum WasmError { /// Other error happenend. Other(String), } + +impl std::error::Error for WasmError {} diff --git a/client/executor/common/src/lib.rs b/client/executor/common/src/lib.rs index 7f3864e6152..df839d4ab65 100644 --- a/client/executor/common/src/lib.rs +++ b/client/executor/common/src/lib.rs @@ -17,6 +17,7 @@ //! A set of common definitions that are needed for defining execution engines. #![warn(missing_docs)] +#![deny(unused_crate_dependencies)] pub mod error; pub mod sandbox; diff --git a/client/executor/common/src/util.rs b/client/executor/common/src/util.rs index 92a48e14018..564f9dadcbe 100644 --- a/client/executor/common/src/util.rs +++ b/client/executor/common/src/util.rs @@ -87,15 +87,12 @@ impl DataSegmentsSnapshot { let init_expr = match segment.offset() { Some(offset) => offset.code(), // Return if the segment is passive - None => return Err(Error::from("Shared memory is not supported".to_string())), + None => return Err(Error::SharedMemUnsupported), }; // [op, End] if init_expr.len() != 2 { - return Err(Error::from( - "initializer expression can have only up to 2 expressions in wasm 1.0" - .to_string(), - )); + return Err(Error::InitializerHasTooManyExpressions); } let offset = match &init_expr[0] { Instruction::I32Const(v) => *v as u32, @@ -106,15 +103,10 @@ impl DataSegmentsSnapshot { // At the moment of writing the Substrate Runtime Interface does not provide // any globals. There is nothing that prevents us from supporting this // if/when we gain those. - return Err(Error::from( - "Imported globals are not supported yet".to_string(), - )); + return Err(Error::ImportedGlobalsUnsupported); } insn => { - return Err(Error::from(format!( - "{:?} is not supported as initializer expression in wasm 1.0", - insn - ))) + return Err(Error::InvalidInitializerExpression(format!("{:?}", insn))) } }; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index c8b763a6b19..08771847c25 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -523,7 +523,7 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] -#[should_panic(expected = "Allocator ran out of space")] +#[should_panic] fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); diff --git a/client/light/src/call_executor.rs b/client/light/src/call_executor.rs index fa0f02cd5ae..458ea2bd6b8 100644 --- a/client/light/src/call_executor.rs +++ b/client/light/src/call_executor.rs @@ -276,7 +276,8 @@ pub fn check_execution_proof_with_make_header( // TODO: Remove when solved: https://github.com/paritytech/substrate/issues/5047 let backend_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&trie_backend); - let runtime_code = backend_runtime_code.runtime_code()?; + let runtime_code = backend_runtime_code.runtime_code() + .map_err(|_e| ClientError::RuntimeCodeMissing)?; execution_proof_check_on_trie_backend::( &trie_backend, diff --git a/client/light/src/fetcher.rs b/client/light/src/fetcher.rs index 33113c2fc7d..60fce87b8d0 100644 --- a/client/light/src/fetcher.rs +++ b/client/light/src/fetcher.rs @@ -239,7 +239,7 @@ impl FetchChecker for LightDataChecker convert_hash(request.header.state_root()), remote_proof, request.keys.iter(), - ).map_err(Into::into) + ).map_err(|e| ClientError::from(e)) } fn check_read_child_proof( @@ -249,14 +249,14 @@ impl FetchChecker for LightDataChecker ) -> ClientResult, Option>>> { let child_info = match ChildType::from_prefixed_key(&request.storage_key) { Some((ChildType::ParentKeyId, storage_key)) => ChildInfo::new_default(storage_key), - None => return Err("Invalid child type".into()), + None => return Err(ClientError::InvalidChildType), }; read_child_proof_check::( convert_hash(request.header.state_root()), remote_proof, &child_info, request.keys.iter(), - ).map_err(Into::into) + ).map_err(|e| ClientError::from(e)) } fn check_execution_proof( @@ -292,10 +292,10 @@ impl FetchChecker for LightDataChecker if *request.header.extrinsics_root() == extrinsics_root { Ok(body) } else { - Err(format!("RemoteBodyRequest: invalid extrinsics root expected: {} but got {}", - *request.header.extrinsics_root(), - extrinsics_root, - ).into()) + Err(ClientError::ExtrinsicRootInvalid { + received: request.header.extrinsics_root().to_string(), + expected: extrinsics_root.to_string(), + }) } } diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index 27f1a9deea4..007cdcbf7a6 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -628,7 +628,7 @@ where let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); let child_info = match ChildType::from_prefixed_key(prefixed_key) { Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), - None => Err("Invalid child storage key".into()), + None => Err(sp_blockchain::Error::InvalidChildStorageKey), }; let proof = match child_info.and_then(|child_info| self.chain.read_child_proof( &BlockId::Hash(block), diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index 084172ee57c..6e0add18adb 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -51,6 +51,17 @@ pub struct OnDemand { requests_send: TracingUnboundedSender>, } + +#[derive(Debug, thiserror::Error)] +#[error("AlwaysBadChecker")] +struct ErrorAlwaysBadChecker; + +impl Into for ErrorAlwaysBadChecker { + fn into(self) -> ClientError { + ClientError::Application(Box::new(self)) + } +} + /// Dummy implementation of `FetchChecker` that always assumes that responses are bad. /// /// Considering that it is the responsibility of the client to build the fetcher, it can use this @@ -65,7 +76,7 @@ impl FetchChecker for AlwaysBadChecker { _remote_header: Option, _remote_proof: StorageProof, ) -> Result { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } fn check_read_proof( @@ -73,7 +84,7 @@ impl FetchChecker for AlwaysBadChecker { _request: &RemoteReadRequest, _remote_proof: StorageProof, ) -> Result,Option>>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } fn check_read_child_proof( @@ -81,7 +92,7 @@ impl FetchChecker for AlwaysBadChecker { _request: &RemoteReadChildRequest, _remote_proof: StorageProof, ) -> Result, Option>>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } fn check_execution_proof( @@ -89,7 +100,7 @@ impl FetchChecker for AlwaysBadChecker { _request: &RemoteCallRequest, _remote_proof: StorageProof, ) -> Result, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } fn check_changes_proof( @@ -97,7 +108,7 @@ impl FetchChecker for AlwaysBadChecker { _request: &RemoteChangesRequest, _remote_proof: ChangesProof ) -> Result, u32)>, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } fn check_body_proof( @@ -105,7 +116,7 @@ impl FetchChecker for AlwaysBadChecker { _request: &RemoteBodyRequest, _body: Vec ) -> Result, ClientError> { - Err(ClientError::Msg("AlwaysBadChecker".into())) + Err(ErrorAlwaysBadChecker.into()) } } diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index fda73cea271..a1b9fbc4eeb 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -541,7 +541,7 @@ impl ChildStateBackend for FullState ChildInfo::new_default(storage_key), - None => return Err("Invalid child storage key".into()), + None => return Err(sp_blockchain::Error::InvalidChildStorageKey), }; self.client.child_storage_keys( &BlockId::Hash(block), @@ -563,7 +563,7 @@ impl ChildStateBackend for FullState ChildInfo::new_default(storage_key), - None => return Err("Invalid child storage key".into()), + None => return Err(sp_blockchain::Error::InvalidChildStorageKey), }; self.client.child_storage( &BlockId::Hash(block), @@ -585,7 +585,7 @@ impl ChildStateBackend for FullState ChildInfo::new_default(storage_key), - None => return Err("Invalid child storage key".into()), + None => return Err(sp_blockchain::Error::InvalidChildStorageKey), }; self.client.child_storage_hash( &BlockId::Hash(block), diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 23af49d38b1..4350e1a2bf2 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -24,7 +24,7 @@ wasmtime = [ test-helpers = [] [dependencies] -derive_more = "0.99.2" +thiserror = "1.0.21" futures01 = { package = "futures", version = "0.1.29" } futures = { version = "0.3.4", features = ["compat"] } jsonrpc-pubsub = "15.1" @@ -32,7 +32,7 @@ jsonrpc-core = "15.1" rand = "0.7.3" parking_lot = "0.10.0" lazy_static = "1.4.0" -log = "0.4.8" +log = "0.4.11" slog = { version = "2.5.2", features = ["nested-values"] } futures-timer = "3.0.1" wasm-timer = "0.2" diff --git a/client/service/src/client/call_executor.rs b/client/service/src/client/call_executor.rs index 164976ecfe8..cd01a587775 100644 --- a/client/service/src/client/call_executor.rs +++ b/client/service/src/client/call_executor.rs @@ -137,7 +137,9 @@ where )?; let state = self.backend.state_at(*id)?; let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state); - let runtime_code = self.check_override(state_runtime_code.runtime_code()?, id)?; + let runtime_code = state_runtime_code.runtime_code() + .map_err(sp_blockchain::Error::RuntimeCode)?; + let runtime_code = self.check_override(runtime_code, id)?; let return_data = StateMachine::new( &state, @@ -211,7 +213,10 @@ where let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&trie_state); // It is important to extract the runtime code here before we create the proof // recorder. - let runtime_code = self.check_override(state_runtime_code.runtime_code()?, at)?; + + let runtime_code = state_runtime_code.runtime_code() + .map_err(sp_blockchain::Error::RuntimeCode)?; + let runtime_code = self.check_override(runtime_code, at)?; let backend = sp_state_machine::ProvingBackend::new_with_recorder( trie_state, @@ -236,7 +241,9 @@ where }, None => { let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state); - let runtime_code = self.check_override(state_runtime_code.runtime_code()?, at)?; + let runtime_code = state_runtime_code.runtime_code() + .map_err(sp_blockchain::Error::RuntimeCode)?; + let runtime_code = self.check_override(runtime_code, at)?; let mut state_machine = StateMachine::new( &state, @@ -273,7 +280,9 @@ where None, ); let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state); - self.executor.runtime_version(&mut ext, &state_runtime_code.runtime_code()?) + let runtime_code = state_runtime_code.runtime_code() + .map_err(sp_blockchain::Error::RuntimeCode)?; + self.executor.runtime_version(&mut ext, &runtime_code) .map_err(|e| sp_blockchain::Error::VersionInvalid(format!("{:?}", e)).into()) } @@ -284,6 +293,9 @@ where method: &str, call_data: &[u8] ) -> Result<(Vec, StorageProof), sp_blockchain::Error> { + let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(trie_state); + let runtime_code = state_runtime_code.runtime_code() + .map_err(sp_blockchain::Error::RuntimeCode)?; sp_state_machine::prove_execution_on_trie_backend::<_, _, NumberFor, _, _>( trie_state, overlay, @@ -291,7 +303,7 @@ where self.spawn_handle.clone(), method, call_data, - &sp_state_machine::backend::BackendRuntimeCode::new(trie_state).runtime_code()?, + &runtime_code, ) .map_err(Into::into) } diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index e8d748011bc..f72fcb81076 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -297,7 +297,8 @@ impl Client where config: ClientConfig, ) -> sp_blockchain::Result { if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() { - let genesis_storage = build_genesis_storage.build_storage()?; + let genesis_storage = build_genesis_storage.build_storage() + .map_err(sp_blockchain::Error::Storage)?; let mut op = backend.begin_operation()?; backend.begin_state_operation(&mut op, BlockId::Hash(Default::default()))?; let state_root = op.reset_storage(genesis_storage)?; @@ -880,7 +881,7 @@ impl Client where &state, changes_trie_state.as_ref(), *parent_hash, - )?; + ).map_err(sp_blockchain::Error::Storage)?; if import_block.header.state_root() != &gen_storage_changes.transaction_storage_root diff --git a/client/service/src/client/wasm_override.rs b/client/service/src/client/wasm_override.rs index 1025b963388..ba76f7a0fcf 100644 --- a/client/service/src/client/wasm_override.rs +++ b/client/service/src/client/wasm_override.rs @@ -37,7 +37,8 @@ //! needed must be provided in the given directory. //! use std::{ - fs, collections::{HashMap, hash_map::DefaultHasher}, path::Path, + fs, collections::{HashMap, hash_map::DefaultHasher}, + path::{Path, PathBuf}, hash::Hasher as _, }; use sp_core::traits::FetchRuntimeCode; @@ -82,6 +83,29 @@ impl FetchRuntimeCode for WasmBlob { } } +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum WasmOverrideError { + #[error("Failed to get runtime version: {0}")] + VersionInvalid(String), + + #[error("WASM override IO error")] + Io(PathBuf, #[source] std::io::Error), + + #[error("Overwriting WASM requires a directory where local \ + WASM is stored. {} is not a directory", .0.display())] + NotADirectory(PathBuf), + + #[error("Duplicate WASM Runtimes found: \n{}\n", .0.join("\n") )] + DuplicateRuntime(Vec), +} + +impl From for sp_blockchain::Error { + fn from(err: WasmOverrideError) -> Self { + Self::Application(Box::new(err)) + } +} + /// Scrapes WASM from a folder and returns WASM from that folder /// if the runtime spec version matches. #[derive(Clone, Debug)] @@ -119,16 +143,13 @@ where /// Scrapes a folder for WASM runtimes. /// Returns a hashmap of the runtime version and wasm runtime code. fn scrape_overrides(dir: &Path, executor: &E) -> Result> { + let handle_err = |e: std::io::Error | -> sp_blockchain::Error { - sp_blockchain::Error::Msg(format!("{}", e.to_string())) + WasmOverrideError::Io(dir.to_owned(), e).into() }; if !dir.is_dir() { - return Err(sp_blockchain::Error::Msg(format!( - "Overwriting WASM requires a directory where \ - local WASM is stored. {:?} is not a directory", - dir, - ))); + return Err(WasmOverrideError::NotADirectory(dir.to_owned()).into()); } let mut overrides = HashMap::new(); @@ -149,9 +170,7 @@ where } if !duplicates.is_empty() { - let duplicate_file_list = duplicates.join("\n"); - let msg = format!("Duplicate WASM Runtimes found: \n{}\n", duplicate_file_list); - return Err(sp_blockchain::Error::Msg(msg)); + return Err(WasmOverrideError::DuplicateRuntime(duplicates).into()); } Ok(overrides) @@ -164,7 +183,7 @@ where ) -> Result { let mut ext = BasicExternalities::default(); executor.runtime_version(&mut ext, &code.runtime_code(heap_pages)) - .map_err(|e| sp_blockchain::Error::VersionInvalid(format!("{:?}", e)).into()) + .map_err(|e| WasmOverrideError::VersionInvalid(format!("{:?}", e)).into()) } } @@ -236,14 +255,10 @@ mod tests { let scraped = WasmOverride::scrape_overrides(dir, exec); match scraped { - Err(e) => { - match e { - sp_blockchain::Error::Msg(msg) => { - let is_match = msg - .matches("Duplicate WASM Runtimes found") - .map(ToString::to_string) - .collect::>(); - assert!(is_match.len() >= 1) + Err(sp_blockchain::Error::Application(e)) => { + match e.downcast_ref::() { + Some(WasmOverrideError::DuplicateRuntime(duplicates)) => { + assert_eq!(duplicates.len(), 1); }, _ => panic!("Test should end with Msg Error Variant") } diff --git a/client/service/src/error.rs b/client/service/src/error.rs index ffe1b394055..3515df78be8 100644 --- a/client/service/src/error.rs +++ b/client/service/src/error.rs @@ -27,25 +27,38 @@ use sp_blockchain; pub type Result = std::result::Result; /// Service errors. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +#[non_exhaustive] pub enum Error { - /// Client error. - Client(sp_blockchain::Error), - /// IO error. - Io(std::io::Error), - /// Consensus error. - Consensus(sp_consensus::Error), - /// Network error. - Network(sc_network::error::Error), - /// Keystore error. - Keystore(sc_keystore::Error), - /// Best chain selection strategy is missing. - #[display(fmt="Best chain selection strategy (SelectChain) is not provided.")] + #[error(transparent)] + Client(#[from] sp_blockchain::Error), + + #[error(transparent)] + Io(#[from] std::io::Error), + + #[error(transparent)] + Consensus(#[from] sp_consensus::Error), + + #[error(transparent)] + Network(#[from] sc_network::error::Error), + + #[error(transparent)] + Keystore(#[from] sc_keystore::Error), + + #[error("Best chain selection strategy (SelectChain) is not provided.")] SelectChainRequired, - /// Tasks executor is missing. - #[display(fmt="Tasks executor hasn't been provided.")] + + #[error("Tasks executor hasn't been provided.")] TaskExecutorRequired, - /// Other error. + + #[error("Prometheus metrics error")] + Prometheus(#[from] prometheus_endpoint::PrometheusError), + + #[error("Application")] + Application(#[from] Box), + + #[error("Other: {0}")] Other(String), } @@ -55,21 +68,8 @@ impl<'a> From<&'a str> for Error { } } -impl From for Error { - fn from(e: prometheus_endpoint::PrometheusError) -> Self { - Error::Other(format!("Prometheus error: {}", e)) - } -} - -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Error::Client(ref err) => Some(err), - Error::Io(ref err) => Some(err), - Error::Consensus(ref err) => Some(err), - Error::Network(ref err) => Some(err), - Error::Keystore(ref err) => Some(err), - _ => None, - } +impl<'a> From for Error { + fn from(s: String) -> Self { + Error::Other(s) } } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 4d3e736d953..18facd720db 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -13,8 +13,9 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +thiserror = "1.0.21" parking_lot = "0.10.0" -log = "0.4.8" +log = "0.4.11" sc-client-api = { version = "2.0.0", path = "../api" } sp-core = { version = "2.0.0", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } diff --git a/client/sync-state-rpc/Cargo.toml b/client/sync-state-rpc/Cargo.toml index 8da372db94f..81204365d08 100644 --- a/client/sync-state-rpc/Cargo.toml +++ b/client/sync-state-rpc/Cargo.toml @@ -13,6 +13,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +thiserror = "1.0.21" jsonrpc-core = "15.0" jsonrpc-core-client = "15.0" jsonrpc-derive = "15.0" diff --git a/client/sync-state-rpc/src/lib.rs b/client/sync-state-rpc/src/lib.rs index fa433e5e31d..573610fb2f6 100644 --- a/client/sync-state-rpc/src/lib.rs +++ b/client/sync-state-rpc/src/lib.rs @@ -17,6 +17,8 @@ //! A RPC handler to create sync states for light clients. //! Currently only usable with BABE + GRANDPA. +#![deny(unused_crate_dependencies)] + use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_blockchain::HeaderBackend; use std::sync::Arc; @@ -28,12 +30,27 @@ type SharedAuthoritySet = sc_finality_grandpa::SharedAuthoritySet<::Hash, NumberFor>; type SharedEpochChanges = sc_consensus_epochs::SharedEpochChanges; -struct Error(sp_blockchain::Error); +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +enum Error { + #[error(transparent)] + Blockchain(#[from] sp_blockchain::Error), + + #[error("Failed to load the block weight for block {0:?}")] + LoadingBlockWeightFailed(::Hash), + + #[error("JsonRpc error: {0}")] + JsonRpc(String), +} -impl From for jsonrpc_core::Error { - fn from(error: Error) -> Self { +impl From> for jsonrpc_core::Error { + fn from(error: Error) -> Self { + let message = match error { + Error::JsonRpc(s) => s, + _ => error.to_string(), + }; jsonrpc_core::Error { - message: error.0.to_string(), + message, code: jsonrpc_core::ErrorCode::ServerError(1), data: None, } @@ -76,20 +93,16 @@ impl SyncStateRpcHandler } } - fn build_sync_state(&self) -> Result, sp_blockchain::Error> { + fn build_sync_state(&self) -> Result, Error> { let finalized_hash = self.client.info().finalized_hash; let finalized_header = self.client.header(BlockId::Hash(finalized_hash))? - .ok_or_else(|| sp_blockchain::Error::Msg( - format!("Failed to get the header for block {:?}", finalized_hash) - ))?; + .ok_or_else(|| sp_blockchain::Error::MissingHeader(finalized_hash.to_string()))?; let finalized_block_weight = sc_consensus_babe::aux_schema::load_block_weight( - &*self.client, - finalized_hash, - )? - .ok_or_else(|| sp_blockchain::Error::Msg( - format!("Failed to load the block weight for block {:?}", finalized_hash) - ))?; + &*self.client, + finalized_hash, + )? + .ok_or_else(|| Error::LoadingBlockWeightFailed(finalized_hash))?; Ok(sc_chain_spec::LightSyncState { finalized_block_header: finalized_header, @@ -114,15 +127,16 @@ impl SyncStateRpcApi for SyncStateRpcHandler let mut chain_spec = self.chain_spec.cloned_box(); - let sync_state = self.build_sync_state().map_err(Error)?; + let sync_state = self.build_sync_state() + .map_err(map_error::>)?; chain_spec.set_light_sync_state(sync_state.to_serializable()); - let string = chain_spec.as_json(raw).map_err(map_error)?; + let string = chain_spec.as_json(raw).map_err(map_error::)?; - serde_json::from_str(&string).map_err(|err| map_error(err.to_string())) + serde_json::from_str(&string).map_err(|err| map_error::(err)) } } -fn map_error(error: String) -> jsonrpc_core::Error { - Error(sp_blockchain::Error::Msg(error)).into() +fn map_error(error: S) -> jsonrpc_core::Error { + Error::::JsonRpc(error.to_string()).into() } diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 5db37f53683..a4d7bc685c9 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.3.4" } -derive_more = "0.99.2" +thiserror = "1.0.21" futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" intervalier = "0.4.0" diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index c5850e765fc..94c80c6f298 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -14,6 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" +thiserror = "1.0.21" futures = "0.3.4" log = "0.4.8" parking_lot = "0.10.0" diff --git a/client/transaction-pool/graph/src/error.rs b/client/transaction-pool/graph/src/error.rs index 392ddaa39be..b599715920b 100644 --- a/client/transaction-pool/graph/src/error.rs +++ b/client/transaction-pool/graph/src/error.rs @@ -26,28 +26,29 @@ use sp_runtime::transaction_validity::{ pub type Result = std::result::Result; /// Transaction pool error type. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(Debug, thiserror::Error, derive_more::From)] +#[allow(missing_docs)] pub enum Error { /// Transaction is not verifiable yet, but might be in the future. - #[display(fmt="Unknown transaction validity: {:?}", _0)] + #[error("Unknown transaction validity: {0:?}")] UnknownTransaction(UnknownTransaction), /// Transaction is invalid. - #[display(fmt="Invalid transaction validity: {:?}", _0)] + #[error("Invalid transaction validity: {0:?}")] InvalidTransaction(InvalidTransaction), /// The transaction validity returned no "provides" tag. /// /// Such transactions are not accepted to the pool, since we use those tags /// to define identity of transactions (occupance of the same "slot"). - #[display(fmt="The transaction does not provide any tags, so the pool can't identify it.")] + #[error("The transaction does not provide any tags, so the pool can't identify it.")] NoTagsProvided, - /// The transaction is temporarily banned. - #[display(fmt="Temporarily Banned")] + + #[error("Temporarily Banned")] TemporarilyBanned, /// The transaction is already in the pool. - #[display(fmt="[{:?}] Already imported", _0)] + #[error("[{0:?}] Already imported")] AlreadyImported(Box), /// The transaction cannot be imported cause it's a replacement and has too low priority. - #[display(fmt="Too low priority ({} > {})", old, new)] + #[error("Too low priority ({0} > {1})", old, new)] TooLowPriority { /// Transaction already in the pool. old: Priority, @@ -55,17 +56,16 @@ pub enum Error { new: Priority }, /// Deps cycle detected and we couldn't import transaction. - #[display(fmt="Cycle Detected")] + #[error("Cycle Detected")] CycleDetected, /// Transaction was dropped immediately after it got inserted. - #[display(fmt="Transaction couldn't enter the pool because of the limit.")] + #[error("Transaction couldn't enter the pool because of the limit.")] ImmediatelyDropped, /// Invalid block id. + #[error("Invlaid block id: {0}")] InvalidBlockId(String), } -impl std::error::Error for Error {} - /// Transaction pool error conversion. pub trait IntoPoolError: ::std::error::Error + Send + Sized { /// Try to extract original `Error` diff --git a/client/transaction-pool/src/error.rs b/client/transaction-pool/src/error.rs index c0f795df180..49fc433e320 100644 --- a/client/transaction-pool/src/error.rs +++ b/client/transaction-pool/src/error.rs @@ -24,30 +24,22 @@ use sp_transaction_pool::error::Error as TxPoolError; pub type Result = std::result::Result; /// Transaction pool error type. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] pub enum Error { - /// Pool error. - Pool(TxPoolError), - /// Blockchain error. - Blockchain(sp_blockchain::Error), - /// Error while converting a `BlockId`. - #[from(ignore)] + #[error("Transaction pool error")] + Pool(#[from] TxPoolError), + + #[error("Blockchain error")] + Blockchain(#[from] sp_blockchain::Error), + + #[error("Block conversion error: {0}")] BlockIdConversion(String), - /// Error while calling the runtime api. - #[from(ignore)] + + #[error("Runtime error: {0}")] RuntimeApi(String), } -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Error::Pool(ref err) => Some(err), - Error::Blockchain(ref err) => Some(err), - Error::BlockIdConversion(_) => None, - Error::RuntimeApi(_) => None, - } - } -} impl sp_transaction_pool::error::IntoPoolError for Error { fn into_pool_error(self) -> std::result::Result { diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index a3c480e9213..92bf9bea2bd 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -21,6 +21,7 @@ sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" sp-version = { version = "2.0.0", default-features = false, path = "../version" } sp-state-machine = { version = "0.8.0", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } +thiserror = { version = "1.0.21", optional = true } [dev-dependencies] sp-test-primitives = { version = "2.0.0", path = "../test-primitives" } @@ -35,4 +36,5 @@ std = [ "sp-state-machine", "sp-version/std", "hash-db", + "thiserror", ] diff --git a/primitives/api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs index a628ade6f9b..aebefe7ea03 100644 --- a/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -708,13 +708,7 @@ impl<'a> ToClientSideDecl<'a> { }, #crate_::NativeOrEncoded::Encoded(r) => { <#ret_type as #crate_::Decode>::decode(&mut &r[..]) - .map_err(|err| - format!( - "Failed to decode result of `{}`: {}", - #function_name, - err.what(), - ).into() - ) + .map_err(|err| { #crate_::ApiError::new(#function_name, err).into() }) } } ) diff --git a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index 3e2fd42951b..14cf47fc64b 100644 --- a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -69,7 +69,9 @@ fn implement_common_api_traits( ) -> Result { let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); - let error_type = error_type.map(|e| quote!(#e)).unwrap_or_else(|| quote!(String)); + let error_type = error_type + .map(|e| quote!(#e)) + .unwrap_or_else(|| quote!( #crate_::ApiError ) ); // Quote using the span from `error_type` to generate nice error messages when the type is // not implementing a trait or similar. diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 9dadce3b554..96da63cf2e2 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -74,6 +74,7 @@ use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use std::{panic::UnwindSafe, cell::RefCell}; + /// Maximum nesting level for extrinsics. pub const MAX_EXTRINSIC_DEPTH: u32 = 256; @@ -288,7 +289,7 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// /// Sets the error type that is being used by the mock implementation. /// /// The error type is used by all runtime apis. It is only required to /// /// be specified in one trait implementation. -/// type Error = String; +/// type Error = sp_api::ApiError; /// /// fn build_block() -> Block { /// unimplemented!("Not Required in tests") @@ -315,6 +316,7 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// # use sp_runtime::{traits::Block as BlockT, generic::BlockId}; /// # use sp_test_primitives::Block; /// # use sp_core::NativeOrEncoded; +/// # use codec; /// # /// # sp_api::decl_runtime_apis! { /// # /// Declare the api trait. @@ -331,15 +333,15 @@ pub use sp_api_proc_macro::impl_runtime_apis; /// /// sp_api::mock_impl_runtime_apis! { /// impl Balance for MockApi { -/// type Error = String; +/// type Error = sp_api::ApiError; /// #[advanced] -/// fn get_balance(&self, at: &BlockId) -> Result, String> { +/// fn get_balance(&self, at: &BlockId) -> Result, Self::Error> { /// println!("Being called at: {}", at); /// /// Ok(self.balance.into()) /// } /// #[advanced] -/// fn set_balance(at: &BlockId, val: u64) -> Result, String> { +/// fn set_balance(at: &BlockId, val: u64) -> Result, Self::Error> { /// if let BlockId::Number(1) = at { /// println!("Being called to set balance to: {}", val); /// } @@ -392,12 +394,42 @@ pub trait ConstructRuntimeApi> { fn construct_runtime_api<'a>(call: &'a C) -> ApiRef<'a, Self::RuntimeApi>; } +/// An error describing which API call failed. +#[cfg_attr(feature = "std", derive(Debug, thiserror::Error, Eq, PartialEq))] +#[cfg_attr(feature = "std", error("Failed to execute API call {tag}"))] +#[cfg(feature = "std")] +pub struct ApiError { + tag: &'static str, + #[source] + error: codec::Error, +} + +#[cfg(feature = "std")] +impl From<(&'static str, codec::Error)> for ApiError { + fn from((tag, error): (&'static str, codec::Error)) -> Self { + Self { + tag, + error, + } + } +} + +#[cfg(feature = "std")] +impl ApiError { + pub fn new(tag: &'static str, error: codec::Error) -> Self { + Self { + tag, + error, + } + } +} + /// Extends the runtime api traits with an associated error type. This trait is given as super /// trait to every runtime api trait. #[cfg(feature = "std")] pub trait ApiErrorExt { /// Error type used by the runtime apis. - type Error: std::fmt::Debug + From; + type Error: std::fmt::Debug + From; } /// Extends the runtime api implementation with some common functionality. @@ -506,7 +538,7 @@ pub struct CallApiAtParams<'a, Block: BlockT, C, NC, Backend: StateBackend { /// Error type used by the implementation. - type Error: std::fmt::Debug + From; + type Error: std::fmt::Debug + From; /// The state backend that is used to store the block states. type StateBackend: StateBackend>; diff --git a/primitives/api/test/tests/decl_and_impl.rs b/primitives/api/test/tests/decl_and_impl.rs index 594882baf1e..be549d7b7f4 100644 --- a/primitives/api/test/tests/decl_and_impl.rs +++ b/primitives/api/test/tests/decl_and_impl.rs @@ -17,6 +17,7 @@ use sp_api::{ RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, + ApiError, ApiExt, }; use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId}; @@ -103,17 +104,27 @@ mock_impl_runtime_apis! { } #[advanced] - fn same_name(_: &BlockId) -> std::result::Result, String> { + fn same_name(_: &BlockId) -> + std::result::Result< + NativeOrEncoded<()>, + ApiError + > + { Ok(().into()) } #[advanced] - fn wild_card(at: &BlockId, _: u32) -> std::result::Result, String> { + fn wild_card(at: &BlockId, _: u32) -> + std::result::Result< + NativeOrEncoded<()>, + ApiError + > + { if let BlockId::Number(1337) = at { // yeah Ok(().into()) } else { - Err("Ohh noooo".into()) + Err(ApiError::new("MockApi", codec::Error::from("Ohh noooo"))) } } } @@ -197,5 +208,8 @@ fn mock_runtime_api_works_with_advanced() { Api::::same_name(&mock, &BlockId::Number(0)).unwrap(); mock.wild_card(&BlockId::Number(1337), 1).unwrap(); - assert_eq!(String::from("Ohh noooo"), mock.wild_card(&BlockId::Number(1336), 1).unwrap_err()); + assert_eq!( + ApiError::new("MockApi", ::codec::Error::from("Ohh noooo")), + mock.wild_card(&BlockId::Number(1336), 1).unwrap_err() + ); } diff --git a/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.rs b/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.rs index 1e71730cd0a..fd654ffdc63 100644 --- a/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.rs +++ b/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.rs @@ -1,4 +1,5 @@ use substrate_test_runtime_client::runtime::Block; +use sp_api::ApiError; sp_api::decl_runtime_apis! { pub trait Api { @@ -11,7 +12,7 @@ struct MockApi; sp_api::mock_impl_runtime_apis! { impl Api for MockApi { #[advanced] - fn test(&self, _: BlockId) -> Result, String> { + fn test(&self, _: BlockId) -> Result, ApiError> { Ok(().into()) } } diff --git a/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.stderr b/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.stderr index efddce05f51..47cd9e01d91 100644 --- a/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.stderr +++ b/primitives/api/test/tests/ui/mock_advanced_block_id_by_value.stderr @@ -1,13 +1,13 @@ error: `BlockId` needs to be taken by reference and not by value! - --> $DIR/mock_advanced_block_id_by_value.rs:11:1 + --> $DIR/mock_advanced_block_id_by_value.rs:12:1 | -11 | / sp_api::mock_impl_runtime_apis! { -12 | | impl Api for MockApi { -13 | | #[advanced] -14 | | fn test(&self, _: BlockId) -> Result, String> { +12 | / sp_api::mock_impl_runtime_apis! { +13 | | impl Api for MockApi { +14 | | #[advanced] +15 | | fn test(&self, _: BlockId) -> Result, ApiError> { ... | -17 | | } -18 | | } +18 | | } +19 | | } | |_^ | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/primitives/api/test/tests/ui/mock_advanced_missing_blockid.rs b/primitives/api/test/tests/ui/mock_advanced_missing_blockid.rs index 407ea90ee88..a15ef133fa6 100644 --- a/primitives/api/test/tests/ui/mock_advanced_missing_blockid.rs +++ b/primitives/api/test/tests/ui/mock_advanced_missing_blockid.rs @@ -1,4 +1,5 @@ use substrate_test_runtime_client::runtime::Block; +use sp_api::ApiError; sp_api::decl_runtime_apis! { pub trait Api { @@ -11,7 +12,7 @@ struct MockApi; sp_api::mock_impl_runtime_apis! { impl Api for MockApi { #[advanced] - fn test(&self) -> Result, String> { + fn test(&self) -> Result, ApiError> { Ok(().into()) } } diff --git a/primitives/api/test/tests/ui/mock_advanced_missing_blockid.stderr b/primitives/api/test/tests/ui/mock_advanced_missing_blockid.stderr index e7a66ebc5db..87d3660316b 100644 --- a/primitives/api/test/tests/ui/mock_advanced_missing_blockid.stderr +++ b/primitives/api/test/tests/ui/mock_advanced_missing_blockid.stderr @@ -1,5 +1,5 @@ error: If using the `advanced` attribute, it is required that the function takes at least one argument, the `BlockId`. - --> $DIR/mock_advanced_missing_blockid.rs:14:3 + --> $DIR/mock_advanced_missing_blockid.rs:15:3 | -14 | fn test(&self) -> Result, String> { +15 | fn test(&self) -> Result, ApiError> { | ^^ diff --git a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr index daac5674d6f..82fd04e8c5e 100644 --- a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr +++ b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr @@ -10,16 +10,16 @@ error: First error type was declared here. 17 | type Error = u32; | ^^^ -error[E0277]: the trait bound `u32: std::convert::From` is not satisfied +error[E0277]: the trait bound `u32: std::convert::From` is not satisfied --> $DIR/mock_only_one_error_type.rs:17:16 | 17 | type Error = u32; - | ^^^ the trait `std::convert::From` is not implemented for `u32` + | ^^^ the trait `std::convert::From` is not implemented for `u32` | ::: $WORKSPACE/primitives/api/src/lib.rs | - | type Error: std::fmt::Debug + From; - | ------------ required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt` + | type Error: std::fmt::Debug + From; + | -------------- required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt` | = help: the following implementations were found: > diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index eac1e032e3e..3458b8c0846 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -18,8 +18,10 @@ log = "0.4.11" lru = "0.6.1" parking_lot = "0.10.0" thiserror = "1.0.21" +futures = "0.3" codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } sp-consensus = { version = "0.8.0", path = "../consensus/common" } sp-runtime = { version = "2.0.0", path = "../runtime" } sp-state-machine = { version = "0.8.0", path = "../state-machine" } sp-database = { version = "2.0.0", path = "../database" } +sp-api = { version = "2.0.0", path = "../api" } diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 326acd6b9bd..01a7a59d6f9 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -172,7 +172,7 @@ pub trait Backend: HeaderBackend + HeaderMetadata: HeaderBackend + HeaderMetadata = result::Result; /// Error when the runtime failed to apply an extrinsic. #[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] pub enum ApplyExtrinsicFailed { /// The transaction cannot be included into the current block. /// @@ -35,114 +37,142 @@ pub enum ApplyExtrinsicFailed { /// unappliable onto the current block. #[error("Extrinsic is not valid: {0:?}")] Validity(#[from] TransactionValidityError), - /// This is used for miscellaneous errors that can be represented by string and not handleable. - /// - /// This will become obsolete with complete migration to v4 APIs. - #[error("Extrinsic failed: {0}")] - Msg(String), + + #[error("Application specific error")] + Application(#[source] Box), } /// Substrate Client error #[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +#[non_exhaustive] pub enum Error { - /// Consensus Error + #[error("Cancelled oneshot channel {0}")] + OneShotCancelled(#[from] futures::channel::oneshot::Canceled), + #[error(transparent)] Consensus(#[from] sp_consensus::Error), - /// Backend error. + #[error("Backend error: {0}")] Backend(String), - /// Unknown block. + #[error("UnknownBlock: {0}")] UnknownBlock(String), - /// The `apply_extrinsic` is not valid due to the given `TransactionValidityError`. + #[error(transparent)] ApplyExtrinsicFailed(#[from] ApplyExtrinsicFailed), - /// Execution error. + + #[error("Child type is invalid")] + InvalidChildType, + + #[error("RemoteBodyRequest: invalid extrinsics root expected: {expected} but got {received}")] + ExtrinsicRootInvalid { received: String, expected: String }, + + // `inner` cannot be made member, since it lacks `std::error::Error` trait bounds. #[error("Execution failed: {0:?}")] Execution(Box), - /// Blockchain error. + #[error("Blockchain")] Blockchain(#[source] Box), - /// Invalid authorities set received from the runtime. + + /// A error used by various storage subsystems. + /// + /// Eventually this will be replaced. + #[error("{0}")] + StorageChanges(sp_state_machine::DefaultError), + + #[error("Invalid child storage key")] + InvalidChildStorageKey, + #[error("Current state of blockchain has invalid authorities set")] InvalidAuthoritiesSet, - /// Could not get runtime version. + #[error("Failed to get runtime version: {0}")] VersionInvalid(String), - /// Genesis config is invalid. + #[error("Genesis config provided is invalid")] GenesisInvalid, - /// Error decoding header justification. + #[error("error decoding justification for header")] JustificationDecode, - /// Justification for header is correctly encoded, but invalid. + #[error("bad justification for header: {0}")] BadJustification(String), - /// Not available on light client. + #[error("This method is not currently available when running in light client mode")] NotAvailableOnLightClient, - /// Invalid remote CHT-based proof. + #[error("Remote node has responded with invalid header proof")] InvalidCHTProof, - /// Remote fetch has been cancelled. + #[error("Remote data fetch has been cancelled")] RemoteFetchCancelled, - /// Remote fetch has been failed. + #[error("Remote data fetch has been failed")] RemoteFetchFailed, - /// Error decoding call result. + #[error("Error decoding call result of {0}")] CallResultDecode(&'static str, #[source] CodecError), - /// Error converting a parameter between runtime and node. - #[error("Error converting `{0}` between runtime and node")] - RuntimeParamConversion(String), - /// Changes tries are not supported. + + #[error(transparent)] + RuntimeApiCodecError(#[from] ApiError), + + #[error("Runtime :code missing in storage")] + RuntimeCodeMissing, + #[error("Changes tries are not supported by the runtime")] ChangesTriesNotSupported, - /// Error reading changes tries configuration. + #[error("Error reading changes tries configuration")] ErrorReadingChangesTriesConfig, - /// Key changes query has failed. + #[error("Failed to check changes proof: {0}")] ChangesTrieAccessFailed(String), - /// Last finalized block not parent of current. + #[error("Did not finalize blocks in sequential order.")] NonSequentialFinalization(String), - /// Safety violation: new best block not descendent of last finalized. + #[error("Potential long-range attack: block not in finalized chain.")] NotInFinalizedChain, - /// Hash that is required for building CHT is missing. + #[error("Failed to get hash of block for building CHT")] MissingHashRequiredForCHT, - /// Invalid calculated state root on block import. + #[error("Calculated state root does not match.")] InvalidStateRoot, - /// Incomplete block import pipeline. + #[error("Incomplete block import pipeline.")] IncompletePipeline, + #[error("Transaction pool not ready for block production.")] TransactionPoolNotReady, + #[error("Database")] DatabaseError(#[from] sp_database::error::DatabaseError), - /// A convenience variant for String - #[error("{0}")] - Msg(String), -} -impl<'a> From<&'a str> for Error { - fn from(s: &'a str) -> Self { - Error::Msg(s.into()) - } -} + #[error("Failed to get header for hash {0}")] + MissingHeader(String), -impl From for Error { - fn from(s: String) -> Self { - Error::Msg(s) - } + + #[error("State Database error: {0}")] + StateDatabase(String), + + #[error(transparent)] + Application(#[from] Box), + + // Should be removed/improved once + // the storage `fn`s returns typed errors. + #[error("Runtime code error: {0}")] + RuntimeCode(&'static str), + + // Should be removed/improved once + // the storage `fn`s returns typed errors. + #[error("Storage error: {0}")] + Storage(String), } -impl From> for Error { - fn from(e: Box) -> Self { +impl From> for Error { + fn from(e: Box) -> Self { Self::from_state(e) } } @@ -163,4 +193,11 @@ impl Error { pub fn from_state(e: Box) -> Self { Error::Execution(e) } + + /// Construct from a state db error. + // Can not be done directly, since that would make cargo run out of stack if + // `sc-state-db` is lib is added as dependency. + pub fn from_state_db(e: E) -> Self where E: std::fmt::Debug { + Error::StateDatabase(format!("{:?}", e)) + } } diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index a21bcf6cca9..11b24d273d5 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -25,6 +25,7 @@ pub type Result = std::result::Result; /// Error type. #[derive(Debug, thiserror::Error)] +#[non_exhaustive] pub enum Error { /// Missing state at block with given descriptor. #[error("State unavailable at block {0}")] diff --git a/primitives/state-machine/src/error.rs b/primitives/state-machine/src/error.rs index 0b02c68f79f..f20f9e530dc 100644 --- a/primitives/state-machine/src/error.rs +++ b/primitives/state-machine/src/error.rs @@ -32,18 +32,18 @@ impl Error for T {} /// would not be executed unless externalities were available. This is included for completeness, /// and as a transition away from the pre-existing framework. #[derive(Debug, Eq, PartialEq)] +#[allow(missing_docs)] #[cfg_attr(feature = "std", derive(thiserror::Error))] pub enum ExecutionError { - /// Backend error. #[cfg_attr(feature = "std", error("Backend error {0:?}"))] Backend(crate::DefaultError), - /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. + #[cfg_attr(feature = "std", error("`:code` entry does not exist in storage"))] CodeEntryDoesNotExist, - /// Backend is incompatible with execution proof generation process. + #[cfg_attr(feature = "std", error("Unable to generate proof"))] UnableToGenerateProof, - /// Invalid execution proof. + #[cfg_attr(feature = "std", error("Invalid execution proof"))] InvalidProof, } diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 57ba3a28ac3..4247e1a50c9 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -14,8 +14,9 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +thiserror = { version = "1.0.21", optional = true } codec = { package = "parity-scale-codec", version = "1.3.1", optional = true } -derive_more = { version = "0.99.2", optional = true } +derive_more = { version = "0.99.11", optional = true } futures = { version = "0.3.1", optional = true } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", features = ["derive"], optional = true} @@ -31,6 +32,7 @@ std = [ "futures", "log", "serde", + "thiserror", "sp-api/std", "sp-blockchain", "sp-runtime/std", diff --git a/primitives/transaction-pool/src/error.rs b/primitives/transaction-pool/src/error.rs index 531b397cb94..e356df75908 100644 --- a/primitives/transaction-pool/src/error.rs +++ b/primitives/transaction-pool/src/error.rs @@ -25,49 +25,49 @@ use sp_runtime::transaction_validity::{ pub type Result = std::result::Result; /// Transaction pool error type. -#[derive(Debug, derive_more::Display, derive_more::From)] +#[derive(Debug, thiserror::Error, derive_more::From)] +#[allow(missing_docs)] pub enum Error { - /// Transaction is not verifiable yet, but might be in the future. - #[display(fmt="Unknown transaction validity: {:?}", _0)] + #[error("Unknown transaction validity: {0:?}")] UnknownTransaction(UnknownTransaction), - /// Transaction is invalid. - #[display(fmt="Invalid transaction validity: {:?}", _0)] + + #[error("Invalid transaction validity: {0:?}")] InvalidTransaction(InvalidTransaction), + /// The transaction validity returned no "provides" tag. /// /// Such transactions are not accepted to the pool, since we use those tags /// to define identity of transactions (occupance of the same "slot"). - #[display(fmt="The transaction does not provide any tags, so the pool can't identify it.")] + #[error("Transaction does not provide any tags, so the pool can't identify it")] NoTagsProvided, - /// The transaction is temporarily banned. - #[display(fmt="Temporarily Banned")] + + #[error("Transaction temporarily Banned")] TemporarilyBanned, - /// The transaction is already in the pool. - #[display(fmt="[{:?}] Already imported", _0)] + + #[error("[{0:?}] Already imported")] AlreadyImported(Box), - /// The transaction cannot be imported cause it's a replacement and has too low priority. - #[display(fmt="Too low priority ({} > {})", old, new)] + + #[error("Too low priority ({} > {})", old, new)] TooLowPriority { /// Transaction already in the pool. old: Priority, /// Transaction entering the pool. new: Priority }, - /// Deps cycle detected and we couldn't import transaction. - #[display(fmt="Cycle Detected")] + #[error("Transaction with cyclic dependency")] CycleDetected, - /// Transaction was dropped immediately after it got inserted. - #[display(fmt="Transaction couldn't enter the pool because of the limit.")] + + #[error("Transaction couldn't enter the pool because of the limit")] ImmediatelyDropped, - /// Invalid block id. + + #[from(ignore)] + #[error("{0}")] InvalidBlockId(String), - /// The pool is not accepting future transactions. - #[display(fmt="The pool is not accepting future transactions")] + + #[error("The pool is not accepting future transactions")] RejectedFutureTransaction, } -impl std::error::Error for Error {} - /// Transaction pool error conversion. pub trait IntoPoolError: std::error::Error + Send + Sized { /// Try to extract original `Error` -- GitLab From ca62de00422f2a7eeeb39fbabc025ff79b768b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Fri, 27 Nov 2020 22:37:38 +0000 Subject: [PATCH 058/163] network: don't force send block announcements (#7601) --- client/network/src/protocol.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 9a8cfe7e1ff..9e589330b7f 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1083,16 +1083,11 @@ impl Protocol { let is_best = self.context_data.chain.info().best_hash == hash; debug!(target: "sync", "Reannouncing block {:?} is_best: {}", hash, is_best); - self.send_announcement(&header, data, is_best, true) - } - - fn send_announcement(&mut self, header: &B::Header, data: Vec, is_best: bool, force: bool) { - let hash = header.hash(); for (who, ref mut peer) in self.context_data.peers.iter_mut() { - trace!(target: "sync", "Announcing block {:?} to {}", hash, who); let inserted = peer.known_blocks.insert(hash); - if inserted || force { + if inserted { + trace!(target: "sync", "Announcing block {:?} to {}", hash, who); let message = message::BlockAnnounce { header: header.clone(), state: if is_best { -- GitLab From b2d9affd7135bdc08daba0ae460219740822980f Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Sat, 28 Nov 2020 09:40:24 +0100 Subject: [PATCH 059/163] Change TRACING_SET to static (#7607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change TRACING_SET to static * Update primitives/io/src/lib.rs Co-authored-by: Bastian Köcher * modify test with nested spans Co-authored-by: Bastian Köcher --- client/executor/runtime-test/src/lib.rs | 11 +++++++++++ client/executor/src/integration_tests/mod.rs | 9 +++++++++ primitives/io/src/lib.rs | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index f4cef65b629..bfba4ef0393 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -261,6 +261,17 @@ sp_core::wasm_export_functions! { wasm_tracing::exit(span_id) } + fn test_nested_spans() { + sp_io::init_tracing(); + let span_id = wasm_tracing::enter_span(Default::default()); + { + sp_io::init_tracing(); + let span_id = wasm_tracing::enter_span(Default::default()); + wasm_tracing::exit(span_id); + } + wasm_tracing::exit(span_id); + } + fn returns_mutable_static() -> u64 { unsafe { MUTABLE_STATIC += 1; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 08771847c25..62368441f58 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -719,6 +719,15 @@ fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) { assert_eq!(span_datum.target, "default"); assert_eq!(span_datum.name, ""); assert_eq!(values.bool_values.get("wasm").unwrap(), &true); + + call_in_wasm( + "test_nested_spans", + Default::default(), + wasm_method, + &mut ext, + ).unwrap(); + let len = traces.lock().unwrap().len(); + assert_eq!(len, 2); } #[test_case(WasmExecutionMethod::Interpreted)] diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 382a0c4b3bd..d812baefb57 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -1093,7 +1093,7 @@ mod tracing_setup { }; use super::{wasm_tracing, Crossing}; - const TRACING_SET : AtomicBool = AtomicBool::new(false); + static TRACING_SET: AtomicBool = AtomicBool::new(false); /// The PassingTracingSubscriber implements `tracing_core::Subscriber` -- GitLab From 72cfd777812d1c374265d17524bec63ee5f07d69 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Nov 2020 11:52:08 +0100 Subject: [PATCH 060/163] sc-network: Log outgoing notifications too (#7624) * Log outgoing notifications too * Update client/network/src/protocol/generic_proto/handler.rs Co-authored-by: Max Inden Co-authored-by: Addie Wagenknecht Co-authored-by: Max Inden --- .../src/protocol/generic_proto/behaviour.rs | 14 +++++++---- .../src/protocol/generic_proto/handler.rs | 21 ++++++++++++++++- client/network/src/service.rs | 23 ++++++++++++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index f84aead4728..f76b3cc7160 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -650,13 +650,17 @@ impl GenericProto { Some(sink) => sink }; + let message = message.into(); + trace!( target: "sub-libp2p", - "External API => Notification({:?}, {:?})", + "External API => Notification({:?}, {:?}, {} bytes)", target, protocol_name, + message.len(), ); - trace!(target: "sub-libp2p", "Handler({:?}) <= Packet", target); + trace!(target: "sub-libp2p", "Handler({:?}) <= Sync notification", target); + notifs_sink.send_sync_notification( protocol_name, message @@ -1930,9 +1934,10 @@ impl NetworkBehaviour for GenericProto { if self.is_open(&source) { trace!( target: "sub-libp2p", - "Handler({:?}) => Notification({:?})", + "Handler({:?}) => Notification({:?}, {} bytes)", source, protocol_name, + message.len() ); trace!(target: "sub-libp2p", "External API <= Message({:?}, {:?})", protocol_name, source); let event = GenericProtoOut::Notification { @@ -1945,9 +1950,10 @@ impl NetworkBehaviour for GenericProto { } else { trace!( target: "sub-libp2p", - "Handler({:?}) => Post-close notification({:?})", + "Handler({:?}) => Post-close notification({:?}, {} bytes)", source, protocol_name, + message.len() ); } } diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index 42cf02f1b77..13d44cd1a09 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -138,6 +138,9 @@ pub struct NotifsHandler { /// Whether we are the connection dialer or listener. endpoint: ConnectedPoint, + /// Remote we are connected to. + peer_id: PeerId, + /// State of this handler. state: State, @@ -260,12 +263,13 @@ impl IntoProtocolsHandler for NotifsHandlerProto { SelectUpgrade::new(in_protocols, self.legacy_protocol.clone()) } - fn into_handler(self, _: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler { + fn into_handler(self, peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler { let num_out_proto = self.out_protocols.len(); NotifsHandler { in_protocols: self.in_protocols, out_protocols: self.out_protocols, + peer_id: peer_id.clone(), endpoint: connected_point.clone(), when_connection_open: Instant::now(), state: State::Closed { @@ -365,6 +369,8 @@ pub struct NotificationsSink { #[derive(Debug)] struct NotificationsSinkInner { + /// Target of the sink. + peer_id: PeerId, /// Sender to use in asynchronous contexts. Uses an asynchronous mutex. async_channel: FuturesMutex>, /// Sender to use in synchronous contexts. Uses a synchronous mutex. @@ -390,6 +396,11 @@ enum NotificationsSinkMessage { } impl NotificationsSink { + /// Returns the [`PeerId`] the sink is connected to. + pub fn peer_id(&self) -> &PeerId { + &self.inner.peer_id + } + /// Sends a notification to the peer. /// /// If too many messages are already buffered, the notification is silently discarded and the @@ -447,6 +458,12 @@ pub struct Ready<'a> { } impl<'a> Ready<'a> { + /// Returns the name of the protocol. Matches the one passed to + /// [`NotificationsSink::reserve_notification`]. + pub fn protocol_name(&self) -> &Cow<'static, str> { + &self.protocol_name + } + /// Consumes this slots reservation and actually queues the notification. /// /// Returns an error if the substream has been closed. @@ -622,6 +639,7 @@ impl ProtocolsHandler for NotifsHandler { let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); let notifications_sink = NotificationsSink { inner: Arc::new(NotificationsSinkInner { + peer_id: self.peer_id.clone(), async_channel: FuturesMutex::new(async_tx), sync_channel: Mutex::new(sync_tx), }), @@ -782,6 +800,7 @@ impl ProtocolsHandler for NotifsHandler { let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); let notifications_sink = NotificationsSink { inner: Arc::new(NotificationsSinkInner { + peer_id: self.peer_id.clone(), async_channel: FuturesMutex::new(async_tx), sync_channel: Mutex::new(sync_tx), }), diff --git a/client/network/src/service.rs b/client/network/src/service.rs index c722c3e32d7..8c0dbd7eec6 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -664,7 +664,7 @@ impl NetworkService { // `peers_notifications_sinks` mutex as soon as possible. let sink = { let peers_notifications_sinks = self.peers_notifications_sinks.lock(); - if let Some(sink) = peers_notifications_sinks.get(&(target, protocol.clone())) { + if let Some(sink) = peers_notifications_sinks.get(&(target.clone(), protocol.clone())) { sink.clone() } else { // Notification silently discarded, as documented. @@ -684,6 +684,14 @@ impl NetworkService { } // Sending is communicated to the `NotificationsSink`. + trace!( + target: "sub-libp2p", + "External API => Notification({:?}, {:?}, {} bytes)", + target, + protocol, + message.len() + ); + trace!(target: "sub-libp2p", "Handler({:?}) <= Sync notification", target); sink.send_sync_notification(protocol, message); } @@ -1139,6 +1147,7 @@ impl NotificationSender { Ok(r) => r, Err(()) => return Err(NotificationSenderError::Closed), }, + peer_id: self.sink.peer_id(), notification_size_metric: self.notification_size_metric.clone(), }) } @@ -1149,6 +1158,9 @@ impl NotificationSender { pub struct NotificationSenderReady<'a> { ready: Ready<'a>, + /// Target of the notification. + peer_id: &'a PeerId, + /// Field extracted from the [`Metrics`] struct and necessary to report the /// notifications-related metrics. notification_size_metric: Option, @@ -1163,6 +1175,15 @@ impl<'a> NotificationSenderReady<'a> { notification_size_metric.observe(notification.len() as f64); } + trace!( + target: "sub-libp2p", + "External API => Notification({:?}, {:?}, {} bytes)", + self.peer_id, + self.ready.protocol_name(), + notification.len() + ); + trace!(target: "sub-libp2p", "Handler({:?}) <= Async notification", self.peer_id); + self.ready .send(notification) .map_err(|()| NotificationSenderError::Closed) -- GitLab From 9450a9d29156a80f48947fdf650396f488ca1c32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Nov 2020 13:51:54 +0100 Subject: [PATCH 061/163] Bump console_log from 0.1.2 to 0.2.0 (#7623) Bumps [console_log](https://github.com/iamcodemaker/console_log) from 0.1.2 to 0.2.0. - [Release notes](https://github.com/iamcodemaker/console_log/releases) - [Commits](https://github.com/iamcodemaker/console_log/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- utils/browser/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b34d5f76c22..8dff54073ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -790,9 +790,9 @@ dependencies = [ [[package]] name = "console_log" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48" +checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" dependencies = [ "log", "web-sys", @@ -9748,7 +9748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ "cfg-if 0.1.10", - "rand 0.3.23", + "rand 0.7.3", "static_assertions", ] diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index e56fea11a38..31fc1e37f3d 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -18,7 +18,7 @@ futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" libp2p-wasm-ext = { version = "0.25", features = ["websocket"] } console_error_panic_hook = "0.1.6" -console_log = "0.1.2" +console_log = "0.2.0" js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.18" -- GitLab From 2fbab7609adc044f6504e2b861c59125aaccdb7b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 30 Nov 2020 04:57:15 -0800 Subject: [PATCH 062/163] `sudo_as` should return a result (#7620) --- frame/sudo/src/lib.rs | 12 +++--------- frame/sudo/src/tests.rs | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 0d21e443266..7629355d98d 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -214,15 +214,9 @@ decl_module! { let who = T::Lookup::lookup(who)?; - let res = match call.dispatch_bypass_filter(frame_system::RawOrigin::Signed(who).into()) { - Ok(_) => true, - Err(e) => { - sp_runtime::print(e); - false - } - }; + let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Signed(who).into()); - Self::deposit_event(RawEvent::SudoAsDone(res)); + Self::deposit_event(RawEvent::SudoAsDone(res.map(|_| ()).map_err(|e| e.error))); // Sudo user does not pay a fee. Ok(Pays::No.into()) } @@ -236,7 +230,7 @@ decl_event!( /// The \[sudoer\] just switched identity; the old key is supplied. KeyChanged(AccountId), /// A sudo just took place. \[result\] - SudoAsDone(bool), + SudoAsDone(DispatchResult), } ); diff --git a/frame/sudo/src/tests.rs b/frame/sudo/src/tests.rs index cba1e1cf605..03ce100c3a4 100644 --- a/frame/sudo/src/tests.rs +++ b/frame/sudo/src/tests.rs @@ -163,7 +163,7 @@ fn sudo_as_emits_events_correctly() { // A non-privileged function will work when passed to `sudo_as` with the root `key`. let call = Box::new(Call::Logger(LoggerCall::non_privileged_log(42, 1))); assert_ok!(Sudo::sudo_as(Origin::signed(1), 2, call)); - let expected_event = TestEvent::sudo(RawEvent::SudoAsDone(true)); + let expected_event = TestEvent::sudo(RawEvent::SudoAsDone(Ok(()))); assert!(System::events().iter().any(|a| a.event == expected_event)); }); } -- GitLab From 779c801d31ff31a9dba9d11326c01c4780b4d589 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Nov 2020 15:05:01 +0100 Subject: [PATCH 063/163] Fix wrong value put for pending_opening (#7633) * Fix wrong value put for pending_opening * Oops, didn't even try compiling it --- client/network/src/protocol/generic_proto/handler.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index 13d44cd1a09..e479a34d14f 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -684,6 +684,7 @@ impl ProtocolsHandler for NotifsHandler { _ => unreachable!() }; + debug_assert_eq!(pending_opening.len(), self.out_protocols.len()); for (n, is_pending) in pending_opening.iter().enumerate() { if *is_pending { continue; @@ -740,8 +741,9 @@ impl ProtocolsHandler for NotifsHandler { match &mut self.state { State::Open { .. } => { + let pending_opening = self.out_protocols.iter().map(|_| false).collect(); self.state = State::Closed { - pending_opening: Vec::new(), + pending_opening, }; }, State::Opening { out_substreams, .. } => { -- GitLab From 237874bb15bbac174b6cb8d594053b5512f32ca2 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Mon, 30 Nov 2020 15:34:54 +0100 Subject: [PATCH 064/163] Rename pallet trait `Trait` to `Config` (#7599) * rename Trait to Config * add test asserting using Trait is still valid. * fix ui tests --- Cargo.lock | 1 + bin/node-template/pallets/template/src/lib.rs | 12 +- .../pallets/template/src/mock.rs | 6 +- bin/node-template/runtime/src/lib.rs | 18 +- bin/node/executor/tests/basic.rs | 4 +- bin/node/runtime/src/impls.rs | 2 +- bin/node/runtime/src/lib.rs | 68 ++++---- bin/utils/subkey/src/lib.rs | 2 +- frame/assets/src/lib.rs | 30 ++-- frame/atomic-swap/src/lib.rs | 20 +-- frame/atomic-swap/src/tests.rs | 6 +- frame/aura/src/lib.rs | 28 ++-- frame/aura/src/mock.rs | 8 +- frame/authority-discovery/src/lib.rs | 20 +-- frame/authorship/src/lib.rs | 16 +- frame/babe/src/equivocation.rs | 10 +- frame/babe/src/lib.rs | 44 ++--- frame/babe/src/mock.rs | 22 +-- frame/babe/src/tests.rs | 8 +- frame/balances/src/lib.rs | 76 ++++----- frame/balances/src/tests.rs | 6 +- frame/balances/src/tests_composite.rs | 8 +- frame/balances/src/tests_local.rs | 8 +- frame/balances/src/weights.rs | 2 +- frame/benchmarking/src/lib.rs | 14 +- frame/benchmarking/src/tests.rs | 18 +- frame/collective/src/benchmarking.rs | 4 +- frame/collective/src/lib.rs | 42 ++--- frame/collective/src/weights.rs | 2 +- frame/contracts/src/benchmarking/code.rs | 20 +-- frame/contracts/src/benchmarking/mod.rs | 30 ++-- frame/contracts/src/benchmarking/sandbox.rs | 6 +- frame/contracts/src/exec.rs | 78 ++++----- frame/contracts/src/gas.rs | 8 +- frame/contracts/src/lib.rs | 46 ++--- frame/contracts/src/rent.rs | 12 +- frame/contracts/src/schedule.rs | 20 +-- frame/contracts/src/storage.rs | 4 +- frame/contracts/src/tests.rs | 50 +++--- frame/contracts/src/wasm/code_cache.rs | 8 +- frame/contracts/src/wasm/env_def/macros.rs | 8 +- frame/contracts/src/wasm/mod.rs | 18 +- frame/contracts/src/wasm/prepare.rs | 14 +- frame/contracts/src/wasm/runtime.rs | 16 +- frame/contracts/src/weights.rs | 2 +- frame/democracy/src/benchmarking.rs | 12 +- frame/democracy/src/lib.rs | 24 +-- frame/democracy/src/tests.rs | 10 +- frame/democracy/src/weights.rs | 2 +- frame/elections-phragmen/src/benchmarking.rs | 26 +-- frame/elections-phragmen/src/lib.rs | 30 ++-- frame/elections-phragmen/src/weights.rs | 2 +- frame/elections/src/lib.rs | 18 +- frame/elections/src/mock.rs | 6 +- frame/elections/src/tests.rs | 4 +- frame/example-offchain-worker/src/lib.rs | 16 +- frame/example-offchain-worker/src/tests.rs | 8 +- frame/example-parallel/src/lib.rs | 8 +- frame/example-parallel/src/tests.rs | 4 +- frame/example/src/lib.rs | 46 ++--- frame/executive/src/lib.rs | 40 ++--- frame/grandpa/src/equivocation.rs | 10 +- frame/grandpa/src/lib.rs | 18 +- frame/grandpa/src/mock.rs | 20 +-- frame/grandpa/src/tests.rs | 4 +- frame/identity/src/benchmarking.rs | 24 +-- frame/identity/src/lib.rs | 22 +-- frame/identity/src/tests.rs | 6 +- frame/identity/src/weights.rs | 2 +- frame/im-online/src/benchmarking.rs | 2 +- frame/im-online/src/lib.rs | 32 ++-- frame/im-online/src/mock.rs | 12 +- frame/im-online/src/weights.rs | 2 +- frame/indices/src/lib.rs | 20 +-- frame/indices/src/mock.rs | 8 +- frame/indices/src/weights.rs | 2 +- frame/membership/src/lib.rs | 22 +-- frame/multisig/src/benchmarking.rs | 6 +- frame/multisig/src/lib.rs | 26 +-- frame/multisig/src/tests.rs | 6 +- frame/multisig/src/weights.rs | 2 +- frame/nicks/src/lib.rs | 26 +-- frame/node-authorization/src/lib.rs | 18 +- frame/offences/benchmarking/src/lib.rs | 28 ++-- frame/offences/benchmarking/src/mock.rs | 18 +- frame/offences/src/lib.rs | 22 +-- frame/offences/src/mock.rs | 6 +- frame/offences/src/tests.rs | 2 +- frame/proxy/src/benchmarking.rs | 18 +- frame/proxy/src/lib.rs | 40 ++--- frame/proxy/src/tests.rs | 8 +- frame/proxy/src/weights.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 16 +- frame/recovery/src/lib.rs | 20 +-- frame/recovery/src/mock.rs | 6 +- frame/scheduler/src/benchmarking.rs | 2 +- frame/scheduler/src/lib.rs | 100 +++++------ frame/scheduler/src/weights.rs | 2 +- frame/scored-pool/src/lib.rs | 26 +-- frame/scored-pool/src/mock.rs | 6 +- frame/session/benchmarking/src/lib.rs | 8 +- frame/session/benchmarking/src/mock.rs | 14 +- frame/session/src/historical/mod.rs | 20 +-- frame/session/src/historical/offchain.rs | 18 +- frame/session/src/historical/onchain.rs | 4 +- frame/session/src/lib.rs | 22 +-- frame/session/src/mock.rs | 8 +- frame/session/src/tests.rs | 2 +- frame/session/src/weights.rs | 2 +- frame/society/src/lib.rs | 24 +-- frame/society/src/mock.rs | 6 +- frame/staking/fuzzer/src/mock.rs | 14 +- frame/staking/src/benchmarking.rs | 8 +- frame/staking/src/lib.rs | 86 +++++----- frame/staking/src/mock.rs | 18 +- frame/staking/src/offchain_election.rs | 12 +- frame/staking/src/slashing.rs | 28 ++-- frame/staking/src/testing_utils.rs | 22 +-- frame/staking/src/tests.rs | 30 ++-- frame/staking/src/weights.rs | 2 +- frame/sudo/src/lib.rs | 26 +-- frame/sudo/src/mock.rs | 20 +-- frame/support/procedural/src/lib.rs | 10 +- .../genesis_config/genesis_config_def.rs | 4 +- frame/support/procedural/src/storage/mod.rs | 8 +- frame/support/src/dispatch.rs | 98 +++++------ frame/support/src/error.rs | 6 +- frame/support/src/event.rs | 70 ++++---- frame/support/src/lib.rs | 26 +-- frame/support/src/metadata.rs | 38 ++--- frame/support/src/origin.rs | 40 ++--- .../src/storage/generator/double_map.rs | 6 +- frame/support/src/storage/generator/map.rs | 6 +- frame/support/src/storage/generator/mod.rs | 8 +- frame/support/src/traits.rs | 12 +- frame/support/src/weights.rs | 26 +-- frame/support/test/Cargo.toml | 2 + frame/support/test/src/lib.rs | 4 +- frame/support/test/tests/construct_runtime.rs | 28 ++-- ...served_keyword_two_times_integrity_test.rs | 2 +- ...ed_keyword_two_times_integrity_test.stderr | 4 +- ...eserved_keyword_two_times_on_initialize.rs | 2 +- ...ved_keyword_two_times_on_initialize.stderr | 4 +- frame/support/test/tests/decl_storage.rs | 40 ++--- .../tests/decl_storage_ui/config_duplicate.rs | 6 +- .../decl_storage_ui/config_get_duplicate.rs | 6 +- .../tests/decl_storage_ui/get_duplicate.rs | 6 +- frame/support/test/tests/derive_no_bound.rs | 10 +- .../test/tests/derive_no_bound_ui/clone.rs | 4 +- .../tests/derive_no_bound_ui/clone.stderr | 4 +- .../test/tests/derive_no_bound_ui/debug.rs | 4 +- .../tests/derive_no_bound_ui/debug.stderr | 6 +- .../test/tests/derive_no_bound_ui/eq.rs | 4 +- .../test/tests/derive_no_bound_ui/eq.stderr | 2 +- .../tests/derive_no_bound_ui/partial_eq.rs | 4 +- .../derive_no_bound_ui/partial_eq.stderr | 4 +- frame/support/test/tests/final_keys.rs | 12 +- frame/support/test/tests/genesisconfig.rs | 10 +- frame/support/test/tests/instance.rs | 54 +++--- frame/support/test/tests/issue2219.rs | 22 +-- frame/support/test/tests/pallet_version.rs | 24 +-- .../tests/pallet_with_name_trait_is_valid.rs | 157 ++++++++++++++++++ .../tests/reserved_keyword/on_initialize.rs | 4 +- .../support/test/tests/storage_transaction.rs | 10 +- frame/support/test/tests/system.rs | 12 +- frame/system/benches/bench.rs | 10 +- frame/system/benchmarking/src/lib.rs | 4 +- frame/system/benchmarking/src/mock.rs | 6 +- frame/system/src/extensions/check_genesis.rs | 12 +- .../system/src/extensions/check_mortality.rs | 10 +- frame/system/src/extensions/check_nonce.rs | 10 +- .../src/extensions/check_spec_version.rs | 12 +- .../system/src/extensions/check_tx_version.rs | 12 +- frame/system/src/extensions/check_weight.rs | 48 +++--- frame/system/src/lib.rs | 38 ++--- frame/system/src/mock.rs | 10 +- frame/system/src/offchain.rs | 2 +- frame/system/src/weights.rs | 2 +- frame/timestamp/src/lib.rs | 26 +-- frame/timestamp/src/weights.rs | 2 +- frame/transaction-payment/src/lib.rs | 54 +++--- frame/transaction-payment/src/payment.rs | 18 +- frame/treasury/src/benchmarking.rs | 18 +- frame/treasury/src/lib.rs | 28 ++-- frame/treasury/src/tests.rs | 6 +- frame/treasury/src/weights.rs | 2 +- frame/utility/src/benchmarking.rs | 8 +- frame/utility/src/lib.rs | 24 +-- frame/utility/src/tests.rs | 18 +- frame/utility/src/weights.rs | 2 +- frame/vesting/src/benchmarking.rs | 6 +- frame/vesting/src/lib.rs | 30 ++-- frame/vesting/src/weights.rs | 2 +- .../api/proc-macro/src/impl_runtime_apis.rs | 2 +- .../runtime/src/offchain/storage_lock.rs | 4 +- primitives/runtime/src/traits.rs | 4 +- test-utils/runtime/src/lib.rs | 8 +- test-utils/runtime/src/system.rs | 6 +- .../frame-utilities-cli/src/module_id.rs | 2 +- utils/frame/rpc/support/src/lib.rs | 12 +- 200 files changed, 1767 insertions(+), 1607 deletions(-) create mode 100644 frame/support/test/tests/pallet_with_name_trait_is_valid.rs diff --git a/Cargo.lock b/Cargo.lock index 8dff54073ac..446b4442cd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1714,6 +1714,7 @@ version = "2.0.0" dependencies = [ "frame-metadata", "frame-support", + "frame-system", "parity-scale-codec", "pretty_assertions", "rustversion", diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index 729a71278aa..24de4f2f50d 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -14,9 +14,9 @@ mod mock; mod tests; /// Configure the pallet by specifying the parameters and types on which it depends. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } // The pallet's runtime storage items. @@ -25,7 +25,7 @@ decl_storage! { // A unique name is used to ensure that the pallet's storage items are isolated. // This name may be updated, but each pallet in the runtime must use a unique name. // ---------------------------------vvvvvvvvvvvvvv - trait Store for Module as TemplateModule { + trait Store for Module as TemplateModule { // Learn more about declaring storage items: // https://substrate.dev/docs/en/knowledgebase/runtime/storage#declaring-storage-items Something get(fn something): Option; @@ -35,7 +35,7 @@ decl_storage! { // Pallets use events to inform users when important changes are made. // https://substrate.dev/docs/en/knowledgebase/runtime/events decl_event!( - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// Event documentation should end with an array that provides descriptive names for event /// parameters. [something, who] SomethingStored(u32, AccountId), @@ -44,7 +44,7 @@ decl_event!( // Errors inform users that something went wrong. decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Error names should be descriptive. NoneValue, /// Errors should have helpful documentation associated with them. @@ -56,7 +56,7 @@ decl_error! { // These functions materialize as "extrinsics", which are often compared to transactions. // Dispatchable functions must be annotated with a weight and must return a DispatchResult. decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { // Errors must be initialized if they are used by the pallet. type Error = Error; diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index a3dff240e48..4c7c16e7f55 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -1,4 +1,4 @@ -use crate::{Module, Trait}; +use crate::{Module, Config}; use sp_core::H256; use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; use sp_runtime::{ @@ -21,7 +21,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } -impl system::Trait for Test { +impl system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); @@ -49,7 +49,7 @@ impl system::Trait for Test { type SystemWeightInfo = (); } -impl Trait for Test { +impl Config for Test { type Event = (); } diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index aadfd931cdb..a899afe9ad1 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -140,7 +140,7 @@ parameter_types! { // Configure FRAME pallets to include in runtime. -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. type BaseCallFilter = (); /// The identifier used to distinguish between accounts. @@ -199,11 +199,11 @@ impl frame_system::Trait for Runtime { type SystemWeightInfo = (); } -impl pallet_aura::Trait for Runtime { +impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; } -impl pallet_grandpa::Trait for Runtime { +impl pallet_grandpa::Config for Runtime { type Event = Event; type Call = Call; @@ -226,7 +226,7 @@ parameter_types! { pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } -impl pallet_timestamp::Trait for Runtime { +impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; @@ -239,7 +239,7 @@ parameter_types! { pub const MaxLocks: u32 = 50; } -impl pallet_balances::Trait for Runtime { +impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; /// The type for recording an account's balance. type Balance = Balance; @@ -255,20 +255,20 @@ parameter_types! { pub const TransactionByteFee: Balance = 1; } -impl pallet_transaction_payment::Trait for Runtime { +impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } -impl pallet_sudo::Trait for Runtime { +impl pallet_sudo::Config for Runtime { type Event = Event; type Call = Call; } /// Configure the pallet template in pallets/template. -impl template::Trait for Runtime { +impl template::Config for Runtime { type Event = Event; } @@ -457,7 +457,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; use frame_system_benchmarking::Module as SystemBench; - impl frame_system_benchmarking::Trait for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} let whitelist: Vec = vec![ // Block Number diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 236e0a823ac..09438bfacd4 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -580,7 +580,7 @@ const CODE_TRANSFER: &str = r#" #[test] fn deploying_wasm_contract_should_work() { let transfer_code = wat::parse_str(CODE_TRANSFER).unwrap(); - let transfer_ch = ::Hashing::hash(&transfer_code); + let transfer_ch = ::Hashing::hash(&transfer_code); let addr = pallet_contracts::Module::::contract_address( &charlie(), @@ -588,7 +588,7 @@ fn deploying_wasm_contract_should_work() { &[], ); - let subsistence = pallet_contracts::Config::::subsistence_threshold_uncached(); + let subsistence = pallet_contracts::ConfigCache::::subsistence_threshold_uncached(); let b = construct_block( &mut new_test_ext(compact_code_unwrap(), false), diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 16666997b3a..acd8def6835 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -200,7 +200,7 @@ mod multiplier_tests { fm = next; iterations += 1; let fee = - ::WeightToFee::calc(&tx_weight); + ::WeightToFee::calc(&tx_weight); let adjusted_fee = fm.saturating_mul_acc_int(fee); println!( "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 4feff5d051a..be3783cd7ca 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -156,7 +156,7 @@ parameter_types! { const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct()); -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -184,7 +184,7 @@ impl frame_system::Trait for Runtime { type SystemWeightInfo = frame_system::weights::SubstrateWeight; } -impl pallet_utility::Trait for Runtime { +impl pallet_utility::Config for Runtime { type Event = Event; type Call = Call; type WeightInfo = pallet_utility::weights::SubstrateWeight; @@ -198,7 +198,7 @@ parameter_types! { pub const MaxSignatories: u16 = 100; } -impl pallet_multisig::Trait for Runtime { +impl pallet_multisig::Config for Runtime { type Event = Event; type Call = Call; type Currency = Balances; @@ -261,7 +261,7 @@ impl InstanceFilter for ProxyType { } } -impl pallet_proxy::Trait for Runtime { +impl pallet_proxy::Config for Runtime { type Event = Event; type Call = Call; type Currency = Balances; @@ -281,7 +281,7 @@ parameter_types! { pub const MaxScheduledPerBlock: u32 = 50; } -impl pallet_scheduler::Trait for Runtime { +impl pallet_scheduler::Config for Runtime { type Event = Event; type Origin = Origin; type PalletsOrigin = OriginCaller; @@ -297,7 +297,7 @@ parameter_types! { pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; } -impl pallet_babe::Trait for Runtime { +impl pallet_babe::Config for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; @@ -324,7 +324,7 @@ parameter_types! { pub const IndexDeposit: Balance = 1 * DOLLARS; } -impl pallet_indices::Trait for Runtime { +impl pallet_indices::Config for Runtime { type AccountIndex = AccountIndex; type Currency = Balances; type Deposit = IndexDeposit; @@ -339,7 +339,7 @@ parameter_types! { pub const MaxLocks: u32 = 50; } -impl pallet_balances::Trait for Runtime { +impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; type Balance = Balance; type DustRemoval = (); @@ -356,7 +356,7 @@ parameter_types! { pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128); } -impl pallet_transaction_payment::Trait for Runtime { +impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; @@ -368,7 +368,7 @@ parameter_types! { pub const MinimumPeriod: Moment = SLOT_DURATION / 2; } -impl pallet_timestamp::Trait for Runtime { +impl pallet_timestamp::Config for Runtime { type Moment = Moment; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; @@ -379,7 +379,7 @@ parameter_types! { pub const UncleGenerations: BlockNumber = 5; } -impl pallet_authorship::Trait for Runtime { +impl pallet_authorship::Config for Runtime { type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -399,9 +399,9 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); } -impl pallet_session::Trait for Runtime { +impl pallet_session::Config for Runtime { type Event = Event; - type ValidatorId = ::AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; type NextSessionRotation = Babe; @@ -412,7 +412,7 @@ impl pallet_session::Trait for Runtime { type WeightInfo = pallet_session::weights::SubstrateWeight; } -impl pallet_session::historical::Trait for Runtime { +impl pallet_session::historical::Config for Runtime { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -443,7 +443,7 @@ parameter_types! { .saturating_sub(ExtrinsicBaseWeight::get()); } -impl pallet_staking::Trait for Runtime { +impl pallet_staking::Config for Runtime { type Currency = Balances; type UnixTime = Timestamp; type CurrencyToVote = U128CurrencyToVote; @@ -489,7 +489,7 @@ parameter_types! { pub const MaxProposals: u32 = 100; } -impl pallet_democracy::Trait for Runtime { +impl pallet_democracy::Config for Runtime { type Proposal = Call; type Event = Event; type Currency = Balances; @@ -541,7 +541,7 @@ parameter_types! { } type CouncilCollective = pallet_collective::Instance1; -impl pallet_collective::Trait for Runtime { +impl pallet_collective::Config for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; @@ -564,7 +564,7 @@ parameter_types! { // Make sure that there are no more than `MaxMembers` members elected via elections-phragmen. const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get()); -impl pallet_elections_phragmen::Trait for Runtime { +impl pallet_elections_phragmen::Config for Runtime { type Event = Event; type ModuleId = ElectionsPhragmenModuleId; type Currency = Balances; @@ -591,7 +591,7 @@ parameter_types! { } type TechnicalCollective = pallet_collective::Instance2; -impl pallet_collective::Trait for Runtime { +impl pallet_collective::Config for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; @@ -607,7 +607,7 @@ type EnsureRootOrHalfCouncil = EnsureOneOf< EnsureRoot, pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective> >; -impl pallet_membership::Trait for Runtime { +impl pallet_membership::Config for Runtime { type Event = Event; type AddOrigin = EnsureRootOrHalfCouncil; type RemoveOrigin = EnsureRootOrHalfCouncil; @@ -636,7 +636,7 @@ parameter_types! { pub const BountyValueMinimum: Balance = 5 * DOLLARS; } -impl pallet_treasury::Trait for Runtime { +impl pallet_treasury::Config for Runtime { type ModuleId = TreasuryModuleId; type Currency = Balances; type ApproveOrigin = EnsureOneOf< @@ -681,7 +681,7 @@ parameter_types! { pub const MaxValueSize: u32 = 16 * 1024; } -impl pallet_contracts::Trait for Runtime { +impl pallet_contracts::Config for Runtime { type Time = Timestamp; type Randomness = RandomnessCollectiveFlip; type Currency = Balances; @@ -699,7 +699,7 @@ impl pallet_contracts::Trait for Runtime { type WeightInfo = pallet_contracts::weights::SubstrateWeight; } -impl pallet_sudo::Trait for Runtime { +impl pallet_sudo::Config for Runtime { type Event = Event; type Call = Call; } @@ -769,7 +769,7 @@ impl frame_system::offchain::SendTransactionTypes for Runtime where type OverarchingCall = Call; } -impl pallet_im_online::Trait for Runtime { +impl pallet_im_online::Config for Runtime { type AuthorityId = ImOnlineId; type Event = Event; type SessionDuration = SessionDuration; @@ -782,16 +782,16 @@ parameter_types! { pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } -impl pallet_offences::Trait for Runtime { +impl pallet_offences::Config for Runtime { type Event = Event; type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; type WeightSoftLimit = OffencesWeightSoftLimit; } -impl pallet_authority_discovery::Trait for Runtime {} +impl pallet_authority_discovery::Config for Runtime {} -impl pallet_grandpa::Trait for Runtime { +impl pallet_grandpa::Config for Runtime { type Event = Event; type Call = Call; @@ -820,7 +820,7 @@ parameter_types! { pub const MaxRegistrars: u32 = 20; } -impl pallet_identity::Trait for Runtime { +impl pallet_identity::Config for Runtime { type Event = Event; type Currency = Balances; type BasicDeposit = BasicDeposit; @@ -842,7 +842,7 @@ parameter_types! { pub const RecoveryDeposit: Balance = 5 * DOLLARS; } -impl pallet_recovery::Trait for Runtime { +impl pallet_recovery::Config for Runtime { type Event = Event; type Call = Call; type Currency = Balances; @@ -863,7 +863,7 @@ parameter_types! { pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie"); } -impl pallet_society::Trait for Runtime { +impl pallet_society::Config for Runtime { type Event = Event; type ModuleId = SocietyModuleId; type Currency = Balances; @@ -884,7 +884,7 @@ parameter_types! { pub const MinVestedTransfer: Balance = 100 * DOLLARS; } -impl pallet_vesting::Trait for Runtime { +impl pallet_vesting::Config for Runtime { type Event = Event; type Currency = Balances; type BlockNumberToBalance = ConvertInto; @@ -1173,9 +1173,9 @@ impl_runtime_apis! { use pallet_offences_benchmarking::Module as OffencesBench; use frame_system_benchmarking::Module as SystemBench; - impl pallet_session_benchmarking::Trait for Runtime {} - impl pallet_offences_benchmarking::Trait for Runtime {} - impl frame_system_benchmarking::Trait for Runtime {} + impl pallet_session_benchmarking::Config for Runtime {} + impl pallet_offences_benchmarking::Config for Runtime {} + impl frame_system_benchmarking::Config for Runtime {} let whitelist: Vec = vec![ // Block Number diff --git a/bin/utils/subkey/src/lib.rs b/bin/utils/subkey/src/lib.rs index 051628e84a1..c38a4857652 100644 --- a/bin/utils/subkey/src/lib.rs +++ b/bin/utils/subkey/src/lib.rs @@ -63,7 +63,7 @@ pub enum Subkey { /// Run the subkey command, given the apropriate runtime. pub fn run() -> Result<(), Error> where - R: frame_system::Trait, + R: frame_system::Config, R::AccountId: Ss58Codec { match Subkey::from_args() { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index e5ad2ae352e..9ed442aada3 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -28,7 +28,7 @@ //! * Asset Transfer //! * Asset Destruction //! -//! To use it in your runtime, you need to implement the assets [`Trait`](./trait.Trait.html). +//! To use it in your runtime, you need to implement the assets [`Config`](./trait.Config.html). //! //! The supported dispatchable functions are documented in the [`Call`](./enum.Call.html) enum. //! @@ -89,10 +89,10 @@ //! use frame_support::{decl_module, dispatch, ensure}; //! use frame_system::ensure_signed; //! -//! pub trait Trait: assets::Trait { } +//! pub trait Config: assets::Config { } //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! pub fn issue_token_airdrop(origin) -> dispatch::DispatchResult { //! let sender = ensure_signed(origin).map_err(|e| e.as_str())?; //! @@ -123,7 +123,7 @@ //! them are violated, the behavior of this module is undefined. //! //! * The total count of assets should be less than -//! `Trait::AssetId::max_value()`. +//! `Config::AssetId::max_value()`. //! //! ## Related Modules //! @@ -139,9 +139,9 @@ use frame_system::ensure_signed; use sp_runtime::traits::One; /// The module configuration trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The units in which we record balances. type Balance: Member + Parameter + AtLeast32BitUnsigned + Default + Copy; @@ -151,7 +151,7 @@ pub trait Trait: frame_system::Trait { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -226,9 +226,9 @@ decl_module! { decl_event! { pub enum Event where - ::AccountId, - ::Balance, - ::AssetId, + ::AccountId, + ::Balance, + ::AssetId, { /// Some assets were issued. \[asset_id, owner, total_supply\] Issued(AssetId, AccountId, Balance), @@ -240,7 +240,7 @@ decl_event! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Transfer amount should be non-zero AmountZero, /// Account balance must be greater than or equal to the transfer amount @@ -251,7 +251,7 @@ decl_error! { } decl_storage! { - trait Store for Module as Assets { + trait Store for Module as Assets { /// The number of units of assets held by any given account. Balances: map hasher(blake2_128_concat) (T::AssetId, T::AccountId) => T::Balance; /// The next asset identifier up for grabs. @@ -264,7 +264,7 @@ decl_storage! { } // The main implementation block for the module. -impl Module { +impl Module { // Public immutables /// Get the asset `id` balance of `who`. @@ -298,7 +298,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -325,7 +325,7 @@ mod tests { type OnKilledAccount = (); type SystemWeightInfo = (); } - impl Trait for Test { + impl Config for Test { type Event = (); type Balance = u64; type AssetId = u32; diff --git a/frame/atomic-swap/src/lib.rs b/frame/atomic-swap/src/lib.rs index 31f0c0f4265..ac9b82b0df0 100644 --- a/frame/atomic-swap/src/lib.rs +++ b/frame/atomic-swap/src/lib.rs @@ -19,7 +19,7 @@ //! //! A module for atomically sending funds. //! -//! - [`atomic_swap::Trait`](./trait.Trait.html) +//! - [`atomic_swap::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -56,7 +56,7 @@ use sp_runtime::RuntimeDebug; /// Pending atomic swap operation. #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode)] -pub struct PendingSwap { +pub struct PendingSwap { /// Source of the swap. pub source: T::AccountId, /// Action of this swap. @@ -74,7 +74,7 @@ pub type HashedProof = [u8; 32]; /// succeeds with best efforts. /// - **Claim**: claim any resources reserved in the first phrase. /// - **Cancel**: cancel any resources reserved in the first phrase. -pub trait SwapAction { +pub trait SwapAction { /// Reserve the resources needed for the swap, from the given `source`. The reservation is /// allowed to fail. If that is the case, the the full swap creation operation is cancelled. fn reserve(&self, source: &AccountId) -> DispatchResult; @@ -115,7 +115,7 @@ impl DerefMut for BalanceSwapAction where C: Reserva } } -impl SwapAction for BalanceSwapAction +impl SwapAction for BalanceSwapAction where C: ReservableCurrency { fn reserve(&self, source: &AccountId) -> DispatchResult { @@ -136,9 +136,9 @@ impl SwapAction for BalanceSwapAction> + Into<::Event>; + type Event: From> + Into<::Event>; /// Swap action. type SwapAction: SwapAction + Parameter; /// Limit of proof size. @@ -155,7 +155,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as AtomicSwap { + trait Store for Module as AtomicSwap { pub PendingSwaps: double_map hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) HashedProof => Option>; @@ -163,7 +163,7 @@ decl_storage! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Swap already exists. AlreadyExist, /// Swap proof is invalid. @@ -186,7 +186,7 @@ decl_error! { decl_event!( /// Event of atomic swap pallet. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, PendingSwap = PendingSwap, { /// Swap created. \[account, proof, swap\] @@ -201,7 +201,7 @@ decl_event!( decl_module! { /// Module definition of atomic swap pallet. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index 060411c8815..7254ceba4f6 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -24,7 +24,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -54,7 +54,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type DustRemoval = (); @@ -67,7 +67,7 @@ parameter_types! { pub const ProofLimit: u32 = 1024; pub const ExpireDuration: u64 = 100; } -impl Trait for Test { +impl Config for Test { type Event = (); type SwapAction = BalanceSwapAction; type ProofLimit = ProofLimit; diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index e8e0e616bc0..34f216850c6 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -17,7 +17,7 @@ //! # Aura Module //! -//! - [`aura::Trait`](./trait.Trait.html) +//! - [`aura::Config`](./trait.Config.html) //! - [`Module`](./struct.Module.html) //! //! ## Overview @@ -66,13 +66,13 @@ use sp_consensus_aura::{ mod mock; mod tests; -pub trait Trait: pallet_timestamp::Trait { +pub trait Config: pallet_timestamp::Config { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default; } decl_storage! { - trait Store for Module as Aura { + trait Store for Module as Aura { /// The last timestamp. LastTimestamp get(fn last): T::Moment; @@ -86,10 +86,10 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { } + pub struct Module for enum Call where origin: T::Origin { } } -impl Module { +impl Module { fn change_authorities(new: Vec) { >::put(&new); @@ -108,11 +108,11 @@ impl Module { } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl pallet_session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -145,7 +145,7 @@ impl pallet_session::OneSessionHandler for Module { } } -impl FindAuthor for Module { +impl FindAuthor for Module { fn find_author<'a, I>(digests: I) -> Option where I: 'a + IntoIterator { @@ -167,7 +167,7 @@ impl FindAuthor for Module { #[doc(hidden)] pub struct FindAccountFromAuthorIndex(sp_std::marker::PhantomData<(T, Inner)>); -impl> FindAuthor +impl> FindAuthor for FindAccountFromAuthorIndex { fn find_author<'a, I>(digests: I) -> Option @@ -183,7 +183,7 @@ impl> FindAuthor /// Find the authority ID of the Aura authority who authored the current block. pub type AuraAuthorId = FindAccountFromAuthorIndex>; -impl IsMember for Module { +impl IsMember for Module { fn is_member(authority_id: &T::AuthorityId) -> bool { Self::authorities() .iter() @@ -191,12 +191,12 @@ impl IsMember for Module { } } -impl Module { +impl Module { /// Determine the Aura slot-duration based on the Timestamp module configuration. pub fn slot_duration() -> T::Moment { // we double the minimum block-period so each author can always propose within // the majority of its slot. - ::MinimumPeriod::get().saturating_mul(2u32.into()) + ::MinimumPeriod::get().saturating_mul(2u32.into()) } fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { @@ -218,13 +218,13 @@ impl Module { } } -impl OnTimestampSet for Module { +impl OnTimestampSet for Module { fn on_timestamp_set(moment: T::Moment) { Self::on_timestamp_set(moment, Self::slot_duration()) } } -impl ProvideInherent for Module { +impl ProvideInherent for Module { type Call = pallet_timestamp::Call; type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index a3875727e47..b06a0f427f1 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -19,7 +19,7 @@ #![cfg(test)] -use crate::{Trait, Module, GenesisConfig}; +use crate::{Config, Module, GenesisConfig}; use sp_consensus_aura::ed25519::AuthorityId; use sp_runtime::{ traits::IdentityLookup, Perbill, @@ -45,7 +45,7 @@ parameter_types! { pub const MinimumPeriod: u64 = 1; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -73,14 +73,14 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; type WeightInfo = (); } -impl Trait for Test { +impl Config for Test { type AuthorityId = AuthorityId; } diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 09be533474f..4db7ba753cb 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -28,10 +28,10 @@ use frame_support::{decl_module, decl_storage}; use sp_authority_discovery::AuthorityId; /// The module's config trait. -pub trait Trait: frame_system::Trait + pallet_session::Trait {} +pub trait Config: frame_system::Config + pallet_session::Config {} decl_storage! { - trait Store for Module as AuthorityDiscovery { + trait Store for Module as AuthorityDiscovery { /// Keys of the current and next authority set. Keys get(fn keys): Vec; } @@ -42,11 +42,11 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { } } -impl Module { +impl Module { /// Retrieve authority identifiers of the current and next authority set. pub fn authorities() -> Vec { Keys::get() @@ -60,11 +60,11 @@ impl Module { } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl pallet_session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(authorities: I) @@ -107,13 +107,13 @@ mod tests { #[derive(Clone, Eq, PartialEq)] pub struct Test; - impl Trait for Test {} + impl Config for Test {} parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); } - impl pallet_session::Trait for Test { + impl pallet_session::Config for Test { type SessionManager = (); type Keys = UintAuthorityId; type ShouldEndSession = pallet_session::PeriodicSessions; @@ -126,7 +126,7 @@ mod tests { type WeightInfo = (); } - impl pallet_session::historical::Trait for Test { + impl pallet_session::historical::Config for Test { type FullIdentification = (); type FullIdentificationOf = (); } @@ -143,7 +143,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 0a10c884957..4809462db6e 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -34,7 +34,7 @@ use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; const MAX_UNCLES: usize = 10; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// Find the author of a block. type FindAuthor: FindAuthor; /// The number of blocks back we should accept uncles. @@ -152,7 +152,7 @@ enum UncleEntryItem { } decl_storage! { - trait Store for Module as Authorship { + trait Store for Module as Authorship { /// Uncles Uncles: Vec>; /// Author of current block. @@ -164,7 +164,7 @@ decl_storage! { decl_error! { /// Error for the authorship module. - pub enum Error for Module { + pub enum Error for Module { /// The uncle parent not in the chain. InvalidUncleParent, /// Uncles already set in the block. @@ -183,7 +183,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn on_initialize(now: T::BlockNumber) -> Weight { @@ -223,7 +223,7 @@ decl_module! { } } -impl Module { +impl Module { /// Fetch the author of the block. /// /// This is safe to invoke in `on_initialize` implementations, as well @@ -337,7 +337,7 @@ impl Module { } } -impl ProvideInherent for Module { +impl ProvideInherent for Module { type Call = Call; type Error = InherentError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; @@ -417,7 +417,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -449,7 +449,7 @@ mod tests { pub const UncleGenerations: u64 = 5; } - impl Trait for Test { + impl Config for Test { type FindAuthor = AuthorGiven; type UncleGenerations = UncleGenerations; type FilterUncle = SealVerify; diff --git a/frame/babe/src/equivocation.rs b/frame/babe/src/equivocation.rs index 322dff92f23..55aaedfe082 100644 --- a/frame/babe/src/equivocation.rs +++ b/frame/babe/src/equivocation.rs @@ -48,14 +48,14 @@ use sp_staking::{ }; use sp_std::prelude::*; -use crate::{Call, Module, Trait}; +use crate::{Call, Module, Config}; /// A trait with utility methods for handling equivocation reports in BABE. /// The trait provides methods for reporting an offence triggered by a valid /// equivocation report, checking the current block author (to declare as the /// reporter), and also for creating and submitting equivocation report /// extrinsics (useful only in offchain context). -pub trait HandleEquivocation { +pub trait HandleEquivocation { /// Report an offence proved by the given reporters. fn report_offence( reporters: Vec, @@ -75,7 +75,7 @@ pub trait HandleEquivocation { fn block_author() -> Option; } -impl HandleEquivocation for () { +impl HandleEquivocation for () { fn report_offence( _reporters: Vec, _offence: BabeEquivocationOffence, @@ -120,7 +120,7 @@ where // We use the authorship pallet to fetch the current block author and use // `offchain::SendTransactionTypes` for unsigned extrinsic creation and // submission. - T: Trait + pallet_authorship::Trait + frame_system::offchain::SendTransactionTypes>, + T: Config + pallet_authorship::Config + frame_system::offchain::SendTransactionTypes>, // A system for reporting offences after valid equivocation reports are // processed. R: ReportOffence< @@ -164,7 +164,7 @@ where /// A `ValidateUnsigned` implementation that restricts calls to `report_equivocation_unsigned` /// to local calls (i.e. extrinsics generated on this node) or that already in a block. This /// guarantees that only block authors can include unsigned equivocation reports. -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { if let Call::report_equivocation_unsigned(equivocation_proof, _) = call { diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 8cab698fda0..a61f1244cbe 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -62,7 +62,7 @@ mod tests; pub use equivocation::{BabeEquivocationOffence, EquivocationHandler, HandleEquivocation}; -pub trait Trait: pallet_timestamp::Trait { +pub trait Config: pallet_timestamp::Config { /// The amount of time, in slots, that each epoch should last. type EpochDuration: Get; @@ -115,7 +115,7 @@ pub trait WeightInfo { pub trait EpochChangeTrigger { /// Trigger an epoch change, if any should take place. This should be called /// during every block, after initialization is done. - fn trigger(now: T::BlockNumber); + fn trigger(now: T::BlockNumber); } /// A type signifying to BABE that an external trigger @@ -123,7 +123,7 @@ pub trait EpochChangeTrigger { pub struct ExternalTrigger; impl EpochChangeTrigger for ExternalTrigger { - fn trigger(_: T::BlockNumber) { } // nothing - trigger is external. + fn trigger(_: T::BlockNumber) { } // nothing - trigger is external. } /// A type signifying to BABE that it should perform epoch changes @@ -131,7 +131,7 @@ impl EpochChangeTrigger for ExternalTrigger { pub struct SameAuthoritiesForever; impl EpochChangeTrigger for SameAuthoritiesForever { - fn trigger(now: T::BlockNumber) { + fn trigger(now: T::BlockNumber) { if >::should_epoch_change(now) { let authorities = >::authorities(); let next_authorities = authorities.clone(); @@ -146,7 +146,7 @@ const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; type MaybeRandomness = Option; decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// An equivocation proof provided as part of an equivocation report is invalid. InvalidEquivocationProof, /// A key ownership proof provided as part of an equivocation report is invalid. @@ -157,7 +157,7 @@ decl_error! { } decl_storage! { - trait Store for Module as Babe { + trait Store for Module as Babe { /// Current epoch index. pub EpochIndex get(fn epoch_index): u64; @@ -230,7 +230,7 @@ decl_storage! { decl_module! { /// The BABE Pallet - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// The number of **slots** that an epoch takes. We couple sessions to /// epochs, i.e. we start a new session once the new epoch begins. const EpochDuration: u64 = T::EpochDuration::get(); @@ -271,7 +271,7 @@ decl_module! { /// the equivocation proof and validate the given key ownership proof /// against the extracted offender. If both are valid, the offence will /// be reported. - #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] + #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] fn report_equivocation( origin, equivocation_proof: EquivocationProof, @@ -294,7 +294,7 @@ decl_module! { /// block authors will call it (validated in `ValidateUnsigned`), as such /// if the block author is defined it will be defined as the equivocation /// reporter. - #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] + #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] fn report_equivocation_unsigned( origin, equivocation_proof: EquivocationProof, @@ -311,7 +311,7 @@ decl_module! { } } -impl RandomnessT<::Hash> for Module { +impl RandomnessT<::Hash> for Module { /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, /// either they make the block or they do not make the block and thus someone else makes the /// next block. Yet, this randomness is not fresh in all BABE blocks. @@ -332,14 +332,14 @@ impl RandomnessT<::Hash> for Module { subject.reserve(VRF_OUTPUT_LENGTH); subject.extend_from_slice(&Self::randomness()[..]); - ::Hashing::hash(&subject[..]) + ::Hashing::hash(&subject[..]) } } /// A BABE public key pub type BabeKey = [u8; PUBLIC_KEY_LENGTH]; -impl FindAuthor for Module { +impl FindAuthor for Module { fn find_author<'a, I>(digests: I) -> Option where I: 'a + IntoIterator { @@ -354,7 +354,7 @@ impl FindAuthor for Module { } } -impl IsMember for Module { +impl IsMember for Module { fn is_member(authority_id: &AuthorityId) -> bool { >::authorities() .iter() @@ -362,7 +362,7 @@ impl IsMember for Module { } } -impl pallet_session::ShouldEndSession for Module { +impl pallet_session::ShouldEndSession for Module { fn should_end_session(now: T::BlockNumber) -> bool { // it might be (and it is in current implementation) that session module is calling // should_end_session() from it's own on_initialize() handler @@ -374,12 +374,12 @@ impl pallet_session::ShouldEndSession for Module { } } -impl Module { +impl Module { /// Determine the BABE slot duration based on the Timestamp module configuration. pub fn slot_duration() -> T::Moment { // we double the minimum block-period so each author can always propose within // the majority of their slot. - ::MinimumPeriod::get().saturating_mul(2u32.into()) + ::MinimumPeriod::get().saturating_mul(2u32.into()) } /// Determine whether an epoch change should take place at this block. @@ -690,11 +690,11 @@ impl Module { } } -impl OnTimestampSet for Module { +impl OnTimestampSet for Module { fn on_timestamp_set(_moment: T::Moment) { } } -impl frame_support::traits::EstimateNextSessionRotation for Module { +impl frame_support::traits::EstimateNextSessionRotation for Module { fn estimate_next_session_rotation(now: T::BlockNumber) -> Option { Self::next_expected_epoch_change(now) } @@ -706,17 +706,17 @@ impl frame_support::traits::EstimateNextSessionRotation frame_support::traits::Lateness for Module { +impl frame_support::traits::Lateness for Module { fn lateness(&self) -> T::BlockNumber { Self::lateness() } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl pallet_session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -766,7 +766,7 @@ fn compute_randomness( sp_io::hashing::blake2_256(&s) } -impl ProvideInherent for Module { +impl ProvideInherent for Module { type Call = pallet_timestamp::Call; type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 9f00a4ddfc3..f3d5bc092bc 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -18,7 +18,7 @@ //! Test utilities use codec::Encode; -use super::{Trait, Module, CurrentSlot}; +use super::{Config, Module, CurrentSlot}; use sp_runtime::{ Perbill, impl_opaque_keys, curve::PiecewiseLinear, @@ -65,7 +65,7 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -107,9 +107,9 @@ impl_opaque_keys! { } } -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type Event = (); - type ValidatorId = ::AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; type NextSessionRotation = Babe; @@ -120,7 +120,7 @@ impl pallet_session::Trait for Test { type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -129,7 +129,7 @@ parameter_types! { pub const UncleGenerations: u64 = 0; } -impl pallet_authorship::Trait for Test { +impl pallet_authorship::Config for Test { type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -140,7 +140,7 @@ parameter_types! { pub const MinimumPeriod: u64 = 1; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; @@ -151,7 +151,7 @@ parameter_types! { pub const ExistentialDeposit: u128 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u128; type DustRemoval = (); @@ -183,7 +183,7 @@ parameter_types! { pub const StakingUnsignedPriority: u64 = u64::max_value() / 2; } -impl pallet_staking::Trait for Test { +impl pallet_staking::Config for Test { type RewardRemainder = (); type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; type Event = (); @@ -212,14 +212,14 @@ parameter_types! { pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } -impl pallet_offences::Trait for Test { +impl pallet_offences::Config for Test { type Event = (); type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; type WeightSoftLimit = OffencesWeightSoftLimit; } -impl Trait for Test { +impl Config for Test { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = crate::ExternalTrigger; diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 06bf84614ca..29b080493f4 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -206,7 +206,7 @@ fn authority_index() { #[test] fn can_predict_next_epoch_change() { new_test_ext(1).execute_with(|| { - assert_eq!(::EpochDuration::get(), 3); + assert_eq!(::EpochDuration::get(), 3); // this sets the genesis slot to 6; go_to_block(1, 6); assert_eq!(Babe::genesis_slot(), 6); @@ -227,7 +227,7 @@ fn can_predict_next_epoch_change() { #[test] fn can_enact_next_config() { new_test_ext(1).execute_with(|| { - assert_eq!(::EpochDuration::get(), 3); + assert_eq!(::EpochDuration::get(), 3); // this sets the genesis slot to 6; go_to_block(1, 6); assert_eq!(Babe::genesis_slot(), 6); @@ -661,7 +661,7 @@ fn report_equivocation_has_valid_weight() { // but there's a lower bound of 100 validators. assert!( (1..=100) - .map(::WeightInfo::report_equivocation) + .map(::WeightInfo::report_equivocation) .collect::>() .windows(2) .all(|w| w[0] == w[1]) @@ -671,7 +671,7 @@ fn report_equivocation_has_valid_weight() { // with every extra validator. assert!( (100..=1000) - .map(::WeightInfo::report_equivocation) + .map(::WeightInfo::report_equivocation) .collect::>() .windows(2) .all(|w| w[0] < w[1]) diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 141a360f7e1..1f119dad76f 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -19,7 +19,7 @@ //! //! The Balances module provides functionality for handling accounts and balances. //! -//! - [`balances::Trait`](./trait.Trait.html) +//! - [`balances::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -99,12 +99,12 @@ //! //! ``` //! use frame_support::traits::Currency; -//! # pub trait Trait: frame_system::Trait { +//! # pub trait Config: frame_system::Config { //! # type Currency: Currency; //! # } //! -//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; //! //! # fn main() {} //! ``` @@ -114,17 +114,17 @@ //! ``` //! use frame_support::traits::{WithdrawReasons, LockableCurrency}; //! use sp_runtime::traits::Bounded; -//! pub trait Trait: frame_system::Trait { +//! pub trait Config: frame_system::Config { //! type Currency: LockableCurrency; //! } -//! # struct StakingLedger { -//! # stash: ::AccountId, -//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, +//! # struct StakingLedger { +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, //! # phantom: std::marker::PhantomData, //! # } //! # const STAKING_ID: [u8; 8] = *b"staking "; //! -//! fn update_ledger( +//! fn update_ledger( //! controller: &T::AccountId, //! ledger: &StakingLedger //! ) { @@ -145,7 +145,7 @@ //! //! ## Assumptions //! -//! * Total issued balanced of all accounts should be less than `Trait::Balance::max_value()`. +//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. #![cfg_attr(not(feature = "std"), no_std)] @@ -179,7 +179,7 @@ use frame_system::{self as system, ensure_signed, ensure_root}; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; pub use weights::WeightInfo; -pub trait Subtrait: frame_system::Trait { +pub trait Subtrait: frame_system::Config { /// The balance of an account. type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; @@ -198,7 +198,7 @@ pub trait Subtrait: frame_system::Trait { type MaxLocks: Get; } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The balance of an account. type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; @@ -207,7 +207,7 @@ pub trait Trait: frame_system::Trait { type DustRemoval: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; @@ -223,18 +223,18 @@ pub trait Trait: frame_system::Trait { type MaxLocks: Get; } -impl, I: Instance> Subtrait for T { +impl, I: Instance> Subtrait for T { type Balance = T::Balance; type ExistentialDeposit = T::ExistentialDeposit; type AccountStore = T::AccountStore; - type WeightInfo = >::WeightInfo; + type WeightInfo = >::WeightInfo; type MaxLocks = T::MaxLocks; } decl_event!( pub enum Event where - ::AccountId, - >::Balance + ::AccountId, + >::Balance { /// An account was created with some free balance. \[account, free_balance\] Endowed(AccountId, Balance), @@ -259,7 +259,7 @@ decl_event!( ); decl_error! { - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// Vesting balance too high to send value VestingBalance, /// Account liquidity restrictions prevent withdrawal @@ -382,7 +382,7 @@ impl Default for Releases { } decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Balances { + trait Store for Module, I: Instance=DefaultInstance> as Balances { /// The total units issued in the system. pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n) @@ -408,7 +408,7 @@ decl_storage! { build(|config: &GenesisConfig| { for (_, balance) in &config.balances { assert!( - *balance >= >::ExistentialDeposit::get(), + *balance >= >::ExistentialDeposit::get(), "the balance of any account should always be more than existential deposit.", ) } @@ -420,7 +420,7 @@ decl_storage! { } decl_module! { - pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { + pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { type Error = Error; /// The minimum amount required to keep an account open. @@ -565,7 +565,7 @@ decl_module! { } } -impl, I: Instance> Module { +impl, I: Instance> Module { // PRIVATE MUTABLES /// Get the free balance of an account. @@ -704,7 +704,7 @@ impl, I: Instance> Module { // of the inner member. mod imbalances { use super::{ - result, DefaultInstance, Imbalance, Trait, Zero, Instance, Saturating, + result, DefaultInstance, Imbalance, Config, Zero, Instance, Saturating, StorageValue, TryDrop, }; use sp_std::mem; @@ -712,9 +712,9 @@ mod imbalances { /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been created without any equal and opposite accounting. #[must_use] - pub struct PositiveImbalance, I: Instance=DefaultInstance>(T::Balance); + pub struct PositiveImbalance, I: Instance=DefaultInstance>(T::Balance); - impl, I: Instance> PositiveImbalance { + impl, I: Instance> PositiveImbalance { /// Create a new positive imbalance from a balance. pub fn new(amount: T::Balance) -> Self { PositiveImbalance(amount) @@ -724,22 +724,22 @@ mod imbalances { /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been destroyed without any equal and opposite accounting. #[must_use] - pub struct NegativeImbalance, I: Instance=DefaultInstance>(T::Balance); + pub struct NegativeImbalance, I: Instance=DefaultInstance>(T::Balance); - impl, I: Instance> NegativeImbalance { + impl, I: Instance> NegativeImbalance { /// Create a new negative imbalance from a balance. pub fn new(amount: T::Balance) -> Self { NegativeImbalance(amount) } } - impl, I: Instance> TryDrop for PositiveImbalance { + impl, I: Instance> TryDrop for PositiveImbalance { fn try_drop(self) -> result::Result<(), Self> { self.drop_zero() } } - impl, I: Instance> Imbalance for PositiveImbalance { + impl, I: Instance> Imbalance for PositiveImbalance { type Opposite = NegativeImbalance; fn zero() -> Self { @@ -784,13 +784,13 @@ mod imbalances { } } - impl, I: Instance> TryDrop for NegativeImbalance { + impl, I: Instance> TryDrop for NegativeImbalance { fn try_drop(self) -> result::Result<(), Self> { self.drop_zero() } } - impl, I: Instance> Imbalance for NegativeImbalance { + impl, I: Instance> Imbalance for NegativeImbalance { type Opposite = PositiveImbalance; fn zero() -> Self { @@ -835,7 +835,7 @@ mod imbalances { } } - impl, I: Instance> Drop for PositiveImbalance { + impl, I: Instance> Drop for PositiveImbalance { /// Basic drop handler will just square up the total issuance. fn drop(&mut self) { >::mutate( @@ -844,7 +844,7 @@ mod imbalances { } } - impl, I: Instance> Drop for NegativeImbalance { + impl, I: Instance> Drop for NegativeImbalance { /// Basic drop handler will just square up the total issuance. fn drop(&mut self) { >::mutate( @@ -854,7 +854,7 @@ mod imbalances { } } -impl, I: Instance> Currency for Module where +impl, I: Instance> Currency for Module where T::Balance: MaybeSerializeDeserialize + Debug { type Balance = T::Balance; @@ -1103,7 +1103,7 @@ impl, I: Instance> Currency for Module where } } -impl, I: Instance> ReservableCurrency for Module where +impl, I: Instance> ReservableCurrency for Module where T::Balance: MaybeSerializeDeserialize + Debug { /// Check if `who` can reserve `value` from their free balance. @@ -1218,7 +1218,7 @@ impl, I: Instance> ReservableCurrency for Module /// NOTE: You probably won't need to use this! This only needs to be "wired in" to System module /// if you're using the local balance storage. **If you're using the composite system account /// storage (which is the default in most examples and tests) then there's no need.** -impl, I: Instance> OnKilledAccount for Module { +impl, I: Instance> OnKilledAccount for Module { fn on_killed_account(who: &T::AccountId) { Account::::mutate_exists(who, |account| { let total = account.as_ref().map(|acc| acc.total()).unwrap_or_default(); @@ -1231,7 +1231,7 @@ impl, I: Instance> OnKilledAccount for Module { } } -impl, I: Instance> LockableCurrency for Module +impl, I: Instance> LockableCurrency for Module where T::Balance: MaybeSerializeDeserialize + Debug { @@ -1296,7 +1296,7 @@ where } } -impl, I: Instance> IsDeadAccount for Module where +impl, I: Instance> IsDeadAccount for Module where T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index b8cf90dad92..beaf2e2c223 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -23,7 +23,7 @@ pub struct CallWithDispatchInfo; impl sp_runtime::traits::Dispatchable for CallWithDispatchInfo { type Origin = (); - type Trait = (); + type Config = (); type Info = frame_support::weights::DispatchInfo; type PostInfo = frame_support::weights::PostDispatchInfo; @@ -55,7 +55,7 @@ macro_rules! decl_tests { pub type System = frame_system::Module<$test>; pub type Balances = Module<$test>; - pub const CALL: &<$test as frame_system::Trait>::Call = &$crate::tests::CallWithDispatchInfo; + pub const CALL: &<$test as frame_system::Config>::Call = &$crate::tests::CallWithDispatchInfo; /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { @@ -91,7 +91,7 @@ macro_rules! decl_tests { <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { assert_eq!(Balances::free_balance(1), 10); assert_ok!(>::transfer(&1, &2, 10, AllowDeath)); - assert!(!<::AccountStore as StoredMap>>::is_explicit(&1)); + assert!(!<::AccountStore as StoredMap>>::is_explicit(&1)); }); } diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index fd4ba1fd3c3..5f0cea7c963 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -29,7 +29,7 @@ use sp_io; use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; use pallet_transaction_payment::CurrencyAdapter; -use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; +use crate::{GenesisConfig, Module, Config, decl_tests, tests::CallWithDispatchInfo}; use frame_system as system; impl_outer_origin!{ @@ -57,7 +57,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub static ExistentialDeposit: u64 = 0; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -87,14 +87,14 @@ impl frame_system::Trait for Test { parameter_types! { pub const TransactionByteFee: u64 = 1; } -impl pallet_transaction_payment::Trait for Test { +impl pallet_transaction_payment::Config for Test { type OnChargeTransaction = CurrencyAdapter, ()>; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } -impl Trait for Test { +impl Config for Test { type Balance = u64; type DustRemoval = (); type Event = Event; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index c0a5d23ff1a..888b8c7d62b 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -29,7 +29,7 @@ use sp_io; use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; use frame_support::traits::StorageMapShim; use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; -use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; +use crate::{GenesisConfig, Module, Config, decl_tests, tests::CallWithDispatchInfo}; use pallet_transaction_payment::CurrencyAdapter; use frame_system as system; @@ -58,7 +58,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub static ExistentialDeposit: u64 = 0; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -88,7 +88,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const TransactionByteFee: u64 = 1; } -impl pallet_transaction_payment::Trait for Test { +impl pallet_transaction_payment::Config for Test { type OnChargeTransaction = CurrencyAdapter, ()>; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; @@ -97,7 +97,7 @@ impl pallet_transaction_payment::Trait for Test { parameter_types! { pub const MaxLocks: u32 = 50; } -impl Trait for Test { +impl Config for Test { type Balance = u64; type DustRemoval = (); type Event = Event; diff --git a/frame/balances/src/weights.rs b/frame/balances/src/weights.rs index 45e4195f962..189947003b1 100644 --- a/frame/balances/src/weights.rs +++ b/frame/balances/src/weights.rs @@ -53,7 +53,7 @@ pub trait WeightInfo { /// Weights for pallet_balances using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn transfer() -> Weight { (94_088_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 284b0545d03..fdfe857e4be 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -137,7 +137,7 @@ pub use sp_storage::TrackedStorageKey; /// /// Test functions are automatically generated for each benchmark and are accessible to you when you /// run `cargo test`. All tests are named `test_benchmark_`, expect you to pass them -/// the Runtime Trait, and run them in a test externalities environment. The test function runs your +/// the Runtime Config, and run them in a test externalities environment. The test function runs your /// benchmark just like a regular benchmark, but only testing at the lowest and highest values for /// each component. The function will return `Ok(())` if the benchmarks return no errors. /// @@ -636,7 +636,7 @@ macro_rules! benchmark_backend { #[allow(non_camel_case_types)] struct $name; #[allow(unused_variables)] - impl, I: Instance)? > + impl, I: Instance)? > $crate::BenchmarkingSetup for $name where $( $where_clause )* { @@ -710,7 +710,7 @@ macro_rules! selected_benchmark { } // Allow us to select a benchmark from the list of available benchmarks. - impl, I: Instance )? > + impl, I: Instance )? > $crate::BenchmarkingSetup for SelectedBenchmark where $( $where_clause )* { @@ -750,9 +750,9 @@ macro_rules! impl_benchmark { ( $( { $( $name_inst:ident )? } $name:ident )* ) ( $( $name_extra:ident ),* ) ) => { - impl, I: Instance)? > + impl, I: Instance)? > $crate::Benchmarking<$crate::BenchmarkResults> for Module - where T: frame_system::Trait, $( $where_clause )* + where T: frame_system::Config, $( $where_clause )* { fn benchmarks(extra: bool) -> Vec<&'static [u8]> { let mut all = vec![ $( stringify!($name).as_ref() ),* ]; @@ -948,8 +948,8 @@ macro_rules! impl_benchmark_test { $name:ident ) => { $crate::paste::item! { - fn [] () -> Result<(), &'static str> - where T: frame_system::Trait, $( $where_clause )* + fn [] () -> Result<(), &'static str> + where T: frame_system::Config, $( $where_clause )* { let selected_benchmark = SelectedBenchmark::$name; let components = < diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 0429d98e186..05a61ee83fb 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -29,16 +29,16 @@ use frame_support::{ use frame_system::{RawOrigin, ensure_signed, ensure_none}; decl_storage! { - trait Store for Module as Test where - ::OtherEvent: Into<::Event> + trait Store for Module as Test where + ::OtherEvent: Into<::Event> { Value get(fn value): Option; } } decl_module! { - pub struct Module for enum Call where - origin: T::Origin, ::OtherEvent: Into<::Event> + pub struct Module for enum Call where + origin: T::Origin, ::OtherEvent: Into<::Event> { #[weight = 0] fn set_value(origin, n: u32) -> DispatchResult { @@ -63,8 +63,8 @@ pub trait OtherTrait { type OtherEvent; } -pub trait Trait: frame_system::Trait + OtherTrait - where Self::OtherEvent: Into<::Event> +pub trait Config: frame_system::Config + OtherTrait + where Self::OtherEvent: Into<::Event> { type Event; } @@ -72,7 +72,7 @@ pub trait Trait: frame_system::Trait + OtherTrait #[derive(Clone, Eq, PartialEq)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -100,7 +100,7 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl Trait for Test { +impl Config for Test { type Event = (); } @@ -113,7 +113,7 @@ fn new_test_ext() -> sp_io::TestExternalities { } benchmarks!{ - where_clause { where ::OtherEvent: Into<::Event> } + where_clause { where ::OtherEvent: Into<::Event> } _ { // Define a common range for `b`. diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index d4e80d51594..551d6c7856c 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -33,9 +33,9 @@ const SEED: u32 = 0; const MAX_BYTES: u32 = 1_024; -fn assert_last_event, I: Instance>(generic_event: >::Event) { +fn assert_last_event, I: Instance>(generic_event: >::Event) { let events = System::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index b7d561672b8..11ec42f25ae 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -121,18 +121,18 @@ impl DefaultVote for MoreThanMajorityThenPrimeDefaultVote { } } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The outer origin type. type Origin: From>; /// The outer call dispatch type. type Proposal: Parameter - + Dispatchable>::Origin, PostInfo=PostDispatchInfo> + + Dispatchable>::Origin, PostInfo=PostDispatchInfo> + From> + GetDispatchInfo; /// The outer event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The time-out for council motions. type MotionDuration: Get; @@ -166,7 +166,7 @@ pub enum RawOrigin { } /// Origin for the collective module. -pub type Origin = RawOrigin<::AccountId, I>; +pub type Origin = RawOrigin<::AccountId, I>; #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// Info for keeping track of a motion being voted on. @@ -184,12 +184,12 @@ pub struct Votes { } decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Collective { + trait Store for Module, I: Instance=DefaultInstance> as Collective { /// The hashes of the active proposals. pub Proposals get(fn proposals): Vec; /// Actual proposal for a given hash, if it's current. pub ProposalOf get(fn proposal_of): - map hasher(identity) T::Hash => Option<>::Proposal>; + map hasher(identity) T::Hash => Option<>::Proposal>; /// Votes on a given proposal, if it is ongoing. pub Voting get(fn voting): map hasher(identity) T::Hash => Option>; @@ -209,8 +209,8 @@ decl_storage! { decl_event! { pub enum Event where - ::Hash, - ::AccountId, + ::Hash, + ::AccountId, { /// A motion (given hash) has been proposed (by given account) with a threshold (given /// `MemberCount`). @@ -239,7 +239,7 @@ decl_event! { } decl_error! { - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// Account is not a member NotMember, /// Duplicate proposals not allowed @@ -276,7 +276,7 @@ fn get_result_weight(result: DispatchResultWithPostInfo) -> Option { // Note that councillor operations are assigned to the operational class. decl_module! { - pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { type Error = Error; fn deposit_event() = default; @@ -365,7 +365,7 @@ decl_module! { DispatchClass::Operational )] fn execute(origin, - proposal: Box<>::Proposal>, + proposal: Box<>::Proposal>, #[compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; @@ -432,7 +432,7 @@ decl_module! { )] fn propose(origin, #[compact] threshold: MemberCount, - proposal: Box<>::Proposal>, + proposal: Box<>::Proposal>, #[compact] length_bound: u32 ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; @@ -682,7 +682,7 @@ decl_module! { } } -impl, I: Instance> Module { +impl, I: Instance> Module { /// Check whether `who` is a member of the collective. pub fn is_member(who: &T::AccountId) -> bool { // Note: The dispatchables *do not* use this to check membership so make sure @@ -698,7 +698,7 @@ impl, I: Instance> Module { hash: &T::Hash, length_bound: u32, weight_bound: Weight - ) -> Result<(>::Proposal, usize), DispatchError> { + ) -> Result<(>::Proposal, usize), DispatchError> { let key = ProposalOf::::hashed_key_for(hash); // read the length of the proposal storage entry directly let proposal_len = storage::read(&key, &mut [0; 0], 0) @@ -728,7 +728,7 @@ impl, I: Instance> Module { seats: MemberCount, voting: Votes, proposal_hash: T::Hash, - proposal: >::Proposal, + proposal: >::Proposal, ) -> (Weight, u32) { Self::deposit_event(RawEvent::Approved(proposal_hash)); @@ -764,7 +764,7 @@ impl, I: Instance> Module { } } -impl, I: Instance> ChangeMembers for Module { +impl, I: Instance> ChangeMembers for Module { /// Update the members of the collective. Votes are updated and the prime is reset. /// /// NOTE: Does not enforce the expected `MaxMembers` limit on the amount of members, but @@ -819,7 +819,7 @@ impl, I: Instance> ChangeMembers for Module { } } -impl, I: Instance> InitializeMembers for Module { +impl, I: Instance> InitializeMembers for Module { fn initialize_members(members: &[T::AccountId]) { if !members.is_empty() { assert!(>::get().is_empty(), "Members are already initialized!"); @@ -952,7 +952,7 @@ mod tests { pub const MaxProposals: u32 = 100; pub const MaxMembers: u32 = 100; } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -979,7 +979,7 @@ mod tests { type OnKilledAccount = (); type SystemWeightInfo = (); } - impl Trait for Test { + impl Config for Test { type Origin = Origin; type Proposal = Call; type Event = Event; @@ -989,7 +989,7 @@ mod tests { type DefaultVote = PrimeDefaultVote; type WeightInfo = (); } - impl Trait for Test { + impl Config for Test { type Origin = Origin; type Proposal = Call; type Event = Event; @@ -999,7 +999,7 @@ mod tests { type DefaultVote = MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = (); } - impl Trait for Test { + impl Config for Test { type Origin = Origin; type Proposal = Call; type Event = Event; diff --git a/frame/collective/src/weights.rs b/frame/collective/src/weights.rs index 4e4ec5196d0..8a76ff516ca 100644 --- a/frame/collective/src/weights.rs +++ b/frame/collective/src/weights.rs @@ -58,7 +58,7 @@ pub trait WeightInfo { /// Weights for pallet_collective using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn set_members(m: u32, n: u32, p: u32, ) -> Weight { (0 as Weight) .saturating_add((20_933_000 as Weight).saturating_mul(m as Weight)) diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index f879d2eed55..847be9b434c 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -24,7 +24,7 @@ //! we define this simple definition of a contract that can be passed to `create_code` that //! compiles it down into a `WasmModule` that can be used as a contract's code. -use crate::Trait; +use crate::Config; use crate::Module as Contracts; use parity_wasm::elements::{Instruction, Instructions, FuncBody, ValueType, BlockType}; @@ -87,9 +87,9 @@ pub struct ImportedMemory { } impl ImportedMemory { - pub fn max() -> Self + pub fn max() -> Self where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { let pages = max_pages::(); @@ -105,15 +105,15 @@ pub struct ImportedFunction { /// A wasm module ready to be put on chain with `put_code`. #[derive(Clone)] -pub struct WasmModule { +pub struct WasmModule { pub code: Vec, pub hash: ::Output, memory: Option, } -impl From for WasmModule +impl From for WasmModule where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { fn from(def: ModuleDefinition) -> Self { @@ -225,9 +225,9 @@ where } } -impl WasmModule +impl WasmModule where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { /// Creates a wasm module with an empty `call` and `deploy` function and nothing else. @@ -483,9 +483,9 @@ pub mod body { } /// The maximum amount of pages any contract is allowed to have according to the current `Schedule`. -pub fn max_pages() -> u32 +pub fn max_pages() -> u32 where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { Contracts::::current_schedule().limits.memory_pages diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index 2e15542368a..4bdd279eb8b 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -50,7 +50,7 @@ const API_BENCHMARK_BATCHES: u32 = 20; const INSTR_BENCHMARK_BATCHES: u32 = 1; /// An instantiated and deployed contract. -struct Contract { +struct Contract { caller: T::AccountId, account_id: T::AccountId, addr: ::Source, @@ -72,14 +72,14 @@ impl Endow { /// The maximum amount of balance a caller can transfer without being brought below /// the existential deposit. This assumes that every caller is funded with the amount /// returned by `caller_funding`. - fn max() -> BalanceOf { + fn max() -> BalanceOf { caller_funding::().saturating_sub(T::Currency::minimum_balance()) } } -impl Contract +impl Contract where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { /// Create new contract and use a default account id as instantiator. @@ -115,7 +115,7 @@ where // storage_size cannot be zero because otherwise a contract that is just above // the subsistence threshold does not pay rent given a large enough subsistence // threshold. But we need rent payments to occur in order to benchmark for worst cases. - let storage_size = Config::::subsistence_threshold_uncached() + let storage_size = ConfigCache::::subsistence_threshold_uncached() .checked_div(&T::RentDepositOffset::get()) .unwrap_or_else(Zero::zero); @@ -212,16 +212,16 @@ where /// A `Contract` that was evicted after accumulating some storage. /// /// This is used to benchmark contract resurrection. -struct Tombstone { +struct Tombstone { /// The contract that was evicted. contract: Contract, /// The storage the contract held when it was avicted. storage: Vec<(StorageKey, Vec)>, } -impl Tombstone +impl Tombstone where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { /// Create and evict a new contract with the supplied storage item count and size each. @@ -243,7 +243,7 @@ where } /// Generate `stor_num` storage items. Each has the size `stor_size`. -fn create_storage( +fn create_storage( stor_num: u32, stor_size: u32 ) -> Result)>, &'static str> { @@ -257,7 +257,7 @@ fn create_storage( } /// The funding that each account that either calls or instantiates contracts is funded with. -fn caller_funding() -> BalanceOf { +fn caller_funding() -> BalanceOf { BalanceOf::::max_value() / 2u32.into() } @@ -299,7 +299,7 @@ benchmarks! { let s in 0 .. code::max_pages::() * 64; let data = vec![42u8; (n * 1024) as usize]; let salt = vec![42u8; (s * 1024) as usize]; - let endowment = Config::::subsistence_threshold_uncached(); + let endowment = ConfigCache::::subsistence_threshold_uncached(); let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, caller_funding::()); let WasmModule { code, hash, .. } = WasmModule::::dummy_with_mem(); @@ -374,7 +374,7 @@ benchmarks! { // the caller should get the reward for being a good snitch assert_eq!( T::Currency::free_balance(&instance.caller), - caller_funding::() - instance.endowment + ::SurchargeReward::get(), + caller_funding::() - instance.endowment + ::SurchargeReward::get(), ); } @@ -1127,7 +1127,7 @@ benchmarks! { .collect::>(); let account_len = accounts.get(0).map(|i| i.encode().len()).unwrap_or(0); let account_bytes = accounts.iter().flat_map(|x| x.encode()).collect(); - let value = Config::::subsistence_threshold_uncached(); + let value = ConfigCache::::subsistence_threshold_uncached(); assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); @@ -1334,7 +1334,7 @@ benchmarks! { let hash_len = hashes.get(0).map(|x| x.encode().len()).unwrap_or(0); let hashes_bytes = hashes.iter().flat_map(|x| x.encode()).collect::>(); let hashes_len = hashes_bytes.len(); - let value = Config::::subsistence_threshold_uncached(); + let value = ConfigCache::::subsistence_threshold_uncached(); assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); @@ -1454,7 +1454,7 @@ benchmarks! { let input_len = inputs.get(0).map(|x| x.len()).unwrap_or(0); let input_bytes = inputs.iter().cloned().flatten().collect::>(); let inputs_len = input_bytes.len(); - let value = Config::::subsistence_threshold_uncached(); + let value = ConfigCache::::subsistence_threshold_uncached(); assert!(value > 0u32.into()); let value_bytes = value.encode(); let value_len = value_bytes.len(); diff --git a/frame/contracts/src/benchmarking/sandbox.rs b/frame/contracts/src/benchmarking/sandbox.rs index 76cebfaf1ed..61277ebce67 100644 --- a/frame/contracts/src/benchmarking/sandbox.rs +++ b/frame/contracts/src/benchmarking/sandbox.rs @@ -20,7 +20,7 @@ ///! environment that provides the seal interface as imported functions. use super::{ - Trait, + Config, code::WasmModule, }; use sp_core::crypto::UncheckedFrom; @@ -39,9 +39,9 @@ impl Sandbox { } } -impl From<&WasmModule> for Sandbox +impl From<&WasmModule> for Sandbox where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { /// Creates an instance from the supplied module and supplies as much memory diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 73e1f564498..8577d04452f 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use crate::{ - CodeHash, Config, Event, RawEvent, Trait, Module as Contracts, + CodeHash, ConfigCache, Event, RawEvent, Config, Module as Contracts, TrieId, BalanceOf, ContractInfo, gas::GasMeter, rent::Rent, storage::{self, Storage}, Error, ContractInfoOf }; @@ -30,14 +30,14 @@ use frame_support::{ }; use pallet_contracts_primitives::{ErrorOrigin, ExecError, ExecReturnValue, ExecResult, ReturnFlags}; -pub type AccountIdOf = ::AccountId; -pub type MomentOf = <::Time as Time>::Moment; -pub type SeedOf = ::Hash; -pub type BlockNumberOf = ::BlockNumber; +pub type AccountIdOf = ::AccountId; +pub type MomentOf = <::Time as Time>::Moment; +pub type SeedOf = ::Hash; +pub type BlockNumberOf = ::BlockNumber; pub type StorageKey = [u8; 32]; /// A type that represents a topic of an event. At the moment a hash is used. -pub type TopicOf = ::Hash; +pub type TopicOf = ::Hash; /// Describes whether we deal with a contract or a plain account. pub enum TransactorKind { @@ -54,7 +54,7 @@ pub enum TransactorKind { /// This interface is specialized to an account of the executing code, so all /// operations are implicitly performed on that account. pub trait Ext { - type T: Trait; + type T: Config; /// Returns the storage entry of the executing account by the given `key`. /// @@ -171,7 +171,7 @@ pub trait Ext { /// Loader is a companion of the `Vm` trait. It loads an appropriate abstract /// executable to be executed by an accompanying `Vm` implementation. -pub trait Loader { +pub trait Loader { type Executable; /// Load the initializer portion of the code specified by the `code_hash`. This @@ -190,7 +190,7 @@ pub trait Loader { /// /// Execution of code can end by either implicit termination (that is, reached the end of /// executable), explicit termination via returning a buffer or termination due to a trap. -pub trait Vm { +pub trait Vm { type Executable; fn execute>( @@ -202,12 +202,12 @@ pub trait Vm { ) -> ExecResult; } -pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { +pub struct ExecutionContext<'a, T: Config + 'a, V, L> { pub caller: Option<&'a ExecutionContext<'a, T, V, L>>, pub self_account: T::AccountId, pub self_trie_id: Option, pub depth: usize, - pub config: &'a Config, + pub config: &'a ConfigCache, pub vm: &'a V, pub loader: &'a L, pub timestamp: MomentOf, @@ -216,7 +216,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { impl<'a, T, E, V, L> ExecutionContext<'a, T, V, L> where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, L: Loader, V: Vm, @@ -225,7 +225,7 @@ where /// /// The specified `origin` address will be used as `sender` for. The `origin` must be a regular /// account (not a contract). - pub fn top_level(origin: T::AccountId, cfg: &'a Config, vm: &'a V, loader: &'a L) -> Self { + pub fn top_level(origin: T::AccountId, cfg: &'a ConfigCache, vm: &'a V, loader: &'a L) -> Self { ExecutionContext { caller: None, self_trie_id: None, @@ -437,7 +437,7 @@ enum TransferCause { /// is specified as `Terminate`. Otherwise, any transfer that would bring the sender below the /// subsistence threshold (for contracts) or the existential deposit (for plain accounts) /// results in an error. -fn transfer<'a, T: Trait, V: Vm, L: Loader>( +fn transfer<'a, T: Config, V: Vm, L: Loader>( cause: TransferCause, origin: TransactorKind, transactor: &T::AccountId, @@ -483,7 +483,7 @@ where /// implies that the control won't be returned to the contract anymore, but there is still some code /// on the path of the return from that call context. Therefore, care must be taken in these /// situations. -struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { +struct CallContext<'a, 'b: 'a, T: Config + 'b, V: Vm + 'b, L: Loader> { ctx: &'a mut ExecutionContext<'b, T, V, L>, caller: T::AccountId, value_transferred: BalanceOf, @@ -493,7 +493,7 @@ struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { impl<'a, 'b: 'a, T, E, V, L> Ext for CallContext<'a, 'b, T, V, L> where - T: Trait + 'b, + T: Config + 'b, T::AccountId: UncheckedFrom + AsRef<[u8]>, V: Vm, L: Loader, @@ -693,13 +693,13 @@ where } } -fn deposit_event( +fn deposit_event( topics: Vec, event: Event, ) { >::deposit_event_indexed( &*topics, - ::Event::from(event).into(), + ::Event::from(event).into(), ) } @@ -716,7 +716,7 @@ mod tests { }; use crate::{ gas::GasMeter, tests::{ExtBuilder, Test, MetaEvent}, - exec::ExecReturnValue, CodeHash, Config, + exec::ExecReturnValue, CodeHash, ConfigCache, gas::Gas, storage::Storage, tests::{ALICE, BOB, CHARLIE}, @@ -769,7 +769,7 @@ mod tests { fn insert(&mut self, f: impl Fn(MockCtx) -> ExecResult + 'a) -> CodeHash { // Generate code hashes as monotonically increasing values. - let code_hash = ::Hash::from_low_u64_be(self.counter); + let code_hash = ::Hash::from_low_u64_be(self.counter); self.counter += 1; self.map.insert(code_hash, MockExecutable::new(f)); @@ -843,7 +843,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); place_contract(&BOB, exec_ch); @@ -867,7 +867,7 @@ mod tests { let loader = MockLoader::empty(); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); set_balance(&origin, 100); set_balance(&dest, 0); @@ -900,7 +900,7 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); place_contract(&BOB, return_ch); set_balance(&origin, 100); @@ -930,7 +930,7 @@ mod tests { let loader = MockLoader::empty(); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); set_balance(&origin, 0); @@ -966,7 +966,7 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); place_contract(&BOB, return_ch); @@ -997,7 +997,7 @@ mod tests { ); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); place_contract(&BOB, return_ch); @@ -1025,7 +1025,7 @@ mod tests { // This one tests passing the input data into a contract via call. ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); place_contract(&BOB, input_data_ch); @@ -1050,7 +1050,7 @@ mod tests { // This one tests passing the input data into a contract via instantiate. ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 100); @@ -1097,7 +1097,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&BOB, 1); place_contract(&BOB, recurse_ch); @@ -1142,7 +1142,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); place_contract(&dest, bob_ch); @@ -1184,7 +1184,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); place_contract(&BOB, bob_ch); place_contract(&CHARLIE, charlie_ch); @@ -1208,7 +1208,7 @@ mod tests { let dummy_ch = loader.insert(|_| exec_success()); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); assert_matches!( @@ -1234,7 +1234,7 @@ mod tests { ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 1000); @@ -1268,7 +1268,7 @@ mod tests { ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 1000); @@ -1303,7 +1303,7 @@ mod tests { // Instantiate a contract and save it's address in `instantiated_contract_address`. let (address, output) = ctx.ext.instantiate( &dummy_ch, - Config::::subsistence_threshold_uncached(), + ConfigCache::::subsistence_threshold_uncached(), ctx.gas_meter, vec![], &[48, 49, 50], @@ -1315,7 +1315,7 @@ mod tests { }); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 1000); set_balance(&BOB, 100); @@ -1368,7 +1368,7 @@ mod tests { }); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 1000); set_balance(&BOB, 100); @@ -1400,7 +1400,7 @@ mod tests { .existential_deposit(15) .build() .execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 1000); @@ -1434,7 +1434,7 @@ mod tests { }); ExtBuilder::default().build().execute_with(|| { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); set_balance(&ALICE, 100); diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 0828a220c04..18a200fd312 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::Trait; +use crate::Config; use sp_std::marker::PhantomData; use sp_runtime::traits::Zero; use frame_support::dispatch::{ @@ -60,7 +60,7 @@ impl TestAuxiliaries for T {} /// Implementing type is expected to be super lightweight hence `Copy` (`Clone` is added /// for consistency). If inlined there should be no observable difference compared /// to a hand-written code. -pub trait Token: Copy + Clone + TestAuxiliaries { +pub trait Token: Copy + Clone + TestAuxiliaries { /// Metadata type, which the token can require for calculating the amount /// of gas to charge. Can be a some configuration type or /// just the `()`. @@ -84,7 +84,7 @@ pub struct ErasedToken { pub token: Box, } -pub struct GasMeter { +pub struct GasMeter { gas_limit: Gas, /// Amount of gas left from initial gas limit. Can reach zero. gas_left: Gas, @@ -92,7 +92,7 @@ pub struct GasMeter { #[cfg(test)] tokens: Vec, } -impl GasMeter { +impl GasMeter { pub fn new(gas_limit: Gas) -> Self { GasMeter { gas_limit, diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 65995afb73d..f0200fbd15f 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -18,7 +18,7 @@ //! //! The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts. //! -//! - [`contract::Trait`](./trait.Trait.html) +//! - [`contract::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -126,18 +126,18 @@ use pallet_contracts_primitives::{ }; use frame_support::weights::Weight; -pub type CodeHash = ::Hash; +pub type CodeHash = ::Hash; pub type TrieId = Vec; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account #[derive(Encode, Decode, RuntimeDebug)] -pub enum ContractInfo { +pub enum ContractInfo { Alive(AliveContractInfo), Tombstone(TombstoneContractInfo), } -impl ContractInfo { +impl ContractInfo { /// If contract is alive then return some alive info pub fn get_alive(self) -> Option> { if let ContractInfo::Alive(alive) = self { @@ -190,7 +190,7 @@ impl ContractInfo { } pub type AliveContractInfo = - RawAliveContractInfo, BalanceOf, ::BlockNumber>; + RawAliveContractInfo, BalanceOf, ::BlockNumber>; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. @@ -230,7 +230,7 @@ pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo { } pub type TombstoneContractInfo = - RawTombstoneContractInfo<::Hash, ::Hashing>; + RawTombstoneContractInfo<::Hash, ::Hashing>; #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct RawTombstoneContractInfo(H, PhantomData); @@ -250,18 +250,18 @@ where } } -impl From> for ContractInfo { +impl From> for ContractInfo { fn from(alive_info: AliveContractInfo) -> Self { Self::Alive(alive_info) } } pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; pub type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { type Time: Time; type Randomness: Randomness; @@ -269,7 +269,7 @@ pub trait Trait: frame_system::Trait { type Currency: Currency; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for rent payments. type RentPayment: OnUnbalanced>; @@ -323,7 +323,7 @@ pub trait Trait: frame_system::Trait { decl_error! { /// Error for the contracts module. - pub enum Error for Module + pub enum Error for Module where T::AccountId: UncheckedFrom, T::AccountId: AsRef<[u8]>, @@ -383,7 +383,7 @@ decl_error! { decl_module! { /// Contracts module. - pub struct Module for enum Call + pub struct Module for enum Call where origin: T::Origin, T::AccountId: UncheckedFrom, @@ -564,7 +564,7 @@ decl_module! { } /// Public APIs provided by the contracts module. -impl Module +impl Module where T::AccountId: UncheckedFrom + AsRef<[u8]>, { @@ -638,7 +638,7 @@ where } } -impl Module +impl Module where T::AccountId: UncheckedFrom + AsRef<[u8]>, { @@ -647,7 +647,7 @@ where gas_meter: &mut GasMeter, func: impl FnOnce(&mut ExecutionContext, WasmLoader>, &mut GasMeter) -> ExecResult, ) -> ExecResult { - let cfg = Config::preload(); + let cfg = ConfigCache::preload(); let vm = WasmVm::new(&cfg.schedule); let loader = WasmLoader::new(&cfg.schedule); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); @@ -659,8 +659,8 @@ decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash + ::AccountId, + ::Hash { /// Contract deployed by address at the specified address. \[owner, contract\] Instantiated(AccountId, AccountId), @@ -699,7 +699,7 @@ decl_event! { } decl_storage! { - trait Store for Module as Contracts + trait Store for Module as Contracts where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -722,7 +722,7 @@ decl_storage! { /// /// We assume that these values can't be changed in the /// course of transaction execution. -pub struct Config { +pub struct ConfigCache { pub schedule: Schedule, pub existential_deposit: BalanceOf, pub tombstone_deposit: BalanceOf, @@ -730,12 +730,12 @@ pub struct Config { pub max_value_size: u32, } -impl Config +impl ConfigCache where T::AccountId: UncheckedFrom + AsRef<[u8]> { - fn preload() -> Config { - Config { + fn preload() -> ConfigCache { + ConfigCache { schedule: >::current_schedule(), existential_deposit: T::Currency::minimum_balance(), tombstone_deposit: T::TombstoneDeposit::get(), diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index a8886b990a9..6ee65a54bb5 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -18,7 +18,7 @@ use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, - TombstoneContractInfo, Trait, CodeHash, Config, Error, + TombstoneContractInfo, Config, CodeHash, ConfigCache, Error, }; use sp_std::prelude::*; use sp_io::hashing::blake2_256; @@ -36,11 +36,11 @@ use sp_runtime::{ /// /// This amount respects the contract's rent allowance and the subsistence deposit. /// Because of that, charging the amount cannot remove the contract. -struct OutstandingAmount { +struct OutstandingAmount { amount: BalanceOf, } -impl OutstandingAmount { +impl OutstandingAmount { /// Create the new outstanding amount. /// /// The amount should be always withdrawable and it should not kill the account. @@ -67,7 +67,7 @@ impl OutstandingAmount { } } -enum Verdict { +enum Verdict { /// The contract is exempted from paying rent. /// /// For example, it already paid its rent in the current block, or it has enough deposit for not @@ -90,7 +90,7 @@ pub struct Rent(sp_std::marker::PhantomData); impl Rent where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]> { /// Returns a fee charged per block from the contract. @@ -129,7 +129,7 @@ where free_balance: &BalanceOf, contract: &AliveContractInfo, ) -> Option> { - let subsistence_threshold = Config::::subsistence_threshold_uncached(); + let subsistence_threshold = ConfigCache::::subsistence_threshold_uncached(); // Reserved balance contributes towards the subsistence threshold to stay consistent // with the existential deposit where the reserved balance is also counted. if *total_balance < subsistence_threshold { diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index 197cc654c59..b80aceb361f 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -17,7 +17,7 @@ //! This module contains the cost schedule and supporting code that constructs a //! sane default schedule from a `WeightInfo` implementation. -use crate::{Trait, weights::WeightInfo}; +use crate::{Config, weights::WeightInfo}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; @@ -42,7 +42,7 @@ pub const INSTR_BENCHMARK_BATCH_SIZE: u32 = 1_000; #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(bound(serialize = "", deserialize = "")))] #[derive(Clone, Encode, Decode, PartialEq, Eq, ScheduleDebug)] -pub struct Schedule { +pub struct Schedule { /// Version of the schedule. pub version: u32, @@ -131,7 +131,7 @@ pub struct Limits { /// and dropping return values in order to maintain a valid module. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, PartialEq, Eq, WeightDebug)] -pub struct InstructionWeights { +pub struct InstructionWeights { pub i64const: u32, pub i64load: u32, pub i64store: u32, @@ -190,7 +190,7 @@ pub struct InstructionWeights { /// Describes the weight for each imported function that a contract is allowed to call. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, PartialEq, Eq, WeightDebug)] -pub struct HostFnWeights { +pub struct HostFnWeights { /// Weight of calling `seal_caller`. pub caller: Weight, @@ -410,7 +410,7 @@ macro_rules! cost_byte_batched { } } -impl Default for Schedule { +impl Default for Schedule { fn default() -> Self { Self { version: 0, @@ -440,7 +440,7 @@ impl Default for Limits { } } -impl Default for InstructionWeights { +impl Default for InstructionWeights { fn default() -> Self { let max_pages = Limits::default().memory_pages; Self { @@ -500,7 +500,7 @@ impl Default for InstructionWeights { } } -impl Default for HostFnWeights { +impl Default for HostFnWeights { fn default() -> Self { Self { caller: cost_batched!(seal_caller), @@ -554,12 +554,12 @@ impl Default for HostFnWeights { } } -struct ScheduleRules<'a, T: Trait> { +struct ScheduleRules<'a, T: Config> { schedule: &'a Schedule, params: Vec, } -impl Schedule { +impl Schedule { pub fn rules(&self, module: &elements::Module) -> impl rules::Rules + '_ { ScheduleRules { schedule: &self, @@ -576,7 +576,7 @@ impl Schedule { } } -impl<'a, T: Trait> rules::Rules for ScheduleRules<'a, T> { +impl<'a, T: Config> rules::Rules for ScheduleRules<'a, T> { fn instruction_cost(&self, instruction: &elements::Instruction) -> Option { use parity_wasm::elements::Instruction::*; let w = &self.schedule.instruction_weights; diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index acd78879615..c9eeba4633a 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -18,7 +18,7 @@ use crate::{ exec::{AccountIdOf, StorageKey}, - AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Trait, TrieId, + AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Config, TrieId, AccountCounter, }; use sp_std::prelude::*; @@ -37,7 +37,7 @@ pub struct Storage(PhantomData); impl Storage where - T: Trait, + T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]> { /// Reads a storage kv pair of a contract. diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 6a0476096c8..44ddb8c2c65 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -16,8 +16,8 @@ use crate::{ BalanceOf, ContractInfo, ContractInfoOf, GenesisConfig, Module, - RawAliveContractInfo, RawEvent, Trait, Schedule, gas::Gas, - Error, Config, RuntimeReturnCode, storage::Storage, + RawAliveContractInfo, RawEvent, Config, Schedule, gas::Gas, + Error, ConfigCache, RuntimeReturnCode, storage::Storage, exec::AccountIdOf, }; use assert_matches::assert_matches; @@ -110,7 +110,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub static ExistentialDeposit: u64 = 0; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -137,7 +137,7 @@ impl frame_system::Trait for Test { type OnKilledAccount = (); type SystemWeightInfo = (); } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = MetaEvent; @@ -149,7 +149,7 @@ impl pallet_balances::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 1; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -176,7 +176,7 @@ impl Convert> for Test { } } -impl Trait for Test { +impl Config for Test { type Time = Timestamp; type Randomness = Randomness; type Currency = Balances; @@ -251,7 +251,7 @@ fn compile_module( fixture_name: &str, ) -> wat::Result<(Vec, ::Output)> where - T: frame_system::Trait, + T: frame_system::Config, { let fixture_path = ["fixtures/", fixture_name, ".wat"].concat(); let wasm_binary = wat::parse_file(fixture_path)?; @@ -367,7 +367,7 @@ fn instantiate_and_call_and_deposit_event() { .build() .execute_with(|| { let _ = Balances::deposit_creating(&ALICE, 1_000_000); - let subsistence = super::Config::::subsistence_threshold_uncached(); + let subsistence = super::ConfigCache::::subsistence_threshold_uncached(); assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); @@ -472,7 +472,7 @@ fn deposit_event_max_value_limit() { addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer, - ::MaxValueSize::get().encode(), + ::MaxValueSize::get().encode(), )); // Call contract with too large a storage value. @@ -482,7 +482,7 @@ fn deposit_event_max_value_limit() { addr, 0, GAS_LIMIT, - (::MaxValueSize::get() + 1).encode(), + (::MaxValueSize::get() + 1).encode(), ), Error::::ValueTooLarge, ); @@ -591,7 +591,7 @@ fn storage_size() { 30_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -725,7 +725,7 @@ fn deduct_blocks() { Origin::signed(ALICE), 30_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -830,7 +830,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn(AccountIdOf) -> bool Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -869,7 +869,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -911,7 +911,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { 1_000, GAS_LIMIT, code_hash.into(), - ::Balance::from(100u32).encode(), // rent allowance + ::Balance::from(100u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -960,14 +960,14 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { // Create let _ = Balances::deposit_creating(&ALICE, 1_000_000); let subsistence_threshold = - Balances::minimum_balance() + ::TombstoneDeposit::get(); + Balances::minimum_balance() + ::TombstoneDeposit::get(); assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 50 + subsistence_threshold, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -1039,7 +1039,7 @@ fn call_removed_contract() { Origin::signed(ALICE), 100, GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode(), // rent allowance + ::Balance::from(1_000u32).encode(), // rent allowance vec![], )); let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); @@ -1177,7 +1177,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, GAS_LIMIT, set_rent_code_hash.into(), - ::Balance::from(0u32).encode(), + ::Balance::from(0u32).encode(), vec![], )); let addr_bob = Contracts::contract_address(&ALICE, &set_rent_code_hash, &[]); @@ -1227,7 +1227,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, GAS_LIMIT, restoration_code_hash.into(), - ::Balance::from(0u32).encode(), + ::Balance::from(0u32).encode(), vec![], )); let addr_django = Contracts::contract_address(&CHARLIE, &restoration_code_hash, &[]); @@ -1384,7 +1384,7 @@ fn storage_max_value_limit() { addr.clone(), 0, GAS_LIMIT * 2, // we are copying a huge buffer - ::MaxValueSize::get().encode(), + ::MaxValueSize::get().encode(), )); // Call contract with too large a storage value. @@ -1394,7 +1394,7 @@ fn storage_max_value_limit() { addr, 0, GAS_LIMIT, - (::MaxValueSize::get() + 1).encode(), + (::MaxValueSize::get() + 1).encode(), ), Error::::ValueTooLarge, ); @@ -1709,7 +1709,7 @@ fn crypto_hashes() { fn transfer_return_code() { let (wasm, code_hash) = compile_module::("transfer_return_code").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let subsistence = Config::::subsistence_threshold_uncached(); + let subsistence = ConfigCache::::subsistence_threshold_uncached(); let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); @@ -1756,7 +1756,7 @@ fn call_return_code() { let (caller_code, caller_hash) = compile_module::("call_return_code").unwrap(); let (callee_code, callee_hash) = compile_module::("ok_trap_revert").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let subsistence = Config::::subsistence_threshold_uncached(); + let subsistence = ConfigCache::::subsistence_threshold_uncached(); let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); let _ = Balances::deposit_creating(&CHARLIE, 10 * subsistence); assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_code)); @@ -1849,7 +1849,7 @@ fn instantiate_return_code() { let (caller_code, caller_hash) = compile_module::("instantiate_return_code").unwrap(); let (callee_code, callee_hash) = compile_module::("ok_trap_revert").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let subsistence = Config::::subsistence_threshold_uncached(); + let subsistence = ConfigCache::::subsistence_threshold_uncached(); let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); let _ = Balances::deposit_creating(&CHARLIE, 10 * subsistence); assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_code)); diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index a64f387097e..d90c7502b85 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -27,7 +27,7 @@ //! Thus, before executing a contract it should be reinstrument with new schedule. use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; -use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; +use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Config}; use sp_std::prelude::*; use sp_runtime::traits::Hash; use sp_core::crypto::UncheckedFrom; @@ -37,7 +37,7 @@ use frame_support::StorageMap; /// as a result of this function. /// /// This function instruments the given code and caches it in the storage. -pub fn save( +pub fn save( original_code: Vec, schedule: &Schedule, ) -> Result, &'static str> where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -55,7 +55,7 @@ pub fn save( /// This version neither checks nor instruments the passed in code. This is useful /// when code needs to be benchmarked without the injected instrumentation. #[cfg(feature = "runtime-benchmarks")] -pub fn save_raw( +pub fn save_raw( original_code: Vec, schedule: &Schedule, ) -> Result, &'static str> where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -73,7 +73,7 @@ pub fn save_raw( /// If the module was instrumented with a lower version of schedule than /// the current one given as an argument, then this function will perform /// re-instrumentation and update the cache in the storage. -pub fn load( +pub fn load( code_hash: &CodeHash, schedule: &Schedule, ) -> Result where T::AccountId: UncheckedFrom + AsRef<[u8]> { diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index 6741896102d..cc61deb074b 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -129,8 +129,8 @@ macro_rules! define_func { args: &[sp_sandbox::Value], ) -> Result where - ::AccountId: - sp_core::crypto::UncheckedFrom<::Hash> + + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + AsRef<[u8]> { #[allow(unused)] @@ -190,8 +190,8 @@ macro_rules! define_env { impl $crate::wasm::env_def::FunctionImplProvider for $init_name where - ::AccountId: - sp_core::crypto::UncheckedFrom<::Hash> + + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + AsRef<[u8]> { fn impls)>(f: &mut F) { diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index baa75ad4972..7d7668d5ec6 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -17,7 +17,7 @@ //! This module provides a means for executing contracts //! represented in wasm. -use crate::{CodeHash, Schedule, Trait}; +use crate::{CodeHash, Schedule, Config}; use crate::wasm::env_def::FunctionImplProvider; use crate::exec::Ext; use crate::gas::GasMeter; @@ -68,17 +68,17 @@ pub struct WasmExecutable { } /// Loader which fetches `WasmExecutable` from the code cache. -pub struct WasmLoader<'a, T: Trait> { +pub struct WasmLoader<'a, T: Config> { schedule: &'a Schedule, } -impl<'a, T: Trait> WasmLoader<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { +impl<'a, T: Config> WasmLoader<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { pub fn new(schedule: &'a Schedule) -> Self { WasmLoader { schedule } } } -impl<'a, T: Trait> crate::exec::Loader for WasmLoader<'a, T> +impl<'a, T: Config> crate::exec::Loader for WasmLoader<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -101,17 +101,17 @@ where } /// Implementation of `Vm` that takes `WasmExecutable` and executes it. -pub struct WasmVm<'a, T: Trait> where T::AccountId: UncheckedFrom + AsRef<[u8]> { +pub struct WasmVm<'a, T: Config> where T::AccountId: UncheckedFrom + AsRef<[u8]> { schedule: &'a Schedule, } -impl<'a, T: Trait> WasmVm<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { +impl<'a, T: Config> WasmVm<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { pub fn new(schedule: &'a Schedule) -> Self { WasmVm { schedule } } } -impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a, T> +impl<'a, T: Config> crate::exec::Vm for WasmVm<'a, T> where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -462,8 +462,8 @@ mod tests { gas_meter: &mut GasMeter, ) -> ExecResult where - ::AccountId: - UncheckedFrom<::Hash> + AsRef<[u8]> + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> { use crate::exec::Vm; diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 73c149d025d..56e21d2ee66 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -20,7 +20,7 @@ use crate::wasm::env_def::ImportSatisfyCheck; use crate::wasm::PrefabWasmModule; -use crate::{Schedule, Trait}; +use crate::{Schedule, Config}; use parity_wasm::elements::{self, Internal, External, MemoryType, Type, ValueType}; use pwasm_utils; @@ -34,13 +34,13 @@ pub const IMPORT_MODULE_FN: &str = "seal0"; /// compiler toolchains might not support specifying other modules than "env" for memory imports. pub const IMPORT_MODULE_MEMORY: &str = "env"; -struct ContractModule<'a, T: Trait> { +struct ContractModule<'a, T: Config> { /// A deserialized module. The module is valid (this is Guaranteed by `new` method). module: elements::Module, schedule: &'a Schedule, } -impl<'a, T: Trait> ContractModule<'a, T> { +impl<'a, T: Config> ContractModule<'a, T> { /// Creates a new instance of `ContractModule`. /// /// Returns `Err` if the `original_code` couldn't be decoded or @@ -369,7 +369,7 @@ impl<'a, T: Trait> ContractModule<'a, T> { } } -fn get_memory_limits(module: Option<&MemoryType>, schedule: &Schedule) +fn get_memory_limits(module: Option<&MemoryType>, schedule: &Schedule) -> Result<(u32, u32), &'static str> { if let Some(memory_type) = module { @@ -410,7 +410,7 @@ fn get_memory_limits(module: Option<&MemoryType>, schedule: &Schedule< /// - all imported functions from the external environment matches defined by `env` module, /// /// The preprocessing includes injecting code for gas metering and metering the height of stack. -pub fn prepare_contract( +pub fn prepare_contract( original_code: &[u8], schedule: &Schedule, ) -> Result { @@ -452,7 +452,7 @@ pub fn prepare_contract( #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking { use super::{ - Trait, ContractModule, PrefabWasmModule, ImportSatisfyCheck, Schedule, get_memory_limits + Config, ContractModule, PrefabWasmModule, ImportSatisfyCheck, Schedule, get_memory_limits }; use parity_wasm::elements::FunctionType; @@ -463,7 +463,7 @@ pub mod benchmarking { } /// Prepare function that neither checks nor instruments the passed in code. - pub fn prepare_contract(original_code: &[u8], schedule: &Schedule) + pub fn prepare_contract(original_code: &[u8], schedule: &Schedule) -> Result { let contract_module = ContractModule::new(original_code, schedule)?; diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 90ea86f9cec..ac1cb1f54d5 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -17,7 +17,7 @@ //! Environment definition of the wasm smart-contract runtime. use crate::{ - HostFnWeights, Schedule, Trait, CodeHash, BalanceOf, Error, + HostFnWeights, Schedule, Config, CodeHash, BalanceOf, Error, exec::{Ext, StorageKey, TopicOf}, gas::{Gas, GasMeter, Token, GasMeterResult}, wasm::env_def::ConvertibleToWasm, @@ -193,7 +193,7 @@ pub enum RuntimeToken { HashBlake128(u32), } -impl Token for RuntimeToken +impl Token for RuntimeToken where T::AccountId: UncheckedFrom, T::AccountId: AsRef<[u8]> { @@ -291,8 +291,8 @@ pub struct Runtime<'a, E: Ext + 'a> { impl<'a, E> Runtime<'a, E> where E: Ext + 'a, - ::AccountId: - UncheckedFrom<::Hash> + AsRef<[u8]> + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> { pub fn new( ext: &'a mut E, @@ -709,7 +709,7 @@ define_env!(Env, , value_len: u32 ) -> ReturnCode => { ctx.charge_gas(RuntimeToken::Transfer)?; - let callee: <::T as frame_system::Trait>::AccountId = + let callee: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(account_ptr, account_len)?; let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; @@ -762,7 +762,7 @@ define_env!(Env, , output_len_ptr: u32 ) -> ReturnCode => { ctx.charge_gas(RuntimeToken::CallBase(input_data_len))?; - let callee: <::T as frame_system::Trait>::AccountId = + let callee: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(callee_ptr, callee_len)?; let value: BalanceOf<::T> = ctx.read_sandbox_memory_as(value_ptr, value_len)?; let input_data = ctx.read_sandbox_memory(input_data_ptr, input_data_len)?; @@ -922,7 +922,7 @@ define_env!(Env, , beneficiary_len: u32 ) => { ctx.charge_gas(RuntimeToken::Terminate)?; - let beneficiary: <::T as frame_system::Trait>::AccountId = + let beneficiary: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; if let Ok(_) = ctx.ext.terminate(&beneficiary).map_err(|e| ctx.store_err(e)) { @@ -1169,7 +1169,7 @@ define_env!(Env, , delta_count: u32 ) => { ctx.charge_gas(RuntimeToken::RestoreTo(delta_count))?; - let dest: <::T as frame_system::Trait>::AccountId = + let dest: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(dest_ptr, dest_len)?; let code_hash: CodeHash<::T> = ctx.read_sandbox_memory_as(code_hash_ptr, code_hash_len)?; diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index 77bb83cf4d4..24c1273a44f 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -144,7 +144,7 @@ pub trait WeightInfo { /// Weights for pallet_contracts using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn update_schedule() -> Weight { (35_214_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index b5de1a91c17..542bfaa79db 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -34,21 +34,21 @@ const MAX_REFERENDUMS: u32 = 99; const MAX_SECONDERS: u32 = 100; const MAX_BYTES: u32 = 16_384; -fn assert_last_event(generic_event: ::Event) { +fn assert_last_event(generic_event: ::Event) { let events = System::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); } -fn funded_account(name: &'static str, index: u32) -> T::AccountId { +fn funded_account(name: &'static str, index: u32) -> T::AccountId { let caller: T::AccountId = account(name, index, SEED); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); caller } -fn add_proposal(n: u32) -> Result { +fn add_proposal(n: u32) -> Result { let other = funded_account::("proposer", n); let value = T::MinimumDeposit::get(); let proposal_hash: T::Hash = T::Hashing::hash_of(&n); @@ -62,7 +62,7 @@ fn add_proposal(n: u32) -> Result { Ok(proposal_hash) } -fn add_referendum(n: u32) -> Result { +fn add_referendum(n: u32) -> Result { let proposal_hash: T::Hash = T::Hashing::hash_of(&n); let vote_threshold = VoteThreshold::SimpleMajority; @@ -84,7 +84,7 @@ fn add_referendum(n: u32) -> Result { Ok(referendum_index) } -fn account_vote(b: BalanceOf) -> AccountVote> { +fn account_vote(b: BalanceOf) -> AccountVote> { let v = Vote { aye: true, conviction: Conviction::Locked1x, diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index fa8d07fd78d..ce89259e55e 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -17,7 +17,7 @@ //! # Democracy Pallet //! -//! - [`democracy::Trait`](./trait.Trait.html) +//! - [`democracy::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -199,13 +199,13 @@ pub type PropIndex = u32; /// A referendum index. pub type ReferendumIndex = u32; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: frame_system::Trait + Sized { +pub trait Config: frame_system::Config + Sized { type Proposal: Parameter + Dispatchable + From>; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Currency type for this module. type Currency: ReservableCurrency @@ -338,7 +338,7 @@ enum Releases { } decl_storage! { - trait Store for Module as Democracy { + trait Store for Module as Democracy { // TODO: Refactor public proposal queue into its own pallet. // https://github.com/paritytech/substrate/issues/5322 /// The number of (public) proposals that have been made so far. @@ -413,9 +413,9 @@ decl_storage! { decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash, - ::BlockNumber, + ::AccountId, + ::Hash, + ::BlockNumber, { /// A motion has been proposed by a public account. \[proposal_index, deposit\] Proposed(PropIndex, Balance), @@ -461,7 +461,7 @@ decl_event! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Value too low ValueLow, /// Proposal does not exist @@ -537,7 +537,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// The minimum period of locking and the period between a proposal being approved and enacted. @@ -1168,7 +1168,7 @@ decl_module! { } } -impl Module { +impl Module { // exposed immutables. /// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 25209901109..6e7b7cfcc6d 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -92,7 +92,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Index = u64; @@ -122,7 +122,7 @@ impl frame_system::Trait for Test { parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } -impl pallet_scheduler::Trait for Test { +impl pallet_scheduler::Config for Test { type Event = Event; type Origin = Origin; type PalletsOrigin = OriginCaller; @@ -135,7 +135,7 @@ impl pallet_scheduler::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = Event; @@ -173,7 +173,7 @@ impl Contains for OneToFive { fn add(_m: &u64) {} } -impl super::Trait for Test { +impl super::Config for Test { type Proposal = Call; type Event = Event; type Currency = pallet_balances::Module; @@ -242,7 +242,7 @@ fn set_balance_proposal(value: u64) -> Vec { fn set_balance_proposal_is_correctly_filtered_out() { for i in 0..10 { let call = Call::decode(&mut &set_balance_proposal(i)[..]).unwrap(); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); } } diff --git a/frame/democracy/src/weights.rs b/frame/democracy/src/weights.rs index e386e5fb553..06899b47dea 100644 --- a/frame/democracy/src/weights.rs +++ b/frame/democracy/src/weights.rs @@ -72,7 +72,7 @@ pub trait WeightInfo { /// Weights for pallet_democracy using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn propose() -> Weight { (87_883_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) diff --git a/frame/elections-phragmen/src/benchmarking.rs b/frame/elections-phragmen/src/benchmarking.rs index e7c3719480b..eaa5bbe9ed4 100644 --- a/frame/elections-phragmen/src/benchmarking.rs +++ b/frame/elections-phragmen/src/benchmarking.rs @@ -30,7 +30,7 @@ const BALANCE_FACTOR: u32 = 250; const MAX_VOTERS: u32 = 500; const MAX_CANDIDATES: u32 = 200; -type Lookup = <::Lookup as StaticLookup>::Source; +type Lookup = <::Lookup as StaticLookup>::Source; macro_rules! whitelist { ($acc:ident) => { @@ -41,7 +41,7 @@ macro_rules! whitelist { } /// grab new account with infinite balance. -fn endowed_account(name: &'static str, index: u32) -> T::AccountId { +fn endowed_account(name: &'static str, index: u32) -> T::AccountId { let account: T::AccountId = account(name, index, 0); let amount = default_stake::(BALANCE_FACTOR); let _ = T::Currency::make_free_balance_be(&account, amount); @@ -53,28 +53,28 @@ fn endowed_account(name: &'static str, index: u32) -> T::AccountId { } /// Account to lookup type of system trait. -fn as_lookup(account: T::AccountId) -> Lookup { +fn as_lookup(account: T::AccountId) -> Lookup { T::Lookup::unlookup(account) } /// Get a reasonable amount of stake based on the execution trait's configuration -fn default_stake(factor: u32) -> BalanceOf { +fn default_stake(factor: u32) -> BalanceOf { let factor = BalanceOf::::from(factor); T::Currency::minimum_balance() * factor } /// Get the current number of candidates. -fn candidate_count() -> u32 { +fn candidate_count() -> u32 { >::decode_len().unwrap_or(0usize) as u32 } /// Get the number of votes of a voter. -fn vote_count_of(who: &T::AccountId) -> u32 { +fn vote_count_of(who: &T::AccountId) -> u32 { >::get(who).1.len() as u32 } /// A `DefunctVoter` struct with correct value -fn defunct_for(who: T::AccountId) -> DefunctVoter> { +fn defunct_for(who: T::AccountId) -> DefunctVoter> { DefunctVoter { who: as_lookup::(who.clone()), candidate_count: candidate_count::(), @@ -83,7 +83,7 @@ fn defunct_for(who: T::AccountId) -> DefunctVoter> { } /// Add `c` new candidates. -fn submit_candidates(c: u32, prefix: &'static str) +fn submit_candidates(c: u32, prefix: &'static str) -> Result, &'static str> { (0..c).map(|i| { @@ -97,7 +97,7 @@ fn submit_candidates(c: u32, prefix: &'static str) } /// Add `c` new candidates with self vote. -fn submit_candidates_with_self_vote(c: u32, prefix: &'static str) +fn submit_candidates_with_self_vote(c: u32, prefix: &'static str) -> Result, &'static str> { let candidates = submit_candidates::(c, prefix)?; @@ -110,7 +110,7 @@ fn submit_candidates_with_self_vote(c: u32, prefix: &'static str) /// Submit one voter. -fn submit_voter(caller: T::AccountId, votes: Vec, stake: BalanceOf) +fn submit_voter(caller: T::AccountId, votes: Vec, stake: BalanceOf) -> Result<(), sp_runtime::DispatchError> { >::vote(RawOrigin::Signed(caller).into(), votes, stake) @@ -118,7 +118,7 @@ fn submit_voter(caller: T::AccountId, votes: Vec, stake: /// create `num_voter` voters who randomly vote for at most `votes` of `all_candidates` if /// available. -fn distribute_voters(mut all_candidates: Vec, num_voters: u32, votes: usize) +fn distribute_voters(mut all_candidates: Vec, num_voters: u32, votes: usize) -> Result<(), &'static str> { let stake = default_stake::(BALANCE_FACTOR); @@ -138,7 +138,7 @@ fn distribute_voters(mut all_candidates: Vec, num_voters /// Fill the seats of members and runners-up up until `m`. Note that this might include either only /// members, or members and runners-up. -fn fill_seats_up_to(m: u32) -> Result, &'static str> { +fn fill_seats_up_to(m: u32) -> Result, &'static str> { let _ = submit_candidates_with_self_vote::(m, "fill_seats_up_to")?; assert_eq!(>::candidates().len() as u32, m, "wrong number of candidates."); >::do_phragmen(); @@ -158,7 +158,7 @@ fn fill_seats_up_to(m: u32) -> Result, &'static str> } /// removes all the storage items to reverse any genesis state. -fn clean() { +fn clean() { >::kill(); >::kill(); >::kill(); diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 8279f9cf11f..c4a71d6595f 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -77,7 +77,7 @@ //! //! ### Module Information //! -//! - [`election_sp_phragmen::Trait`](./trait.Trait.html) +//! - [`election_sp_phragmen::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) @@ -112,9 +112,9 @@ pub use weights::WeightInfo; pub const MAXIMUM_VOTE: usize = 16; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// An indication that the renouncing account currently has which of the below roles. #[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)] @@ -140,9 +140,9 @@ pub struct DefunctVoter { pub candidate_count: u32 } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type.c - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Identifier for the elections-phragmen pallet's lock type ModuleId: Get; @@ -193,7 +193,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as PhragmenElection { + trait Store for Module as PhragmenElection { // ---- State /// The current elected membership. Sorted based on account id. pub Members get(fn members): Vec<(T::AccountId, BalanceOf)>; @@ -251,7 +251,7 @@ decl_storage! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Cannot vote when no candidates or members exist. UnableToVote, /// Must vote for at least one candidate. @@ -290,7 +290,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -667,7 +667,7 @@ decl_module! { decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId, + ::AccountId, { /// A new term with \[new_members\]. This indicates that enough candidates existed to run the /// election, not that enough have has been elected. The inner value must be examined for @@ -694,7 +694,7 @@ decl_event!( } ); -impl Module { +impl Module { /// Attempts to remove a member `who`. If a runner-up exists, it is used as the replacement and /// Ok(true). is returned. /// @@ -1027,7 +1027,7 @@ impl Module { } } -impl Contains for Module { +impl Contains for Module { fn contains(who: &T::AccountId) -> bool { Self::is_member(who) } @@ -1046,7 +1046,7 @@ impl Contains for Module { } } -impl ContainsLengthBound for Module { +impl ContainsLengthBound for Module { fn min_len() -> usize { 0 } /// Implementation uses a parameter type so calling is cost-free. @@ -1076,7 +1076,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -1108,7 +1108,7 @@ mod tests { pub const ExistentialDeposit: u64 = 1; } - impl pallet_balances::Trait for Test { + impl pallet_balances::Config for Test { type Balance = u64; type Event = Event; type DustRemoval = (); @@ -1175,7 +1175,7 @@ mod tests { pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; } - impl Trait for Test { + impl Config for Test { type ModuleId = ElectionsPhragmenModuleId; type Event = Event; type Currency = Balances; diff --git a/frame/elections-phragmen/src/weights.rs b/frame/elections-phragmen/src/weights.rs index 2702aec0a01..48fd40e782e 100644 --- a/frame/elections-phragmen/src/weights.rs +++ b/frame/elections-phragmen/src/weights.rs @@ -59,7 +59,7 @@ pub trait WeightInfo { /// Weights for pallet_elections_phragmen using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn vote(v: u32, ) -> Weight { (89_627_000 as Weight) .saturating_add((197_000 as Weight).saturating_mul(v as Weight)) diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index dccc42f2441..1490b6d86ae 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -139,9 +139,9 @@ pub const VOTER_SET_SIZE: usize = 64; /// NUmber of approvals grouped in one chunk. pub const APPROVAL_SET_SIZE: usize = 8; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// Index used to access chunks. type SetIndex = u32; @@ -152,8 +152,8 @@ type ApprovalFlag = u32; /// Number of approval flags that can fit into [`ApprovalFlag`] type. const APPROVAL_FLAG_LEN: usize = 32; -pub trait Trait: frame_system::Trait { - type Event: From> + Into<::Event>; +pub trait Config: frame_system::Config { + type Event: From> + Into<::Event>; /// Identifier for the elections pallet's lock type ModuleId: Get; @@ -218,7 +218,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as Elections { + trait Store for Module as Elections { // ---- parameters /// How long to give each top candidate to present themselves after the vote ends. @@ -286,7 +286,7 @@ decl_storage! { decl_error! { /// Error for the elections module. - pub enum Error for Module { + pub enum Error for Module { /// Reporter must be a voter. NotVoter, /// Target for inactivity cleanup must be active. @@ -345,7 +345,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// How much should be locked up in order to submit one's candidacy. A reasonable @@ -706,7 +706,7 @@ decl_module! { } decl_event!( - pub enum Event where ::AccountId { + pub enum Event where ::AccountId { /// Reaped \[voter, reaper\]. VoterReaped(AccountId, AccountId), /// Slashed \[reaper\]. @@ -719,7 +719,7 @@ decl_event!( } ); -impl Module { +impl Module { // exposed immutables. /// True if we're currently in a presentation period. diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 0d57089af5e..293074469c5 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -37,7 +37,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -68,7 +68,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type DustRemoval = (); @@ -110,7 +110,7 @@ parameter_types!{ pub const ElectionModuleId: LockIdentifier = *b"py/elect"; } -impl elections::Trait for Test { +impl elections::Config for Test { type Event = Event; type Currency = Balances; type BadPresentation = (); diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index d3579ca3374..38a16953572 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -680,8 +680,8 @@ fn retracting_active_voter_should_slash_reporter() { assert_ok!(Elections::end_block(System::block_number())); assert_eq!(Elections::vote_index(), 2); - assert_eq!(::InactiveGracePeriod::get(), 1); - assert_eq!(::VotingPeriod::get(), 4); + assert_eq!(::InactiveGracePeriod::get(), 1); + assert_eq!(::VotingPeriod::get(), 4); assert_eq!(Elections::voter_info(4), Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 })); assert_ok!(Elections::reap_inactive_voter(Origin::signed(4), diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index b64e3f8dd83..29e545ae2d9 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -24,7 +24,7 @@ //! Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's //! documentation. //! -//! - [`pallet_example_offchain_worker::Trait`](./trait.Trait.html) +//! - [`pallet_example_offchain_worker::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -103,12 +103,12 @@ pub mod crypto { } /// This pallet's configuration trait -pub trait Trait: CreateSignedTransaction> { +pub trait Config: CreateSignedTransaction> { /// The identifier type for an offchain worker. type AuthorityId: AppCrypto; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching dispatch call type. type Call: From>; @@ -149,7 +149,7 @@ impl SignedPayload for PricePayload as ExampleOffchainWorker { + trait Store for Module as ExampleOffchainWorker { /// A vector of recently submitted prices. /// /// This is used to calculate average price, should have bounded size. @@ -165,7 +165,7 @@ decl_storage! { decl_event!( /// Events generated by the module. - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// Event generated when new price is accepted to contribute to the average. /// \[price, who\] NewPrice(u32, AccountId), @@ -174,7 +174,7 @@ decl_event!( decl_module! { /// A public part of the pallet. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; /// Submit new price to the list. @@ -310,7 +310,7 @@ enum TransactionType { /// /// This greatly helps with error messages, as the ones inside the macro /// can sometimes be hard to debug. -impl Module { +impl Module { /// Chooses which transaction type to send. /// /// This function serves mostly to showcase `StorageValue` helper @@ -679,7 +679,7 @@ impl Module { } #[allow(deprecated)] // ValidateUnsigned -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; /// Validate unsigned call to this module. diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 204b366964f..809e3b7ba64 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -56,7 +56,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); @@ -118,7 +118,7 @@ parameter_types! { pub const UnsignedPriority: u64 = 1 << 20; } -impl Trait for Test { +impl Config for Test { type Event = (); type AuthorityId = crypto::TestAuthId; type Call = Call; @@ -282,7 +282,7 @@ fn should_submit_unsigned_transaction_on_chain_for_any_account() { let signature_valid = ::Public, - ::BlockNumber + ::BlockNumber > as SignedPayload>::verify::(&price_payload, signature); assert!(signature_valid); @@ -335,7 +335,7 @@ fn should_submit_unsigned_transaction_on_chain_for_all_accounts() { let signature_valid = ::Public, - ::BlockNumber + ::BlockNumber > as SignedPayload>::verify::(&price_payload, signature); assert!(signature_valid); diff --git a/frame/example-parallel/src/lib.rs b/frame/example-parallel/src/lib.rs index 4b7ce72b4d4..b616e3d4927 100644 --- a/frame/example-parallel/src/lib.rs +++ b/frame/example-parallel/src/lib.rs @@ -34,15 +34,15 @@ use sp_std::vec::Vec; #[cfg(test)] mod tests; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching dispatch call type. type Call: From>; } decl_storage! { - trait Store for Module as ExampleOffchainWorker { + trait Store for Module as ExampleOffchainWorker { /// A vector of current participants /// /// To enlist someone to participate, signed payload should be @@ -87,7 +87,7 @@ impl EnlistedParticipant { decl_module! { /// A public part of the pallet. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; /// Get the new event running. diff --git a/frame/example-parallel/src/tests.rs b/frame/example-parallel/src/tests.rs index 1da8c603882..d2c37640013 100644 --- a/frame/example-parallel/src/tests.rs +++ b/frame/example-parallel/src/tests.rs @@ -39,7 +39,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); @@ -73,7 +73,7 @@ parameter_types! { pub const UnsignedPriority: u64 = 1 << 20; } -impl Trait for Test { +impl Config for Test { type Event = (); type Call = Call; } diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 103bcfe6968..fb84a48a8d2 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -63,7 +63,7 @@ //! // Include the following links that shows what trait needs to be implemented to use the pallet //! // and the supported dispatchables that are documented in the Call enum. //! -//! - \[`::Trait`](./trait.Trait.html) +//! - \[`::Config`](./trait.Config.html) //! - \[`Call`](./enum.Call.html) //! - \[`Module`](./struct.Module.html) //! @@ -212,7 +212,7 @@ //! \```rust //! use ; //! -//! pub trait Trait: ::Trait { } +//! pub trait Config: ::Config { } //! \``` //! //! \### Simple Code Snippet @@ -286,9 +286,9 @@ use sp_runtime::{ // - The final weight of each dispatch is calculated as the argument of the call multiplied by the // parameter given to the `WeightForSetDummy`'s constructor. // - assigns a dispatch class `operational` if the argument of the call is more than 1000. -struct WeightForSetDummy(BalanceOf); +struct WeightForSetDummy(BalanceOf); -impl WeighData<(&BalanceOf,)> for WeightForSetDummy +impl WeighData<(&BalanceOf,)> for WeightForSetDummy { fn weigh_data(&self, target: (&BalanceOf,)) -> Weight { let multiplier = self.0; @@ -296,7 +296,7 @@ impl WeighData<(&BalanceOf,)> for WeightForSetDumm } } -impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { +impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { fn classify_dispatch(&self, target: (&BalanceOf,)) -> DispatchClass { if *target.0 > >::from(1000u32) { DispatchClass::Operational @@ -306,23 +306,23 @@ impl ClassifyDispatch<(&BalanceOf,)> for WeightFor } } -impl PaysFee<(&BalanceOf,)> for WeightForSetDummy { +impl PaysFee<(&BalanceOf,)> for WeightForSetDummy { fn pays_fee(&self, _target: (&BalanceOf,)) -> Pays { Pays::Yes } } /// A type alias for the balance type from this pallet's point of view. -type BalanceOf = ::Balance; +type BalanceOf = ::Balance; /// Our pallet's configuration trait. All our types and constants go in here. If the /// pallet is dependent on specific other pallets, then their configuration traits /// should be added to our implied traits list. /// -/// `frame_system::Trait` should always be included in our implied traits. -pub trait Trait: pallet_balances::Trait { +/// `frame_system::Config` should always be included in our implied traits. +pub trait Config: pallet_balances::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } decl_storage! { @@ -333,7 +333,7 @@ decl_storage! { // It is important to update your storage name so that your pallet's // storage items are isolated from other pallets. // ---------------------------------vvvvvvv - trait Store for Module as Example { + trait Store for Module as Example { // Any storage declarations of the form: // `pub? Name get(fn getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` // where `` is either: @@ -371,7 +371,7 @@ decl_event!( /// Events are a simple means of reporting specific conditions and /// circumstances that have happened that users, Dapps and/or chain explorers would find /// interesting and otherwise difficult to detect. - pub enum Event where B = ::Balance { + pub enum Event where B = ::Balance { // Just a normal `enum`, here's a dummy event to ensure it compiles. /// Dummy event, just here so there's a generic type that's used. Dummy(B), @@ -414,7 +414,7 @@ decl_event!( // `ensure_root` and `ensure_none`. decl_module! { // Simple declaration of the `Module` type. Lets the macro know what its working on. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// Deposit one of this pallet's events by using the default implementation. /// It is also possible to provide a custom implementation. /// For non-generic events, the generic parameter just needs to be dropped, so that it @@ -548,7 +548,7 @@ decl_module! { // - Public interface. These are functions that are `pub` and generally fall into inspector // functions that do not write to storage and operation functions that do. // - Private functions. These are your usual private utilities unavailable to other pallets. -impl Module { +impl Module { // Add public immutables and private mutables. #[allow(dead_code)] fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> DispatchResult { @@ -571,7 +571,7 @@ impl Module { // decodable type that implements `SignedExtension`. See the trait definition for the full list of // bounds. As a convention, you can follow this approach to create an extension for your pallet: // - If the extension does not carry any data, then use a tuple struct with just a `marker` -// (needed for the compiler to accept `T: Trait`) will suffice. +// (needed for the compiler to accept `T: Config`) will suffice. // - Otherwise, create a tuple struct which contains the external data. Of course, for the entire // struct to be decodable, each individual item also needs to be decodable. // @@ -602,21 +602,21 @@ impl Module { /// Additionally, it drops any transaction with an encoded length higher than 200 bytes. No /// particular reason why, just to demonstrate the power of signed extensions. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct WatchDummy(PhantomData); +pub struct WatchDummy(PhantomData); -impl sp_std::fmt::Debug for WatchDummy { +impl sp_std::fmt::Debug for WatchDummy { fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "WatchDummy") } } -impl SignedExtension for WatchDummy +impl SignedExtension for WatchDummy where - ::Call: IsSubType>, + ::Call: IsSubType>, { const IDENTIFIER: &'static str = "WatchDummy"; type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = (); type Pre = (); @@ -744,7 +744,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -774,7 +774,7 @@ mod tests { parameter_types! { pub const ExistentialDeposit: u64 = 1; } - impl pallet_balances::Trait for Test { + impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type DustRemoval = (); @@ -783,7 +783,7 @@ mod tests { type AccountStore = System; type WeightInfo = (); } - impl Trait for Test { + impl Config for Test { type Event = (); } type System = frame_system::Module; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index ccb5c2d2628..c91287df5b9 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -145,7 +145,7 @@ pub type OriginOf = as Dispatchable>::Origin; /// Main entry point for certain runtime actions as e.g. `execute_block`. /// /// Generic parameters: -/// - `System`: Something that implements `frame_system::Trait` +/// - `System`: Something that implements `frame_system::Config` /// - `Block`: The block type of the runtime /// - `Context`: The context that is used when checking an extrinsic. /// - `UnsignedValidator`: The unsigned transaction validator of the runtime. @@ -158,7 +158,7 @@ pub struct Executive, Context: Default, UnsignedValidator, @@ -185,7 +185,7 @@ where } impl< - System: frame_system::Trait, + System: frame_system::Config, Block: traits::Block, Context: Default, UnsignedValidator, @@ -505,10 +505,10 @@ mod tests { UnknownTransaction, TransactionSource, TransactionValidity }; - pub trait Trait: frame_system::Trait {} + pub trait Config: frame_system::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 100] fn some_function(origin) { // NOTE: does not make any different. @@ -555,7 +555,7 @@ mod tests { } } - impl sp_runtime::traits::ValidateUnsigned for Module { + impl sp_runtime::traits::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned( @@ -594,7 +594,7 @@ mod tests { write: 100, }; } - impl frame_system::Trait for Runtime { + impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -626,7 +626,7 @@ mod tests { parameter_types! { pub const ExistentialDeposit: Balance = 1; } - impl pallet_balances::Trait for Runtime { + impl pallet_balances::Config for Runtime { type Balance = Balance; type Event = Event; type DustRemoval = (); @@ -639,13 +639,13 @@ mod tests { parameter_types! { pub const TransactionByteFee: Balance = 0; } - impl pallet_transaction_payment::Trait for Runtime { + impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } - impl custom::Trait for Runtime {} + impl custom::Config for Runtime {} pub struct RuntimeVersion; impl frame_support::traits::Get for RuntimeVersion { @@ -668,8 +668,8 @@ mod tests { type TestXt = sp_runtime::testing::TestXt; type TestBlock = Block; type TestUncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic< - ::AccountId, - ::Call, + ::AccountId, + ::Call, (), SignedExtra, >; @@ -715,9 +715,9 @@ mod tests { balances: vec![(1, 211)], }.assimilate_storage(&mut t).unwrap(); let xt = TestXt::new(Call::Balances(BalancesCall::transfer(2, 69)), sign_extra(1, 0, 0)); - let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); + let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); let fee: Balance - = ::WeightToFee::calc(&weight); + = ::WeightToFee::calc(&weight); let mut t = sp_io::TestExternalities::new(t); t.execute_with(|| { Executive::initialize_block(&Header::new( @@ -818,7 +818,7 @@ mod tests { let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; // on_initialize weight + block execution weight - let base_block_weight = 175 + ::BlockExecutionWeight::get(); + let base_block_weight = 175 + ::BlockExecutionWeight::get(); let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get() - base_block_weight; let num_to_exhaust_block = limit / (encoded_len + 5); t.execute_with(|| { @@ -861,7 +861,7 @@ mod tests { let mut t = new_test_ext(1); t.execute_with(|| { // Block execution weight + on_initialize weight from custom module - let base_block_weight = 175 + ::BlockExecutionWeight::get(); + let base_block_weight = 175 + ::BlockExecutionWeight::get(); Executive::initialize_block(&Header::new( 1, @@ -879,7 +879,7 @@ mod tests { assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. - let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); + let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); assert_eq!( >::block_weight().total(), base_block_weight + 3 * extrinsic_weight, @@ -946,9 +946,9 @@ mod tests { sign_extra(1, 0, 0), ); let weight = xt.get_dispatch_info().weight - + ::ExtrinsicBaseWeight::get(); + + ::ExtrinsicBaseWeight::get(); let fee: Balance = - ::WeightToFee::calc(&weight); + ::WeightToFee::calc(&weight); Executive::initialize_block(&Header::new( 1, H256::default(), @@ -1106,7 +1106,7 @@ mod tests { let runtime_upgrade_weight = ::on_runtime_upgrade(); let frame_system_on_initialize_weight = frame_system::Module::::on_initialize(block_number); let on_initialize_weight = >::on_initialize(block_number); - let base_block_weight = ::BlockExecutionWeight::get(); + let base_block_weight = ::BlockExecutionWeight::get(); // Weights are recorded correctly assert_eq!( diff --git a/frame/grandpa/src/equivocation.rs b/frame/grandpa/src/equivocation.rs index e9662a726c4..72f1434b24a 100644 --- a/frame/grandpa/src/equivocation.rs +++ b/frame/grandpa/src/equivocation.rs @@ -54,13 +54,13 @@ use sp_staking::{ SessionIndex, }; -use super::{Call, Module, Trait}; +use super::{Call, Module, Config}; /// A trait with utility methods for handling equivocation reports in GRANDPA. /// The offence type is generic, and the trait provides , reporting an offence /// triggered by a valid equivocation report, and also for creating and /// submitting equivocation report extrinsics (useful only in offchain context). -pub trait HandleEquivocation { +pub trait HandleEquivocation { /// The offence type used for reporting offences on valid equivocation reports. type Offence: GrandpaOffence; @@ -86,7 +86,7 @@ pub trait HandleEquivocation { fn block_author() -> Option; } -impl HandleEquivocation for () { +impl HandleEquivocation for () { type Offence = GrandpaEquivocationOffence; fn report_offence( @@ -136,7 +136,7 @@ where // We use the authorship pallet to fetch the current block author and use // `offchain::SendTransactionTypes` for unsigned extrinsic creation and // submission. - T: Trait + pallet_authorship::Trait + frame_system::offchain::SendTransactionTypes>, + T: Config + pallet_authorship::Config + frame_system::offchain::SendTransactionTypes>, // A system for reporting offences after valid equivocation reports are // processed. R: ReportOffence, @@ -187,7 +187,7 @@ pub struct GrandpaTimeSlot { /// A `ValidateUnsigned` implementation that restricts calls to `report_equivocation_unsigned` /// to local calls (i.e. extrinsics generated on this node) or that already in a block. This /// guarantees that only block authors can include unsigned equivocation reports. -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { if let Call::report_equivocation_unsigned(equivocation_proof, _) = call { diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index fe836ac913c..15099672d0d 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -67,9 +67,9 @@ pub use equivocation::{ HandleEquivocation, }; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The event type of this module. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The function call. type Call: From>; @@ -188,7 +188,7 @@ decl_event! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Attempt to signal GRANDPA pause when the authority set isn't live /// (either paused or already pending pause). PauseFailed, @@ -209,7 +209,7 @@ decl_error! { } decl_storage! { - trait Store for Module as GrandpaFinality { + trait Store for Module as GrandpaFinality { /// State of the current authority set. State get(fn state): StoredState = StoredState::Live; @@ -241,7 +241,7 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -372,7 +372,7 @@ decl_module! { } } -impl Module { +impl Module { /// Get the current set of authorities, along with their respective weights. pub fn grandpa_authorities() -> AuthorityList { storage::unhashed::get_or_default::(GRANDPA_AUTHORITIES_KEY).into() @@ -583,12 +583,12 @@ impl Module { } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl pallet_session::OneSessionHandler for Module - where T: pallet_session::Trait +impl pallet_session::OneSessionHandler for Module + where T: pallet_session::Config { type Key = AuthorityId; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index d3461eec12d..fd731c9cda3 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -19,7 +19,7 @@ #![cfg(test)] -use crate::{AuthorityId, AuthorityList, ConsensusLog, Module, Trait}; +use crate::{AuthorityId, AuthorityList, ConsensusLog, Module, Config}; use ::grandpa as finality_grandpa; use codec::Encode; use frame_support::{ @@ -79,7 +79,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -122,7 +122,7 @@ parameter_types! { } /// Custom `SessionHandler` since we use `TestSessionKeys` as `Keys`. -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type Event = TestEvent; type ValidatorId = u64; type ValidatorIdOf = pallet_staking::StashOf; @@ -135,7 +135,7 @@ impl pallet_session::Trait for Test { type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -144,7 +144,7 @@ parameter_types! { pub const UncleGenerations: u64 = 0; } -impl pallet_authorship::Trait for Test { +impl pallet_authorship::Config for Test { type FindAuthor = (); type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -155,7 +155,7 @@ parameter_types! { pub const ExistentialDeposit: u128 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u128; type DustRemoval = (); @@ -169,7 +169,7 @@ parameter_types! { pub const MinimumPeriod: u64 = 3; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -198,7 +198,7 @@ parameter_types! { pub const StakingUnsignedPriority: u64 = u64::max_value() / 2; } -impl pallet_staking::Trait for Test { +impl pallet_staking::Config for Test { type RewardRemainder = (); type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; type Event = TestEvent; @@ -227,14 +227,14 @@ parameter_types! { pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } -impl pallet_offences::Trait for Test { +impl pallet_offences::Config for Test { type Event = TestEvent; type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; type WeightSoftLimit = OffencesWeightSoftLimit; } -impl Trait for Test { +impl Config for Test { type Event = TestEvent; type Call = Call; diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 4916808fe00..4963d7e6b6d 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -850,7 +850,7 @@ fn report_equivocation_has_valid_weight() { // but there's a lower bound of 100 validators. assert!( (1..=100) - .map(::WeightInfo::report_equivocation) + .map(::WeightInfo::report_equivocation) .collect::>() .windows(2) .all(|w| w[0] == w[1]) @@ -860,7 +860,7 @@ fn report_equivocation_has_valid_weight() { // with every extra validator. assert!( (100..=1000) - .map(::WeightInfo::report_equivocation) + .map(::WeightInfo::report_equivocation) .collect::>() .windows(2) .all(|w| w[0] < w[1]) diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index d7876514452..0176986c822 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -29,16 +29,16 @@ use crate::Module as Identity; const SEED: u32 = 0; -fn assert_last_event(generic_event: ::Event) { +fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); } // Adds `r` registrars to the Identity Pallet. These registrars will have set fees and fields. -fn add_registrars(r: u32) -> Result<(), &'static str> { +fn add_registrars(r: u32) -> Result<(), &'static str> { for i in 0..r { let registrar: T::AccountId = account("registrar", i, SEED); let _ = T::Currency::make_free_balance_be(®istrar, BalanceOf::::max_value()); @@ -57,7 +57,7 @@ fn add_registrars(r: u32) -> Result<(), &'static str> { // Create `s` sub-accounts for the identity of `who` and return them. // Each will have 32 bytes of raw data added to it. -fn create_sub_accounts(who: &T::AccountId, s: u32) -> Result, &'static str> { +fn create_sub_accounts(who: &T::AccountId, s: u32) -> Result, &'static str> { let mut subs = Vec::new(); let who_origin = RawOrigin::Signed(who.clone()); let data = Data::Raw(vec![0; 32]); @@ -77,7 +77,7 @@ fn create_sub_accounts(who: &T::AccountId, s: u32) -> Result(who: &T::AccountId, s: u32) -> Result, &'static str> { +fn add_sub_accounts(who: &T::AccountId, s: u32) -> Result, &'static str> { let who_origin = RawOrigin::Signed(who.clone()); let subs = create_sub_accounts::(who, s)?; @@ -88,7 +88,7 @@ fn add_sub_accounts(who: &T::AccountId, s: u32) -> Result(num_fields: u32) -> IdentityInfo { +fn create_identity_info(num_fields: u32) -> IdentityInfo { let data = Data::Raw(vec![0; 32]); let info = IdentityInfo { @@ -121,7 +121,7 @@ benchmarks! { // Create their main identity with x additional fields let info = create_identity_info::(x); let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller)); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller)); Identity::::set_identity(caller_origin, info)?; }; } @@ -143,7 +143,7 @@ benchmarks! { // The target user let caller: T::AccountId = whitelisted_caller(); let caller_lookup: ::Source = T::Lookup::unlookup(caller.clone()); - let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); // Add an initial identity @@ -200,7 +200,7 @@ benchmarks! { clear_identity { let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); let caller_lookup = ::unlookup(caller.clone()); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -237,7 +237,7 @@ benchmarks! { cancel_request { let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); let r in ...; @@ -300,7 +300,7 @@ benchmarks! { provide_judgement { // The user let user: T::AccountId = account("user", r, SEED); - let user_origin = ::Origin::from(RawOrigin::Signed(user.clone())); + let user_origin = ::Origin::from(RawOrigin::Signed(user.clone())); let user_lookup = ::unlookup(user.clone()); let _ = T::Currency::make_free_balance_be(&user, BalanceOf::::max_value()); @@ -328,7 +328,7 @@ benchmarks! { let x in _ .. _ => {}; let target: T::AccountId = account("target", 0, SEED); - let target_origin: ::Origin = RawOrigin::Signed(target.clone()).into(); + let target_origin: ::Origin = RawOrigin::Signed(target.clone()).into(); let target_lookup: ::Source = T::Lookup::unlookup(target.clone()); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 0ee6563a561..c0afffc0524 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -17,7 +17,7 @@ //! # Identity Module //! -//! - [`identity::Trait`](./trait.Trait.html) +//! - [`identity::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -68,7 +68,7 @@ //! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost. //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html #![cfg_attr(not(feature = "std"), no_std)] @@ -91,12 +91,12 @@ use frame_support::{ use frame_system::ensure_signed; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: ReservableCurrency; @@ -399,7 +399,7 @@ pub struct RegistrarInfo< } decl_storage! { - trait Store for Module as Identity { + trait Store for Module as Identity { /// Information that is pertinent to identify the entity behind an account. /// /// TWOX-NOTE: OK ― `AccountId` is a secure hash. @@ -428,7 +428,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// A name was set or reset (which will remove all judgements). \[who\] IdentitySet(AccountId), /// A name was cleared, and the given balance returned. \[who, deposit\] @@ -456,7 +456,7 @@ decl_event!( decl_error! { /// Error for the identity module. - pub enum Error for Module { + pub enum Error for Module { /// Too many subs-accounts. TooManySubAccounts, /// Account isn't found. @@ -494,7 +494,7 @@ decl_error! { decl_module! { /// Identity module declaration. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// The amount held on deposit for a registered identity. const BasicDeposit: BalanceOf = T::BasicDeposit::get(); @@ -1125,7 +1125,7 @@ decl_module! { } } -impl Module { +impl Module { /// Get the subs of an account. pub fn subs(who: &T::AccountId) -> Vec<(T::AccountId, Data)> { SubsOf::::get(who).1 diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index 0637ac6aafc..aefce1f8ff6 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -42,7 +42,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -72,7 +72,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type Balance = u64; type Event = (); type DustRemoval = (); @@ -103,7 +103,7 @@ type EnsureTwoOrRoot = EnsureOneOf< EnsureRoot, EnsureSignedBy >; -impl Trait for Test { +impl Config for Test { type Event = (); type Currency = Balances; type Slashed = (); diff --git a/frame/identity/src/weights.rs b/frame/identity/src/weights.rs index 44efbb31035..431a26cc096 100644 --- a/frame/identity/src/weights.rs +++ b/frame/identity/src/weights.rs @@ -64,7 +64,7 @@ pub trait WeightInfo { /// Weights for pallet_identity using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn add_registrar(r: u32, ) -> Weight { (28_965_000 as Weight) .saturating_add((421_000 as Weight).saturating_mul(r as Weight)) diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index b92be023ce4..452a9f26ed7 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -34,7 +34,7 @@ use crate::Module as ImOnline; const MAX_KEYS: u32 = 1000; const MAX_EXTERNAL_ADDRESSES: u32 = 100; -pub fn create_heartbeat(k: u32, e: u32) -> +pub fn create_heartbeat(k: u32, e: u32) -> Result<(crate::Heartbeat, ::Signature), &'static str> { let mut keys = Vec::new(); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 2d3693d1272..09cb2afa22b 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -30,7 +30,7 @@ //! as the [NetworkState](../../client/offchain/struct.NetworkState.html). //! It is submitted as an Unsigned Transaction via off-chain workers. //! -//! - [`im_online::Trait`](./trait.Trait.html) +//! - [`im_online::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -47,10 +47,10 @@ //! use frame_system::ensure_signed; //! use pallet_im_online::{self as im_online}; //! -//! pub trait Trait: im_online::Trait {} +//! pub trait Config: im_online::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; @@ -227,12 +227,12 @@ pub struct Heartbeat pub validators_len: u32, } -pub trait Trait: SendTransactionTypes> + pallet_session::historical::Trait { +pub trait Config: SendTransactionTypes> + pallet_session::historical::Config { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// An expected duration of the session. /// @@ -262,7 +262,7 @@ pub trait Trait: SendTransactionTypes> + pallet_session::historical:: decl_event!( pub enum Event where - ::AuthorityId, + ::AuthorityId, IdentificationTuple = IdentificationTuple, { /// A new heartbeat was received from `AuthorityId` \[authority_id\] @@ -275,7 +275,7 @@ decl_event!( ); decl_storage! { - trait Store for Module as ImOnline { + trait Store for Module as ImOnline { /// The block number after which it's ok to send heartbeats in current session. /// /// At the beginning of each session we set this to a value that should @@ -307,7 +307,7 @@ decl_storage! { decl_error! { /// Error for the im-online module. - pub enum Error for Module { + pub enum Error for Module { /// Non existent public key. InvalidKey, /// Duplicated heartbeat. @@ -316,7 +316,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -332,7 +332,7 @@ decl_module! { /// # // NOTE: the weight includes the cost of validate_unsigned as it is part of the cost to // import block with such an extrinsic. - #[weight = ::WeightInfo::validate_unsigned_and_then_heartbeat( + #[weight = ::WeightInfo::validate_unsigned_and_then_heartbeat( heartbeat.validators_len as u32, heartbeat.network_state.external_addresses.len() as u32, )] @@ -393,11 +393,11 @@ decl_module! { } } -type OffchainResult = Result::BlockNumber>>; +type OffchainResult = Result::BlockNumber>>; /// Keep track of number of authored blocks per authority, uncles are counted as /// well since they're a valid proof of being online. -impl pallet_authorship::EventHandler for Module { +impl pallet_authorship::EventHandler for Module { fn note_author(author: T::ValidatorId) { Self::note_authorship(author); } @@ -407,7 +407,7 @@ impl pallet_authorship::EventHandler Module { +impl Module { /// Returns `true` if a heartbeat has been received for the authority at /// `authority_index` in the authorities series or if the authority has /// authored at least one block, during the current session. Otherwise @@ -610,11 +610,11 @@ impl Module { } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl pallet_session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -677,7 +677,7 @@ impl pallet_session::OneSessionHandler for Module { /// Invalid transaction custom error. Returned when validators_len field in heartbeat is incorrect. const INVALID_VALIDATORS_LEN: u8 = 10; -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned( diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index dae4bb3447e..9a049a47188 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -21,7 +21,7 @@ use std::cell::RefCell; -use crate::{Module, Trait}; +use crate::{Module, Config}; use sp_runtime::Perbill; use sp_staking::{SessionIndex, offence::{ReportOffence, OffenceError}}; use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; @@ -109,7 +109,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -146,7 +146,7 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); } -impl pallet_session::Trait for Runtime { +impl pallet_session::Config for Runtime { type ShouldEndSession = pallet_session::PeriodicSessions; type SessionManager = pallet_session::historical::NoteHistoricalRoot; type SessionHandler = (ImOnline, ); @@ -159,7 +159,7 @@ impl pallet_session::Trait for Runtime { type WeightInfo = (); } -impl pallet_session::historical::Trait for Runtime { +impl pallet_session::historical::Config for Runtime { type FullIdentification = u64; type FullIdentificationOf = ConvertInto; } @@ -168,7 +168,7 @@ parameter_types! { pub const UncleGenerations: u32 = 5; } -impl pallet_authorship::Trait for Runtime { +impl pallet_authorship::Config for Runtime { type FindAuthor = (); type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -179,7 +179,7 @@ parameter_types! { pub const UnsignedPriority: u64 = 1 << 20; } -impl Trait for Runtime { +impl Config for Runtime { type AuthorityId = UintAuthorityId; type Event = (); type ReportUnresponsiveness = OffenceHandler; diff --git a/frame/im-online/src/weights.rs b/frame/im-online/src/weights.rs index f9df679bd2b..c0f11c69c4b 100644 --- a/frame/im-online/src/weights.rs +++ b/frame/im-online/src/weights.rs @@ -49,7 +49,7 @@ pub trait WeightInfo { /// Weights for pallet_im_online using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight { (114_379_000 as Weight) .saturating_add((219_000 as Weight).saturating_mul(k as Weight)) diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 6d467aa6734..18eb5449848 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -37,10 +37,10 @@ use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Re use frame_system::{ensure_signed, ensure_root}; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// The module's config trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// Type used for storing an account's index; implies the maximum number of accounts the system /// can hold. type AccountIndex: Parameter + Member + Codec + Default + AtLeast32Bit + Copy; @@ -52,14 +52,14 @@ pub trait Trait: frame_system::Trait { type Deposit: Get>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } decl_storage! { - trait Store for Module as Indices { + trait Store for Module as Indices { /// The lookup from index to account. pub Accounts build(|config: &GenesisConfig| config.indices.iter() @@ -75,8 +75,8 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, - ::AccountIndex + ::AccountId, + ::AccountIndex { /// A account index was assigned. \[index, who\] IndexAssigned(AccountId, AccountIndex), @@ -88,7 +88,7 @@ decl_event!( ); decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// The index was not already assigned. NotAssigned, /// The index is assigned to another account. @@ -103,7 +103,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system = frame_system { + pub struct Module for enum Call where origin: T::Origin, system = frame_system { /// The deposit needed for reserving an index. const Deposit: BalanceOf = T::Deposit::get(); @@ -275,7 +275,7 @@ decl_module! { } } -impl Module { +impl Module { // PUBLIC IMMUTABLES /// Lookup an T::AccountIndex to get an Id, if there's one there. @@ -295,7 +295,7 @@ impl Module { } } -impl StaticLookup for Module { +impl StaticLookup for Module { type Source = MultiAddress; type Target = T::AccountId; diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index cfbd2e38c3d..dbbde888c16 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -23,7 +23,7 @@ use sp_runtime::testing::Header; use sp_runtime::Perbill; use sp_core::H256; use frame_support::{impl_outer_origin, impl_outer_event, parameter_types, weights::Weight}; -use crate::{self as indices, Module, Trait}; +use crate::{self as indices, Module, Config}; use frame_system as system; use pallet_balances as balances; @@ -49,7 +49,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); @@ -81,7 +81,7 @@ parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type DustRemoval = (); @@ -95,7 +95,7 @@ parameter_types! { pub const Deposit: u64 = 1; } -impl Trait for Test { +impl Config for Test { type AccountIndex = u64; type Currency = Balances; type Deposit = Deposit; diff --git a/frame/indices/src/weights.rs b/frame/indices/src/weights.rs index 36d990cec52..96470625329 100644 --- a/frame/indices/src/weights.rs +++ b/frame/indices/src/weights.rs @@ -53,7 +53,7 @@ pub trait WeightInfo { /// Weights for pallet_indices using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn claim() -> Weight { (53_799_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 06188c42b21..60cd7ae1eda 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -30,9 +30,9 @@ use frame_support::{ }; use frame_system::ensure_signed; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Required origin for adding a member (though can always be Root). type AddOrigin: EnsureOrigin; @@ -59,7 +59,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Membership { + trait Store for Module, I: Instance=DefaultInstance> as Membership { /// The current membership, stored as an ordered Vec. Members get(fn members): Vec; @@ -80,8 +80,8 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, - >::Event, + ::AccountId, + >::Event, { /// The given member was added; see the transaction for who. MemberAdded, @@ -100,7 +100,7 @@ decl_event!( decl_error! { /// Error for the nicks module. - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// Already a member. AlreadyMember, /// Not a member. @@ -109,7 +109,7 @@ decl_error! { } decl_module! { - pub struct Module, I: Instance=DefaultInstance> + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: T::Origin { @@ -253,7 +253,7 @@ decl_module! { } } -impl, I: Instance> Module { +impl, I: Instance> Module { fn rejig_prime(members: &[T::AccountId]) { if let Some(prime) = Prime::::get() { match members.binary_search(&prime) { @@ -264,7 +264,7 @@ impl, I: Instance> Module { } } -impl, I: Instance> Contains for Module { +impl, I: Instance> Contains for Module { fn sorted_members() -> Vec { Self::members() } @@ -300,7 +300,7 @@ mod tests { pub static Members: Vec = vec![]; pub static Prime: Option = None; } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -359,7 +359,7 @@ mod tests { } } - impl Trait for Test { + impl Config for Test { type Event = (); type AddOrigin = EnsureSignedBy; type RemoveOrigin = EnsureSignedBy; diff --git a/frame/multisig/src/benchmarking.rs b/frame/multisig/src/benchmarking.rs index bf89ec8b09b..0b549b3d947 100644 --- a/frame/multisig/src/benchmarking.rs +++ b/frame/multisig/src/benchmarking.rs @@ -29,7 +29,7 @@ use crate::Module as Multisig; const SEED: u32 = 0; -fn setup_multi(s: u32, z: u32) +fn setup_multi(s: u32, z: u32) -> Result<(Vec, Vec), &'static str> { let mut signatories: Vec = Vec::new(); @@ -42,7 +42,7 @@ fn setup_multi(s: u32, z: u32) } signatories.sort(); // Must first convert to outer call type. - let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); + let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); let call_data = call.encode(); return Ok((signatories, call_data)) } @@ -55,7 +55,7 @@ benchmarks! { let z in 0 .. 10_000; let max_signatories = T::MaxSignatories::get().into(); let (mut signatories, _) = setup_multi::(max_signatories, z)?; - let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); + let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); let call_hash = call.using_encoded(blake2_256); let multi_account_id = Multisig::::multi_account_id(&signatories, 1); let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 873508259a8..b39b979f999 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -18,7 +18,7 @@ //! # Multisig Module //! A module for doing multisig dispatch. //! -//! - [`multisig::Trait`](./trait.Trait.html) +//! - [`multisig::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -41,7 +41,7 @@ //! * `cancel_as_multi` - Cancel a call from a composite origin. //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -62,14 +62,14 @@ use frame_system::{self as system, ensure_signed, RawOrigin}; use sp_runtime::{DispatchError, DispatchResult, traits::{Dispatchable, Zero}}; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Just a bunch of bytes, but they should decode to a valid `Call`. pub type OpaqueCall = Vec; /// Configuration trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable @@ -123,7 +123,7 @@ pub struct Multisig { } decl_storage! { - trait Store for Module as Multisig { + trait Store for Module as Multisig { /// The set of open multisig operations. pub Multisigs: double_map hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) [u8; 32] @@ -134,7 +134,7 @@ decl_storage! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Threshold must be 2 or greater. MinimumThreshold, /// Call is already approved by this signatory. @@ -169,8 +169,8 @@ decl_error! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, - BlockNumber = ::BlockNumber, + AccountId = ::AccountId, + BlockNumber = ::BlockNumber, CallHash = [u8; 32] { /// A new multisig operation has begun. \[approving, multisig, call_hash\] @@ -191,7 +191,7 @@ enum CallOrHash { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// Deposit one of this module's events by using the default implementation. @@ -232,7 +232,7 @@ decl_module! { )] fn as_multi_threshold_1(origin, other_signatories: Vec, - call: Box<::Call>, + call: Box<::Call>, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let max_sigs = T::MaxSignatories::get() as usize; @@ -443,7 +443,7 @@ decl_module! { } } -impl Module { +impl Module { /// Derive a multi-account ID from the sorted list of accounts and the threshold that are /// required. /// @@ -615,7 +615,7 @@ impl Module { } /// Attempt to decode and return the call, provided by the user or from storage. - fn get_call(hash: &[u8; 32], maybe_known: Option<&[u8]>) -> Option<(::Call, usize)> { + fn get_call(hash: &[u8; 32], maybe_known: Option<&[u8]>) -> Option<(::Call, usize)> { maybe_known.map_or_else(|| { Calls::::get(hash).and_then(|(data, ..)| { Decode::decode(&mut &data[..]).ok().map(|d| (d, data.len())) diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index ca15e04597e..6e889518434 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -59,7 +59,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; type Origin = Origin; type Index = u64; @@ -89,7 +89,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = TestEvent; @@ -114,7 +114,7 @@ impl Filter for TestBaseCallFilter { } } } -impl Trait for Test { +impl Config for Test { type Event = TestEvent; type Call = Call; type Currency = Balances; diff --git a/frame/multisig/src/weights.rs b/frame/multisig/src/weights.rs index ab55b181f5a..c0f6399e764 100644 --- a/frame/multisig/src/weights.rs +++ b/frame/multisig/src/weights.rs @@ -58,7 +58,7 @@ pub trait WeightInfo { /// Weights for pallet_multisig using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn as_multi_threshold_1(z: u32, ) -> Weight { (14_183_000 as Weight) .saturating_add((1_000 as Weight).saturating_mul(z as Weight)) diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index ddeadfb7680..e6658025042 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -17,7 +17,7 @@ //! # Nicks Module //! -//! - [`nicks::Trait`](./trait.Trait.html) +//! - [`nicks::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -37,7 +37,7 @@ //! * `kill_name` - Forcibly remove the associated name; the deposit is lost. //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html #![cfg_attr(not(feature = "std"), no_std)] @@ -51,12 +51,12 @@ use frame_support::{ }; use frame_system::ensure_signed; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: ReservableCurrency; @@ -78,14 +78,14 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as Nicks { + trait Store for Module as Nicks { /// The lookup table for names. NameOf: map hasher(twox_64_concat) T::AccountId => Option<(Vec, BalanceOf)>; } } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// A name was set. \[who\] NameSet(AccountId), /// A name was forcibly set. \[target\] @@ -101,7 +101,7 @@ decl_event!( decl_error! { /// Error for the nicks module. - pub enum Error for Module { + pub enum Error for Module { /// A name is too short. TooShort, /// A name is too long. @@ -113,7 +113,7 @@ decl_error! { decl_module! { /// Nicks module declaration. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -262,7 +262,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -292,7 +292,7 @@ mod tests { parameter_types! { pub const ExistentialDeposit: u64 = 1; } - impl pallet_balances::Trait for Test { + impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = (); @@ -309,7 +309,7 @@ mod tests { ord_parameter_types! { pub const One: u64 = 1; } - impl Trait for Test { + impl Config for Test { type Event = (); type Currency = Balances; type ReservationFee = ReservationFee; diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 91f89ad1d91..df6b391cc7a 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -76,9 +76,9 @@ impl WeightInfo for () { fn remove_connections() -> Weight { 50_000_000 } } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The event type of this module. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The maximum number of well known nodes that are allowed to set type MaxWellKnownNodes: Get; @@ -103,7 +103,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as NodeAuthorization { + trait Store for Module as NodeAuthorization { /// The set of well known nodes. This is stored sorted (just by value). pub WellKnownNodes get(fn well_known_nodes): BTreeSet; /// A map that maintains the ownership of each node. @@ -123,7 +123,7 @@ decl_storage! { decl_event! { pub enum Event where - ::AccountId, + ::AccountId, { /// The given well known node was added. NodeAdded(PeerId, AccountId), @@ -149,7 +149,7 @@ decl_event! { decl_error! { /// Error for the node authorization module. - pub enum Error for Module { + pub enum Error for Module { /// The PeerId is too long. PeerIdTooLong, /// Too many well known nodes. @@ -170,7 +170,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// The maximum number of authorized well known nodes const MaxWellKnownNodes: u32 = T::MaxWellKnownNodes::get(); @@ -403,7 +403,7 @@ decl_module! { } } -impl Module { +impl Module { fn initialize_nodes(nodes: &Vec<(PeerId, T::AccountId)>) { let peer_ids = nodes.iter() .map(|item| item.0.clone()) @@ -453,7 +453,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -491,7 +491,7 @@ mod tests { pub const MaxWellKnownNodes: u32 = 4; pub const MaxPeerIdLength: u32 = 2; } - impl Trait for Test { + impl Config for Test { type Event = (); type MaxWellKnownNodes = MaxWellKnownNodes; type MaxPeerIdLength = MaxPeerIdLength; diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index 47055eab73d..cdac46acb45 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -24,22 +24,22 @@ mod mock; use sp_std::prelude::*; use sp_std::vec; -use frame_system::{RawOrigin, Module as System, Trait as SystemTrait}; +use frame_system::{RawOrigin, Module as System, Config as SystemTrait}; use frame_benchmarking::{benchmarks, account}; use frame_support::traits::{Currency, OnInitialize}; use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}}; use sp_staking::offence::{ReportOffence, Offence, OffenceDetails}; -use pallet_balances::{Trait as BalancesTrait}; +use pallet_balances::{Config as BalancesTrait}; use pallet_babe::BabeEquivocationOffence; use pallet_grandpa::{GrandpaEquivocationOffence, GrandpaTimeSlot}; -use pallet_im_online::{Trait as ImOnlineTrait, Module as ImOnline, UnresponsivenessOffence}; -use pallet_offences::{Trait as OffencesTrait, Module as Offences}; -use pallet_session::historical::{Trait as HistoricalTrait, IdentificationTuple}; -use pallet_session::{Trait as SessionTrait, SessionManager}; +use pallet_im_online::{Config as ImOnlineTrait, Module as ImOnline, UnresponsivenessOffence}; +use pallet_offences::{Config as OffencesTrait, Module as Offences}; +use pallet_session::historical::{Config as HistoricalTrait, IdentificationTuple}; +use pallet_session::{Config as SessionTrait, SessionManager}; use pallet_staking::{ - Module as Staking, Trait as StakingTrait, RewardDestination, ValidatorPrefs, + Module as Staking, Config as StakingTrait, RewardDestination, ValidatorPrefs, Exposure, IndividualExposure, ElectionStatus, MAX_NOMINATIONS, Event as StakingEvent }; @@ -50,9 +50,9 @@ const MAX_OFFENDERS: u32 = 100; const MAX_NOMINATORS: u32 = 100; const MAX_DEFERRED_OFFENCES: u32 = 100; -pub struct Module(Offences); +pub struct Module(Offences); -pub trait Trait: +pub trait Config: SessionTrait + StakingTrait + OffencesTrait @@ -80,17 +80,17 @@ impl IdTupleConvert for T where type LookupSourceOf = <::Lookup as StaticLookup>::Source; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -struct Offender { +struct Offender { pub controller: T::AccountId, pub stash: T::AccountId, pub nominator_stashes: Vec, } -fn bond_amount() -> BalanceOf { +fn bond_amount() -> BalanceOf { T::Currency::minimum_balance().saturating_mul(10_000u32.into()) } -fn create_offender(n: u32, nominators: u32) -> Result, &'static str> { +fn create_offender(n: u32, nominators: u32) -> Result, &'static str> { let stash: T::AccountId = account("stash", n, SEED); let controller: T::AccountId = account("controller", n, SEED); let controller_lookup: LookupSourceOf = T::Lookup::unlookup(controller.clone()); @@ -149,7 +149,7 @@ fn create_offender(n: u32, nominators: u32) -> Result, &'s Ok(Offender { controller, stash, nominator_stashes }) } -fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< +fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< (Vec>, Vec>), &'static str > { @@ -176,7 +176,7 @@ fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< } #[cfg(test)] -fn check_events::Event>>(expected: I) { +fn check_events::Event>>(expected: I) { let events = System::::events() .into_iter() .map(|frame_system::EventRecord { event, .. }| event).collect::>(); let expected = expected.collect::>(); diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 527e0ede81a..269324033bb 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -40,7 +40,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; @@ -70,7 +70,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: Balance = 10; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = Balance; type Event = Event; @@ -83,13 +83,13 @@ impl pallet_balances::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 5; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -120,7 +120,7 @@ parameter_types! { pub const Offset: u64 = 0; } -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions; @@ -149,7 +149,7 @@ parameter_types! { pub type Extrinsic = sp_runtime::testing::TestXt; -impl pallet_staking::Trait for Test { +impl pallet_staking::Config for Test { type Currency = Balances; type UnixTime = pallet_timestamp::Module; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; @@ -174,7 +174,7 @@ impl pallet_staking::Trait for Test { type WeightInfo = (); } -impl pallet_im_online::Trait for Test { +impl pallet_im_online::Config for Test { type AuthorityId = UintAuthorityId; type Event = Event; type SessionDuration = Period; @@ -187,7 +187,7 @@ parameter_types! { pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } -impl pallet_offences::Trait for Test { +impl pallet_offences::Config for Test { type Event = Event; type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; @@ -199,7 +199,7 @@ impl frame_system::offchain::SendTransactionTypes for Test where Call: Fro type OverarchingCall = Call; } -impl crate::Trait for Test {} +impl crate::Config for Test {} pub type Block = sp_runtime::generic::Block; pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index e72498273ce..e3f01823c18 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -42,11 +42,11 @@ use codec::{Encode, Decode}; type OpaqueTimeSlot = Vec; /// A type alias for a report identifier. -type ReportIdOf = ::Hash; +type ReportIdOf = ::Hash; /// Type of data stored as a deferred offence pub type DeferredOffenceOf = ( - Vec::AccountId, ::IdentificationTuple>>, + Vec::AccountId, ::IdentificationTuple>>, Vec, SessionIndex, ); @@ -66,9 +66,9 @@ impl WeightInfo for () { } /// Offences trait -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// Full identification of the validator. type IdentificationTuple: Parameter + Ord; /// A handler called for every offence report. @@ -80,7 +80,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as Offences { + trait Store for Module as Offences { /// The primary structure that holds all offence records keyed by report identifiers. Reports get(fn reports): map hasher(twox_64_concat) ReportIdOf @@ -116,7 +116,7 @@ decl_event!( ); decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; fn on_initialize(now: T::BlockNumber) -> Weight { @@ -158,7 +158,7 @@ decl_module! { } } -impl> +impl> ReportOffence for Module where T::IdentificationTuple: Clone, @@ -210,7 +210,7 @@ where } } -impl Module { +impl Module { /// Tries (without checking) to report an offence. Stores them in [`DeferredOffences`] in case /// it fails. Returns false in case it has to store the offence. fn report_or_store_offence( @@ -293,7 +293,7 @@ impl Module { } } -struct TriageOutcome { +struct TriageOutcome { /// Other reports for the same report kinds. concurrent_offenders: Vec>, } @@ -304,13 +304,13 @@ struct TriageOutcome { /// This struct is responsible for aggregating storage writes and the underlying storage should not /// accessed directly meanwhile. #[must_use = "The changes are not saved without called `save`"] -struct ReportIndexStorage> { +struct ReportIndexStorage> { opaque_time_slot: OpaqueTimeSlot, concurrent_reports: Vec>, same_kind_reports: Vec<(O::TimeSlot, ReportIdOf)>, } -impl> ReportIndexStorage { +impl> ReportIndexStorage { /// Preload indexes from the storage for the specific `time_slot` and the kind of the offence. fn load(time_slot: &O::TimeSlot) -> Self { let opaque_time_slot = time_slot.encode(); diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 58ee97a9bcb..690db58a871 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -20,7 +20,7 @@ #![cfg(test)] use std::cell::RefCell; -use crate::{Module, Trait}; +use crate::{Module, Config}; use codec::Encode; use sp_runtime::Perbill; use sp_staking::{ @@ -95,7 +95,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -127,7 +127,7 @@ parameter_types! { pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } -impl Trait for Runtime { +impl Config for Runtime { type Event = TestEvent; type IdentificationTuple = u64; type OnOffenceHandler = OnOffenceHandler; diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index ca9f46a1988..18582ec042c 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -342,7 +342,7 @@ fn weight_soft_limit_is_used() { new_test_ext().execute_with(|| { set_can_report(false); // Only 2 can fit in one block - set_offence_weight(::WeightSoftLimit::get() / 2); + set_offence_weight(::WeightSoftLimit::get() / 2); // Queue 3 offences // #1 diff --git a/frame/proxy/src/benchmarking.rs b/frame/proxy/src/benchmarking.rs index 5f1d79741dd..ac0fa52c970 100644 --- a/frame/proxy/src/benchmarking.rs +++ b/frame/proxy/src/benchmarking.rs @@ -27,15 +27,15 @@ use crate::Module as Proxy; const SEED: u32 = 0; -fn assert_last_event(generic_event: ::Event) { +fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); } -fn add_proxies(n: u32, maybe_who: Option) -> Result<(), &'static str> { +fn add_proxies(n: u32, maybe_who: Option) -> Result<(), &'static str> { let caller = maybe_who.unwrap_or_else(|| whitelisted_caller()); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); for i in 0..n { @@ -49,7 +49,7 @@ fn add_proxies(n: u32, maybe_who: Option) -> Result<(), Ok(()) } -fn add_announcements( +fn add_announcements( n: u32, maybe_who: Option, maybe_real: Option @@ -91,7 +91,7 @@ benchmarks! { T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); - let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); }: _(RawOrigin::Signed(caller), real, Some(T::ProxyType::default()), Box::new(call)) verify { assert_last_event::(RawEvent::ProxyExecuted(Ok(())).into()) @@ -106,7 +106,7 @@ benchmarks! { T::Currency::make_free_balance_be(&delegate, BalanceOf::::max_value()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); - let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); Proxy::::announce( RawOrigin::Signed(delegate.clone()).into(), real.clone(), @@ -126,7 +126,7 @@ benchmarks! { T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); - let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); Proxy::::announce( RawOrigin::Signed(caller.clone()).into(), real.clone(), @@ -147,7 +147,7 @@ benchmarks! { T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); - let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); Proxy::::announce( RawOrigin::Signed(caller.clone()).into(), real.clone(), @@ -169,7 +169,7 @@ benchmarks! { // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); add_announcements::(a, Some(caller.clone()), None)?; - let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); let call_hash = T::CallHasher::hash_of(&call); }: _(RawOrigin::Signed(caller.clone()), real.clone(), call_hash) verify { diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 75ab3902dc8..3d707d23836 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -23,7 +23,7 @@ //! wish to execute some duration prior to execution happens. In this case, the target account may //! reject the announcement and in doing so, veto the execution. //! -//! - [`proxy::Trait`](./trait.Trait.html) +//! - [`proxy::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -33,7 +33,7 @@ //! ### Dispatchable Functions //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -55,17 +55,17 @@ use frame_system::{self as system, ensure_signed}; use frame_support::dispatch::DispatchError; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Configuration trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable + GetDispatchInfo + From> + IsSubType> - + IsType<::Call>; + + IsType<::Call>; /// The currency mechanism. type Currency: ReservableCurrency; @@ -74,7 +74,7 @@ pub trait Trait: frame_system::Trait { /// The instance filter determines whether a given call may be proxied under this type. /// /// IMPORTANT: `Default` must be provided and MUST BE the the *most permissive* value. - type ProxyType: Parameter + Member + Ord + PartialOrd + InstanceFilter<::Call> + type ProxyType: Parameter + Member + Ord + PartialOrd + InstanceFilter<::Call> + Default; /// The base amount of currency needed to reserve for creating a proxy. @@ -137,10 +137,10 @@ pub struct Announcement { height: BlockNumber, } -type CallHashOf = <::CallHasher as Hash>::Output; +type CallHashOf = <::CallHasher as Hash>::Output; decl_storage! { - trait Store for Module as Proxy { + trait Store for Module as Proxy { /// The set of account proxies. Maps the account which has delegated to the accounts /// which are being delegated to, together with the amount held on deposit. pub Proxies get(fn proxies): map hasher(twox_64_concat) T::AccountId @@ -153,7 +153,7 @@ decl_storage! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// There are too many proxies registered or too many announcements pending. TooMany, /// Proxy registration not found. @@ -174,8 +174,8 @@ decl_error! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, - ProxyType = ::ProxyType, + AccountId = ::AccountId, + ProxyType = ::ProxyType, Hash = CallHashOf, { /// A proxy was executed correctly, with the given \[result\]. @@ -189,7 +189,7 @@ decl_event! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// Deposit one of this module's events by using the default implementation. @@ -239,7 +239,7 @@ decl_module! { fn proxy(origin, real: T::AccountId, force_proxy_type: Option, - call: Box<::Call>, + call: Box<::Call>, ) { let who = ensure_signed(origin)?; let def = Self::find_proxy(&real, &who, force_proxy_type)?; @@ -509,7 +509,7 @@ decl_module! { delegate: T::AccountId, real: T::AccountId, force_proxy_type: Option, - call: Box<::Call>, + call: Box<::Call>, ) { ensure_signed(origin)?; let def = Self::find_proxy(&real, &delegate, force_proxy_type)?; @@ -525,7 +525,7 @@ decl_module! { } } -impl Module { +impl Module { /// Calculate the address of an anonymous account. /// @@ -680,12 +680,12 @@ impl Module { fn do_proxy( def: ProxyDefinition, real: T::AccountId, - call: ::Call, + call: ::Call, ) { // This is a freshly authenticated new account, the origin restrictions doesn't apply. let mut origin: T::Origin = frame_system::RawOrigin::Signed(real).into(); - origin.add_filter(move |c: &::Call| { - let c = ::Call::from_ref(c); + origin.add_filter(move |c: &::Call| { + let c = ::Call::from_ref(c); // We make sure the proxy call does access this pallet to change modify proxies. match c.is_sub_type() { // Proxy call cannot add or remove a proxy with more permissions than it already has. @@ -714,7 +714,7 @@ pub mod migration { /// `ProxyDefinition` which additionally included a `BlockNumber` delay value. This function, /// simply takes any existing proxies using the old tuple format, and migrates it to the new /// struct by setting the delay to zero. - pub fn migrate_to_time_delayed_proxies() -> Weight { + pub fn migrate_to_time_delayed_proxies() -> Weight { Proxies::::translate::<(Vec<(T::AccountId, T::ProxyType)>, BalanceOf), _>( |_, (targets, deposit)| Some(( targets.into_iter() diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index bcf3b678ed6..0338b983595 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -61,7 +61,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Index = u64; @@ -91,7 +91,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = TestEvent; @@ -100,7 +100,7 @@ impl pallet_balances::Trait for Test { type AccountStore = System; type WeightInfo = (); } -impl pallet_utility::Trait for Test { +impl pallet_utility::Config for Test { type Event = TestEvent; type Call = Call; type WeightInfo = (); @@ -143,7 +143,7 @@ impl Filter for BaseFilter { } } } -impl Trait for Test { +impl Config for Test { type Event = TestEvent; type Call = Call; type Currency = Balances; diff --git a/frame/proxy/src/weights.rs b/frame/proxy/src/weights.rs index 944fe53a149..8f5a608aa58 100644 --- a/frame/proxy/src/weights.rs +++ b/frame/proxy/src/weights.rs @@ -58,7 +58,7 @@ pub trait WeightInfo { /// Weights for pallet_proxy using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn proxy(p: u32, ) -> Weight { (32_194_000 as Weight) .saturating_add((215_000 as Weight).saturating_mul(p as Weight)) diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index c1747669dab..ffa4da978a8 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -39,10 +39,10 @@ //! ``` //! use frame_support::{decl_module, dispatch, traits::Randomness}; //! -//! pub trait Trait: frame_system::Trait {} +//! pub trait Config: frame_system::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn random_module_example(origin) -> dispatch::DispatchResult { //! let _random_value = >::random(&b"my context"[..]); @@ -63,18 +63,18 @@ use frame_support::{ }; use safe_mix::TripletMix; use codec::Encode; -use frame_system::Trait; +use frame_system::Config; const RANDOM_MATERIAL_LEN: u32 = 81; -fn block_number_to_index(block_number: T::BlockNumber) -> usize { +fn block_number_to_index(block_number: T::BlockNumber) -> usize { // on_initialize is called on the first block after genesis let index = (block_number - 1u32.into()) % RANDOM_MATERIAL_LEN.into(); index.try_into().ok().expect("Something % 81 is always smaller than usize; qed") } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { fn on_initialize(block_number: T::BlockNumber) -> Weight { let parent_hash = >::parent_hash(); @@ -91,7 +91,7 @@ decl_module! { } decl_storage! { - trait Store for Module as RandomnessCollectiveFlip { + trait Store for Module as RandomnessCollectiveFlip { /// Series of block headers from the last 81 blocks that acts as random seed material. This /// is arranged as a ring buffer with `block_number % 81` being the index into the `Vec` of /// the oldest hash. @@ -99,7 +99,7 @@ decl_storage! { } } -impl Randomness for Module { +impl Randomness for Module { /// This randomness uses a low-influence function, drawing upon the block hashes from the /// previous 81 blocks. Its result for any given subject will be known far in advance by anyone /// observing the chain. Any block producer has significant influence over their block hashes @@ -157,7 +157,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index c97824497fd..023a805a719 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -17,7 +17,7 @@ //! # Recovery Pallet //! -//! - [`recovery::Trait`](./trait.Trait.html) +//! - [`recovery::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -172,12 +172,12 @@ mod mock; mod tests; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; /// Configuration trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable + GetDispatchInfo; @@ -237,7 +237,7 @@ pub struct RecoveryConfig { } decl_storage! { - trait Store for Module as Recovery { + trait Store for Module as Recovery { /// The set of recoverable accounts and their recovery configuration. pub Recoverable get(fn recovery_config): map hasher(twox_64_concat) T::AccountId @@ -262,7 +262,7 @@ decl_storage! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, { /// A recovery process has been set up for an \[account\]. RecoveryCreated(AccountId), @@ -284,7 +284,7 @@ decl_event! { } decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// User is not allowed to make a call on behalf of this account NotAllowed, /// Threshold must be greater than zero @@ -321,7 +321,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// The base amount of currency needed to reserve for creating a recovery configuration. @@ -361,7 +361,7 @@ decl_module! { )] fn as_recovered(origin, account: T::AccountId, - call: Box<::Call> + call: Box<::Call> ) -> DispatchResult { let who = ensure_signed(origin)?; // Check `who` is allowed to make a call on behalf of `account` @@ -677,7 +677,7 @@ decl_module! { } } -impl Module { +impl Module { /// Check that friends list is sorted and has no duplicates. fn is_sorted_and_unique(friends: &Vec) -> bool { friends.windows(2).all(|w| w[0] < w[1]) diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 35373562487..9f15f31bd42 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -58,7 +58,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -90,7 +90,7 @@ parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u128; type DustRemoval = (); @@ -107,7 +107,7 @@ parameter_types! { pub const RecoveryDeposit: u64 = 10; } -impl Trait for Test { +impl Config for Test { type Event = TestEvent; type Call = Call; type Currency = Balances; diff --git a/frame/scheduler/src/benchmarking.rs b/frame/scheduler/src/benchmarking.rs index 753e9244628..6a67efc9d2d 100644 --- a/frame/scheduler/src/benchmarking.rs +++ b/frame/scheduler/src/benchmarking.rs @@ -31,7 +31,7 @@ use frame_system::Module as System; const BLOCK_NUMBER: u32 = 2; // Add `n` named items to the schedule -fn fill_schedule (when: T::BlockNumber, n: u32) -> Result<(), &'static str> { +fn fill_schedule (when: T::BlockNumber, n: u32) -> Result<(), &'static str> { // Essentially a no-op call. let call = frame_system::Call::set_storage(vec![]); for i in 0..n { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index c467678a466..4cdfe4ddf04 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -18,7 +18,7 @@ //! # Scheduler //! A module for scheduling dispatches. //! -//! - [`scheduler::Trait`](./trait.Trait.html) +//! - [`scheduler::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -29,7 +29,7 @@ //! may be named or anonymous and may be canceled. //! //! **NOTE:** The scheduled calls will be dispatched with the default filter -//! for the origin: namely `frame_system::Trait::BaseCallFilter` for all origin +//! for the origin: namely `frame_system::Config::BaseCallFilter` for all origin //! except root which will get no filter. And not the filter contained in origin //! use to call `fn schedule`. //! @@ -70,27 +70,27 @@ pub use weights::WeightInfo; /// pallet is dependent on specific other pallets, then their configuration traits /// should be added to our implied traits list. /// -/// `system::Trait` should always be included in our implied traits. -pub trait Trait: system::Trait { +/// `system::Config` should always be included in our implied traits. +pub trait Config: system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The aggregated origin which the dispatch will take. type Origin: OriginTrait + From + IsType<::Origin>; + Self::PalletsOrigin> + From + IsType<::Origin>; /// The caller origin, overarching type of all pallets origins. type PalletsOrigin: From> + Codec + Clone + Eq; /// The aggregated call type. - type Call: Parameter + Dispatchable::Origin> + GetDispatchInfo + From>; + type Call: Parameter + Dispatchable::Origin> + GetDispatchInfo + From>; /// The maximum weight that may be scheduled per block for any dispatchables of less priority /// than `schedule::HARD_DEADLINE`. type MaximumWeight: Get; /// Required origin to schedule or cancel calls. - type ScheduleOrigin: EnsureOrigin<::Origin>; + type ScheduleOrigin: EnsureOrigin<::Origin>; /// The maximum number of scheduled calls in the queue for a single block. /// Not strictly enforced, but used for weight estimation. @@ -150,10 +150,10 @@ impl Default for Releases { } decl_storage! { - trait Store for Module as Scheduler { + trait Store for Module as Scheduler { /// Items to be executed, indexed by the block number that they should be executed on. pub Agenda: map hasher(twox_64_concat) T::BlockNumber - => Vec::Call, T::BlockNumber, T::PalletsOrigin, T::AccountId>>>; + => Vec::Call, T::BlockNumber, T::PalletsOrigin, T::AccountId>>>; /// Lookup from identity to the block number and index of the task. Lookup: map hasher(twox_64_concat) Vec => Option>; @@ -166,7 +166,7 @@ decl_storage! { } decl_event!( - pub enum Event where ::BlockNumber { + pub enum Event where ::BlockNumber { /// Scheduled some task. \[when, index\] Scheduled(BlockNumber, u32), /// Canceled some task. \[when, index\] @@ -177,7 +177,7 @@ decl_event!( ); decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Failed to schedule a call FailedToSchedule, /// Cannot find the scheduled call. @@ -191,7 +191,7 @@ decl_error! { decl_module! { /// Scheduler module declaration. - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { type Error = Error; fn deposit_event() = default; @@ -210,10 +210,10 @@ decl_module! { when: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, - call: Box<::Call>, + call: Box<::Call>, ) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_schedule(DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call)?; } @@ -230,7 +230,7 @@ decl_module! { #[weight = T::WeightInfo::cancel(T::MaxScheduledPerBlock::get())] fn cancel(origin, when: T::BlockNumber, index: u32) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_cancel(Some(origin.caller().clone()), (when, index))?; } @@ -250,10 +250,10 @@ decl_module! { when: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, - call: Box<::Call>, + call: Box<::Call>, ) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_schedule_named( id, DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call )?; @@ -272,7 +272,7 @@ decl_module! { #[weight = T::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get())] fn cancel_named(origin, id: Vec) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_cancel_named(Some(origin.caller().clone()), id)?; } @@ -286,10 +286,10 @@ decl_module! { after: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, - call: Box<::Call>, + call: Box<::Call>, ) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_schedule( DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call )?; @@ -306,10 +306,10 @@ decl_module! { after: T::BlockNumber, maybe_periodic: Option>, priority: schedule::Priority, - call: Box<::Call>, + call: Box<::Call>, ) { T::ScheduleOrigin::ensure_origin(origin.clone())?; - let origin = ::Origin::from(origin); + let origin = ::Origin::from(origin); Self::do_schedule_named( id, DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call )?; @@ -347,7 +347,7 @@ decl_module! { *cumulative_weight = cumulative_weight .saturating_add(s.call.get_dispatch_info().weight); - let origin = <::Origin as From>::from( + let origin = <::Origin as From>::from( s.origin.clone() ).into(); @@ -415,7 +415,7 @@ decl_module! { } } -impl Module { +impl Module { /// Migrate storage format from V1 to V2. /// Return true if migration is performed. pub fn migrate_v1_to_t2() -> bool { @@ -423,7 +423,7 @@ impl Module { StorageVersion::put(Releases::V2); Agenda::::translate::< - Vec::Call, T::BlockNumber>>>, _ + Vec::Call, T::BlockNumber>>>, _ >(|_, agenda| Some( agenda .into_iter() @@ -447,7 +447,7 @@ impl Module { /// Helper to migrate scheduler when the pallet origin type has changed. pub fn migrate_origin + codec::Decode>() { Agenda::::translate::< - Vec::Call, T::BlockNumber, OldOrigin, T::AccountId>>>, _ + Vec::Call, T::BlockNumber, OldOrigin, T::AccountId>>>, _ >(|_, agenda| Some( agenda .into_iter() @@ -485,7 +485,7 @@ impl Module { maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call + call: ::Call ) -> Result, DispatchError> { let when = Self::resolve_time(when)?; @@ -569,7 +569,7 @@ impl Module { maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call, + call: ::Call, ) -> Result, DispatchError> { // ensure id it is unique if Lookup::::contains_key(&id) { @@ -657,7 +657,7 @@ impl Module { } } -impl schedule::Anon::Call, T::PalletsOrigin> for Module { +impl schedule::Anon::Call, T::PalletsOrigin> for Module { type Address = TaskAddress; fn schedule( @@ -665,7 +665,7 @@ impl schedule::Anon::Call, T::PalletsOrig maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call + call: ::Call ) -> Result { Self::do_schedule(when, maybe_periodic, priority, origin, call) } @@ -686,7 +686,7 @@ impl schedule::Anon::Call, T::PalletsOrig } } -impl schedule::Named::Call, T::PalletsOrigin> for Module { +impl schedule::Named::Call, T::PalletsOrigin> for Module { type Address = TaskAddress; fn schedule_named( @@ -695,7 +695,7 @@ impl schedule::Named::Call, T::PalletsOri maybe_periodic: Option>, priority: schedule::Priority, origin: T::PalletsOrigin, - call: ::Call, + call: ::Call, ) -> Result { Self::do_schedule_named(id, when, maybe_periodic, priority, origin, call).map_err(|_| ()) } @@ -746,8 +746,8 @@ mod tests { pub fn log() -> Vec<(OriginCaller, u32)> { LOG.with(|log| log.borrow().clone()) } - pub trait Trait: system::Trait { - type Event: From + Into<::Event>; + pub trait Config: system::Config { + type Event: From + Into<::Event>; } decl_event! { pub enum Event { @@ -755,10 +755,10 @@ mod tests { } } decl_module! { - pub struct Module for enum Call + pub struct Module for enum Call where - origin: ::Origin, - ::Origin: OriginTrait + origin: ::Origin, + ::Origin: OriginTrait { fn deposit_event() = default; @@ -816,7 +816,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Call = Call; @@ -843,7 +843,7 @@ mod tests { type OnKilledAccount = (); type SystemWeightInfo = (); } - impl logger::Trait for Test { + impl logger::Config for Test { type Event = (); } parameter_types! { @@ -854,7 +854,7 @@ mod tests { pub const One: u64 = 1; } - impl Trait for Test { + impl Config for Test { type Event = (); type Origin = Origin; type PalletsOrigin = OriginCaller; @@ -889,7 +889,7 @@ mod tests { fn basic_scheduling_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_ok!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call)); run_to_block(3); assert!(logger::log().is_empty()); @@ -905,7 +905,7 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(2); let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); // This will schedule the call 3 blocks after the next block... so block 3 + 3 = 6 assert_ok!(Scheduler::do_schedule(DispatchTime::After(3), None, 127, root(), call)); run_to_block(5); @@ -922,7 +922,7 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(2); let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_ok!(Scheduler::do_schedule(DispatchTime::After(0), None, 127, root(), call)); // Will trigger on the next block. run_to_block(3); @@ -960,7 +960,7 @@ mod tests { fn reschedule_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call).unwrap(), (4, 0)); run_to_block(3); @@ -985,7 +985,7 @@ mod tests { fn reschedule_named_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), None, 127, root(), call ).unwrap(), (4, 0)); @@ -1012,7 +1012,7 @@ mod tests { fn reschedule_named_perodic_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), Some((3, 3)), 127, root(), call ).unwrap(), (4, 0)); @@ -1203,10 +1203,10 @@ mod tests { #[test] fn on_initialize_weight_is_correct() { new_test_ext().execute_with(|| { - let base_weight: Weight = ::DbWeight::get().reads_writes(1, 2); + let base_weight: Weight = ::DbWeight::get().reads_writes(1, 2); let base_multiplier = 0; - let named_multiplier = ::DbWeight::get().writes(1); - let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); + let named_multiplier = ::DbWeight::get().writes(1); + let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); // Named assert_ok!( diff --git a/frame/scheduler/src/weights.rs b/frame/scheduler/src/weights.rs index 3699e6f85b2..3c8be54c9ae 100644 --- a/frame/scheduler/src/weights.rs +++ b/frame/scheduler/src/weights.rs @@ -52,7 +52,7 @@ pub trait WeightInfo { /// Weights for pallet_scheduler using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn schedule(s: u32, ) -> Weight { (35_029_000 as Weight) .saturating_add((77_000 as Weight).saturating_mul(s as Weight)) diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 90d4aca4e42..afcac229367 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -37,7 +37,7 @@ //! from the `Pool` and `Members`; the entity is immediately replaced //! by the next highest scoring candidate in the pool, if available. //! -//! - [`scored_pool::Trait`](./trait.Trait.html) +//! - [`scored_pool::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -58,10 +58,10 @@ //! use frame_system::ensure_signed; //! use pallet_scored_pool::{self as scored_pool}; //! -//! pub trait Trait: scored_pool::Trait {} +//! pub trait Config: scored_pool::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn candidate(origin) -> dispatch::DispatchResult { //! let who = ensure_signed(origin)?; @@ -103,8 +103,8 @@ use frame_support::{ use frame_system::{ensure_root, ensure_signed}; use sp_runtime::traits::{AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}; -type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type PoolT = Vec<(::AccountId, Option<>::Score>)>; +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type PoolT = Vec<(::AccountId, Option<>::Score>)>; /// The enum is supplied when refreshing the members set. /// Depending on the enum variant the corresponding associated @@ -116,7 +116,7 @@ enum ChangeReceiver { MembershipChanged, } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The currency used for deposits. type Currency: Currency + ReservableCurrency; @@ -125,7 +125,7 @@ pub trait Trait: frame_system::Trait { AtLeast32Bit + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; // The deposit which is reserved from candidates if they want to // start a candidacy. The deposit gets returned when the candidacy is @@ -156,7 +156,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as ScoredPool { + trait Store for Module, I: Instance=DefaultInstance> as ScoredPool { /// The current pool of candidates, stored as an ordered Vec /// (ordered descending by score, `None` last, highest first). Pool get(fn pool) config(): PoolT; @@ -204,7 +204,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, { /// The given member was removed. See the transaction for who. MemberRemoved, @@ -225,7 +225,7 @@ decl_event!( decl_error! { /// Error for the scored-pool module. - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// Already a member. AlreadyInPool, /// Index out of bounds. @@ -236,7 +236,7 @@ decl_error! { } decl_module! { - pub struct Module, I: Instance=DefaultInstance> + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: T::Origin { @@ -275,7 +275,7 @@ decl_module! { // can be inserted as last element in pool, since entities with // `None` are always sorted to the end. - >::append((who.clone(), Option::<>::Score>::None)); + >::append((who.clone(), Option::<>::Score>::None)); >::insert(&who, true); @@ -382,7 +382,7 @@ decl_module! { } } -impl, I: Instance> Module { +impl, I: Instance> Module { /// Fetches the `MemberCount` highest scoring members from /// `Pool` and puts them into `Members`. diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 59c0dc66cca..537084bb394 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -49,7 +49,7 @@ ord_parameter_types! { pub const ScoreOrigin: u64 = 3; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -77,7 +77,7 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = (); @@ -114,7 +114,7 @@ impl InitializeMembers for TestChangeMembers { } } -impl Trait for Test { +impl Config for Test { type Event = (); type KickOrigin = EnsureSignedBy; type MembershipInitialized = TestChangeMembers; diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index 277200b2695..bd85b97c0d3 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -41,10 +41,10 @@ use sp_runtime::traits::{One, StaticLookup}; const MAX_VALIDATORS: u32 = 1000; -pub struct Module(pallet_session::Module); -pub trait Trait: pallet_session::Trait + pallet_session::historical::Trait + pallet_staking::Trait {} +pub struct Module(pallet_session::Module); +pub trait Config: pallet_session::Config + pallet_session::historical::Config + pallet_staking::Config {} -impl OnInitialize for Module { +impl OnInitialize for Module { fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight { pallet_session::Module::::on_initialize(n) } @@ -121,7 +121,7 @@ benchmarks! { /// Sets up the benchmark for checking a membership proof. It creates the given /// number of validators, sets random session keys and then creates a membership /// proof for the first authority and returns its key and the proof. -fn check_membership_proof_setup( +fn check_membership_proof_setup( n: u32, ) -> ( (sp_runtime::KeyTypeId, &'static [u8; 32]), diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 6a9cfc5f98a..af3112823d9 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -45,7 +45,7 @@ impl_outer_dispatch! { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; @@ -75,7 +75,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: Balance = 10; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = Balance; type Event = (); @@ -88,13 +88,13 @@ impl pallet_balances::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 5; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -120,7 +120,7 @@ impl pallet_session::SessionHandler for TestSessionHandler { fn on_disabled(_: usize) {} } -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions<(), ()>; @@ -157,7 +157,7 @@ impl frame_system::offchain::SendTransactionTypes for Test where type Extrinsic = Extrinsic; } -impl pallet_staking::Trait for Test { +impl pallet_staking::Config for Test { type Currency = Balances; type UnixTime = pallet_timestamp::Module; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; @@ -182,7 +182,7 @@ impl pallet_staking::Trait for Test { type WeightInfo = (); } -impl crate::Trait for Test {} +impl crate::Config for Test {} pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/frame/session/src/historical/mod.rs b/frame/session/src/historical/mod.rs index 20c3d57464c..53f4dd7639b 100644 --- a/frame/session/src/historical/mod.rs +++ b/frame/session/src/historical/mod.rs @@ -41,8 +41,8 @@ mod shared; pub mod offchain; pub mod onchain; -/// Trait necessary for the historical module. -pub trait Trait: super::Trait { +/// Config necessary for the historical module. +pub trait Config: super::Config { /// Full identification of the validator. type FullIdentification: Parameter; @@ -57,7 +57,7 @@ pub trait Trait: super::Trait { } decl_storage! { - trait Store for Module as Session { + trait Store for Module as Session { /// Mapping from historical session indices to session-data root hash and validator count. HistoricalSessions get(fn historical_root): map hasher(twox_64_concat) SessionIndex => Option<(T::Hash, ValidatorCount)>; @@ -71,10 +71,10 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin {} + pub struct Module for enum Call where origin: T::Origin {} } -impl Module { +impl Module { /// Prune historical stored session roots up to (but not including) /// `up_to`. pub fn prune_up_to(up_to: SessionIndex) { @@ -116,7 +116,7 @@ pub trait SessionManager: crate::SessionManager /// sets the historical trie root of the ending session. pub struct NoteHistoricalRoot(sp_std::marker::PhantomData<(T, I)>); -impl crate::SessionManager for NoteHistoricalRoot +impl crate::SessionManager for NoteHistoricalRoot where I: SessionManager { fn new_session(new_index: SessionIndex) -> Option> { @@ -160,15 +160,15 @@ impl crate::SessionManager for NoteHistoricalRoot = (::ValidatorId, ::FullIdentification); +pub type IdentificationTuple = (::ValidatorId, ::FullIdentification); /// A trie instance for checking and generating proofs. -pub struct ProvingTrie { +pub struct ProvingTrie { db: MemoryDB, root: T::Hash, } -impl ProvingTrie { +impl ProvingTrie { fn generate_for(validators: I) -> Result where I: IntoIterator { @@ -260,7 +260,7 @@ impl ProvingTrie { } } -impl> frame_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> +impl> frame_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> for Module { type Proof = MembershipProof; diff --git a/frame/session/src/historical/offchain.rs b/frame/session/src/historical/offchain.rs index 97655d1a18b..616cdede254 100644 --- a/frame/session/src/historical/offchain.rs +++ b/frame/session/src/historical/offchain.rs @@ -29,18 +29,18 @@ use sp_runtime::{offchain::storage::StorageValueRef, KeyTypeId}; use sp_session::MembershipProof; use super::super::{Module as SessionModule, SessionIndex}; -use super::{IdentificationTuple, ProvingTrie, Trait}; +use super::{IdentificationTuple, ProvingTrie, Config}; use super::shared; use sp_std::prelude::*; /// A set of validators, which was used for a fixed session index. -struct ValidatorSet { +struct ValidatorSet { validator_set: Vec>, } -impl ValidatorSet { +impl ValidatorSet { /// Load the set of validators for a particular session index from the off-chain storage. /// /// If none is found or decodable given `prefix` and `session`, it will return `None`. @@ -61,7 +61,7 @@ impl ValidatorSet { /// Implement conversion into iterator for usage /// with [ProvingTrie](super::ProvingTrie::generate_for). -impl sp_std::iter::IntoIterator for ValidatorSet { +impl sp_std::iter::IntoIterator for ValidatorSet { type Item = (T::ValidatorId, T::FullIdentification); type IntoIter = sp_std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { @@ -74,7 +74,7 @@ impl sp_std::iter::IntoIterator for ValidatorSet { /// Based on the yielded `MembershipProof` the implementer may decide what /// to do, i.e. in case of a failed proof, enqueue a transaction back on /// chain reflecting that, with all its consequences such as i.e. slashing. -pub fn prove_session_membership>( +pub fn prove_session_membership>( session_index: SessionIndex, session_key: (KeyTypeId, D), ) -> Option { @@ -97,7 +97,7 @@ pub fn prove_session_membership>( /// Due to re-organisation it could be that the `first_to_keep` might be less /// than the stored one, in which case the conservative choice is made to keep records /// up to the one that is the lesser. -pub fn prune_older_than(first_to_keep: SessionIndex) { +pub fn prune_older_than(first_to_keep: SessionIndex) { let derived_key = shared::LAST_PRUNE.to_vec(); let entry = StorageValueRef::persistent(derived_key.as_ref()); match entry.mutate(|current: Option>| -> Result<_, ()> { @@ -127,7 +127,7 @@ pub fn prune_older_than(first_to_keep: SessionIndex) { } /// Keep the newest `n` items, and prune all items older than that. -pub fn keep_newest(n_to_keep: usize) { +pub fn keep_newest(n_to_keep: usize) { let session_index = >::current_index(); let n_to_keep = n_to_keep as SessionIndex; if n_to_keep < session_index { @@ -189,8 +189,8 @@ mod tests { #[test] fn encode_decode_roundtrip() { use codec::{Decode, Encode}; - use super::super::super::Trait as SessionTrait; - use super::super::Trait as HistoricalTrait; + use super::super::super::Config as SessionTrait; + use super::super::Config as HistoricalTrait; let sample = ( 22u32 as ::ValidatorId, diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs index 745603a4982..dd6c9de9b58 100644 --- a/frame/session/src/historical/onchain.rs +++ b/frame/session/src/historical/onchain.rs @@ -20,9 +20,9 @@ use codec::Encode; use sp_runtime::traits::Convert; -use super::super::Trait as SessionTrait; +use super::super::Config as SessionTrait; use super::super::{Module as SessionModule, SessionIndex}; -use super::Trait as HistoricalTrait; +use super::Config as HistoricalTrait; use super::shared; use sp_std::prelude::*; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index c0a8fc29165..40ae5bed83e 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -20,7 +20,7 @@ //! The Session module allows validators to manage their session keys, provides a function for changing //! the session length, and handles session rotation. //! -//! - [`session::Trait`](./trait.Trait.html) +//! - [`session::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -88,7 +88,7 @@ //! ``` //! use pallet_session as session; //! -//! fn validators() -> Vec<::ValidatorId> { +//! fn validators() -> Vec<::ValidatorId> { //! >::validators() //! } //! # fn main(){} @@ -346,15 +346,15 @@ impl SessionHandler for TestSessionHandler { fn on_disabled(_: usize) {} } -impl ValidatorRegistration for Module { +impl ValidatorRegistration for Module { fn is_registered(id: &T::ValidatorId) -> bool { Self::load_keys(id).is_some() } } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// A stable ID for a validator. type ValidatorId: Member + Parameter; @@ -392,7 +392,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as Session { + trait Store for Module as Session { /// The current set of validators. Validators get(fn validators): Vec; @@ -483,7 +483,7 @@ decl_event!( decl_error! { /// Error for the session module. - pub enum Error for Module { + pub enum Error for Module { /// Invalid ownership proof. InvalidProof, /// No associated validator ID for account. @@ -496,7 +496,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -560,7 +560,7 @@ decl_module! { } } -impl Module { +impl Module { /// Move on to next session. Register new validator set and session keys. Changes /// to the validator set have a session of delay to take effect. This allows for /// equivocation punishment after a fork. @@ -776,7 +776,7 @@ impl Module { /// registering account-ID of that session key index. pub struct FindAccountFromAuthorIndex(sp_std::marker::PhantomData<(T, Inner)>); -impl> FindAuthor +impl> FindAuthor for FindAccountFromAuthorIndex { fn find_author<'a, I>(digests: I) -> Option @@ -789,7 +789,7 @@ impl> FindAuthor } } -impl EstimateNextNewSession for Module { +impl EstimateNextNewSession for Module { /// This session module always calls new_session and next_session at the same time, hence we /// do a simple proxy and pass the function to next rotation. fn estimate_next_new_session(now: T::BlockNumber) -> Option { diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 1d787ac53b4..d485565db23 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -172,7 +172,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -200,7 +200,7 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -211,7 +211,7 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); } -impl Trait for Test { +impl Config for Test { type ShouldEndSession = TestShouldEndSession; #[cfg(feature = "historical")] type SessionManager = crate::historical::NoteHistoricalRoot; @@ -228,7 +228,7 @@ impl Trait for Test { } #[cfg(feature = "historical")] -impl crate::historical::Trait for Test { +impl crate::historical::Config for Test { type FullIdentification = u64; type FullIdentificationOf = sp_runtime::traits::ConvertInto; } diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 75def78046b..36857824de8 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -285,7 +285,7 @@ fn session_keys_generate_output_works_as_set_keys_input() { assert_ok!( Session::set_keys( Origin::signed(2), - ::Keys::decode(&mut &new_keys[..]).expect("Decode keys"), + ::Keys::decode(&mut &new_keys[..]).expect("Decode keys"), vec![], ) ); diff --git a/frame/session/src/weights.rs b/frame/session/src/weights.rs index f1fc18b0ef9..243ddc04b08 100644 --- a/frame/session/src/weights.rs +++ b/frame/session/src/weights.rs @@ -50,7 +50,7 @@ pub trait WeightInfo { /// Weights for pallet_session using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn set_keys() -> Weight { (86_033_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index cbfe5a00de2..7859f6659cf 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -17,7 +17,7 @@ //! # Society Module //! -//! - [`society::Trait`](./trait.Trait.html) +//! - [`society::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -268,13 +268,13 @@ use frame_support::traits::{ }; use frame_system::{self as system, ensure_signed, ensure_root}; -type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; /// The module's configuration trait. -pub trait Trait: system::Trait { +pub trait Config: system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The societies's module id type ModuleId: Get; @@ -403,7 +403,7 @@ impl BidKind { // This module's storage items. decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Society { + trait Store for Module, I: Instance=DefaultInstance> as Society { /// The first member. pub Founder get(fn founder) build(|config: &GenesisConfig| config.members.first().cloned()): Option; @@ -472,7 +472,7 @@ decl_storage! { // The module's dispatchable functions. decl_module! { /// The module declaration. - pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: T::Origin { + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: T::Origin { type Error = Error; /// The minimum amount of a deposit required for a bid to be made. const CandidateDeposit: BalanceOf = T::CandidateDeposit::get(); @@ -1065,7 +1065,7 @@ decl_module! { decl_error! { /// Errors for this module. - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// An incorrect position was provided. BadPosition, /// User is not a member. @@ -1108,7 +1108,7 @@ decl_error! { decl_event! { /// Events for this module. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, Balance = BalanceOf { /// The society is founded by the given identity. \[founder\] @@ -1151,7 +1151,7 @@ decl_event! { /// Simple ensure origin struct to filter for the founder account. pub struct EnsureFounder(sp_std::marker::PhantomData); -impl EnsureOrigin for EnsureFounder { +impl EnsureOrigin for EnsureFounder { type Success = T::AccountId; fn try_origin(o: T::Origin) -> Result { o.into().and_then(|o| match (o, Founder::::get()) { @@ -1182,7 +1182,7 @@ fn pick_usize<'a, R: RngCore>(rng: &mut R, max: usize) -> usize { (rng.next_u32() % (max as u32 + 1)) as usize } -impl, I: Instance> Module { +impl, I: Instance> Module { /// Puts a bid into storage ordered by smallest to largest value. /// Allows a maximum of 1000 bids in queue, removing largest value people first. fn put_bid( @@ -1669,7 +1669,7 @@ impl, I: Instance> Module { } } -impl OnUnbalanced> for Module { +impl OnUnbalanced> for Module { fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { let numeric_amount = amount.peek(); diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 212bcfd404f..d4fa1bcfbc7 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -60,7 +60,7 @@ ord_parameter_types! { pub const SuspensionJudgementSetAccount: u128 = 2; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -88,7 +88,7 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = (); @@ -98,7 +98,7 @@ impl pallet_balances::Trait for Test { type WeightInfo = (); } -impl Trait for Test { +impl Config for Test { type Event = (); type Currency = pallet_balances::Module; type Randomness = TestRandomness; diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index 96df7674e9f..ac9a2b23579 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -43,7 +43,7 @@ impl_outer_dispatch! { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type DbWeight = (); @@ -73,7 +73,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: Balance = 10; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = Balance; type Event = (); @@ -82,7 +82,7 @@ impl pallet_balances::Trait for Test { type AccountStore = System; type WeightInfo = (); } -impl pallet_indices::Trait for Test { +impl pallet_indices::Config for Test { type AccountIndex = AccountIndex; type Event = (); type Currency = Balances; @@ -92,13 +92,13 @@ impl pallet_indices::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 5; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = pallet_staking::Exposure; type FullIdentificationOf = pallet_staking::ExposureOf; } @@ -124,7 +124,7 @@ impl pallet_session::SessionHandler for TestSessionHandler { fn on_disabled(_: usize) {} } -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions<(), ()>; @@ -161,7 +161,7 @@ impl frame_system::offchain::SendTransactionTypes for Test where type Extrinsic = Extrinsic; } -impl pallet_staking::Trait for Test { +impl pallet_staking::Config for Test { type Currency = Balances; type UnixTime = pallet_timestamp::Module; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 94a97debe4f..f6aedf760d9 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -31,7 +31,7 @@ const MAX_SLASHES: u32 = 1000; // Add slashing spans to a user account. Not relevant for actual use, only to benchmark // read and write operations. -fn add_slashing_spans(who: &T::AccountId, spans: u32) { +fn add_slashing_spans(who: &T::AccountId, spans: u32) { if spans == 0 { return } // For the first slashing span, we initialize @@ -48,7 +48,7 @@ fn add_slashing_spans(who: &T::AccountId, spans: u32) { // This function clears all existing validators and nominators from the set, and generates one new // validator being nominated by n nominators, and returns the validator stash account and the // nominators' stash and controller. It also starts an era and creates pending payouts. -pub fn create_validator_with_nominators( +pub fn create_validator_with_nominators( n: u32, upper_bound: u32, dead: bool, @@ -729,7 +729,7 @@ mod tests { let (validator_stash, nominators) = create_validator_with_nominators::( n, - ::MaxNominatorRewardedPerValidator::get() as u32, + ::MaxNominatorRewardedPerValidator::get() as u32, false, RewardDestination::Staked, ).unwrap(); @@ -753,7 +753,7 @@ mod tests { let (validator_stash, _nominators) = create_validator_with_nominators::( n, - ::MaxNominatorRewardedPerValidator::get() as u32, + ::MaxNominatorRewardedPerValidator::get() as u32, false, RewardDestination::Staked, ).unwrap(); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index e5aaae6bbb8..5f5f5ff2bb6 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -19,7 +19,7 @@ //! //! The Staking module is used to manage funds at stake by network maintainers. //! -//! - [`staking::Trait`](./trait.Trait.html) +//! - [`staking::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -107,7 +107,7 @@ //! //! Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the //! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to the -//! validator as well as its nominators. Only the [`Trait::MaxNominatorRewardedPerValidator`] +//! validator as well as its nominators. Only the [`Config::MaxNominatorRewardedPerValidator`] //! biggest stakers can claim their reward. This is to limit the i/o cost to mutate storage for each //! nominator's account. //! @@ -154,10 +154,10 @@ //! use frame_system::ensure_signed; //! use pallet_staking::{self as staking}; //! -//! pub trait Trait: staking::Trait {} +//! pub trait Config: staking::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! /// Reward a validator. //! #[weight = 0] //! pub fn reward_myself(origin) -> dispatch::DispatchResult { @@ -175,7 +175,7 @@ //! ### Era payout //! //! The era payout is computed using yearly inflation curve defined at -//! [`T::RewardCurve`](./trait.Trait.html#associatedtype.RewardCurve) as such: +//! [`T::RewardCurve`](./trait.Config.html#associatedtype.RewardCurve) as such: //! //! ```nocompile //! staker_payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year @@ -186,7 +186,7 @@ //! remaining_payout = max_yearly_inflation * total_tokens / era_per_year - staker_payout //! ``` //! The remaining reward is send to the configurable end-point -//! [`T::RewardRemainder`](./trait.Trait.html#associatedtype.RewardRemainder). +//! [`T::RewardRemainder`](./trait.Config.html#associatedtype.RewardRemainder). //! //! ### Reward Calculation //! @@ -232,7 +232,7 @@ //! //! The controller account can free a portion (or all) of the funds using the //! [`unbond`](enum.Call.html#variant.unbond) call. Note that the funds are not immediately -//! accessible. Instead, a duration denoted by [`BondingDuration`](./trait.Trait.html#associatedtype.BondingDuration) +//! accessible. Instead, a duration denoted by [`BondingDuration`](./trait.Config.html#associatedtype.BondingDuration) //! (in number of eras) must pass until the funds can actually be removed. Once the //! `BondingDuration` is over, the [`withdraw_unbonded`](./enum.Call.html#variant.withdraw_unbonded) //! call can be used to actually withdraw the funds. @@ -385,12 +385,12 @@ pub type OffchainAccuracy = PerU16; /// The balance type of this module. pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = - <::Currency as Currency<::AccountId>>::PositiveImbalance; + <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, RuntimeDebug)] @@ -732,8 +732,8 @@ impl Default for ElectionStatus { /// Means for interacting with a specialized version of the `session` trait. /// -/// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Trait` -pub trait SessionInterface: frame_system::Trait { +/// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Config` +pub trait SessionInterface: frame_system::Config { /// Disable a given validator by stash ID. /// /// Returns `true` if new era should be forced at the end of this session. @@ -746,22 +746,22 @@ pub trait SessionInterface: frame_system::Trait { fn prune_historical_up_to(up_to: SessionIndex); } -impl SessionInterface<::AccountId> for T where - T: pallet_session::Trait::AccountId>, - T: pallet_session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, +impl SessionInterface<::AccountId> for T where + T: pallet_session::Config::AccountId>, + T: pallet_session::historical::Config< + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: - Convert<::AccountId, Option<::AccountId>>, + Convert<::AccountId, Option<::AccountId>>, { - fn disable_validator(validator: &::AccountId) -> Result { + fn disable_validator(validator: &::AccountId) -> Result { >::disable(validator) } - fn validators() -> Vec<::AccountId> { + fn validators() -> Vec<::AccountId> { >::validators() } @@ -770,7 +770,7 @@ impl SessionInterface<::AccountId> for T whe } } -pub trait Trait: frame_system::Trait + SendTransactionTypes> { +pub trait Config: frame_system::Config + SendTransactionTypes> { /// The staking balance. type Currency: LockableCurrency; @@ -792,7 +792,7 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { type RewardRemainder: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced reduction when slashing a staker. type Slash: OnUnbalanced>; @@ -904,7 +904,7 @@ impl Default for Releases { } decl_storage! { - trait Store for Module as Staking { + trait Store for Module as Staking { /// Number of eras to keep in history. /// /// Information is kept for eras in `[current_era - history_depth; current_era]`. @@ -1121,7 +1121,7 @@ decl_storage! { } decl_event!( - pub enum Event where Balance = BalanceOf, ::AccountId { + pub enum Event where Balance = BalanceOf, ::AccountId { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. /// \[era_index, validator_payout, remainder\] @@ -1153,7 +1153,7 @@ decl_event!( decl_error! { /// Error for the staking module. - pub enum Error for Module { + pub enum Error for Module { /// Not a controller account. NotController, /// Not a stash account. @@ -1223,7 +1223,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// Number of sessions per era. const SessionsPerEra: SessionIndex = T::SessionsPerEra::get(); @@ -2159,7 +2159,7 @@ decl_module! { } } -impl Module { +impl Module { /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { // Weight note: consider making the stake accessible through stash. @@ -3083,7 +3083,7 @@ impl Module { /// /// Once the first new_session is planned, all session must start and then end in order, though /// some session can lag in between the newest session planned and the latest session started. -impl pallet_session::SessionManager for Module { +impl pallet_session::SessionManager for Module { fn new_session(new_index: SessionIndex) -> Option> { Self::new_session(new_index) } @@ -3095,7 +3095,7 @@ impl pallet_session::SessionManager for Module { } } -impl historical::SessionManager>> for Module { +impl historical::SessionManager>> for Module { fn new_session(new_index: SessionIndex) -> Option>)>> { @@ -3124,7 +3124,7 @@ impl historical::SessionManager pallet_authorship::EventHandler for Module where - T: Trait + pallet_authorship::Trait + pallet_session::Trait + T: Config + pallet_authorship::Config + pallet_session::Config { fn note_author(author: T::AccountId) { Self::reward_by_ids(vec![(author, 20)]) @@ -3141,7 +3141,7 @@ impl pallet_authorship::EventHandler for Module /// if any. pub struct StashOf(sp_std::marker::PhantomData); -impl Convert> for StashOf { +impl Convert> for StashOf { fn convert(controller: T::AccountId) -> Option { >::ledger(&controller).map(|l| l.stash) } @@ -3154,7 +3154,7 @@ impl Convert> for StashOf { /// `active_era`. It can differ from the latest planned exposure in `current_era`. pub struct ExposureOf(sp_std::marker::PhantomData); -impl Convert>>> +impl Convert>>> for ExposureOf { fn convert(validator: T::AccountId) -> Option>> { @@ -3167,19 +3167,19 @@ impl Convert> } /// This is intended to be used with `FilterHistoricalOffences`. -impl +impl OnOffenceHandler, Weight> for Module where - T: pallet_session::Trait::AccountId>, - T: pallet_session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, + T: pallet_session::Config::AccountId>, + T: pallet_session::historical::Config< + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert< - ::AccountId, - Option<::AccountId>, + ::AccountId, + Option<::AccountId>, >, { fn on_offence( @@ -3310,7 +3310,7 @@ pub struct FilterHistoricalOffences { impl ReportOffence for FilterHistoricalOffences, R> where - T: Trait, + T: Config, R: ReportOffence, O: Offence, { @@ -3335,7 +3335,7 @@ impl ReportOffence } #[allow(deprecated)] -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { if let Call::submit_election_solution_unsigned( diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 3aa3e9ae03d..4bc1921c494 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -141,7 +141,7 @@ parameter_types! { pub static MaxIterations: u32 = 0; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; @@ -168,7 +168,7 @@ impl frame_system::Trait for Test { type OnKilledAccount = (); type SystemWeightInfo = (); } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = MaxLocks; type Balance = Balance; type Event = MetaEvent; @@ -187,7 +187,7 @@ sp_runtime::impl_opaque_keys! { pub other: OtherSessionHandler, } } -impl pallet_session::Trait for Test { +impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; type ShouldEndSession = pallet_session::PeriodicSessions; @@ -200,11 +200,11 @@ impl pallet_session::Trait for Test { type WeightInfo = (); } -impl pallet_session::historical::Trait for Test { +impl pallet_session::historical::Config for Test { type FullIdentification = crate::Exposure; type FullIdentificationOf = crate::ExposureOf; } -impl pallet_authorship::Trait for Test { +impl pallet_authorship::Config for Test { type FindAuthor = Author11; type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -213,7 +213,7 @@ impl pallet_authorship::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 5; } -impl pallet_timestamp::Trait for Test { +impl pallet_timestamp::Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -253,7 +253,7 @@ impl OnUnbalanced> for RewardRemainderMock { } } -impl Trait for Test { +impl Config for Test { type Currency = Balances; type UnixTime = Timestamp; type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote; @@ -659,7 +659,7 @@ pub(crate) fn start_era(era_index: EraIndex) { pub(crate) fn current_total_payout_for_duration(duration: u64) -> Balance { inflation::compute_total_payout( - ::RewardCurve::get(), + ::RewardCurve::get(), Staking::eras_total_stake(Staking::active_era().unwrap().index), Balances::total_issuance(), duration, @@ -667,7 +667,7 @@ pub(crate) fn current_total_payout_for_duration(duration: u64) -> Balance { } pub(crate) fn reward_all_elected() { - let rewards = ::SessionInterface::validators() + let rewards = ::SessionInterface::validators() .into_iter() .map(|v| (v, 1)); diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index cb4d460f680..35d9fa7c1f8 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -19,7 +19,7 @@ use crate::{ Call, CompactAssignments, ElectionSize, Module, NominatorIndex, Nominators, OffchainAccuracy, - Trait, ValidatorIndex, WeightInfo, + Config, ValidatorIndex, WeightInfo, }; use codec::Decode; use frame_support::{traits::Get, weights::Weight, IterableStorageMap}; @@ -71,7 +71,7 @@ pub(crate) const DEFAULT_LONGEVITY: u64 = 25; /// don't run twice within a window of length [`OFFCHAIN_REPEAT`]. /// /// Returns `Ok(())` if offchain worker should happen, `Err(reason)` otherwise. -pub(crate) fn set_check_offchain_execution_status( +pub(crate) fn set_check_offchain_execution_status( now: T::BlockNumber, ) -> Result<(), &'static str> { let storage = StorageValueRef::persistent(&OFFCHAIN_HEAD_DB); @@ -108,7 +108,7 @@ pub(crate) fn set_check_offchain_execution_status( /// The internal logic of the offchain worker of this module. This runs the phragmen election, /// compacts and reduces the solution, computes the score and submits it back to the chain as an /// unsigned transaction, without any signature. -pub(crate) fn compute_offchain_election() -> Result<(), OffchainElectionError> { +pub(crate) fn compute_offchain_election() -> Result<(), OffchainElectionError> { let iters = get_balancing_iters::(); // compute raw solution. Note that we use `OffchainAccuracy`. let ElectionResult { @@ -151,7 +151,7 @@ pub(crate) fn compute_offchain_election() -> Result<(), OffchainElecti /// Get a random number of iterations to run the balancing. /// /// Uses the offchain seed to generate a random number. -pub fn get_balancing_iters() -> usize { +pub fn get_balancing_iters() -> usize { match T::MaxIterations::get() { 0 => 0, max @ _ => { @@ -257,7 +257,7 @@ pub fn maximum_compact_len( /// /// Indeed, the score must be computed **after** this step. If this step reduces the score too much, /// then the solution will be discarded. -pub fn trim_to_weight( +pub fn trim_to_weight( maximum_allowed_voters: u32, mut compact: CompactAssignments, nominator_index: FN, @@ -318,7 +318,7 @@ where /// Takes an election result and spits out some data that can be submitted to the chain. /// /// This does a lot of stuff; read the inline comments. -pub fn prepare_submission( +pub fn prepare_submission( assignments: Vec>, winners: Vec<(T::AccountId, ExtendedBalance)>, do_reduce: bool, diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index af9a92f16a4..b1f0c9d9a44 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -50,7 +50,7 @@ //! Based on research at https://research.web3.foundation/en/latest/polkadot/slashing/npos/ use super::{ - EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, + EraIndex, Config, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, NegativeImbalanceOf, UnappliedSlash, Error, }; use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug, DispatchResult}; @@ -190,7 +190,7 @@ impl SpanRecord { /// Parameters for performing a slash. #[derive(Clone)] -pub(crate) struct SlashParams<'a, T: 'a + Trait> { +pub(crate) struct SlashParams<'a, T: 'a + Config> { /// The stash account being slashed. pub(crate) stash: &'a T::AccountId, /// The proportion of the slash. @@ -214,7 +214,7 @@ pub(crate) struct SlashParams<'a, T: 'a + Trait> { /// /// The pending slash record returned does not have initialized reporters. Those have /// to be set at a higher level, if any. -pub(crate) fn compute_slash(params: SlashParams) +pub(crate) fn compute_slash(params: SlashParams) -> Option>> { let SlashParams { @@ -309,7 +309,7 @@ pub(crate) fn compute_slash(params: SlashParams) // doesn't apply any slash, but kicks out the validator if the misbehavior is from // the most recent slashing span. -fn kick_out_if_recent( +fn kick_out_if_recent( params: SlashParams, ) { // these are not updated by era-span or end-span. @@ -338,7 +338,7 @@ fn kick_out_if_recent( /// Slash nominators. Accepts general parameters and the prior slash percentage of the validator. /// /// Returns the amount of reward to pay out. -fn slash_nominators( +fn slash_nominators( params: SlashParams, prior_slash_p: Perbill, nominators_slashed: &mut Vec<(T::AccountId, BalanceOf)>, @@ -418,7 +418,7 @@ fn slash_nominators( // dropping this struct applies any necessary slashes, which can lead to free balance // being 0, and the account being garbage-collected -- a dead account should get no new // metadata. -struct InspectingSpans<'a, T: Trait + 'a> { +struct InspectingSpans<'a, T: Config + 'a> { dirty: bool, window_start: EraIndex, stash: &'a T::AccountId, @@ -430,7 +430,7 @@ struct InspectingSpans<'a, T: Trait + 'a> { } // fetches the slashing spans record for a stash account, initializing it if necessary. -fn fetch_spans<'a, T: Trait + 'a>( +fn fetch_spans<'a, T: Config + 'a>( stash: &'a T::AccountId, window_start: EraIndex, paid_out: &'a mut BalanceOf, @@ -455,7 +455,7 @@ fn fetch_spans<'a, T: Trait + 'a>( } } -impl<'a, T: 'a + Trait> InspectingSpans<'a, T> { +impl<'a, T: 'a + Config> InspectingSpans<'a, T> { fn span_index(&self) -> SpanIndex { self.spans.span_index } @@ -526,7 +526,7 @@ impl<'a, T: 'a + Trait> InspectingSpans<'a, T> { } } -impl<'a, T: 'a + Trait> Drop for InspectingSpans<'a, T> { +impl<'a, T: 'a + Config> Drop for InspectingSpans<'a, T> { fn drop(&mut self) { // only update on disk if we slashed this account. if !self.dirty { return } @@ -542,13 +542,13 @@ impl<'a, T: 'a + Trait> Drop for InspectingSpans<'a, T> { } /// Clear slashing metadata for an obsolete era. -pub(crate) fn clear_era_metadata(obsolete_era: EraIndex) { +pub(crate) fn clear_era_metadata(obsolete_era: EraIndex) { as Store>::ValidatorSlashInEra::remove_prefix(&obsolete_era); as Store>::NominatorSlashInEra::remove_prefix(&obsolete_era); } /// Clear slashing metadata for a dead account. -pub(crate) fn clear_stash_metadata( +pub(crate) fn clear_stash_metadata( stash: &T::AccountId, num_slashing_spans: u32, ) -> DispatchResult { @@ -576,7 +576,7 @@ pub(crate) fn clear_stash_metadata( // apply the slash to a stash account, deducting any missing funds from the reward // payout, saturating at 0. this is mildly unfair but also an edge-case that // can only occur when overlapping locked funds have been slashed. -pub fn do_slash( +pub fn do_slash( stash: &T::AccountId, value: BalanceOf, reward_payout: &mut BalanceOf, @@ -613,7 +613,7 @@ pub fn do_slash( } /// Apply a previously-unapplied slash. -pub(crate) fn apply_slash(unapplied_slash: UnappliedSlash>) { +pub(crate) fn apply_slash(unapplied_slash: UnappliedSlash>) { let mut slashed_imbalance = NegativeImbalanceOf::::zero(); let mut reward_payout = unapplied_slash.payout; @@ -638,7 +638,7 @@ pub(crate) fn apply_slash(unapplied_slash: UnappliedSlash( +fn pay_reporters( reward_payout: BalanceOf, slashed_imbalance: NegativeImbalanceOf, reporters: &[T::AccountId], diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index 25cfffeac2c..9b6df1f2d48 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -29,13 +29,13 @@ use sp_npos_elections::*; const SEED: u32 = 0; /// This function removes all validators and nominators from storage. -pub fn clear_validators_and_nominators() { +pub fn clear_validators_and_nominators() { Validators::::remove_all(); Nominators::::remove_all(); } /// Grab a funded user. -pub fn create_funded_user( +pub fn create_funded_user( string: &'static str, n: u32, balance_factor: u32, @@ -49,7 +49,7 @@ pub fn create_funded_user( } /// Create a stash and controller pair. -pub fn create_stash_controller( +pub fn create_stash_controller( n: u32, balance_factor: u32, destination: RewardDestination, @@ -66,7 +66,7 @@ pub fn create_stash_controller( /// Create a stash and controller pair, where the controller is dead, and payouts go to controller. /// This is used to test worst case payout scenarios. -pub fn create_stash_and_dead_controller( +pub fn create_stash_and_dead_controller( n: u32, balance_factor: u32, destination: RewardDestination, @@ -83,7 +83,7 @@ pub fn create_stash_and_dead_controller( } /// create `max` validators. -pub fn create_validators( +pub fn create_validators( max: u32, balance_factor: u32, ) -> Result::Source>, &'static str> { @@ -115,7 +115,7 @@ pub fn create_validators( /// Else, all of them are considered and `edge_per_nominator` random validators are voted for. /// /// Return the validators choosen to be nominated. -pub fn create_validators_with_nominators_for_era( +pub fn create_validators_with_nominators_for_era( validators: u32, nominators: u32, edge_per_nominator: usize, @@ -173,7 +173,7 @@ pub fn create_validators_with_nominators_for_era( /// Build a _really bad_ but acceptable solution for election. This should always yield a solution /// which has a less score than the seq-phragmen. -pub fn get_weak_solution( +pub fn get_weak_solution( do_reduce: bool, ) -> (Vec, CompactAssignments, ElectionScore, ElectionSize) { let mut backing_stake_of: BTreeMap> = BTreeMap::new(); @@ -282,7 +282,7 @@ pub fn get_weak_solution( /// Create a solution for seq-phragmen. This uses the same internal function as used by the offchain /// worker code. -pub fn get_seq_phragmen_solution( +pub fn get_seq_phragmen_solution( do_reduce: bool, ) -> ( Vec, @@ -307,7 +307,7 @@ pub fn get_seq_phragmen_solution( } /// Returns a solution in which only one winner is elected with just a self vote. -pub fn get_single_winner_solution( +pub fn get_single_winner_solution( winner: T::AccountId, ) -> Result< ( @@ -352,7 +352,7 @@ pub fn get_single_winner_solution( } /// get the active era. -pub fn current_era() -> EraIndex { +pub fn current_era() -> EraIndex { >::current_era().unwrap_or(0) } @@ -366,7 +366,7 @@ pub fn init_active_era() { /// Create random assignments for the given list of winners. Each assignment will have /// MAX_NOMINATIONS edges. -pub fn create_assignments_for_offchain( +pub fn create_assignments_for_offchain( num_assignments: u32, winners: Vec<::Source>, ) -> Result< diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 2a02d87aa2c..c50964a33bb 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -3267,7 +3267,7 @@ mod offchain_election { ElectionSize::default(), ), Error::::OffchainElectionEarlySubmission, - Some(::DbWeight::get().reads(1)), + Some(::DbWeight::get().reads(1)), ); }) } @@ -3303,7 +3303,7 @@ mod offchain_election { score, ), Error::::OffchainElectionWeakSubmission, - Some(::DbWeight::get().reads(3)) + Some(::DbWeight::get().reads(3)) ); }) } @@ -4340,7 +4340,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( // then the nominator can't claim its reward // * A nominator can't claim another nominator reward ExtBuilder::default().build_and_execute(|| { - for i in 0..=::MaxNominatorRewardedPerValidator::get() { + for i in 0..=::MaxNominatorRewardedPerValidator::get() { let stash = 10_000 + i as AccountId; let controller = 20_000 + i as AccountId; let balance = 10_000 + i as Balance; @@ -4366,7 +4366,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( mock::make_all_reward_payment(1); // Assert only nominators from 1 to Max are rewarded - for i in 0..=::MaxNominatorRewardedPerValidator::get() { + for i in 0..=::MaxNominatorRewardedPerValidator::get() { let stash = 10_000 + i as AccountId; let balance = 10_000 + i as Balance; if stash == 10_000 { @@ -4569,14 +4569,14 @@ fn bond_during_era_correctly_populates_claimed_rewards() { fn offences_weight_calculated_correctly() { ExtBuilder::default().nominate(true).build_and_execute(|| { // On offence with zero offenders: 4 Reads, 1 Write - let zero_offence_weight = ::DbWeight::get().reads_writes(4, 1); + let zero_offence_weight = ::DbWeight::get().reads_writes(4, 1); assert_eq!(Staking::on_offence(&[], &[Perbill::from_percent(50)], 0), Ok(zero_offence_weight)); // On Offence with N offenders, Unapplied: 4 Reads, 1 Write + 4 Reads, 5 Writes - let n_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) - + ::DbWeight::get().reads_writes(4, 5); + let n_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(4, 5); - let offenders: Vec::AccountId, pallet_session::historical::IdentificationTuple>> + let offenders: Vec::AccountId, pallet_session::historical::IdentificationTuple>> = (1..10).map(|i| OffenceDetails { offender: (i, Staking::eras_stakers(Staking::active_era().unwrap().index, i)), @@ -4595,14 +4595,14 @@ fn offences_weight_calculated_correctly() { let n = 1; // Number of offenders let rw = 3 + 3 * n; // rw reads and writes - let one_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) - + ::DbWeight::get().reads_writes(rw, rw) + let one_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(rw, rw) // One `slash_cost` - + ::DbWeight::get().reads_writes(6, 5) + + ::DbWeight::get().reads_writes(6, 5) // `slash_cost` * nominators (1) - + ::DbWeight::get().reads_writes(6, 5) + + ::DbWeight::get().reads_writes(6, 5) // `reward_cost` * reporters (1) - + ::DbWeight::get().reads_writes(2, 2); + + ::DbWeight::get().reads_writes(2, 2); assert_eq!(Staking::on_offence(&one_offender, &[Perbill::from_percent(50)], 0), Ok(one_offence_unapplied_weight)); }); @@ -4614,7 +4614,7 @@ fn on_initialize_weight_is_correct() { assert_eq!(Validators::::iter().count(), 0); assert_eq!(Nominators::::iter().count(), 0); // When this pallet has nothing, we do 4 reads each block - let base_weight = ::DbWeight::get().reads(4); + let base_weight = ::DbWeight::get().reads(4); assert_eq!(base_weight, Staking::on_initialize(0)); }); @@ -4636,7 +4636,7 @@ fn on_initialize_weight_is_correct() { // With 4 validators and 5 nominator, we should increase weight by: // - (4 + 5) reads // - 3 Writes - let final_weight = ::DbWeight::get().reads_writes(4 + 9, 3); + let final_weight = ::DbWeight::get().reads_writes(4 + 9, 3); assert_eq!(final_weight, Staking::on_initialize(System::block_number())); }); } diff --git a/frame/staking/src/weights.rs b/frame/staking/src/weights.rs index cb301276e0f..2e715c53356 100644 --- a/frame/staking/src/weights.rs +++ b/frame/staking/src/weights.rs @@ -72,7 +72,7 @@ pub trait WeightInfo { /// Weights for pallet_staking using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn bond() -> Weight { (99_659_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 7629355d98d..e8a13c8b00f 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -17,7 +17,7 @@ //! # Sudo Module //! -//! - [`sudo::Trait`](./trait.Trait.html) +//! - [`sudo::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -55,10 +55,10 @@ //! use frame_support::{decl_module, dispatch}; //! use frame_system::ensure_root; //! -//! pub trait Trait: frame_system::Trait {} +//! pub trait Config: frame_system::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn privileged_function(origin) -> dispatch::DispatchResult { //! ensure_root(origin)?; @@ -82,7 +82,7 @@ //! * [Democracy](../pallet_democracy/index.html) //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html //! [`Origin`]: https://docs.substrate.dev/docs/substrate-types #![cfg_attr(not(feature = "std"), no_std)] @@ -105,9 +105,9 @@ mod mock; #[cfg(test)] mod tests; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A sudo-able call. type Call: Parameter + UnfilteredDispatchable + GetDispatchInfo; @@ -115,7 +115,7 @@ pub trait Trait: frame_system::Trait { decl_module! { /// Sudo module declaration. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; fn deposit_event() = default; @@ -131,7 +131,7 @@ decl_module! { /// - Weight of derivative `call` execution + 10,000. /// # #[weight = (call.get_dispatch_info().weight + 10_000, call.get_dispatch_info().class)] - fn sudo(origin, call: Box<::Call>) -> DispatchResultWithPostInfo { + fn sudo(origin, call: Box<::Call>) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); @@ -153,7 +153,7 @@ decl_module! { /// - The weight of this call is defined by the caller. /// # #[weight = (*_weight, call.get_dispatch_info().class)] - fn sudo_unchecked_weight(origin, call: Box<::Call>, _weight: Weight) -> DispatchResultWithPostInfo { + fn sudo_unchecked_weight(origin, call: Box<::Call>, _weight: Weight) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); @@ -206,7 +206,7 @@ decl_module! { )] fn sudo_as(origin, who: ::Source, - call: Box<::Call> + call: Box<::Call> ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; @@ -224,7 +224,7 @@ decl_module! { } decl_event!( - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// A sudo just took place. \[result\] Sudid(DispatchResult), /// The \[sudoer\] just switched identity; the old key is supplied. @@ -235,7 +235,7 @@ decl_event!( ); decl_storage! { - trait Store for Module as Sudo { + trait Store for Module as Sudo { /// The `AccountId` of the sudo key. Key get(fn key) config(): T::AccountId; } @@ -243,7 +243,7 @@ decl_storage! { decl_error! { /// Error for the Sudo module - pub enum Error for Module { + pub enum Error for Module { /// Sender must be the Sudo account RequireSudo, } diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index 7996cd05d07..c21f7895264 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -33,26 +33,26 @@ pub mod logger { use super::*; use frame_system::ensure_root; - pub trait Trait: frame_system::Trait { - type Event: From> + Into<::Event>; + pub trait Config: frame_system::Config { + type Event: From> + Into<::Event>; } decl_storage! { - trait Store for Module as Logger { + trait Store for Module as Logger { AccountLog get(fn account_log): Vec; I32Log get(fn i32_log): Vec; } } decl_event! { - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { AppendI32(i32, Weight), AppendI32AndAccount(AccountId, i32, Weight), } } decl_module! { - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { fn deposit_event() = default; #[weight = *weight] @@ -118,7 +118,7 @@ impl Filter for BlockEverything { } } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BlockEverything; type Origin = Origin; type Call = Call; @@ -146,13 +146,13 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -// Implement the logger module's `Trait` on the Test runtime. -impl logger::Trait for Test { +// Implement the logger module's `Config` on the Test runtime. +impl logger::Config for Test { type Event = TestEvent; } -// Implement the sudo module's `Trait` on the Test runtime. -impl Trait for Test { +// Implement the sudo module's `Config` on the Test runtime. +impl Config for Test { type Event = TestEvent; type Call = Call; } diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index a6fb58846cb..8d3d1ce5900 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -35,7 +35,7 @@ use proc_macro::TokenStream; /// /// ```nocompile /// decl_storage! { -/// trait Store for Module as Example { +/// trait Store for Module as Example { /// Foo get(fn foo) config(): u32=12; /// Bar: map hasher(identity) u32 => u32; /// pub Zed build(|config| vec![(0, 0)]): map hasher(identity) u32 => u32; @@ -43,7 +43,7 @@ use proc_macro::TokenStream; /// } /// ``` /// -/// Declaration is set with the header `(pub) trait Store for Module as Example`, +/// Declaration is set with the header `(pub) trait Store for Module as Example`, /// with `Store` a (pub) trait generated associating each storage item to the `Module` and /// `as Example` setting the prefix used for storage items of this module. `Example` must be unique: /// another module with the same name and the same inner storage item name will conflict. @@ -169,7 +169,7 @@ use proc_macro::TokenStream; /// /// ```nocompile /// decl_storage! { -/// trait Store for Module as Example { +/// trait Store for Module as Example { /// /// // Your storage items /// } @@ -202,7 +202,7 @@ use proc_macro::TokenStream; /// (`DefaultInstance` type is optional): /// /// ```nocompile -/// trait Store for Module, I: Instance=DefaultInstance> as Example {} +/// trait Store for Module, I: Instance=DefaultInstance> as Example {} /// ``` /// /// Accessing the structure no requires the instance as generic parameter: @@ -214,7 +214,7 @@ use proc_macro::TokenStream; /// This macro supports a where clause which will be replicated to all generated types. /// /// ```nocompile -/// trait Store for Module as Example where T::AccountId: std::fmt::Display {} +/// trait Store for Module as Example where T::AccountId: std::fmt::Display {} /// ``` /// /// ## Limitations diff --git a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs index 6339134ea0d..93543075a3d 100644 --- a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -33,11 +33,11 @@ pub struct GenesisConfigFieldDef { pub struct GenesisConfigDef { pub is_generic: bool, pub fields: Vec, - /// For example: `, I: Instance=DefaultInstance>`. + /// For example: `, I: Instance=DefaultInstance>`. pub genesis_struct_decl: TokenStream, /// For example: ``. pub genesis_struct: TokenStream, - /// For example: `, I: Instance>`. + /// For example: `, I: Instance>`. pub genesis_impl: TokenStream, /// The where clause to use to constrain generics if genesis config is generic. pub genesis_where_clause: Option, diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 0aa0a3cad7c..bc23dad74bc 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -42,7 +42,7 @@ pub struct DeclStorageDef { module_name: syn::Ident, /// Usually `T`. module_runtime_generic: syn::Ident, - /// Usually `Trait` + /// Usually `Config` module_runtime_trait: syn::Path, /// For instantiable module: usually `I: Instance=DefaultInstance`. module_instance: Option, @@ -77,7 +77,7 @@ pub struct DeclStorageDefExt { module_name: syn::Ident, /// Usually `T`. module_runtime_generic: syn::Ident, - /// Usually `Trait`. + /// Usually `Config`. module_runtime_trait: syn::Path, /// For instantiable module: usually `I: Instance=DefaultInstance`. module_instance: Option, @@ -93,7 +93,7 @@ pub struct DeclStorageDefExt { crate_name: syn::Ident, /// Full struct expansion: `Module`. module_struct: proc_macro2::TokenStream, - /// Impl block for module: ``. + /// Impl block for module: ``. module_impl: proc_macro2::TokenStream, /// For instantiable: `I`. optional_instance: Option, @@ -212,7 +212,7 @@ pub struct StorageLineDefExt { storage_struct: proc_macro2::TokenStream, /// If storage is generic over runtime then `T`. optional_storage_runtime_comma: Option, - /// If storage is generic over runtime then `T: Trait`. + /// If storage is generic over runtime then `T: Config`. optional_storage_runtime_bound_comma: Option, /// The where clause to use to constrain generics if storage is generic over runtime. optional_storage_where_clause: Option, diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index d55faa28d11..2477f9421ff 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -72,9 +72,9 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{Trait, ensure_signed}; +/// # use frame_system::{Config, ensure_signed}; /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// /// // Private functions are dispatchable, but not available to other /// // FRAME pallets. @@ -98,7 +98,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// /// The declaration is set with the header where: /// -/// * `Module`: The struct generated by the macro, with type `Trait`. +/// * `Module`: The struct generated by the macro, with type `Config`. /// * `Call`: The enum generated for every pallet, which implements [`Callable`](./dispatch/trait.Callable.html). /// * `origin`: Alias of `T::Origin`, declared by the [`impl_outer_origin!`](./macro.impl_outer_origin.html) macro. /// * `Result`: The expected return type from pallet functions. @@ -114,9 +114,9 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{Trait, ensure_signed}; +/// # use frame_system::{Config, ensure_signed}; /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 0] /// fn my_long_function(origin) -> dispatch::DispatchResult { /// // Your implementation @@ -149,9 +149,9 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo}; -/// # use frame_system::{Trait, ensure_signed}; +/// # use frame_system::{Config, ensure_signed}; /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 1_000_000] /// fn my_long_function(origin, do_expensive_calc: bool) -> DispatchResultWithPostInfo { /// ensure_signed(origin).map_err(|e| e.with_weight(100_000))?; @@ -178,9 +178,9 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::transactional; -/// # use frame_system::Trait; +/// # use frame_system::Config; /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 0] /// #[transactional] /// fn my_short_function(origin) { @@ -199,9 +199,9 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{Trait, ensure_signed, ensure_root}; +/// # use frame_system::{Config, ensure_signed, ensure_root}; /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 0] /// fn my_privileged_function(origin) -> dispatch::DispatchResult { /// ensure_root(origin)?; @@ -236,10 +236,10 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # pub struct DefaultInstance; /// # pub trait Instance: 'static {} /// # impl Instance for DefaultInstance {} -/// pub trait Trait: frame_system::Trait {} +/// pub trait Config: frame_system::Config {} /// /// decl_module! { -/// pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { +/// pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { /// // Your implementation /// } /// } @@ -261,10 +261,10 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # extern crate frame_support; /// # use frame_support::dispatch; /// # use frame_system::{self as system, ensure_signed}; -/// pub trait Trait: system::Trait where Self::AccountId: From {} +/// pub trait Config: system::Config where Self::AccountId: From {} /// /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { +/// pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// // Your implementation /// } /// } @@ -1272,11 +1272,11 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn on_initialize() -> $return:ty { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_initialize(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) -> $return { + fn on_initialize(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) -> $return { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_initialize")); { $( $impl )* } } @@ -1289,8 +1289,8 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn on_initialize($param:ident : $param_ty:ty) -> $return:ty { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize($param: $param_ty) -> $return { @@ -1305,8 +1305,8 @@ macro_rules! decl_module { $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1326,10 +1326,10 @@ macro_rules! decl_module { let result: $return = (|| { $( $impl )* })(); $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); let additional_write = < - <$trait_instance as $system::Trait>::DbWeight as $crate::traits::Get<_> + <$trait_instance as $system::Config>::DbWeight as $crate::traits::Get<_> >::get().writes(1); result.saturating_add(additional_write) @@ -1350,10 +1350,10 @@ macro_rules! decl_module { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_runtime_upgrade")); $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); < - <$trait_instance as $system::Trait>::DbWeight as $crate::traits::Get<_> + <$trait_instance as $system::Config>::DbWeight as $crate::traits::Get<_> >::get().writes(1) } } @@ -1394,11 +1394,11 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn on_finalize() { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_finalize(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) { + fn on_finalize(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_finalize")); { $( $impl )* } } @@ -1411,8 +1411,8 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn on_finalize($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize($param: $param_ty) { @@ -1427,8 +1427,8 @@ macro_rules! decl_module { $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { } @@ -1440,11 +1440,11 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn offchain_worker() { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn offchain_worker(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) { $( $impl )* } + fn offchain_worker(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) { $( $impl )* } } }; @@ -1454,8 +1454,8 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } fn offchain_worker($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn offchain_worker($param: $param_ty) { $( $impl )* } @@ -1467,8 +1467,8 @@ macro_rules! decl_module { $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; { $( $other_where_bounds:tt )* } ) => { - impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + impl<$trait_instance: $system::Config + $trait_name$(, $instance: $instantiable)?> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1824,7 +1824,7 @@ macro_rules! decl_module { fn storage_version() -> Option<$crate::traits::PalletVersion> { let key = $crate::traits::PalletVersion::storage_key::< - <$trait_instance as $system::Trait>::PalletInfo, Self + <$trait_instance as $system::Config>::PalletInfo, Self >().expect("Every active pallet has a name in the runtime; qed"); $crate::storage::unhashed::get(&key) @@ -1837,7 +1837,7 @@ macro_rules! decl_module { { fn on_genesis() { $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); } } @@ -2019,7 +2019,7 @@ macro_rules! impl_outer_dispatch { } impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; - type Trait = $call_type; + type Config = $call_type; type Info = $crate::weights::DispatchInfo; type PostInfo = $crate::weights::PostDispatchInfo; fn dispatch( @@ -2412,12 +2412,12 @@ mod tests { IntegrityTest, Get, }; - pub trait Trait: system::Trait + Sized where Self::AccountId: From { } + pub trait Config: system::Config + Sized where Self::AccountId: From { } pub mod system { use super::*; - pub trait Trait: 'static { + pub trait Config: 'static { type AccountId; type Call; type BaseCallFilter; @@ -2443,11 +2443,11 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system = system, T::AccountId: From { + pub struct Module for enum Call where origin: T::Origin, system = system, T::AccountId: From { /// Hi, this is a comment. #[weight = 0] fn aux_0(_origin) -> DispatchResult { unreachable!() } @@ -2548,7 +2548,7 @@ mod tests { ]; pub struct TraitImpl {} - impl Trait for TraitImpl { } + impl Config for TraitImpl { } type Test = Module; @@ -2562,7 +2562,7 @@ mod tests { } } - impl system::Trait for TraitImpl { + impl system::Config for TraitImpl { type Origin = OuterOrigin; type AccountId = u32; type Call = OuterCall; diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index c0a886907d0..0e3f66f9f3c 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -39,7 +39,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// # /// decl_error! { /// /// Errors that can occur in my module. -/// pub enum MyError for Module { +/// pub enum MyError for Module { /// /// Hey this is an error message that indicates bla. /// MyCoolErrorMessage, /// /// You are just not cool enough for my module! @@ -47,13 +47,13 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// } /// } /// -/// # use frame_system::Trait; +/// # use frame_system::Config; /// /// // You need to register the error type in `decl_module!` as well to make the error /// // exported in the metadata. /// /// decl_module! { -/// pub struct Module for enum Call where origin: T::Origin { +/// pub struct Module for enum Call where origin: T::Origin { /// type Error = MyError; /// /// #[weight = 0] diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index 3538748c30f..3cb91e4a3e3 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -37,7 +37,7 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE /// # Generic Event Example: /// /// ```rust -/// trait Trait { +/// trait Config { /// type Balance; /// type Token; /// } @@ -45,7 +45,7 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE /// mod event1 { /// // Event that specifies the generic parameter explicitly (`Balance`). /// frame_support::decl_event!( -/// pub enum Event where Balance = ::Balance { +/// pub enum Event where Balance = ::Balance { /// Message(Balance), /// } /// ); @@ -56,7 +56,7 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE /// // If no name for the generic parameter is specified explicitly, /// // the name will be taken from the type name of the trait. /// frame_support::decl_event!( -/// pub enum Event where ::Balance { +/// pub enum Event where ::Balance { /// Message(Balance), /// } /// ); @@ -65,7 +65,7 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE /// mod event3 { /// // And we even support declaring multiple generic parameters! /// frame_support::decl_event!( -/// pub enum Event where ::Balance, ::Token { +/// pub enum Event where ::Balance, ::Token { /// Message(Balance, Token), /// } /// ); @@ -82,7 +82,7 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE ///# struct DefaultInstance; ///# trait Instance {} ///# impl Instance for DefaultInstance {} -/// trait Trait { +/// trait Config { /// type Balance; /// type Token; /// } @@ -90,8 +90,8 @@ pub use frame_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnE /// // For module with instances, DefaultInstance is optional /// frame_support::decl_event!( /// pub enum Event where -/// ::Balance, -/// ::Token +/// ::Balance, +/// ::Token /// { /// Message(Balance, Token), /// } @@ -258,10 +258,10 @@ macro_rules! __decl_generic_event { { $( $events:tt )* }; { ,$( $generic_param:ident = $generic_type:ty ),* }; ) => { - /// [`RawEvent`] specialized for the configuration [`Trait`] + /// [`RawEvent`] specialized for the configuration [`Config`] /// /// [`RawEvent`]: enum.RawEvent.html - /// [`Trait`]: trait.Trait.html + /// [`Config`]: trait.Config.html pub type Event<$event_generic_param $(, $instance $( = $event_default_instance)? )?> = RawEvent<$( $generic_type ),* $(, $instance)? >; #[derive( @@ -551,7 +551,7 @@ mod tests { use codec::{Encode, Decode}; mod system { - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -559,7 +559,7 @@ mod tests { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } decl_event!( @@ -570,7 +570,7 @@ mod tests { } mod system_renamed { - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -578,7 +578,7 @@ mod tests { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } decl_event!( @@ -591,17 +591,17 @@ mod tests { mod event_module { use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } decl_event!( /// Event without renaming the generic parameter `Balance` and `Origin`. - pub enum Event where ::Balance, ::Origin + pub enum Event where ::Balance, ::Origin { /// Hi, I am a comment. TestEvent(Balance, Origin), @@ -614,19 +614,19 @@ mod tests { mod event_module2 { use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } decl_event!( /// Event with renamed generic parameter pub enum Event where - BalanceRenamed = ::Balance, - OriginRenamed = ::Origin + BalanceRenamed = ::Balance, + OriginRenamed = ::Origin { TestEvent(BalanceRenamed), TestOrigin(OriginRenamed), @@ -645,19 +645,19 @@ mod tests { mod event_module4 { use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } decl_event!( /// Event finish formatting on an unnamed one with trailing comma pub enum Event where - ::Balance, - ::Origin, + ::Balance, + ::Origin, { TestEvent(Balance, Origin), } @@ -667,19 +667,19 @@ mod tests { mod event_module5 { use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } decl_event!( /// Event finish formatting on an named one with trailing comma pub enum Event where - BalanceRenamed = ::Balance, - OriginRenamed = ::Origin, + BalanceRenamed = ::Balance, + OriginRenamed = ::Origin, { TestEvent(BalanceRenamed, OriginRenamed), TrailingCommaInArgs( @@ -714,37 +714,37 @@ mod tests { } } - impl event_module::Trait for TestRuntime { + impl event_module::Config for TestRuntime { type Balance = u32; } - impl event_module2::Trait for TestRuntime { + impl event_module2::Config for TestRuntime { type Balance = u32; } - impl system::Trait for TestRuntime { + impl system::Config for TestRuntime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl event_module::Trait for TestRuntime2 { + impl event_module::Config for TestRuntime2 { type Balance = u32; } - impl event_module2::Trait for TestRuntime2 { + impl event_module2::Config for TestRuntime2 { type Balance = u32; } - impl system_renamed::Trait for TestRuntime2 { + impl system_renamed::Config for TestRuntime2 { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl system::Trait for TestRuntime2 { + impl system::Config for TestRuntime2 { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 3c191ed6ae4..55bca2610a1 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -346,14 +346,14 @@ pub use frame_support_procedural::{ /// This is useful for type generic over runtime: /// ``` /// # use frame_support::CloneNoBound; -/// trait Trait { +/// trait Config { /// type C: Clone; /// } /// /// // Foo implements [`Clone`] because `C` bounds [`Clone`]. /// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Clone`]. /// #[derive(CloneNoBound)] -/// struct Foo { +/// struct Foo { /// c: T::C, /// } /// ``` @@ -364,14 +364,14 @@ pub use frame_support_procedural::CloneNoBound; /// This is useful for type generic over runtime: /// ``` /// # use frame_support::{EqNoBound, PartialEqNoBound}; -/// trait Trait { +/// trait Config { /// type C: Eq; /// } /// /// // Foo implements [`Eq`] because `C` bounds [`Eq`]. /// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Eq`]. /// #[derive(PartialEqNoBound, EqNoBound)] -/// struct Foo { +/// struct Foo { /// c: T::C, /// } /// ``` @@ -382,14 +382,14 @@ pub use frame_support_procedural::EqNoBound; /// This is useful for type generic over runtime: /// ``` /// # use frame_support::PartialEqNoBound; -/// trait Trait { +/// trait Config { /// type C: PartialEq; /// } /// /// // Foo implements [`PartialEq`] because `C` bounds [`PartialEq`]. /// // Otherwise compilation will fail with an output telling `c` doesn't implement [`PartialEq`]. /// #[derive(PartialEqNoBound)] -/// struct Foo { +/// struct Foo { /// c: T::C, /// } /// ``` @@ -401,14 +401,14 @@ pub use frame_support_procedural::PartialEqNoBound; /// ``` /// # use frame_support::DebugNoBound; /// # use core::fmt::Debug; -/// trait Trait { +/// trait Config { /// type C: Debug; /// } /// /// // Foo implements [`Debug`] because `C` bounds [`Debug`]. /// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Debug`]. /// #[derive(DebugNoBound)] -/// struct Foo { +/// struct Foo { /// c: T::C, /// } /// ``` @@ -565,7 +565,7 @@ mod tests { use sp_std::{marker::PhantomData, result}; use sp_io::TestExternalities; - pub trait Trait: 'static { + pub trait Config: 'static { type BlockNumber: Codec + EncodeLike + Default; type Origin; type PalletInfo: crate::traits::PalletInfo; @@ -575,16 +575,16 @@ mod tests { mod module { #![allow(dead_code)] - use super::Trait; + use super::Config; decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } } use self::module::Module; decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { pub Data get(fn data) build(|_| vec![(15u32, 42u64)]): map hasher(twox_64_concat) u32 => u64; pub OptionLinkedMap: map hasher(blake2_128_concat) u32 => Option; @@ -606,7 +606,7 @@ mod tests { } struct Test; - impl Trait for Test { + impl Config for Test { type BlockNumber = u32; type Origin = u32; type PalletInfo = (); diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 80737e4b13d..f72365985da 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -27,23 +27,23 @@ pub use frame_metadata::{ /// Example: /// ``` ///# mod module0 { -///# pub trait Trait: 'static { +///# pub trait Config: 'static { ///# type Origin; ///# type BlockNumber; ///# type PalletInfo: frame_support::traits::PalletInfo; ///# type DbWeight: frame_support::traits::Get; ///# } ///# frame_support::decl_module! { -///# pub struct Module for enum Call where origin: T::Origin, system=self {} +///# pub struct Module for enum Call where origin: T::Origin, system=self {} ///# } ///# ///# frame_support::decl_storage! { -///# trait Store for Module as TestStorage {} +///# trait Store for Module as TestStorage {} ///# } ///# } ///# use module0 as module1; ///# use module0 as module2; -///# impl module0::Trait for Runtime { +///# impl module0::Config for Runtime { ///# type Origin = u32; ///# type BlockNumber = u32; ///# type PalletInfo = (); @@ -297,7 +297,7 @@ mod tests { mod system { use super::*; - pub trait Trait: 'static { + pub trait Config: 'static { type BaseCallFilter; const ASSOCIATED_CONST: u64 = 500; type Origin: Into, Self::Origin>> @@ -311,7 +311,7 @@ mod tests { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { /// Hi, I am a comment. const BlockNumber: T::BlockNumber = 100.into(); const GetType: T::AccountId = T::SomeValue::get().into(); @@ -341,19 +341,19 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } mod event_module { use crate::dispatch::DispatchResult; use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_event!( - pub enum Event where ::Balance + pub enum Event where ::Balance { /// Hi, I am a comment. TestEvent(Balance), @@ -361,7 +361,7 @@ mod tests { ); decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system { + pub struct Module for enum Call where origin: T::Origin, system=system { type Error = Error; #[weight = 0] @@ -370,7 +370,7 @@ mod tests { } crate::decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Some user input error UserInputError, /// Something bad happened @@ -383,23 +383,23 @@ mod tests { mod event_module2 { use super::system; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Balance; } decl_event!( - pub enum Event where ::Balance + pub enum Event where ::Balance { TestEvent(Balance), } ); decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } crate::decl_storage! { - trait Store for Module as TestStorage { + trait Store for Module as TestStorage { StorageMethod : Option; } add_extra_genesis { @@ -433,11 +433,11 @@ mod tests { } } - impl event_module::Trait for TestRuntime { + impl event_module::Config for TestRuntime { type Balance = u32; } - impl event_module2::Trait for TestRuntime { + impl event_module2::Config for TestRuntime { type Balance = u32; } @@ -445,7 +445,7 @@ mod tests { pub const SystemValue: u32 = 600; } - impl system::Trait for TestRuntime { + impl system::Config for TestRuntime { type BaseCallFilter = (); type Origin = Origin; type AccountId = u32; @@ -480,7 +480,7 @@ mod tests { struct ConstantAssociatedConstByteGetter; impl DefaultByte for ConstantAssociatedConstByteGetter { fn default_byte(&self) -> Vec { - ::ASSOCIATED_CONST.encode() + ::ASSOCIATED_CONST.encode() } } diff --git a/frame/support/src/origin.rs b/frame/support/src/origin.rs index b96a56c8e1d..980ab902a38 100644 --- a/frame/support/src/origin.rs +++ b/frame/support/src/origin.rs @@ -181,12 +181,12 @@ macro_rules! impl_outer_origin { index { $( $index:tt )? }, )* ) => { - // WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`, except + // WARNING: All instance must hold the filter `frame_system::Config::BaseCallFilter`, except // when caller is system Root. One can use `OriginTrait::reset_filter` to do so. #[derive(Clone)] pub struct $name { caller: $caller_name, - filter: $crate::sp_std::rc::Rc::Call) -> bool>>, + filter: $crate::sp_std::rc::Rc::Call) -> bool>>, } #[cfg(not(feature = "std"))] @@ -213,9 +213,9 @@ macro_rules! impl_outer_origin { } impl $crate::traits::OriginTrait for $name { - type Call = <$runtime as $system::Trait>::Call; + type Call = <$runtime as $system::Config>::Call; type PalletsOrigin = $caller_name; - type AccountId = <$runtime as $system::Trait>::AccountId; + type AccountId = <$runtime as $system::Config>::AccountId; fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static) { let f = self.filter.clone(); @@ -227,8 +227,8 @@ macro_rules! impl_outer_origin { fn reset_filter(&mut self) { let filter = < - <$runtime as $system::Trait>::BaseCallFilter - as $crate::traits::Filter<<$runtime as $system::Trait>::Call> + <$runtime as $system::Config>::BaseCallFilter + as $crate::traits::Filter<<$runtime as $system::Config>::Call> >::filter; self.filter = $crate::sp_std::rc::Rc::new(Box::new(filter)); @@ -246,7 +246,7 @@ macro_rules! impl_outer_origin { &self.caller } - /// Create with system none origin and `frame-system::Trait::BaseCallFilter`. + /// Create with system none origin and `frame-system::Config::BaseCallFilter`. fn none() -> Self { $system::RawOrigin::None.into() } @@ -254,8 +254,8 @@ macro_rules! impl_outer_origin { fn root() -> Self { $system::RawOrigin::Root.into() } - /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. - fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self { + /// Create with system signed origin and `frame-system::Config::BaseCallFilter`. + fn signed(by: <$runtime as $system::Config>::AccountId) -> Self { $system::RawOrigin::Signed(by).into() } } @@ -280,7 +280,7 @@ macro_rules! impl_outer_origin { // For backwards compatibility and ease of accessing these functions. #[allow(dead_code)] impl $name { - /// Create with system none origin and `frame-system::Trait::BaseCallFilter`. + /// Create with system none origin and `frame-system::Config::BaseCallFilter`. pub fn none() -> Self { <$name as $crate::traits::OriginTrait>::none() } @@ -288,8 +288,8 @@ macro_rules! impl_outer_origin { pub fn root() -> Self { <$name as $crate::traits::OriginTrait>::root() } - /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. - pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self { + /// Create with system signed origin and `frame-system::Config::BaseCallFilter`. + pub fn signed(by: <$runtime as $system::Config>::AccountId) -> Self { <$name as $crate::traits::OriginTrait>::signed(by) } } @@ -302,7 +302,7 @@ macro_rules! impl_outer_origin { impl From<$system::Origin<$runtime>> for $name { /// Convert to runtime origin: /// * root origin is built with no filter - /// * others use `frame-system::Trait::BaseCallFilter` + /// * others use `frame-system::Config::BaseCallFilter` fn from(x: $system::Origin<$runtime>) -> Self { let o: $caller_name = x.into(); o.into() @@ -335,10 +335,10 @@ macro_rules! impl_outer_origin { } } } - impl From::AccountId>> for $name { + impl From::AccountId>> for $name { /// Convert to runtime origin with caller being system signed or none and use filter - /// `frame-system::Trait::BaseCallFilter`. - fn from(x: Option<<$runtime as $system::Trait>::AccountId>) -> Self { + /// `frame-system::Config::BaseCallFilter`. + fn from(x: Option<<$runtime as $system::Config>::AccountId>) -> Self { <$system::Origin<$runtime>>::from(x).into() } } @@ -352,7 +352,7 @@ macro_rules! impl_outer_origin { } impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $name { - /// Convert to runtime origin using `frame-system::Trait::BaseCallFilter`. + /// Convert to runtime origin using `frame-system::Config::BaseCallFilter`. fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self { let x: $caller_name = x.into(); x.into() @@ -388,7 +388,7 @@ mod tests { mod frame_system { use super::*; - pub trait Trait { + pub trait Config { type AccountId; type Call; type BaseCallFilter; @@ -410,7 +410,7 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } mod origin_without_generic { @@ -439,7 +439,7 @@ mod tests { } } - impl frame_system::Trait for TestRuntime { + impl frame_system::Config for TestRuntime { type AccountId = u32; type Call = u32; type BaseCallFilter = BaseCallFilter; diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index cbc62c83de8..6fb3abca5ca 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -425,7 +425,7 @@ mod test_iterators { storage::{generator::StorageDoubleMap, IterableStorageDoubleMap, unhashed}, }; - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -433,14 +433,14 @@ mod test_iterators { } crate::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } #[derive(PartialEq, Eq, Clone, Encode, Decode)] struct NoDef(u32); crate::decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { DoubleMap: double_map hasher(blake2_128_concat) u16, hasher(twox_64_concat) u32 => u64; } } diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 601fd4c4a8d..2c2390865d0 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -325,7 +325,7 @@ mod test_iterators { storage::{generator::StorageMap, IterableStorageMap, unhashed}, }; - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -333,14 +333,14 @@ mod test_iterators { } crate::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } #[derive(PartialEq, Eq, Clone, Encode, Decode)] struct NoDef(u32); crate::decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { Map: map hasher(blake2_128_concat) u16 => u64; } } diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 9346718f634..4b444ce074f 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -42,14 +42,14 @@ mod tests { struct Runtime; - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; type DbWeight: crate::traits::Get; } - impl Trait for Runtime { + impl Config for Runtime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); @@ -57,11 +57,11 @@ mod tests { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } crate::decl_storage! { - trait Store for Module as Runtime { + trait Store for Module as Runtime { Value get(fn value) config(): (u64, u64); NumberMap: map hasher(identity) u32 => u64; DoubleMap: double_map hasher(identity) u32, hasher(identity) u32 => u64; diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index b40ebe3dba6..19c23a464db 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1653,16 +1653,16 @@ pub trait EnsureOrigin { /// Implemented for pallet dispatchable type by `decl_module` and for runtime dispatchable by /// `construct_runtime` and `impl_outer_dispatch`. pub trait UnfilteredDispatchable { - /// The origin type of the runtime, (i.e. `frame_system::Trait::Origin`). + /// The origin type of the runtime, (i.e. `frame_system::Config::Origin`). type Origin; /// Dispatch this call but do not check the filter in origin. fn dispatch_bypass_filter(self, origin: Self::Origin) -> crate::dispatch::DispatchResultWithPostInfo; } -/// Methods available on `frame_system::Trait::Origin`. +/// Methods available on `frame_system::Config::Origin`. pub trait OriginTrait: Sized { - /// Runtime call type, as in `frame_system::Trait::Call` + /// Runtime call type, as in `frame_system::Config::Call` type Call; /// The caller origin, overarching type of all pallets origins. @@ -1674,7 +1674,7 @@ pub trait OriginTrait: Sized { /// Add a filter to the origin. fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static); - /// Reset origin filters to default one, i.e `frame_system::Trait::BaseCallFilter`. + /// Reset origin filters to default one, i.e `frame_system::Config::BaseCallFilter`. fn reset_filter(&mut self); /// Replace the caller with caller from the other origin @@ -1686,13 +1686,13 @@ pub trait OriginTrait: Sized { /// Get the caller. fn caller(&self) -> &Self::PalletsOrigin; - /// Create with system none origin and `frame-system::Trait::BaseCallFilter`. + /// Create with system none origin and `frame-system::Config::BaseCallFilter`. fn none() -> Self; /// Create with system root origin and no filter. fn root() -> Self; - /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. + /// Create with system signed origin and `frame-system::Config::BaseCallFilter`. fn signed(by: Self::AccountId) -> Self; } diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 74f0773aa54..6a62befd6d5 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -39,9 +39,9 @@ //! `Yes`**. //! //! ``` -//! # use frame_system::Trait; +//! # use frame_system::Config; //! frame_support::decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 1000] //! fn dispatching(origin) { unimplemented!() } //! } @@ -52,10 +52,10 @@ //! 2.1 Define weight and class, **in which case `PaysFee` would be `Yes`**. //! //! ``` -//! # use frame_system::Trait; +//! # use frame_system::Config; //! # use frame_support::weights::DispatchClass; //! frame_support::decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = (1000, DispatchClass::Operational)] //! fn dispatching(origin) { unimplemented!() } //! } @@ -66,10 +66,10 @@ //! 2.2 Define weight and `PaysFee`, **in which case `ClassifyDispatch` would be `Normal`**. //! //! ``` -//! # use frame_system::Trait; +//! # use frame_system::Config; //! # use frame_support::weights::Pays; //! frame_support::decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = (1000, Pays::No)] //! fn dispatching(origin) { unimplemented!() } //! } @@ -80,10 +80,10 @@ //! 3. Define all 3 parameters. //! //! ``` -//! # use frame_system::Trait; +//! # use frame_system::Config; //! # use frame_support::weights::{DispatchClass, Pays}; //! frame_support::decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = (1000, DispatchClass::Operational, Pays::No)] //! fn dispatching(origin) { unimplemented!() } //! } @@ -100,10 +100,10 @@ //! all 3 are static values, providing a raw tuple is easier. //! //! ``` -//! # use frame_system::Trait; +//! # use frame_system::Config; //! # use frame_support::weights::{DispatchClass, FunctionOf, Pays}; //! frame_support::decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = FunctionOf( //! // weight, function. //! |args: (&u32, &u64)| *args.0 as u64 + args.1, @@ -701,7 +701,7 @@ mod tests { use crate::{decl_module, parameter_types, traits::Get}; use super::*; - pub trait Trait: 'static { + pub trait Config: 'static { type Origin; type Balance; type BlockNumber; @@ -718,7 +718,7 @@ mod tests { }; } - impl Trait for TraitImpl { + impl Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type Balance = u32; @@ -727,7 +727,7 @@ mod tests { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { // no arguments, fixed weight #[weight = 1000] fn f00(_origin) { unimplemented!(); } diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index ee8ace5c983..6d8064102c4 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -25,6 +25,7 @@ trybuild = "1.0.33" pretty_assertions = "0.6.1" rustversion = "1.0.0" frame-metadata = { version = "12.0.0", default-features = false, path = "../../metadata" } +frame-system = { version = "2.0.0", default-features = false, path = "../../system" } [features] default = ["std"] @@ -33,6 +34,7 @@ std = [ "codec/std", "sp-io/std", "frame-support/std", + "frame-system/std", "sp-inherents/std", "sp-core/std", "sp-std/std", diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index a917c781c06..2baf698f1e5 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -26,7 +26,7 @@ mod pallet_version; /// The configuration trait -pub trait Trait: 'static { +pub trait Config: 'static { /// The runtime origin type. type Origin: codec::Codec + codec::EncodeLike + Default; /// The block number type. @@ -39,5 +39,5 @@ pub trait Trait: 'static { frame_support::decl_module! { /// Some test module - pub struct Module for enum Call where origin: T::Origin, system=self {} + pub struct Module for enum Call where origin: T::Origin, system=self {} } diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 4ff4fc68286..33bb4a9cc87 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -37,11 +37,11 @@ thread_local! { mod module1 { use super::*; - pub trait Trait: system::Trait {} + pub trait Config: system::Config {} frame_support::decl_module! { - pub struct Module, I: Instance = DefaultInstance> for enum Call - where origin: ::Origin, system=system + pub struct Module, I: Instance = DefaultInstance> for enum Call + where origin: ::Origin, system=system { #[weight = 0] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { @@ -55,31 +55,31 @@ mod module1 { frame_support::decl_event! { pub enum Event where - ::AccountId + ::AccountId { A(AccountId), } } frame_support::decl_error! { - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { Something } } frame_support::decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Module {} + trait Store for Module, I: Instance=DefaultInstance> as Module {} } } mod module2 { use super::*; - pub trait Trait: system::Trait {} + pub trait Config: system::Config {} frame_support::decl_module! { - pub struct Module for enum Call - where origin: ::Origin, system=system + pub struct Module for enum Call + where origin: ::Origin, system=system { #[weight = 0] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { @@ -102,25 +102,25 @@ mod module2 { } frame_support::decl_error! { - pub enum Error for Module { + pub enum Error for Module { Something } } frame_support::decl_storage! { - trait Store for Module as Module {} + trait Store for Module as Module {} } } -impl module1::Trait for Runtime {} -impl module2::Trait for Runtime {} +impl module1::Config for Runtime {} +impl module2::Config for Runtime {} pub type Signature = sr25519::Signature; pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs index 56eff29c5dc..cc7c1ff219d 100644 --- a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs @@ -1,5 +1,5 @@ frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { fn integrity_test() {} fn integrity_test() {} diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr index 25f3b891d9b..3bf5f58b43a 100644 --- a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr @@ -2,7 +2,7 @@ error: `integrity_test` can only be passed once as input. --> $DIR/reserved_keyword_two_times_integrity_test.rs:1:1 | 1 | / frame_support::decl_module! { -2 | | pub struct Module for enum Call where origin: T::Origin, system=self { +2 | | pub struct Module for enum Call where origin: T::Origin, system=self { 3 | | fn integrity_test() {} 4 | | 5 | | fn integrity_test() {} @@ -16,7 +16,7 @@ error[E0601]: `main` function not found in crate `$CRATE` --> $DIR/reserved_keyword_two_times_integrity_test.rs:1:1 | 1 | / frame_support::decl_module! { -2 | | pub struct Module for enum Call where origin: T::Origin, system=self { +2 | | pub struct Module for enum Call where origin: T::Origin, system=self { 3 | | fn integrity_test() {} 4 | | 5 | | fn integrity_test() {} diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs index 3e1bc25c8d5..ddde7c72c1c 100644 --- a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs @@ -1,5 +1,5 @@ frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { fn on_initialize() -> Weight { 0 } diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr index 34c5ff3f941..2911d7ded8a 100644 --- a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr @@ -2,7 +2,7 @@ error: `on_initialize` can only be passed once as input. --> $DIR/reserved_keyword_two_times_on_initialize.rs:1:1 | 1 | / frame_support::decl_module! { -2 | | pub struct Module for enum Call where origin: T::Origin, system=self { +2 | | pub struct Module for enum Call where origin: T::Origin, system=self { 3 | | fn on_initialize() -> Weight { 4 | | 0 ... | @@ -16,7 +16,7 @@ error[E0601]: `main` function not found in crate `$CRATE` --> $DIR/reserved_keyword_two_times_on_initialize.rs:1:1 | 1 | / frame_support::decl_module! { -2 | | pub struct Module for enum Call where origin: T::Origin, system=self { +2 | | pub struct Module for enum Call where origin: T::Origin, system=self { 3 | | fn on_initialize() -> Weight { 4 | | 0 ... | diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 8d5727ce910..97cf68c799b 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -24,13 +24,13 @@ mod tests { use std::marker::PhantomData; frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_storage! { - trait Store for Module as TestStorage { + trait Store for Module as TestStorage { // non-getters: pub / $default /// Hello, this is doc! @@ -81,14 +81,14 @@ mod tests { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl Trait for TraitImpl {} + impl Config for TraitImpl {} const EXPECTED_METADATA: StorageMetadata = StorageMetadata { prefix: DecodeDifferent::Encode("TestStorage"), @@ -414,16 +414,16 @@ mod tests { #[cfg(test)] #[allow(dead_code)] mod test2 { - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } type PairOf = (T, T); frame_support::decl_storage! { - trait Store for Module as TestStorage { + trait Store for Module as TestStorage { SingleDef : u32; PairDef : PairOf; Single : Option; @@ -438,26 +438,26 @@ mod test2 { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl Trait for TraitImpl {} + impl Config for TraitImpl {} } #[cfg(test)] #[allow(dead_code)] mod test3 { - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { Foo get(fn foo) config(initial_foo): u32; } } @@ -466,14 +466,14 @@ mod test3 { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl Trait for TraitImpl {} + impl Config for TraitImpl {} } #[cfg(test)] @@ -482,17 +482,17 @@ mod test_append_and_len { use sp_io::TestExternalities; use codec::{Encode, Decode}; - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } #[derive(PartialEq, Eq, Clone, Encode, Decode)] struct NoDef(u32); frame_support::decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { NoDefault: Option; JustVec: Vec; @@ -511,14 +511,14 @@ mod test_append_and_len { struct Test {} - impl frame_support_test::Trait for Test { + impl frame_support_test::Config for Test { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl Trait for Test {} + impl Config for Test {} #[test] fn default_for_option() { diff --git a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs index 58923ed1929..c7de52dd893 100644 --- a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs @@ -15,14 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub trait Trait: frame_support_test::Trait {} +pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage!{ - trait Store for Module as FinalKeysNone { + trait Store for Module as FinalKeysNone { pub Value config(value): u32; pub Value2 config(value): u32; } diff --git a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs index e77dcea404c..60bfa7f89c3 100644 --- a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs @@ -15,14 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub trait Trait: frame_support_test::Trait {} +pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage!{ - trait Store for Module as FinalKeysNone { + trait Store for Module as FinalKeysNone { pub Value get(fn value) config(): u32; pub Value2 config(value): u32; } diff --git a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs index b6ccb7ebb7b..921dfa6b774 100644 --- a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs @@ -15,14 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub trait Trait: frame_support_test::Trait {} +pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage!{ - trait Store for Module as FinalKeysNone { + trait Store for Module as FinalKeysNone { pub Value get(fn value) config(): u32; pub Value2 get(fn value) config(): u32; } diff --git a/frame/support/test/tests/derive_no_bound.rs b/frame/support/test/tests/derive_no_bound.rs index 29f813c6498..48f2f3ec3f6 100644 --- a/frame/support/test/tests/derive_no_bound.rs +++ b/frame/support/test/tests/derive_no_bound.rs @@ -28,19 +28,19 @@ fn runtime_debug_no_bound_display_correctly() { assert_eq!(format!("{:?}", Unnamed(1)), "Unnamed(1)"); } -trait Trait { +trait Config { type C: std::fmt::Debug + Clone + Eq + PartialEq; } struct Runtime; struct ImplNone; -impl Trait for Runtime { +impl Config for Runtime { type C = u32; } #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound)] -struct StructNamed { +struct StructNamed { a: u32, b: u64, c: T::C, @@ -77,7 +77,7 @@ fn test_struct_named() { } #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound)] -struct StructUnnamed(u32, u64, T::C, core::marker::PhantomData<(U, V)>); +struct StructUnnamed(u32, u64, T::C, core::marker::PhantomData<(U, V)>); #[test] fn test_struct_unnamed() { @@ -109,7 +109,7 @@ fn test_struct_unnamed() { } #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound)] -enum Enum { +enum Enum { VariantUnnamed(u32, u64, T::C, core::marker::PhantomData<(U, V)>), VariantNamed { a: u32, diff --git a/frame/support/test/tests/derive_no_bound_ui/clone.rs b/frame/support/test/tests/derive_no_bound_ui/clone.rs index 6b80dcedc38..2bc1cc492d1 100644 --- a/frame/support/test/tests/derive_no_bound_ui/clone.rs +++ b/frame/support/test/tests/derive_no_bound_ui/clone.rs @@ -1,9 +1,9 @@ -trait Trait { +trait Config { type C; } #[derive(frame_support::CloneNoBound)] -struct Foo { +struct Foo { c: T::C, } diff --git a/frame/support/test/tests/derive_no_bound_ui/clone.stderr b/frame/support/test/tests/derive_no_bound_ui/clone.stderr index 4b9cccf0b0f..af322f386ae 100644 --- a/frame/support/test/tests/derive_no_bound_ui/clone.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/clone.stderr @@ -1,7 +1,7 @@ -error[E0277]: the trait bound `::C: std::clone::Clone` is not satisfied +error[E0277]: the trait bound `::C: std::clone::Clone` is not satisfied --> $DIR/clone.rs:7:2 | 7 | c: T::C, - | ^ the trait `std::clone::Clone` is not implemented for `::C` + | ^ the trait `std::clone::Clone` is not implemented for `::C` | = note: required by `std::clone::Clone::clone` diff --git a/frame/support/test/tests/derive_no_bound_ui/debug.rs b/frame/support/test/tests/derive_no_bound_ui/debug.rs index f2411da4b41..6016c3e6d98 100644 --- a/frame/support/test/tests/derive_no_bound_ui/debug.rs +++ b/frame/support/test/tests/derive_no_bound_ui/debug.rs @@ -1,9 +1,9 @@ -trait Trait { +trait Config { type C; } #[derive(frame_support::DebugNoBound)] -struct Foo { +struct Foo { c: T::C, } diff --git a/frame/support/test/tests/derive_no_bound_ui/debug.stderr b/frame/support/test/tests/derive_no_bound_ui/debug.stderr index 838bd7f68a6..7580cab2ea0 100644 --- a/frame/support/test/tests/derive_no_bound_ui/debug.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/debug.stderr @@ -1,8 +1,8 @@ -error[E0277]: `::C` doesn't implement `std::fmt::Debug` +error[E0277]: `::C` doesn't implement `std::fmt::Debug` --> $DIR/debug.rs:7:2 | 7 | c: T::C, - | ^ `::C` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^ `::C` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | - = help: the trait `std::fmt::Debug` is not implemented for `::C` + = help: the trait `std::fmt::Debug` is not implemented for `::C` = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/frame/support/test/tests/derive_no_bound_ui/eq.rs b/frame/support/test/tests/derive_no_bound_ui/eq.rs index 9e4026734fb..a4845262636 100644 --- a/frame/support/test/tests/derive_no_bound_ui/eq.rs +++ b/frame/support/test/tests/derive_no_bound_ui/eq.rs @@ -1,9 +1,9 @@ -trait Trait { +trait Config { type C; } #[derive(frame_support::EqNoBound)] -struct Foo { +struct Foo { c: T::C, } diff --git a/frame/support/test/tests/derive_no_bound_ui/eq.stderr b/frame/support/test/tests/derive_no_bound_ui/eq.stderr index 08341c4d65a..bd5df600dc4 100644 --- a/frame/support/test/tests/derive_no_bound_ui/eq.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/eq.stderr @@ -1,7 +1,7 @@ error[E0277]: can't compare `Foo` with `Foo` --> $DIR/eq.rs:6:8 | -6 | struct Foo { +6 | struct Foo { | ^^^ no implementation for `Foo == Foo` | = help: the trait `std::cmp::PartialEq` is not implemented for `Foo` diff --git a/frame/support/test/tests/derive_no_bound_ui/partial_eq.rs b/frame/support/test/tests/derive_no_bound_ui/partial_eq.rs index 1720776a400..7bd6b7ef6a2 100644 --- a/frame/support/test/tests/derive_no_bound_ui/partial_eq.rs +++ b/frame/support/test/tests/derive_no_bound_ui/partial_eq.rs @@ -1,9 +1,9 @@ -trait Trait { +trait Config { type C; } #[derive(frame_support::PartialEqNoBound)] -struct Foo { +struct Foo { c: T::C, } diff --git a/frame/support/test/tests/derive_no_bound_ui/partial_eq.stderr b/frame/support/test/tests/derive_no_bound_ui/partial_eq.stderr index d85757c520a..64f844e547b 100644 --- a/frame/support/test/tests/derive_no_bound_ui/partial_eq.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/partial_eq.stderr @@ -1,7 +1,7 @@ -error[E0369]: binary operation `==` cannot be applied to type `::C` +error[E0369]: binary operation `==` cannot be applied to type `::C` --> $DIR/partial_eq.rs:7:2 | 7 | c: T::C, | ^ | - = note: the trait `std::cmp::PartialEq` is not implemented for `::C` + = note: the trait `std::cmp::PartialEq` is not implemented for `::C` diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index 6bd12528254..e7c95c6b432 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -21,14 +21,14 @@ use frame_support::{StorageDoubleMap, StorageMap, StorageValue, StoragePrefixedM use sp_io::{TestExternalities, hashing::{twox_64, twox_128, blake2_128}}; mod no_instance { - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage!{ - trait Store for Module as FinalKeysNone { + trait Store for Module as FinalKeysNone { pub Value config(value): u32; pub Map: map hasher(blake2_128_concat) u32 => u32; @@ -45,15 +45,15 @@ mod no_instance { } mod instance { - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module, I: Instance = DefaultInstance> + pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage!{ - trait Store for Module, I: Instance = DefaultInstance> + trait Store for Module, I: Instance = DefaultInstance> as FinalKeysSome { pub Value config(value): u32; diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index f268f11a4dc..4a875bb6889 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -15,28 +15,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub trait Trait: frame_support_test::Trait {} +pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test {} } frame_support::decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test { pub AppendableDM config(t): double_map hasher(identity) u32, hasher(identity) T::BlockNumber => Vec; } } struct Test; -impl frame_support_test::Trait for Test { +impl frame_support_test::Config for Test { type BlockNumber = u32; type Origin = (); type PalletInfo = (); type DbWeight = (); } -impl Trait for Test {} +impl Config for Test {} #[test] fn init_genesis_config() { diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 6c90767f92e..b5bb6dd671b 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -41,16 +41,16 @@ mod module1 { use super::*; use sp_std::ops::Add; - pub trait Trait: system::Trait where ::BlockNumber: From { - type Event: From> + Into<::Event>; + pub trait Config: system::Config where ::BlockNumber: From { + type Event: From> + Into<::Event>; type Origin: From>; type SomeParameter: Get; type GenericType: Default + Clone + Codec + EncodeLike; } frame_support::decl_module! { - pub struct Module, I: Instance> for enum Call where - origin: ::Origin, + pub struct Module, I: Instance> for enum Call where + origin: ::Origin, system = system, T::BlockNumber: From { @@ -67,7 +67,7 @@ mod module1 { } frame_support::decl_storage! { - trait Store for Module, I: Instance> as Module1 where + trait Store for Module, I: Instance> as Module1 where T::BlockNumber: From + std::fmt::Display { pub Value config(value): T::GenericType; @@ -83,7 +83,7 @@ mod module1 { } frame_support::decl_error! { - pub enum Error for Module, I: Instance> where + pub enum Error for Module, I: Instance> where T::BlockNumber: From, T::BlockNumber: Add, T::AccountId: AsRef<[u8]>, @@ -101,14 +101,14 @@ mod module1 { } #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug, Encode, Decode)] - pub enum Origin, I> where T::BlockNumber: From { + pub enum Origin, I> where T::BlockNumber: From { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), } pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678"; - impl, I: Instance> ProvideInherent for Module where + impl, I: Instance> ProvideInherent for Module where T::BlockNumber: From { type Call = Call; @@ -131,17 +131,17 @@ mod module1 { mod module2 { use super::*; - pub trait Trait: system::Trait { + pub trait Config: system::Config { type Amount: Parameter + Default; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; type Origin: From>; } - impl, I: Instance> Currency for Module {} + impl, I: Instance> Currency for Module {} frame_support::decl_module! { - pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, + pub struct Module, I: Instance=DefaultInstance> for enum Call where + origin: ::Origin, system = system { fn deposit_event() = default; @@ -149,7 +149,7 @@ mod module2 { } frame_support::decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Module2 { + trait Store for Module, I: Instance=DefaultInstance> as Module2 { pub Value config(value): T::Amount; pub Map config(map): map hasher(identity) u64 => u64; pub DoubleMap config(double_map): double_map hasher(identity) u64, hasher(identity) u64 => u64; @@ -157,20 +157,20 @@ mod module2 { } frame_support::decl_event! { - pub enum Event where Amount = >::Amount { + pub enum Event where Amount = >::Amount { Variant(Amount), } } #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug, Encode, Decode)] - pub enum Origin, I=DefaultInstance> { + pub enum Origin, I=DefaultInstance> { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), } pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678"; - impl, I: Instance> ProvideInherent for Module { + impl, I: Instance> ProvideInherent for Module { type Call = Call; type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; @@ -190,13 +190,13 @@ mod module2 { mod module3 { use super::*; - pub trait Trait: module2::Trait + module2::Trait + system::Trait { + pub trait Config: module2::Config + module2::Config + system::Config { type Currency: Currency; type Currency2: Currency; } frame_support::decl_module! { - pub struct Module for enum Call where origin: ::Origin, system=system {} + pub struct Module for enum Call where origin: ::Origin, system=system {} } } @@ -204,39 +204,39 @@ parameter_types! { pub const SomeValue: u32 = 100; } -impl module1::Trait for Runtime { +impl module1::Config for Runtime { type Event = Event; type Origin = Origin; type SomeParameter = SomeValue; type GenericType = u32; } -impl module1::Trait for Runtime { +impl module1::Config for Runtime { type Event = Event; type Origin = Origin; type SomeParameter = SomeValue; type GenericType = u32; } -impl module2::Trait for Runtime { +impl module2::Config for Runtime { type Amount = u16; type Event = Event; type Origin = Origin; } -impl module2::Trait for Runtime { +impl module2::Config for Runtime { type Amount = u32; type Event = Event; type Origin = Origin; } -impl module2::Trait for Runtime { +impl module2::Config for Runtime { type Amount = u32; type Event = Event; type Origin = Origin; } -impl module2::Trait for Runtime { +impl module2::Config for Runtime { type Amount = u64; type Event = Event; type Origin = Origin; } -impl module3::Trait for Runtime { +impl module3::Config for Runtime { type Currency = Module2_2; type Currency2 = Module2_3; } @@ -246,7 +246,7 @@ pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter= (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index 596a3b6ffb2..70a84dfee59 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -27,9 +27,9 @@ mod module { use super::*; pub type Request = ( - ::AccountId, + ::AccountId, Role, - ::BlockNumber, + ::BlockNumber, ); pub type Requests = Vec>; @@ -39,7 +39,7 @@ mod module { } #[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Debug)] - pub struct RoleParameters { + pub struct RoleParameters { // minimum actors to maintain - if role is unstaking // and remaining actors would be less that this value - prevent or punish for unstaking pub min_actors: u32, @@ -65,7 +65,7 @@ mod module { pub startup_grace_period: T::BlockNumber, } - impl Default for RoleParameters { + impl Default for RoleParameters { fn default() -> Self { Self { max_actors: 10, @@ -81,18 +81,18 @@ mod module { } } - pub trait Trait: system::Trait {} + pub trait Config: system::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=system {} + pub struct Module for enum Call where origin: T::Origin, system=system {} } #[derive(Encode, Decode, Copy, Clone, Serialize, Deserialize)] - pub struct Data { + pub struct Data { pub data: T::BlockNumber, } - impl Default for Data { + impl Default for Data { fn default() -> Self { Self { data: T::BlockNumber::default(), @@ -101,7 +101,7 @@ mod module { } frame_support::decl_storage! { - trait Store for Module as Actors { + trait Store for Module as Actors { /// requirements to enter and maintain status in roles pub Parameters get(fn parameters) build(|config: &GenesisConfig| { if config.enable_storage_role { @@ -157,7 +157,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Hash = H256; type Origin = Origin; @@ -169,7 +169,7 @@ impl system::Trait for Runtime { type DbWeight = (); } -impl module::Trait for Runtime {} +impl module::Config for Runtime {} frame_support::construct_runtime!( pub enum Runtime where diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index d6293ac6a30..00750c67672 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -37,11 +37,11 @@ const SOME_TEST_VERSION: PalletVersion = PalletVersion { major: 3000, minor: 30, mod module1 { use super::*; - pub trait Trait: system::Trait {} + pub trait Config: system::Config {} frame_support::decl_module! { - pub struct Module for enum Call where - origin: ::Origin, + pub struct Module for enum Call where + origin: ::Origin, system = system, {} } @@ -52,11 +52,11 @@ mod module1 { mod module2 { use super::*; - pub trait Trait: system::Trait {} + pub trait Config: system::Config {} frame_support::decl_module! { - pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, + pub struct Module, I: Instance=DefaultInstance> for enum Call where + origin: ::Origin, system = system { fn on_runtime_upgrade() -> Weight { @@ -78,21 +78,21 @@ mod module2 { } frame_support::decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Module2 {} + trait Store for Module, I: Instance=DefaultInstance> as Module2 {} } } -impl module1::Trait for Runtime {} -impl module2::Trait for Runtime {} -impl module2::Trait for Runtime {} -impl module2::Trait for Runtime {} +impl module1::Config for Runtime {} +impl module2::Config for Runtime {} +impl module2::Config for Runtime {} +impl module2::Config for Runtime {} pub type Signature = sr25519::Signature; pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter= (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs new file mode 100644 index 00000000000..3bb5e0ce667 --- /dev/null +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -0,0 +1,157 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +pub trait Trait: frame_system::Config { + type Balance: frame_support::dispatch::Parameter; + /// The overarching event type. + type Event: From> + Into<::Event>; +} + +frame_support::decl_storage! { + trait Store for Module as Example { + Dummy get(fn dummy) config(): Option; + } +} + +frame_support::decl_event!( + pub enum Event where B = ::Balance { + Dummy(B), + } +); + +frame_support::decl_error!( + pub enum Error for Module { + Dummy, + } +); + +frame_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + type Error = Error; + const Foo: u32 = u32::max_value(); + + #[weight = 0] + fn accumulate_dummy(origin, increase_by: T::Balance) { + unimplemented!(); + } + + fn on_initialize(_n: T::BlockNumber) -> frame_support::weights::Weight { + 0 + } + } +} + +impl sp_runtime::traits::ValidateUnsigned for Module { + type Call = Call; + + fn validate_unsigned( + _source: sp_runtime::transaction_validity::TransactionSource, + _call: &Self::Call, + ) -> sp_runtime::transaction_validity::TransactionValidity { + unimplemented!(); + } +} + +pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"12345678"; + +impl sp_inherents::ProvideInherent for Module { + type Call = Call; + type Error = sp_inherents::MakeFatalError; + const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(_data: &sp_inherents::InherentData) -> Option { + unimplemented!(); + } + + fn check_inherent(_: &Self::Call, _: &sp_inherents::InherentData) -> std::result::Result<(), Self::Error> { + unimplemented!(); + } +} + +#[cfg(test)] +mod tests { + use crate as pallet_test; + + use frame_support::parameter_types; + use sp_runtime::traits::Block; + + type SignedExtra = ( + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + ); + type TestBlock = sp_runtime::generic::Block; + type TestHeader = sp_runtime::generic::Header; + type TestUncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic< + ::AccountId, + ::Call, + (), + SignedExtra, + >; + + frame_support::construct_runtime!( + pub enum Runtime where + Block = TestBlock, + NodeBlock = TestBlock, + UncheckedExtrinsic = TestUncheckedExtrinsic + { + System: frame_system::{Module, Call, Config, Storage, Event}, + PalletTest: pallet_test::{Module, Call, Storage, Event, Config, ValidateUnsigned, Inherent}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); + } + + impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = sp_core::H256; + type Call = Call; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = TestHeader; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type PalletInfo = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + } + + impl pallet_test::Trait for Runtime { + type Balance = u32; + type Event = (); + } +} diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.rs b/frame/support/test/tests/reserved_keyword/on_initialize.rs index 781b72bd04e..72d53abfb10 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.rs +++ b/frame/support/test/tests/reserved_keyword/on_initialize.rs @@ -4,7 +4,7 @@ macro_rules! reserved { mod $reserved { pub use frame_support::dispatch; - pub trait Trait: frame_support_test::Trait {} + pub trait Config: frame_support_test::Config {} pub mod system { use frame_support::dispatch; @@ -15,7 +15,7 @@ macro_rules! reserved { } frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test { + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test { #[weight = 0] fn $reserved(_origin) -> dispatch::DispatchResult { unreachable!() } } diff --git a/frame/support/test/tests/storage_transaction.rs b/frame/support/test/tests/storage_transaction.rs index 5c687ef0500..93b531a678d 100644 --- a/frame/support/test/tests/storage_transaction.rs +++ b/frame/support/test/tests/storage_transaction.rs @@ -22,10 +22,10 @@ use frame_support::{ use sp_io::TestExternalities; use sp_std::result; -pub trait Trait: frame_support_test::Trait {} +pub trait Config: frame_support_test::Config {} frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=frame_support_test { + pub struct Module for enum Call where origin: T::Origin, system=frame_support_test { #[weight = 0] #[transactional] fn value_commits(_origin, v: u32) { @@ -42,7 +42,7 @@ frame_support::decl_module! { } frame_support::decl_storage!{ - trait Store for Module as StorageTransactions { + trait Store for Module as StorageTransactions { pub Value: u32; pub Map: map hasher(twox_64_concat) String => u32; } @@ -50,14 +50,14 @@ frame_support::decl_storage!{ struct Runtime; -impl frame_support_test::Trait for Runtime { +impl frame_support_test::Config for Runtime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } -impl Trait for Runtime {} +impl Config for Runtime {} #[test] fn storage_transaction_basic_commit() { diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index f30b6e4c2af..2021aa43f51 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -19,7 +19,7 @@ use frame_support::{ codec::{Encode, Decode, EncodeLike}, traits::Get, weights::RuntimeDbWeight, }; -pub trait Trait: 'static + Eq + Clone { +pub trait Config: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; @@ -34,18 +34,18 @@ pub trait Trait: 'static + Eq + Clone { } frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { #[weight = 0] fn noop(origin) {} } } -impl Module { +impl Module { pub fn deposit_event(_event: impl Into) {} } frame_support::decl_event!( - pub enum Event where BlockNumber = ::BlockNumber { + pub enum Event where BlockNumber = ::BlockNumber { ExtrinsicSuccess, ExtrinsicFailed, Ignore(BlockNumber), @@ -53,7 +53,7 @@ frame_support::decl_event!( ); frame_support::decl_error! { - pub enum Error for Module { + pub enum Error for Module { /// Test error documentation TestError, /// Error documentation @@ -79,7 +79,7 @@ impl From> for RawOrigin { } } -pub type Origin = RawOrigin<::AccountId>; +pub type Origin = RawOrigin<::AccountId>; #[allow(dead_code)] pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 00c965136c0..bedb99b9f89 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -24,12 +24,12 @@ use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header mod module { use super::*; - pub trait Trait: system::Trait { - type Event: From + Into<::Event>; + pub trait Config: system::Config { + type Event: From + Into<::Event>; } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { pub fn deposit_event() = default; } } @@ -60,7 +60,7 @@ frame_support::parameter_types! { } #[derive(Clone, Eq, PartialEq)] pub struct Runtime; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -88,7 +88,7 @@ impl system::Trait for Runtime { type SystemWeightInfo = (); } -impl module::Trait for Runtime { +impl module::Config for Runtime { type Event = Event; } diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index b631d00e47c..1f543754336 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -31,8 +31,8 @@ use frame_system::{Module as System, Call, RawOrigin, DigestItemOf, AccountInfo} mod mock; -pub struct Module(System); -pub trait Trait: frame_system::Trait {} +pub struct Module(System); +pub trait Config: frame_system::Config {} benchmarks! { _ { } diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 33255d7b50e..b6ebecc9bb0 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -38,7 +38,7 @@ pub struct Call; impl Dispatchable for Call { type Origin = (); - type Trait = (); + type Config = (); type Info = DispatchInfo; type PostInfo = PostDispatchInfo; fn dispatch(self, _origin: Self::Origin) @@ -50,7 +50,7 @@ impl Dispatchable for Call { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; @@ -78,7 +78,7 @@ impl frame_system::Trait for Test { type SystemWeightInfo = (); } -impl crate::Trait for Test {} +impl crate::Config for Test {} pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs index d0a346519ca..f60437887b1 100644 --- a/frame/system/src/extensions/check_genesis.rs +++ b/frame/system/src/extensions/check_genesis.rs @@ -16,7 +16,7 @@ // limitations under the License. use codec::{Encode, Decode}; -use crate::{Trait, Module}; +use crate::{Config, Module}; use sp_runtime::{ traits::{SignedExtension, Zero}, transaction_validity::TransactionValidityError, @@ -24,9 +24,9 @@ use sp_runtime::{ /// Genesis hash check to provide replay protection between different networks. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckGenesis(sp_std::marker::PhantomData); +pub struct CheckGenesis(sp_std::marker::PhantomData); -impl sp_std::fmt::Debug for CheckGenesis { +impl sp_std::fmt::Debug for CheckGenesis { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckGenesis") @@ -38,16 +38,16 @@ impl sp_std::fmt::Debug for CheckGenesis { } } -impl CheckGenesis { +impl CheckGenesis { /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckGenesis { +impl SignedExtension for CheckGenesis { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = T::Hash; type Pre = (); const IDENTIFIER: &'static str = "CheckGenesis"; diff --git a/frame/system/src/extensions/check_mortality.rs b/frame/system/src/extensions/check_mortality.rs index 7e3f65d0324..fbc37f527d8 100644 --- a/frame/system/src/extensions/check_mortality.rs +++ b/frame/system/src/extensions/check_mortality.rs @@ -16,7 +16,7 @@ // limitations under the License. use codec::{Encode, Decode}; -use crate::{Trait, Module, BlockHash}; +use crate::{Config, Module, BlockHash}; use frame_support::StorageMap; use sp_runtime::{ generic::Era, @@ -28,16 +28,16 @@ use sp_runtime::{ /// Check for transaction mortality. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckMortality(Era, sp_std::marker::PhantomData); +pub struct CheckMortality(Era, sp_std::marker::PhantomData); -impl CheckMortality { +impl CheckMortality { /// utility constructor. Used only in client/factory code. pub fn from(era: Era) -> Self { Self(era, sp_std::marker::PhantomData) } } -impl sp_std::fmt::Debug for CheckMortality { +impl sp_std::fmt::Debug for CheckMortality { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckMortality({:?})", self.0) @@ -49,7 +49,7 @@ impl sp_std::fmt::Debug for CheckMortality { } } -impl SignedExtension for CheckMortality { +impl SignedExtension for CheckMortality { type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = T::Hash; diff --git a/frame/system/src/extensions/check_nonce.rs b/frame/system/src/extensions/check_nonce.rs index e7316457aaf..a1a310833cd 100644 --- a/frame/system/src/extensions/check_nonce.rs +++ b/frame/system/src/extensions/check_nonce.rs @@ -16,7 +16,7 @@ // limitations under the License. use codec::{Encode, Decode}; -use crate::Trait; +use crate::Config; use frame_support::{ weights::DispatchInfo, StorageMap, @@ -35,16 +35,16 @@ use sp_std::vec; /// Note that this does not set any priority by default. Make sure that AT LEAST one of the signed /// extension sets some kind of priority upon validating transactions. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckNonce(#[codec(compact)] T::Index); +pub struct CheckNonce(#[codec(compact)] T::Index); -impl CheckNonce { +impl CheckNonce { /// utility constructor. Used only in client/factory code. pub fn from(nonce: T::Index) -> Self { Self(nonce) } } -impl sp_std::fmt::Debug for CheckNonce { +impl sp_std::fmt::Debug for CheckNonce { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckNonce({})", self.0) @@ -56,7 +56,7 @@ impl sp_std::fmt::Debug for CheckNonce { } } -impl SignedExtension for CheckNonce where +impl SignedExtension for CheckNonce where T::Call: Dispatchable { type AccountId = T::AccountId; diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs index 8dc4d8d9ced..f4838ab3547 100644 --- a/frame/system/src/extensions/check_spec_version.rs +++ b/frame/system/src/extensions/check_spec_version.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Trait, Module}; +use crate::{Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::SignedExtension, @@ -24,9 +24,9 @@ use sp_runtime::{ /// Ensure the runtime version registered in the transaction is the same as at present. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckSpecVersion(sp_std::marker::PhantomData); +pub struct CheckSpecVersion(sp_std::marker::PhantomData); -impl sp_std::fmt::Debug for CheckSpecVersion { +impl sp_std::fmt::Debug for CheckSpecVersion { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckSpecVersion") @@ -38,16 +38,16 @@ impl sp_std::fmt::Debug for CheckSpecVersion { } } -impl CheckSpecVersion { +impl CheckSpecVersion { /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckSpecVersion { +impl SignedExtension for CheckSpecVersion { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = u32; type Pre = (); const IDENTIFIER: &'static str = "CheckSpecVersion"; diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs index ee6f3349365..5a1c8cc7386 100644 --- a/frame/system/src/extensions/check_tx_version.rs +++ b/frame/system/src/extensions/check_tx_version.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Trait, Module}; +use crate::{Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::SignedExtension, @@ -24,9 +24,9 @@ use sp_runtime::{ /// Ensure the transaction version registered in the transaction is the same as at present. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckTxVersion(sp_std::marker::PhantomData); +pub struct CheckTxVersion(sp_std::marker::PhantomData); -impl sp_std::fmt::Debug for CheckTxVersion { +impl sp_std::fmt::Debug for CheckTxVersion { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckTxVersion") @@ -38,16 +38,16 @@ impl sp_std::fmt::Debug for CheckTxVersion { } } -impl CheckTxVersion { +impl CheckTxVersion { /// Create new `SignedExtension` to check transaction version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckTxVersion { +impl SignedExtension for CheckTxVersion { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = u32; type Pre = (); const IDENTIFIER: &'static str = "CheckTxVersion"; diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 39439a3e2d8..6dfff865d45 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Trait, Module}; +use crate::{Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::{SignedExtension, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Printable}, @@ -33,9 +33,9 @@ use frame_support::{ /// Block resource (weight) limit check. #[derive(Encode, Decode, Clone, Eq, PartialEq, Default)] -pub struct CheckWeight(sp_std::marker::PhantomData); +pub struct CheckWeight(sp_std::marker::PhantomData); -impl CheckWeight where +impl CheckWeight where T::Call: Dispatchable { /// Get the quota ratio of each dispatch class type. This indicates that all operational and mandatory @@ -213,7 +213,7 @@ impl CheckWeight where } } -impl SignedExtension for CheckWeight where +impl SignedExtension for CheckWeight where T::Call: Dispatchable { type AccountId = T::AccountId; @@ -294,7 +294,7 @@ impl SignedExtension for CheckWeight where } } -impl sp_std::fmt::Debug for CheckWeight { +impl sp_std::fmt::Debug for CheckWeight { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckWeight") @@ -316,11 +316,11 @@ mod tests { use frame_support::weights::{Weight, Pays}; fn normal_weight_limit() -> Weight { - ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() + ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() } fn normal_length_limit() -> u32 { - ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() + ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() } #[test] @@ -341,7 +341,7 @@ mod tests { check(|max, len| { assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); }); check(|max, len| { assert_ok!(CheckWeight::::do_validate(max, len)); @@ -352,7 +352,7 @@ mod tests { fn normal_extrinsic_limited_by_maximum_extrinsic_weight() { new_test_ext().execute_with(|| { let max = DispatchInfo { - weight: ::MaximumExtrinsicWeight::get() + 1, + weight: ::MaximumExtrinsicWeight::get() + 1, class: DispatchClass::Normal, ..Default::default() }; @@ -370,9 +370,9 @@ mod tests { new_test_ext().execute_with(|| { let operational_limit = CheckWeight::::get_dispatch_limit_ratio( DispatchClass::Operational - ) * ::MaximumBlockWeight::get(); - let base_weight = ::ExtrinsicBaseWeight::get(); - let block_base = ::BlockExecutionWeight::get(); + ) * ::MaximumBlockWeight::get(); + let base_weight = ::ExtrinsicBaseWeight::get(); + let block_base = ::BlockExecutionWeight::get(); let weight = operational_limit - base_weight - block_base; let okay = DispatchInfo { @@ -406,7 +406,7 @@ mod tests { new_test_ext().execute_with(|| { System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Normal); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); }); } @@ -426,8 +426,8 @@ mod tests { assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(System::block_weight().total(), 768); assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); // Checking single extrinsic should not take current block weight into account. assert_eq!(CheckWeight::::check_extrinsic_weight(&rest_operational), Ok(())); }); @@ -446,8 +446,8 @@ mod tests { // Extra 15 here from block execution + base extrinsic weight assert_eq!(System::block_weight().total(), 266); assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); }); } @@ -553,11 +553,11 @@ mod tests { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; let medium = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get(), + weight: normal_limit - ::ExtrinsicBaseWeight::get(), ..Default::default() }; let big = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, + weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, ..Default::default() }; let len = 0_usize; @@ -589,7 +589,7 @@ mod tests { // We allow 75% for normal transaction, so we put 25% - extrinsic base weight BlockWeight::mutate(|current_weight| { - current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) + current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); @@ -623,7 +623,7 @@ mod tests { let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), ); assert!( @@ -632,7 +632,7 @@ mod tests { ); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), ); }) } @@ -644,12 +644,12 @@ mod tests { let len = 0_usize; // Initial weight from `BlockExecutionWeight` - assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); + assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); assert!(r.is_ok()); assert_eq!( System::block_weight().total(), - ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() + ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() ); }) } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 595b001ea6b..af185139fb6 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -20,7 +20,7 @@ //! The System module provides low-level access to core types and cross-cutting utilities. //! It acts as the base layer for other pallets to interact with the Substrate framework components. //! -//! - [`system::Trait`](./trait.Trait.html) +//! - [`system::Config`](./trait.Config.html) //! //! ## Overview //! @@ -74,10 +74,10 @@ //! use frame_support::{decl_module, dispatch}; //! use frame_system::{self as system, ensure_signed}; //! -//! pub trait Trait: system::Trait {} +//! pub trait Config: system::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn system_module_example(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; @@ -160,7 +160,7 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { H::ordered_trie_root(xts) } -pub trait Trait: 'static + Eq + Clone { +pub trait Config: 'static + Eq + Clone { /// The basic call filter to use in Origin. All origins are built with this filter as base, /// except Root. type BaseCallFilter: Filter; @@ -270,8 +270,8 @@ pub trait Trait: 'static + Eq + Clone { type SystemWeightInfo: WeightInfo; } -pub type DigestOf = generic::Digest<::Hash>; -pub type DigestItemOf = generic::DigestItem<::Hash>; +pub type DigestOf = generic::Digest<::Hash>; +pub type DigestItemOf = generic::DigestItem<::Hash>; pub type Key = Vec; pub type KeyValue = (Vec, Vec); @@ -329,7 +329,7 @@ impl From> for RawOrigin { } /// Exposed trait-generic origin type. -pub type Origin = RawOrigin<::AccountId>; +pub type Origin = RawOrigin<::AccountId>; // Create a Hash with 69 for each byte, // only used to build genesis config. @@ -390,7 +390,7 @@ impl From for LastRuntimeUpgradeInfo { } decl_storage! { - trait Store for Module as System { + trait Store for Module as System { /// The full account information for a particular account ID. pub Account get(fn account): map hasher(blake2_128_concat) T::AccountId => AccountInfo; @@ -478,7 +478,7 @@ decl_storage! { decl_event!( /// Event for the System module. - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// An extrinsic completed successfully. \[info\] ExtrinsicSuccess(DispatchInfo), /// An extrinsic failed. \[error, info\] @@ -494,7 +494,7 @@ decl_event!( decl_error! { /// Error for the System module - pub enum Error for Module { + pub enum Error for Module { /// The name of specification does not match between the current runtime /// and the new runtime. InvalidSpecName, @@ -513,7 +513,7 @@ decl_error! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { + pub struct Module for enum Call where origin: T::Origin, system=self { type Error = Error; /// The maximum number of blocks to allow in mortal eras. @@ -897,7 +897,7 @@ pub enum RefStatus { Unreferenced, } -impl Module { +impl Module { /// Deposits an event into this block's event record. pub fn deposit_event(event: impl Into) { Self::deposit_event_indexed(&[], event.into()); @@ -1252,7 +1252,7 @@ impl Module { /// Event handler which calls on_created_account when it happens. pub struct CallOnCreatedAccount(PhantomData); -impl Happened for CallOnCreatedAccount { +impl Happened for CallOnCreatedAccount { fn happened(who: &T::AccountId) { Module::::on_created_account(who.clone()); } @@ -1260,15 +1260,15 @@ impl Happened for CallOnCreatedAccount { /// Event handler which calls kill_account when it happens. pub struct CallKillAccount(PhantomData); -impl Happened for CallKillAccount { +impl Happened for CallKillAccount { fn happened(who: &T::AccountId) { Module::::kill_account(who) } } -impl BlockNumberProvider for Module +impl BlockNumberProvider for Module { - type BlockNumber = ::BlockNumber; + type BlockNumber = ::BlockNumber; fn current_block_number() -> Self::BlockNumber { Module::::block_number() @@ -1278,7 +1278,7 @@ impl BlockNumberProvider for Module // Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for // storing a single item which is required to not be empty/default for the account to exist. // Anything more complex will need more sophisticated logic. -impl StoredMap for Module { +impl StoredMap for Module { fn get(k: &T::AccountId) -> T::AccountData { Account::::get(k).data } @@ -1345,7 +1345,7 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S } -impl IsDeadAccount for Module { +impl IsDeadAccount for Module { fn is_dead_account(who: &T::AccountId) -> bool { !Account::::contains_key(who) } @@ -1358,7 +1358,7 @@ impl Default for ChainContext { } } -impl Lookup for ChainContext { +impl Lookup for ChainContext { type Source = ::Source; type Target = ::Target; diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index cd67a741140..b6e1a4f35af 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -71,7 +71,7 @@ pub struct Call; impl Dispatchable for Call { type Origin = Origin; - type Trait = (); + type Config = (); type Info = DispatchInfo; type PostInfo = PostDispatchInfo; fn dispatch(self, _origin: Self::Origin) @@ -80,7 +80,7 @@ impl Dispatchable for Call { } } -impl Trait for Test { +impl Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -109,16 +109,16 @@ impl Trait for Test { } pub type System = Module; -pub type SysEvent = ::Event; +pub type SysEvent = ::Event; -pub const CALL: &::Call = &Call; +pub const CALL: &::Call = &Call; /// Create new externalities for `System` module tests. pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = GenesisConfig::default().build_storage::().unwrap().into(); // Add to each test the initial weight of a block ext.execute_with(|| System::register_extra_weight_unchecked( - ::BlockExecutionWeight::get(), + ::BlockExecutionWeight::get(), DispatchClass::Mandatory )); ext diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 25d18ac6bf2..f5186234b60 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -447,7 +447,7 @@ pub trait AppCrypto { /// // TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`? // Seems that this may cause issues with bounds resolution. -pub trait SigningTypes: crate::Trait { +pub trait SigningTypes: crate::Config { /// A public key that is capable of identifing `AccountId`s. /// /// Usually that's either a raw crypto public key (e.g. `sr25519::Public`) or diff --git a/frame/system/src/weights.rs b/frame/system/src/weights.rs index 5f3c84deb41..99ea4a033ca 100644 --- a/frame/system/src/weights.rs +++ b/frame/system/src/weights.rs @@ -54,7 +54,7 @@ pub trait WeightInfo { /// Weights for frame_system using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn remark(_b: u32, ) -> Weight { (1_973_000 as Weight) } diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index d546a34017d..66043cbe3aa 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -19,7 +19,7 @@ //! //! The Timestamp module provides functionality to get and set the on-chain time. //! -//! - [`timestamp::Trait`](./trait.Trait.html) +//! - [`timestamp::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) //! @@ -46,7 +46,7 @@ //! * `get` - Gets the current time for the current block. If this function is called prior to //! setting the timestamp, it will return the timestamp of the previous block. //! -//! ### Trait Getters +//! ### Config Getters //! //! * `MinimumPeriod` - Gets the minimum (and advised) period between blocks for the chain. //! @@ -66,10 +66,10 @@ //! # use pallet_timestamp as timestamp; //! use frame_system::ensure_signed; //! -//! pub trait Trait: timestamp::Trait {} +//! pub trait Config: timestamp::Config {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { +//! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 0] //! pub fn get_time(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; @@ -118,7 +118,7 @@ use sp_timestamp::{ pub use weights::WeightInfo; /// The module configuration trait -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// Type used for expressing timestamp. type Moment: Parameter + Default + AtLeast32Bit + Scale + Copy; @@ -137,7 +137,7 @@ pub trait Trait: frame_system::Trait { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// The minimum period between blocks. Beware that this is different to the *expected* period /// that the block production apparatus provides. Your chosen consensus system will generally /// work with this to determine a sensible block time. e.g. For Aura, it will be double this @@ -194,7 +194,7 @@ decl_module! { } decl_storage! { - trait Store for Module as Timestamp { + trait Store for Module as Timestamp { /// Current time for the current block. pub Now get(fn now): T::Moment; @@ -203,7 +203,7 @@ decl_storage! { } } -impl Module { +impl Module { /// Get the current time for the current block. /// /// NOTE: if this function is called prior to setting the timestamp, @@ -225,7 +225,7 @@ fn extract_inherent_data(data: &InherentData) -> Result ProvideInherent for Module { +impl ProvideInherent for Module { type Call = Call; type Error = InherentError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; @@ -260,7 +260,7 @@ impl ProvideInherent for Module { } } -impl Time for Module { +impl Time for Module { type Moment = T::Moment; /// Before the first set of now with inherent the value returned is zero. @@ -272,7 +272,7 @@ impl Time for Module { /// Before the timestamp inherent is applied, it returns the time of previous block. /// /// On genesis the time returned is not valid. -impl UnixTime for Module { +impl UnixTime for Module { fn now() -> core::time::Duration { // now is duration since unix epoch in millisecond as documented in // `sp_timestamp::InherentDataProvider`. @@ -314,7 +314,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -344,7 +344,7 @@ mod tests { parameter_types! { pub const MinimumPeriod: u64 = 5; } - impl Trait for Test { + impl Config for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; diff --git a/frame/timestamp/src/weights.rs b/frame/timestamp/src/weights.rs index 67ce28ba911..d3f2dcc7ba6 100644 --- a/frame/timestamp/src/weights.rs +++ b/frame/timestamp/src/weights.rs @@ -50,7 +50,7 @@ pub trait WeightInfo { /// Weights for pallet_timestamp using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn set() -> Weight { (11_650_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 751aa57da0f..554b2e801af 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -25,11 +25,11 @@ //! chance to be included by the transaction queue. //! //! Additionally, this module allows one to configure: -//! - The mapping between one unit of weight to one unit of fee via [`Trait::WeightToFee`]. +//! - The mapping between one unit of weight to one unit of fee via [`Config::WeightToFee`]. //! - A means of updating the fee for the next block, via defining a multiplier, based on the //! final state of the chain at the end of the previous block. This can be configured via -//! [`Trait::FeeMultiplierUpdate`] -//! - How the fees are paid via [`Trait::OnChargeTransaction`]. +//! [`Config::FeeMultiplierUpdate`] +//! - How the fees are paid via [`Config::OnChargeTransaction`]. #![cfg_attr(not(feature = "std"), no_std)] @@ -63,7 +63,7 @@ pub use payment::*; pub type Multiplier = FixedU128; type BalanceOf = - <::OnChargeTransaction as OnChargeTransaction>::Balance; + <::OnChargeTransaction as OnChargeTransaction>::Balance; /// A struct to update the weight multiplier per block. It implements `Convert`, meaning that it can convert the previous multiplier to the next one. This should @@ -135,7 +135,7 @@ impl MultiplierUpdate for () { } impl MultiplierUpdate for TargetedFeeAdjustment - where T: frame_system::Trait, S: Get, V: Get, M: Get, + where T: frame_system::Config, S: Get, V: Get, M: Get, { fn min() -> Multiplier { M::get() @@ -149,7 +149,7 @@ impl MultiplierUpdate for TargetedFeeAdjustment } impl Convert for TargetedFeeAdjustment - where T: frame_system::Trait, S: Get, V: Get, M: Get, + where T: frame_system::Config, S: Get, V: Get, M: Get, { fn convert(previous: Multiplier) -> Multiplier { // Defensive only. The multiplier in storage should always be at most positive. Nonetheless @@ -160,8 +160,8 @@ impl Convert for TargetedFeeAdjustment::AvailableBlockRatio::get() * - ::MaximumBlockWeight::get(); + ::AvailableBlockRatio::get() * + ::MaximumBlockWeight::get(); let normal_block_weight = >::block_weight() .get(frame_support::weights::DispatchClass::Normal) @@ -213,7 +213,7 @@ impl Default for Releases { } } -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// Handler for withdrawing, refunding and depositing the transaction fee. /// Transaction fees are withdrawn before the transaction is executed. /// After the transaction was executed the transaction weight can be @@ -233,7 +233,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as TransactionPayment { + trait Store for Module as TransactionPayment { pub NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::saturating_from_integer(1); StorageVersion build(|_: &GenesisConfig| Releases::V2): Releases; @@ -241,7 +241,7 @@ decl_storage! { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); @@ -263,7 +263,7 @@ decl_module! { assert!( ::max_value() >= Multiplier::checked_from_integer( - ::MaximumBlockWeight::get().try_into().unwrap() + ::MaximumBlockWeight::get().try_into().unwrap() ).unwrap(), ); @@ -296,7 +296,7 @@ decl_module! { } } -impl Module where +impl Module where BalanceOf: FixedPointOperand { /// Query the data that we know about the fee of a given `call`. @@ -407,13 +407,13 @@ impl Module where fn weight_to_fee(weight: Weight) -> BalanceOf { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. - let capped_weight = weight.min(::MaximumBlockWeight::get()); + let capped_weight = weight.min(::MaximumBlockWeight::get()); T::WeightToFee::calc(&capped_weight) } } impl Convert> for Module where - T: Trait, + T: Config, BalanceOf: FixedPointOperand, { /// Compute the fee for the specified weight. @@ -429,9 +429,9 @@ impl Convert> for Module where /// Require the transactor pay for themselves and maybe include a tip to gain additional priority /// in the queue. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); -impl ChargeTransactionPayment where +impl ChargeTransactionPayment where T::Call: Dispatchable, BalanceOf: Send + Sync + FixedPointOperand, { @@ -449,14 +449,14 @@ impl ChargeTransactionPayment where ) -> Result< ( BalanceOf, - <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, + <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ), TransactionValidityError, > { let tip = self.0; let fee = Module::::compute_fee(len as u32, info, tip); - <::OnChargeTransaction as OnChargeTransaction>::withdraw_fee(who, call, info, fee, tip) + <::OnChargeTransaction as OnChargeTransaction>::withdraw_fee(who, call, info, fee, tip) .map(|i| (fee, i)) } @@ -478,7 +478,7 @@ impl ChargeTransactionPayment where } } -impl sp_std::fmt::Debug for ChargeTransactionPayment { +impl sp_std::fmt::Debug for ChargeTransactionPayment { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "ChargeTransactionPayment<{:?}>", self.0) @@ -489,7 +489,7 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment } } -impl SignedExtension for ChargeTransactionPayment where +impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync + From + FixedPointOperand, T::Call: Dispatchable, { @@ -503,7 +503,7 @@ impl SignedExtension for ChargeTransactionPayment whe // who paid the fee Self::AccountId, // imbalance resulting from withdrawing the fee - <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, + <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -573,7 +573,7 @@ mod tests { }; use smallvec::smallvec; - const CALL: &::Call = + const CALL: &::Call = &Call::Balances(BalancesCall::transfer(2, 69)); impl_outer_dispatch! { @@ -608,7 +608,7 @@ mod tests { pub static WeightToFee: u64 = 1; } - impl frame_system::Trait for Runtime { + impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -640,7 +640,7 @@ mod tests { pub const ExistentialDeposit: u64 = 1; } - impl pallet_balances::Trait for Runtime { + impl pallet_balances::Config for Runtime { type Balance = u64; type Event = Event; type DustRemoval = (); @@ -663,7 +663,7 @@ mod tests { } } - impl Trait for Runtime { + impl Config for Runtime { type OnChargeTransaction = CurrencyAdapter; type TransactionByteFee = TransactionByteFee; type WeightToFee = WeightToFee; @@ -841,7 +841,7 @@ mod tests { // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 + (10000 - ::MaximumBlockWeight::get()) as u64 ); }); } diff --git a/frame/transaction-payment/src/payment.rs b/frame/transaction-payment/src/payment.rs index de39215b575..f84b19d78c2 100644 --- a/frame/transaction-payment/src/payment.rs +++ b/frame/transaction-payment/src/payment.rs @@ -1,5 +1,5 @@ ///! Traits and default implementation for paying transaction fees. -use crate::Trait; +use crate::Config; use codec::FullCodec; use frame_support::{ traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReasons}, @@ -12,10 +12,10 @@ use sp_runtime::{ use sp_std::{fmt::Debug, marker::PhantomData}; type NegativeImbalanceOf = - ::AccountId>>::NegativeImbalance; + ::AccountId>>::NegativeImbalance; /// Handle withdrawing, refunding and depositing of transaction fees. -pub trait OnChargeTransaction { +pub trait OnChargeTransaction { /// The underlying integer type in which fees are calculated. type Balance: AtLeast32BitUnsigned + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; type LiquidityInfo: Default; @@ -55,17 +55,17 @@ pub struct CurrencyAdapter(PhantomData<(C, OU)>); /// Default implementation for a Currency and an OnUnbalanced handler. impl OnChargeTransaction for CurrencyAdapter where - T: Trait, - T::TransactionByteFee: Get<::AccountId>>::Balance>, - C: Currency<::AccountId>, + T: Config, + T::TransactionByteFee: Get<::AccountId>>::Balance>, + C: Currency<::AccountId>, C::PositiveImbalance: - Imbalance<::AccountId>>::Balance, Opposite = C::NegativeImbalance>, + Imbalance<::AccountId>>::Balance, Opposite = C::NegativeImbalance>, C::NegativeImbalance: - Imbalance<::AccountId>>::Balance, Opposite = C::PositiveImbalance>, + Imbalance<::AccountId>>::Balance, Opposite = C::PositiveImbalance>, OU: OnUnbalanced>, { type LiquidityInfo = Option>; - type Balance = ::AccountId>>::Balance; + type Balance = ::AccountId>>::Balance; /// Withdraw the predicted fee from the transaction origin. /// diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 2794e6cc432..4606689e86d 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -30,7 +30,7 @@ use crate::Module as Treasury; const SEED: u32 = 0; // Create the pre-requisite information needed to create a treasury `propose_spend`. -fn setup_proposal, I: Instance>(u: u32) -> ( +fn setup_proposal, I: Instance>(u: u32) -> ( T::AccountId, BalanceOf, ::Source, @@ -44,7 +44,7 @@ fn setup_proposal, I: Instance>(u: u32) -> ( } // Create the pre-requisite information needed to create a `report_awesome`. -fn setup_awesome, I: Instance>(length: u32) -> (T::AccountId, Vec, T::AccountId) { +fn setup_awesome, I: Instance>(length: u32) -> (T::AccountId, Vec, T::AccountId) { let caller = whitelisted_caller(); let value = T::TipReportDepositBase::get() + T::DataDepositPerByte::get() * length.into() @@ -56,7 +56,7 @@ fn setup_awesome, I: Instance>(length: u32) -> (T::AccountId, Vec, I: Instance>(r: u32, t: u32) -> +fn setup_tip, I: Instance>(r: u32, t: u32) -> Result<(T::AccountId, Vec, T::AccountId, BalanceOf), &'static str> { let tippers_count = T::Tippers::count(); @@ -77,7 +77,7 @@ fn setup_tip, I: Instance>(r: u32, t: u32) -> // Create `t` new tips for the tip proposal with `hash`. // This function automatically makes the tip able to close. -fn create_tips, I: Instance>(t: u32, hash: T::Hash, value: BalanceOf) -> +fn create_tips, I: Instance>(t: u32, hash: T::Hash, value: BalanceOf) -> Result<(), &'static str> { for i in 0 .. t { @@ -94,7 +94,7 @@ fn create_tips, I: Instance>(t: u32, hash: T::Hash, value: BalanceOf } // Create proposals that are approved for use in `on_initialize`. -fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &'static str> { +fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &'static str> { for i in 0 .. n { let (caller, value, lookup) = setup_proposal::(i); Treasury::::propose_spend( @@ -110,7 +110,7 @@ fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &'s } // Create bounties that are approved for use in `on_initialize`. -fn create_approved_bounties, I: Instance>(n: u32) -> Result<(), &'static str> { +fn create_approved_bounties, I: Instance>(n: u32) -> Result<(), &'static str> { for i in 0 .. n { let (caller, _curator, _fee, value, reason) = setup_bounty::(i, MAX_BYTES); Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; @@ -122,7 +122,7 @@ fn create_approved_bounties, I: Instance>(n: u32) -> Result<(), &'st } // Create the pre-requisite information needed to create a treasury `propose_bounty`. -fn setup_bounty, I: Instance>(u: u32, d: u32) -> ( +fn setup_bounty, I: Instance>(u: u32, d: u32) -> ( T::AccountId, T::AccountId, BalanceOf, @@ -140,7 +140,7 @@ fn setup_bounty, I: Instance>(u: u32, d: u32) -> ( (caller, curator, fee, value, reason) } -fn create_bounty, I: Instance>() -> Result<( +fn create_bounty, I: Instance>() -> Result<( ::Source, BountyIndex, ), &'static str> { @@ -155,7 +155,7 @@ fn create_bounty, I: Instance>() -> Result<( Ok((curator_lookup, bounty_id)) } -fn setup_pod_account, I: Instance>() { +fn setup_pod_account, I: Instance>() { let pot_account = Treasury::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 2ada0660f9e..e180f64d1cb 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -20,7 +20,7 @@ //! The Treasury module provides a "pot" of funds that can be managed by stakeholders in the //! system and a structure for making spending proposals from this pot. //! -//! - [`treasury::Trait`](./trait.Trait.html) +//! - [`treasury::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -38,7 +38,7 @@ //! given without first having a pre-determined stakeholder group come to consensus on how much //! should be paid. //! -//! A group of `Tippers` is determined through the config `Trait`. After half of these have declared +//! A group of `Tippers` is determined through the config `Config`. After half of these have declared //! some amount that they believe a particular reported reason deserves, then a countdown period is //! entered where any remaining members can declare their tip amounts also. After the close of the //! countdown period, the median of all declared tips is paid to the reported beneficiary, along @@ -155,13 +155,13 @@ use frame_system::{self as system, ensure_signed}; pub use weights::WeightInfo; type BalanceOf = - <>::Currency as Currency<::AccountId>>::Balance; + <>::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = - <>::Currency as Currency<::AccountId>>::PositiveImbalance; + <>::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = - <>::Currency as Currency<::AccountId>>::NegativeImbalance; + <>::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The treasury's module id, used for deriving its sovereign account ID. type ModuleId: Get; @@ -192,7 +192,7 @@ pub trait Trait: frame_system::Trait { type DataDepositPerByte: Get>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced decrease when slashing for a rejected proposal or bounty. type OnSlash: OnUnbalanced>; @@ -332,7 +332,7 @@ pub enum BountyStatus { } decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Treasury { + trait Store for Module, I: Instance=DefaultInstance> as Treasury { /// Number of proposals that have been made. ProposalCount get(fn proposal_count): ProposalIndex; @@ -388,8 +388,8 @@ decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash, + ::AccountId, + ::Hash, { /// New proposal. \[proposal_index\] Proposed(ProposalIndex), @@ -433,7 +433,7 @@ decl_event!( decl_error! { /// Error for the treasury module. - pub enum Error for Module, I: Instance> { + pub enum Error for Module, I: Instance> { /// Proposer's balance is too low. InsufficientProposersBalance, /// No proposal or bounty at that index. @@ -465,7 +465,7 @@ decl_error! { } decl_module! { - pub struct Module, I: Instance=DefaultInstance> + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: T::Origin { @@ -1159,7 +1159,7 @@ decl_module! { } } -impl, I: Instance> Module { +impl, I: Instance> Module { // Add public immutables and private mutables. /// The account ID of the treasury pot. @@ -1452,7 +1452,7 @@ impl, I: Instance> Module { } } -impl, I: Instance> OnUnbalanced> for Module { +impl, I: Instance> OnUnbalanced> for Module { fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { let numeric_amount = amount.peek(); diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 88c4f23b91a..bbc38ddc8f8 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -59,7 +59,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -89,7 +89,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type Event = Event; @@ -140,7 +140,7 @@ parameter_types! { pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); pub const BountyValueMinimum: u64 = 1; } -impl Trait for Test { +impl Config for Test { type ModuleId = TreasuryModuleId; type Currency = pallet_balances::Module; type ApproveOrigin = frame_system::EnsureRoot; diff --git a/frame/treasury/src/weights.rs b/frame/treasury/src/weights.rs index 646b9869f47..013a27a5cdc 100644 --- a/frame/treasury/src/weights.rs +++ b/frame/treasury/src/weights.rs @@ -68,7 +68,7 @@ pub trait WeightInfo { /// Weights for pallet_treasury using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn propose_spend() -> Weight { (56_844_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs index 413ed66ac84..501e1b293bc 100644 --- a/frame/utility/src/benchmarking.rs +++ b/frame/utility/src/benchmarking.rs @@ -25,9 +25,9 @@ use frame_benchmarking::{benchmarks, account, whitelisted_caller}; const SEED: u32 = 0; -fn assert_last_event(generic_event: ::Event) { +fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); @@ -38,7 +38,7 @@ benchmarks! { batch { let c in 0 .. 1000; - let mut calls: Vec<::Call> = Vec::new(); + let mut calls: Vec<::Call> = Vec::new(); for i in 0 .. c { let call = frame_system::Call::remark(vec![]).into(); calls.push(call); @@ -59,7 +59,7 @@ benchmarks! { batch_all { let c in 0 .. 1000; - let mut calls: Vec<::Call> = Vec::new(); + let mut calls: Vec<::Call> = Vec::new(); for i in 0 .. c { let call = frame_system::Call::remark(vec![]).into(); calls.push(call); diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index e7ff09c8f0d..3aee32b250d 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -18,7 +18,7 @@ //! # Utility Module //! A stateless module with helpers for dispatch management which does no re-authentication. //! -//! - [`utility::Trait`](./trait.Trait.html) +//! - [`utility::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -50,7 +50,7 @@ //! * `as_derivative` - Dispatch a call from a derivative signed origin. //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -74,9 +74,9 @@ use sp_runtime::{DispatchError, traits::Dispatchable}; pub use weights::WeightInfo; /// Configuration trait. -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable @@ -88,7 +88,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as Utility {} + trait Store for Module as Utility {} } decl_event! { @@ -111,7 +111,7 @@ impl TypeId for IndexedUtilityModuleId { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// Deposit one of this module's events by using the default implementation. fn deposit_event() = default; @@ -122,7 +122,7 @@ decl_module! { /// - `calls`: The calls to be dispatched from the same origin. /// /// If origin is root then call are dispatch without checking origin filter. (This includes - /// bypassing `frame_system::Trait::BaseCallFilter`). + /// bypassing `frame_system::Config::BaseCallFilter`). /// /// # /// - Complexity: O(C) where C is the number of calls to be batched. @@ -149,7 +149,7 @@ decl_module! { } }, )] - fn batch(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { + fn batch(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); // Track the actual weight of each of the batch calls. @@ -197,7 +197,7 @@ decl_module! { .saturating_add(T::DbWeight::get().reads_writes(1, 1)), call.get_dispatch_info().class, )] - fn as_derivative(origin, index: u16, call: Box<::Call>) -> DispatchResultWithPostInfo { + fn as_derivative(origin, index: u16, call: Box<::Call>) -> DispatchResultWithPostInfo { let mut origin = origin; let who = ensure_signed(origin.clone())?; let pseudonym = Self::derivative_account_id(who, index); @@ -222,7 +222,7 @@ decl_module! { /// - `calls`: The calls to be dispatched from the same origin. /// /// If origin is root then call are dispatch without checking origin filter. (This includes - /// bypassing `frame_system::Trait::BaseCallFilter`). + /// bypassing `frame_system::Config::BaseCallFilter`). /// /// # /// - Complexity: O(C) where C is the number of calls to be batched. @@ -244,7 +244,7 @@ decl_module! { }, )] #[transactional] - fn batch_all(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { + fn batch_all(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); // Track the actual weight of each of the batch calls. @@ -274,7 +274,7 @@ decl_module! { } } -impl Module { +impl Module { /// Derive a derivative account ID from the owner account and the sub-account index. pub fn derivative_account_id(who: T::AccountId, index: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, index).using_encoded(blake2_256); diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index a3c33bdf208..5c1cbaf94cb 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -37,10 +37,10 @@ use crate as utility; pub mod example { use super::*; use frame_support::dispatch::WithPostDispatchInfo; - pub trait Trait: frame_system::Trait { } + pub trait Config: frame_system::Config { } decl_module! { - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { #[weight = *weight] fn noop(_origin, weight: Weight) { } @@ -97,7 +97,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; type Origin = Origin; type Index = u64; @@ -127,7 +127,7 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; } -impl pallet_balances::Trait for Test { +impl pallet_balances::Config for Test { type MaxLocks = (); type Balance = u64; type DustRemoval = (); @@ -142,7 +142,7 @@ parameter_types! { pub const MaxSignatories: u16 = 3; } -impl example::Trait for Test {} +impl example::Config for Test {} pub struct TestBaseCallFilter; impl Filter for TestBaseCallFilter { @@ -158,7 +158,7 @@ impl Filter for TestBaseCallFilter { } } } -impl Trait for Test { +impl Config for Test { type Event = TestEvent; type Call = Call; type WeightInfo = (); @@ -428,7 +428,7 @@ fn batch_handles_weight_refund() { assert_eq!( extract_actual_weight(&result, &info), // Real weight is 2 calls at end_weight - ::WeightInfo::batch(2) + end_weight * 2, + ::WeightInfo::batch(2) + end_weight * 2, ); }); } @@ -465,7 +465,7 @@ fn batch_all_revert() { ]), DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: Some(::WeightInfo::batch_all(2) + info.weight * 2), + actual_weight: Some(::WeightInfo::batch_all(2) + info.weight * 2), pays_fee: Pays::Yes }, error: pallet_balances::Error::::InsufficientBalance.into() @@ -536,7 +536,7 @@ fn batch_all_handles_weight_refund() { assert_eq!( extract_actual_weight(&result, &info), // Real weight is 2 calls at end_weight - ::WeightInfo::batch_all(2) + end_weight * 2, + ::WeightInfo::batch_all(2) + end_weight * 2, ); }); } diff --git a/frame/utility/src/weights.rs b/frame/utility/src/weights.rs index 73e4e3b1d93..c03ef0d064b 100644 --- a/frame/utility/src/weights.rs +++ b/frame/utility/src/weights.rs @@ -51,7 +51,7 @@ pub trait WeightInfo { /// Weights for pallet_utility using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn batch(c: u32, ) -> Weight { (20_071_000 as Weight) .saturating_add((2_739_000 as Weight).saturating_mul(c as Weight)) diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 652d10aab3a..0cb030668d0 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -29,9 +29,9 @@ use crate::Module as Vesting; const SEED: u32 = 0; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -fn add_locks(who: &T::AccountId, n: u8) { +fn add_locks(who: &T::AccountId, n: u8) { for id in 0..n { let lock_id = [id; 8]; let locked = 100u32; @@ -40,7 +40,7 @@ fn add_locks(who: &T::AccountId, n: u8) { } } -fn add_vesting_schedule(who: &T::AccountId) -> Result<(), &'static str> { +fn add_vesting_schedule(who: &T::AccountId) -> Result<(), &'static str> { let locked = 100u32; let per_block = 10u32; let starting_block = 1u32; diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index c09516c2cc2..4dbe27649ce 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -17,7 +17,7 @@ //! # Vesting Module //! -//! - [`vesting::Trait`](./trait.Trait.html) +//! - [`vesting::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview @@ -43,7 +43,7 @@ //! "vested" so far. //! //! [`Call`]: ./enum.Call.html -//! [`Trait`]: ./trait.Trait.html +//! [`Config`]: ./trait.Config.html #![cfg_attr(not(feature = "std"), no_std)] @@ -64,12 +64,12 @@ use frame_support::traits::{ use frame_system::{ensure_signed, ensure_root}; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type MaxLocksOf = <::Currency as LockableCurrency<::AccountId>>::MaxLocks; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type MaxLocksOf = <::Currency as LockableCurrency<::AccountId>>::MaxLocks; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: LockableCurrency; @@ -120,7 +120,7 @@ impl< } decl_storage! { - trait Store for Module as Vesting { + trait Store for Module as Vesting { /// Information regarding the vesting of a given account. pub Vesting get(fn vesting): map hasher(blake2_128_concat) T::AccountId @@ -156,7 +156,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// The amount vested has been updated. This could indicate more funds are available. The /// balance given is the amount which is left unvested (and thus locked). /// \[account, unvested\] @@ -168,7 +168,7 @@ decl_event!( decl_error! { /// Error for the vesting module. - pub enum Error for Module { + pub enum Error for Module { /// The account given is not vesting. NotVesting, /// An existing vesting schedule already exists for this account that cannot be clobbered. @@ -180,7 +180,7 @@ decl_error! { decl_module! { /// Vesting module declaration. - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { type Error = Error; /// The minimum amount to be transferred to create a new vesting schedule. @@ -309,7 +309,7 @@ decl_module! { } } -impl Module { +impl Module { /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their /// current unvested amount. fn update_lock(who: T::AccountId) -> DispatchResult { @@ -330,7 +330,7 @@ impl Module { } } -impl VestingSchedule for Module where +impl VestingSchedule for Module where BalanceOf: MaybeSerializeDeserialize + Debug { type Moment = T::BlockNumber; @@ -413,7 +413,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -443,7 +443,7 @@ mod tests { parameter_types! { pub const MaxLocks: u32 = 10; } - impl pallet_balances::Trait for Test { + impl pallet_balances::Config for Test { type Balance = u64; type DustRemoval = (); type Event = (); @@ -456,7 +456,7 @@ mod tests { pub const MinVestedTransfer: u64 = 256 * 2; pub static ExistentialDeposit: u64 = 0; } - impl Trait for Test { + impl Config for Test { type Event = (); type Currency = Balances; type BlockNumberToBalance = Identity; diff --git a/frame/vesting/src/weights.rs b/frame/vesting/src/weights.rs index 23a46ec763d..3d2d6dd9670 100644 --- a/frame/vesting/src/weights.rs +++ b/frame/vesting/src/weights.rs @@ -54,7 +54,7 @@ pub trait WeightInfo { /// Weights for pallet_vesting using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { fn vest_locked(l: u32, ) -> Weight { (57_472_000 as Weight) .saturating_add((155_000 as Weight).saturating_mul(l as Weight)) diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 85f5a1797b1..5839618e373 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -410,7 +410,7 @@ fn extend_with_runtime_decl_path(mut trait_: Path) -> Path { .segments .last() .as_ref() - .expect("Trait path should always contain at least one item; qed") + .expect("Config path should always contain at least one item; qed") .ident; generate_runtime_mod_name_for_trait(trait_name) diff --git a/primitives/runtime/src/offchain/storage_lock.rs b/primitives/runtime/src/offchain/storage_lock.rs index a3838f21fd1..451753931ec 100644 --- a/primitives/runtime/src/offchain/storage_lock.rs +++ b/primitives/runtime/src/offchain/storage_lock.rs @@ -438,11 +438,11 @@ pub trait BlockNumberProvider { /// /// In case of using crate `sp_runtime` without the crate `frame` /// system, it is already implemented for - /// `frame_system::Module` as: + /// `frame_system::Module` as: /// /// ```ignore /// fn current_block_number() -> Self { - /// frame_system::Module::block_number() + /// frame_system::Module::block_number() /// } /// ``` /// . diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 4ce9ac0afa9..d475be3579b 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -693,7 +693,7 @@ pub trait Dispatchable { /// identifier for the caller. The origin can be empty in the case of an inherent extrinsic. type Origin; /// ... - type Trait; + type Config; /// An opaque set of information attached to the transaction. This could be constructed anywhere /// down the line in a runtime. The current Substrate runtime uses a struct with the same name /// to represent the dispatch class and weight. @@ -712,7 +712,7 @@ pub type PostDispatchInfoOf = ::PostInfo; impl Dispatchable for () { type Origin = (); - type Trait = (); + type Config = (); type Info = (); type PostInfo = (); fn dispatch(self, _origin: Self::Origin) -> crate::DispatchResultWithInfo { diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 20244677710..b4a69a491d5 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -197,7 +197,7 @@ impl ExtrinsicT for Extrinsic { impl sp_runtime::traits::Dispatchable for Extrinsic { type Origin = Origin; - type Trait = (); + type Config = (); type Info = (); type PostInfo = (); fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { @@ -436,7 +436,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Call = Extrinsic; @@ -464,7 +464,7 @@ impl frame_system::Trait for Runtime { type SystemWeightInfo = (); } -impl pallet_timestamp::Trait for Runtime { +impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = (); @@ -477,7 +477,7 @@ parameter_types! { pub const ExpectedBlockTime: u64 = 10_000; } -impl pallet_babe::Trait for Runtime { +impl pallet_babe::Config for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; // there is no actual runtime in this test-runtime, so testing crates diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index 818487a89e5..db22a6092c7 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -32,7 +32,7 @@ use sp_runtime::{ }, }; use codec::{KeyedVec, Encode, Decode}; -use frame_system::Trait; +use frame_system::Config; use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId }; @@ -42,11 +42,11 @@ const NONCE_OF: &[u8] = b"nonce:"; const BALANCE_OF: &[u8] = b"balance:"; decl_module! { - pub struct Module for enum Call where origin: T::Origin {} + pub struct Module for enum Call where origin: T::Origin {} } decl_storage! { - trait Store for Module as TestRuntime { + trait Store for Module as TestRuntime { ExtrinsicData: map hasher(blake2_128_concat) u32 => Vec; // The current block number being processed. Set by `execute_block`. Number get(fn number): Option; diff --git a/utils/frame/frame-utilities-cli/src/module_id.rs b/utils/frame/frame-utilities-cli/src/module_id.rs index cc76c70d0fa..ae26f31ad24 100644 --- a/utils/frame/frame-utilities-cli/src/module_id.rs +++ b/utils/frame/frame-utilities-cli/src/module_id.rs @@ -64,7 +64,7 @@ impl ModuleIdCmd { /// runs the command pub fn run(&self) -> Result<(), Error> where - R: frame_system::Trait, + R: frame_system::Config, R::AccountId: Ss58Codec, { if self.id.len() != 8 { diff --git a/utils/frame/rpc/support/src/lib.rs b/utils/frame/rpc/support/src/lib.rs index dc87d618520..85cb433cb2b 100644 --- a/utils/frame/rpc/support/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -40,11 +40,11 @@ use sc_rpc_api::state::StateClient; /// # use codec::Encode; /// # use frame_support::{decl_storage, decl_module}; /// # use substrate_frame_rpc_support::StorageQuery; -/// # use frame_system::Trait; +/// # use frame_system::Config; /// # use sc_rpc_api::state::StateClient; /// # -/// # // Hash would normally be ::Hash, but we don't have -/// # // frame_system::Trait implemented for TestRuntime. Here we just pretend. +/// # // Hash would normally be ::Hash, but we don't have +/// # // frame_system::Config implemented for TestRuntime. Here we just pretend. /// # type Hash = (); /// # /// # fn main() -> Result<(), RpcError> { @@ -54,7 +54,7 @@ use sc_rpc_api::state::StateClient; /// # struct TestRuntime; /// # /// # decl_module! { -/// # pub struct Module for enum Call where origin: T::Origin {} +/// # pub struct Module for enum Call where origin: T::Origin {} /// # } /// # /// pub type Loc = (i64, i64, i64); @@ -62,7 +62,7 @@ use sc_rpc_api::state::StateClient; /// /// // Note that all fields are marked pub. /// decl_storage! { -/// trait Store for Module as TestRuntime { +/// trait Store for Module as TestRuntime { /// pub LastActionId: u64; /// pub Voxels: map hasher(blake2_128_concat) Loc => Block; /// pub Actions: map hasher(blake2_128_concat) u64 => Loc; @@ -125,7 +125,7 @@ impl StorageQuery { /// Send this query over RPC, await the typed result. /// - /// Hash should be ::Hash. + /// Hash should be ::Hash. /// /// # Arguments /// -- GitLab From 21fe14af6e830023bdd2781bd89bf8012585a8a1 Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Mon, 30 Nov 2020 16:53:33 +0100 Subject: [PATCH 065/163] resolve unresolved error nits of #7617 (#7631) * handle executor should_panic test better * Revert "reduce should panic, due to extended error messages" This reverts commit c0805940184a62cd9302603ad911c3591e70a60c. * remove excessive constraints * remove duplicate documentation messages for error variants * reduce T: constraints to the abs minimum * whoops * fewer bounds again Co-authored-by: Bernhard Schuster --- Cargo.lock | 2 +- client/consensus/slots/src/lib.rs | 4 +- client/executor/common/src/error.rs | 56 +++++++++----------- client/executor/src/integration_tests/mod.rs | 2 +- client/transaction-pool/graph/src/error.rs | 20 +++---- primitives/allocator/Cargo.toml | 6 +-- primitives/allocator/src/error.rs | 16 ++---- 7 files changed, 46 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 446b4442cd0..190dbaf7179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7977,11 +7977,11 @@ dependencies = [ name = "sp-allocator" version = "2.0.0" dependencies = [ - "derive_more", "log", "sp-core", "sp-std", "sp-wasm-interface", + "thiserror", ] [[package]] diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index ab8fc16007c..571766bc44b 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -475,7 +475,7 @@ pub enum CheckedHeader { #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] -pub enum Error where T: SlotData + Clone + Debug + Send + Sync + 'static { +pub enum Error where T: Debug { #[error("Slot duration is invalid: {0:?}")] SlotDurationInvalid(SlotDuration), } @@ -493,7 +493,7 @@ impl Deref for SlotDuration { } } -impl SlotData for SlotDuration { +impl SlotData for SlotDuration { /// Get the slot duration in milliseconds. fn slot_duration(&self) -> u64 where T: SlotData, diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index caf6159da07..df0eaf8cc26 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -28,75 +28,69 @@ pub type Result = std::result::Result; #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum Error { - /// Unserializable Data #[error("Unserializable data encountered")] InvalidData(#[from] sp_serializer::Error), - /// Trap occurred during execution + #[error(transparent)] Trap(#[from] wasmi::Trap), - /// Wasmi loading/instantiating error + #[error(transparent)] Wasmi(#[from] wasmi::Error), - /// Error in the API. Parameter is an error message. + #[error("API Error: {0}")] ApiError(String), - /// Method is not found + #[error("Method not found: '{0}'")] MethodNotFound(String), - /// Code is invalid (expected single byte) - #[error("Invalid Code: '{0}'")] + + #[error("Invalid Code (expected single byte): '{0}'")] InvalidCode(String), - /// Could not get runtime version. + #[error("On-chain runtime does not specify version")] VersionInvalid, - /// Externalities have failed. + #[error("Externalities error")] Externalities, - /// Invalid index. + #[error("Invalid index provided")] InvalidIndex, - /// Invalid return type. + #[error("Invalid type returned (should be u64)")] InvalidReturn, - /// Runtime failed. + #[error("Runtime error")] Runtime, - /// Runtime panicked. + #[error("Runtime panicked: {0}")] RuntimePanicked(String), - /// Invalid memory reference. + #[error("Invalid memory reference")] InvalidMemoryReference, - /// The runtime must provide a global named `__heap_base` of type i32 for specifying where the - /// allocator is allowed to place its data. - #[error("The runtime doesn't provide a global named `__heap_base`")] + + #[error("The runtime doesn't provide a global named `__heap_base` of type `i32`")] HeapBaseNotFoundOrInvalid, - /// The runtime WebAssembly module is not allowed to have the `start` function. - #[error("The runtime has the `start` function")] + + #[error("The runtime must not have the `start` function defined")] RuntimeHasStartFn, - /// Some other error occurred + #[error("Other: {0}")] Other(String), - /// Some error occurred in the allocator - #[error("Allocation Error")] + + #[error(transparent)] Allocator(#[from] sp_allocator::Error), - /// Execution of a host function failed. + #[error("Host function {0} execution failed with: {1}")] FunctionExecution(String, String), - /// No table is present. - /// - /// Call was requested that requires table but none was present in the instance. + #[error("No table exported by wasm blob")] NoTable, - /// No table entry is present. - /// - /// Call was requested that requires specific entry in the table to be present. + #[error("No table entry with index {0} in wasm blob exported table")] NoTableEntryWithIndex(u32), - /// Table entry is not a function. + #[error("Table element with index {0} is not a function in wasm blob exported table")] TableElementIsNotAFunction(u32), - /// Function in table is null and thus cannot be called. + #[error("Table entry with index {0} in wasm blob is null")] FunctionRefIsNull(u32), diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 62368441f58..d41784f5aa0 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -523,7 +523,7 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] -#[should_panic] +#[should_panic(expected = "Allocator ran out of space")] fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); diff --git a/client/transaction-pool/graph/src/error.rs b/client/transaction-pool/graph/src/error.rs index b599715920b..01fcb9f8dc9 100644 --- a/client/transaction-pool/graph/src/error.rs +++ b/client/transaction-pool/graph/src/error.rs @@ -32,36 +32,36 @@ pub enum Error { /// Transaction is not verifiable yet, but might be in the future. #[error("Unknown transaction validity: {0:?}")] UnknownTransaction(UnknownTransaction), - /// Transaction is invalid. + #[error("Invalid transaction validity: {0:?}")] InvalidTransaction(InvalidTransaction), /// The transaction validity returned no "provides" tag. /// /// Such transactions are not accepted to the pool, since we use those tags /// to define identity of transactions (occupance of the same "slot"). - #[error("The transaction does not provide any tags, so the pool can't identify it.")] + #[error("The transaction validity returned no `provides` tags, so the pool can't identify it.")] NoTagsProvided, #[error("Temporarily Banned")] TemporarilyBanned, - /// The transaction is already in the pool. - #[error("[{0:?}] Already imported")] + + #[error("[{0:?}] Transaction is already in the pool")] AlreadyImported(Box), - /// The transaction cannot be imported cause it's a replacement and has too low priority. - #[error("Too low priority ({0} > {1})", old, new)] + + #[error("Transaction cannot be imported due to too low priority ({0} > {1})", old, new)] TooLowPriority { /// Transaction already in the pool. old: Priority, /// Transaction entering the pool. new: Priority }, - /// Deps cycle detected and we couldn't import transaction. - #[error("Cycle Detected")] + + #[error("Dependency cycle detected")] CycleDetected, - /// Transaction was dropped immediately after it got inserted. + #[error("Transaction couldn't enter the pool because of the limit.")] ImmediatelyDropped, - /// Invalid block id. + #[error("Invlaid block id: {0}")] InvalidBlockId(String), } diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 93991a4aeb2..130723730c4 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -17,8 +17,8 @@ targets = ["x86_64-unknown-linux-gnu"] sp-std = { version = "2.0.0", path = "../std", default-features = false } sp-core = { version = "2.0.0", path = "../core", default-features = false } sp-wasm-interface = { version = "2.0.0", path = "../wasm-interface", default-features = false } -log = { version = "0.4.8", optional = true } -derive_more = { version = "0.99.2", optional = true } +log = { version = "0.4.11", optional = true } +thiserror = { version = "1.0.21", optional = true } [features] default = [ "std" ] @@ -27,5 +27,5 @@ std = [ "sp-core/std", "sp-wasm-interface/std", "log", - "derive_more", + "thiserror", ] diff --git a/primitives/allocator/src/error.rs b/primitives/allocator/src/error.rs index 7b634af4d5b..77c911cef9d 100644 --- a/primitives/allocator/src/error.rs +++ b/primitives/allocator/src/error.rs @@ -17,23 +17,15 @@ /// The error type used by the allocators. #[derive(sp_core::RuntimeDebug)] -#[cfg_attr(feature = "std", derive(derive_more::Display))] +#[cfg_attr(feature = "std", derive(thiserror::Error))] pub enum Error { /// Someone tried to allocate more memory than the allowed maximum per allocation. - #[cfg_attr(feature = "std", display(fmt="Requested allocation size is too large"))] + #[cfg_attr(feature = "std", error("Requested allocation size is too large"))] RequestedAllocationTooLarge, /// Allocator run out of space. - #[cfg_attr(feature = "std", display(fmt="Allocator ran out of space"))] + #[cfg_attr(feature = "std", error("Allocator ran out of space"))] AllocatorOutOfSpace, /// Some other error occurred. + #[cfg_attr(feature = "std", error("Other: {0}"))] Other(&'static str) } - -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - _ => None, - } - } -} -- GitLab From f5088c50a8361f9efc71a75754b0776b6e24ab8a Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 30 Nov 2020 18:43:47 +0100 Subject: [PATCH 066/163] Fix bad state transition with DisabledPendingEnable+OpenDesiredByRemote (#7638) --- .../src/protocol/generic_proto/behaviour.rs | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index f76b3cc7160..51d7252d5f9 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -1575,34 +1575,20 @@ impl NetworkBehaviour for GenericProto { } } - // DisabledPendingEnable => DisabledPendingEnable | Incoming + // DisabledPendingEnable => Enabled | DisabledPendingEnable PeerState::DisabledPendingEnable { mut connections, timer, timer_deadline } => { if let Some((_, connec_state)) = connections.iter_mut().find(|(c, _)| *c == connection) { if let ConnectionState::Closed = *connec_state { - *connec_state = ConnectionState::OpenDesiredByRemote; - - let incoming_id = self.next_incoming_index; - self.next_incoming_index.0 = match self.next_incoming_index.0.checked_add(1) { - Some(v) => v, - None => { - error!(target: "sub-libp2p", "Overflow in next_incoming_index"); - return - } - }; - - debug!(target: "sub-libp2p", "PSM <= Incoming({}, {:?}).", - source, incoming_id); - self.peerset.incoming(source.clone(), incoming_id); - self.incoming.push(IncomingPeer { + debug!(target: "sub-libp2p", "Handler({:?}, {:?}) <= Open", + source, connection); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: source.clone(), - alive: true, - incoming_id, + handler: NotifyHandler::One(connection), + event: NotifsHandlerIn::Open, }); + *connec_state = ConnectionState::Opening; - *entry.into_mut() = PeerState::Incoming { - connections, - backoff_until: Some(timer_deadline), - }; + *entry.into_mut() = PeerState::Enabled { connections }; } else { // Connections in `OpeningThenClosing` are in a Closed phase, and -- GitLab From 125cf193f424f80fdba9efb0fb92ada9a4a96749 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Mon, 30 Nov 2020 21:33:49 +0100 Subject: [PATCH 067/163] Renames of `Trait` to `Config` in README.md, weight templates and few minor ones (#7636) * manual rename * renamse in README.md * fix template --- .maintain/frame-weight-template.hbs | 2 +- bin/node-template/README.md | 6 +-- frame/assets/README.md | 8 +-- frame/atomic-swap/README.md | 2 +- frame/aura/README.md | 2 +- frame/balances/README.md | 12 ++--- frame/benchmarking/src/tests.rs | 12 ++--- frame/contracts/README.md | 2 +- frame/democracy/README.md | 2 +- frame/elections-phragmen/README.md | 2 +- frame/example-offchain-worker/README.md | 2 +- frame/example/README.md | 4 +- frame/identity/README.md | 4 +- frame/im-online/README.md | 6 +-- frame/multisig/README.md | 4 +- frame/nicks/README.md | 4 +- frame/offences/benchmarking/src/lib.rs | 54 +++++++++---------- frame/proxy/README.md | 4 +- frame/randomness-collective-flip/README.md | 4 +- frame/recovery/README.md | 2 +- frame/scheduler/README.md | 4 +- frame/scored-pool/README.md | 6 +-- frame/session/README.md | 4 +- frame/session/src/historical/offchain.rs | 8 +-- frame/session/src/historical/onchain.rs | 12 ++--- frame/society/README.md | 2 +- frame/staking/README.md | 14 ++--- frame/sudo/README.md | 8 +-- frame/system/README.md | 6 +-- frame/timestamp/README.md | 8 +-- frame/transaction-payment/README.md | 4 +- frame/treasury/README.md | 4 +- frame/utility/README.md | 4 +- frame/vesting/README.md | 4 +- .../api/proc-macro/src/impl_runtime_apis.rs | 2 +- utils/frame/benchmarking-cli/src/template.hbs | 2 +- 36 files changed, 115 insertions(+), 115 deletions(-) diff --git a/.maintain/frame-weight-template.hbs b/.maintain/frame-weight-template.hbs index aac37f0833c..6e555da968d 100644 --- a/.maintain/frame-weight-template.hbs +++ b/.maintain/frame-weight-template.hbs @@ -45,7 +45,7 @@ pub trait WeightInfo { /// Weights for {{pallet}} using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { +impl WeightInfo for SubstrateWeight { {{~#each benchmarks as |benchmark|}} fn {{benchmark.name~}} ( diff --git a/bin/node-template/README.md b/bin/node-template/README.md index c1aeefe8950..8c8b82a14bb 100644 --- a/bin/node-template/README.md +++ b/bin/node-template/README.md @@ -157,7 +157,7 @@ Review the [FRAME runtime implementation](./runtime/src/lib.rs) included in this the following: - This file configures several pallets to include in the runtime. Each pallet configuration is - defined by a code block that begins with `impl $PALLET_NAME::Trait for Runtime`. + defined by a code block that begins with `impl $PALLET_NAME::Config for Runtime`. - The pallets are composed into a single runtime by way of the [`construct_runtime!`](https://crates.parity.io/frame_support/macro.construct_runtime.html) macro, which is part of the core @@ -181,8 +181,8 @@ A FRAME pallet is compromised of a number of blockchain primitives: - Events: Substrate uses [events](https://substrate.dev/docs/en/knowledgebase/runtime/events) to notify users of important changes in the runtime. - Errors: When a dispatchable fails, it returns an error. -- Trait: The `Trait` configuration interface is used to define the types and parameters upon which - a FRAME pallet depends. +- Config: The `Config` configuration interface is used to define the types and parameters upon + which a FRAME pallet depends. ## Generate a Custom Node Template diff --git a/frame/assets/README.md b/frame/assets/README.md index 6b3fe21e527..804856f90d0 100644 --- a/frame/assets/README.md +++ b/frame/assets/README.md @@ -11,7 +11,7 @@ with a fixed supply, including: * Asset Transfer * Asset Destruction -To use it in your runtime, you need to implement the assets [`Trait`](https://docs.rs/pallet-assets/latest/pallet_assets/trait.Trait.html). +To use it in your runtime, you need to implement the assets [`Config`](https://docs.rs/pallet-assets/latest/pallet_assets/trait.Config.html). The supported dispatchable functions are documented in the [`Call`](https://docs.rs/pallet-assets/latest/pallet_assets/enum.Call.html) enum. @@ -72,10 +72,10 @@ use pallet_assets as assets; use frame_support::{decl_module, dispatch, ensure}; use frame_system::ensure_signed; -pub trait Trait: assets::Trait { } +pub trait Config: assets::Config { } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { pub fn issue_token_airdrop(origin) -> dispatch::DispatchResult { let sender = ensure_signed(origin).map_err(|e| e.as_str())?; @@ -106,7 +106,7 @@ Below are assumptions that must be held when using this module. If any of them are violated, the behavior of this module is undefined. * The total count of assets should be less than - `Trait::AssetId::max_value()`. + `Config::AssetId::max_value()`. ## Related Modules diff --git a/frame/atomic-swap/README.md b/frame/atomic-swap/README.md index 1287e90bc0d..eeac282f1d5 100644 --- a/frame/atomic-swap/README.md +++ b/frame/atomic-swap/README.md @@ -2,7 +2,7 @@ A module for atomically sending funds. -- [`atomic_swap::Trait`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/trait.Trait.html) +- [`atomic_swap::Config`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/trait.Config.html) - [`Call`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/enum.Call.html) - [`Module`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/struct.Module.html) diff --git a/frame/aura/README.md b/frame/aura/README.md index 4f3eacbad8a..253e0d3651c 100644 --- a/frame/aura/README.md +++ b/frame/aura/README.md @@ -1,6 +1,6 @@ # Aura Module -- [`aura::Trait`](https://docs.rs/pallet-aura/latest/pallet_aura/trait.Trait.html) +- [`aura::Config`](https://docs.rs/pallet-aura/latest/pallet_aura/trait.Config.html) - [`Module`](https://docs.rs/pallet-aura/latest/pallet_aura/struct.Module.html) ## Overview diff --git a/frame/balances/README.md b/frame/balances/README.md index a93ed5f306e..9a2f3c394c9 100644 --- a/frame/balances/README.md +++ b/frame/balances/README.md @@ -2,7 +2,7 @@ The Balances module provides functionality for handling accounts and balances. -- [`balances::Trait`](https://docs.rs/pallet-balances/latest/pallet_balances/trait.Trait.html) +- [`balances::Config`](https://docs.rs/pallet-balances/latest/pallet_balances/trait.Config.html) - [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/enum.Call.html) - [`Module`](https://docs.rs/pallet-balances/latest/pallet_balances/struct.Module.html) @@ -83,8 +83,8 @@ The Contract module uses the `Currency` trait to handle gas payment, and its typ ```rust use frame_support::traits::Currency; -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; ``` @@ -93,11 +93,11 @@ The Staking module uses the `LockableCurrency` trait to lock a stash account's f ```rust use frame_support::traits::{WithdrawReasons, LockableCurrency}; use sp_runtime::traits::Bounded; -pub trait Trait: frame_system::Trait { +pub trait Config: frame_system::Config { type Currency: LockableCurrency; } -fn update_ledger( +fn update_ledger( controller: &T::AccountId, ledger: &StakingLedger ) { @@ -117,6 +117,6 @@ The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-bala ## Assumptions -* Total issued balanced of all accounts should be less than `Trait::Balance::max_value()`. +* Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. License: Apache-2.0 \ No newline at end of file diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 05a61ee83fb..70359f2065e 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -30,7 +30,7 @@ use frame_system::{RawOrigin, ensure_signed, ensure_none}; decl_storage! { trait Store for Module as Test where - ::OtherEvent: Into<::Event> + ::OtherEvent: Into<::Event> { Value get(fn value): Option; } @@ -38,7 +38,7 @@ decl_storage! { decl_module! { pub struct Module for enum Call where - origin: T::Origin, ::OtherEvent: Into<::Event> + origin: T::Origin, ::OtherEvent: Into<::Event> { #[weight = 0] fn set_value(origin, n: u32) -> DispatchResult { @@ -59,11 +59,11 @@ impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } -pub trait OtherTrait { +pub trait OtherConfig { type OtherEvent; } -pub trait Config: frame_system::Config + OtherTrait +pub trait Config: frame_system::Config + OtherConfig where Self::OtherEvent: Into<::Event> { type Event; @@ -104,7 +104,7 @@ impl Config for Test { type Event = (); } -impl OtherTrait for Test { +impl OtherConfig for Test { type OtherEvent = (); } @@ -113,7 +113,7 @@ fn new_test_ext() -> sp_io::TestExternalities { } benchmarks!{ - where_clause { where ::OtherEvent: Into<::Event> } + where_clause { where ::OtherEvent: Into<::Event> } _ { // Define a common range for `b`. diff --git a/frame/contracts/README.md b/frame/contracts/README.md index dddcc3c8b8b..a6317d8aa24 100644 --- a/frame/contracts/README.md +++ b/frame/contracts/README.md @@ -2,7 +2,7 @@ The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts. -- [`contract::Trait`](https://docs.rs/pallet-contracts/latest/pallet_contracts/trait.Trait.html) +- [`contract::Config`](https://docs.rs/pallet-contracts/latest/pallet_contracts/trait.Config.html) - [`Call`](https://docs.rs/pallet-contracts/latest/pallet_contracts/enum.Call.html) ## Overview diff --git a/frame/democracy/README.md b/frame/democracy/README.md index ffbf2f36a17..f2a8e5488df 100644 --- a/frame/democracy/README.md +++ b/frame/democracy/README.md @@ -1,6 +1,6 @@ # Democracy Pallet -- [`democracy::Trait`](https://docs.rs/pallet-democracy/latest/pallet_democracy/trait.Trait.html) +- [`democracy::Config`](https://docs.rs/pallet-democracy/latest/pallet_democracy/trait.Config.html) - [`Call`](https://docs.rs/pallet-democracy/latest/pallet_democracy/enum.Call.html) ## Overview diff --git a/frame/elections-phragmen/README.md b/frame/elections-phragmen/README.md index 5507d539706..38f9ec7b6f3 100644 --- a/frame/elections-phragmen/README.md +++ b/frame/elections-phragmen/README.md @@ -60,7 +60,7 @@ being re-elected at the end of each round. ### Module Information -- [`election_sp_phragmen::Trait`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Trait.html) +- [`election_sp_phragmen::Config`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Config.html) - [`Call`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/enum.Call.html) - [`Module`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/struct.Module.html) diff --git a/frame/example-offchain-worker/README.md b/frame/example-offchain-worker/README.md index a2a95a8cfb9..c036ec8fb19 100644 --- a/frame/example-offchain-worker/README.md +++ b/frame/example-offchain-worker/README.md @@ -7,7 +7,7 @@ concepts, APIs and structures common to most offchain workers. Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's documentation. -- [`pallet_example_offchain_worker::Trait`](./trait.Trait.html) +- [`pallet_example_offchain_worker::Config`](./trait.Config.html) - [`Call`](./enum.Call.html) - [`Module`](./struct.Module.html) diff --git a/frame/example/README.md b/frame/example/README.md index f1435a297b0..5748169bc77 100644 --- a/frame/example/README.md +++ b/frame/example/README.md @@ -46,7 +46,7 @@ Copy and paste this template from frame/example/src/lib.rs into file // Include the following links that shows what trait needs to be implemented to use the pallet // and the supported dispatchables that are documented in the Call enum. -- \[`::Trait`](https://docs.rs/pallet-example/latest/pallet_example/trait.Trait.html) +- \[`::Config`](https://docs.rs/pallet-example/latest/pallet_example/trait.Config.html) - \[`Call`](https://docs.rs/pallet-example/latest/pallet_example/enum.Call.html) - \[`Module`](https://docs.rs/pallet-example/latest/pallet_example/struct.Module.html) @@ -195,7 +195,7 @@ Copy and paste this template from frame/example/src/lib.rs into file \```rust use ; -pub trait Trait: ::Trait { } +pub trait Config: ::Config { } \``` \### Simple Code Snippet diff --git a/frame/identity/README.md b/frame/identity/README.md index 8927febec6b..412d67ca2b8 100644 --- a/frame/identity/README.md +++ b/frame/identity/README.md @@ -1,6 +1,6 @@ # Identity Module -- [`identity::Trait`](https://docs.rs/pallet-identity/latest/pallet_identity/trait.Trait.html) +- [`identity::Config`](https://docs.rs/pallet-identity/latest/pallet_identity/trait.Config.html) - [`Call`](https://docs.rs/pallet-identity/latest/pallet_identity/enum.Call.html) ## Overview @@ -51,6 +51,6 @@ no state-bloat attack is viable. * `kill_identity` - Forcibly remove the associated identity; the deposit is lost. [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/frame/im-online/README.md b/frame/im-online/README.md index 9a65bb6a980..e0043970ac8 100644 --- a/frame/im-online/README.md +++ b/frame/im-online/README.md @@ -13,7 +13,7 @@ and includes the recent best block number of the local validators chain as well as the `NetworkState`. It is submitted as an Unsigned Transaction via off-chain workers. -- [`im_online::Trait`](https://docs.rs/pallet-im-online/latest/pallet_im_online/trait.Trait.html) +- [`im_online::Config`](https://docs.rs/pallet-im-online/latest/pallet_im_online/trait.Config.html) - [`Call`](https://docs.rs/pallet-im-online/latest/pallet_im_online/enum.Call.html) - [`Module`](https://docs.rs/pallet-im-online/latest/pallet_im_online/struct.Module.html) @@ -30,10 +30,10 @@ use frame_support::{decl_module, dispatch}; use frame_system::ensure_signed; use pallet_im_online::{self as im_online}; -pub trait Trait: im_online::Trait {} +pub trait Config: im_online::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { let _sender = ensure_signed(origin)?; diff --git a/frame/multisig/README.md b/frame/multisig/README.md index 2209e876f84..a0851f948d1 100644 --- a/frame/multisig/README.md +++ b/frame/multisig/README.md @@ -1,7 +1,7 @@ # Multisig Module A module for doing multisig dispatch. -- [`multisig::Trait`](https://docs.rs/pallet-multisig/latest/pallet_multisig/trait.Trait.html) +- [`multisig::Config`](https://docs.rs/pallet-multisig/latest/pallet_multisig/trait.Config.html) - [`Call`](https://docs.rs/pallet-multisig/latest/pallet_multisig/enum.Call.html) ## Overview @@ -24,6 +24,6 @@ not available or desired. * `cancel_as_multi` - Cancel a call from a composite origin. [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/frame/nicks/README.md b/frame/nicks/README.md index b4c88eff431..fa6a3be0e4e 100644 --- a/frame/nicks/README.md +++ b/frame/nicks/README.md @@ -1,6 +1,6 @@ # Nicks Module -- [`nicks::Trait`](https://docs.rs/pallet-nicks/latest/pallet_nicks/trait.Trait.html) +- [`nicks::Config`](https://docs.rs/pallet-nicks/latest/pallet_nicks/trait.Config.html) - [`Call`](https://docs.rs/pallet-nicks/latest/pallet_nicks/enum.Call.html) ## Overview @@ -20,6 +20,6 @@ have not been designed to be economically secure. Do not use this pallet as-is i * `kill_name` - Forcibly remove the associated name; the deposit is lost. [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index cdac46acb45..1d133c1b613 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -24,22 +24,22 @@ mod mock; use sp_std::prelude::*; use sp_std::vec; -use frame_system::{RawOrigin, Module as System, Config as SystemTrait}; +use frame_system::{RawOrigin, Module as System, Config as SystemConfig}; use frame_benchmarking::{benchmarks, account}; use frame_support::traits::{Currency, OnInitialize}; use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}}; use sp_staking::offence::{ReportOffence, Offence, OffenceDetails}; -use pallet_balances::{Config as BalancesTrait}; +use pallet_balances::{Config as BalancesConfig}; use pallet_babe::BabeEquivocationOffence; use pallet_grandpa::{GrandpaEquivocationOffence, GrandpaTimeSlot}; -use pallet_im_online::{Config as ImOnlineTrait, Module as ImOnline, UnresponsivenessOffence}; -use pallet_offences::{Config as OffencesTrait, Module as Offences}; -use pallet_session::historical::{Config as HistoricalTrait, IdentificationTuple}; -use pallet_session::{Config as SessionTrait, SessionManager}; +use pallet_im_online::{Config as ImOnlineConfig, Module as ImOnline, UnresponsivenessOffence}; +use pallet_offences::{Config as OffencesConfig, Module as Offences}; +use pallet_session::historical::{Config as HistoricalConfig, IdentificationTuple}; +use pallet_session::{Config as SessionConfig, SessionManager}; use pallet_staking::{ - Module as Staking, Config as StakingTrait, RewardDestination, ValidatorPrefs, + Module as Staking, Config as StakingConfig, RewardDestination, ValidatorPrefs, Exposure, IndividualExposure, ElectionStatus, MAX_NOMINATIONS, Event as StakingEvent }; @@ -53,32 +53,32 @@ const MAX_DEFERRED_OFFENCES: u32 = 100; pub struct Module(Offences); pub trait Config: - SessionTrait - + StakingTrait - + OffencesTrait - + ImOnlineTrait - + HistoricalTrait - + BalancesTrait + SessionConfig + + StakingConfig + + OffencesConfig + + ImOnlineConfig + + HistoricalConfig + + BalancesConfig + IdTupleConvert {} /// A helper trait to make sure we can convert `IdentificationTuple` coming from historical /// and the one required by offences. -pub trait IdTupleConvert { +pub trait IdTupleConvert { /// Convert identification tuple from `historical` trait to the one expected by `offences`. - fn convert(id: IdentificationTuple) -> ::IdentificationTuple; + fn convert(id: IdentificationTuple) -> ::IdentificationTuple; } -impl IdTupleConvert for T where - ::IdentificationTuple: From> +impl IdTupleConvert for T where + ::IdentificationTuple: From> { - fn convert(id: IdentificationTuple) -> ::IdentificationTuple { + fn convert(id: IdentificationTuple) -> ::IdentificationTuple { id.into() } } -type LookupSourceOf = <::Lookup as StaticLookup>::Source; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type LookupSourceOf = <::Lookup as StaticLookup>::Source; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; struct Offender { pub controller: T::AccountId, @@ -165,10 +165,10 @@ fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< let id_tuples = offenders.iter() .map(|offender| - ::ValidatorIdOf::convert(offender.controller.clone()) + ::ValidatorIdOf::convert(offender.controller.clone()) .expect("failed to get validator id from account id")) .map(|validator_id| - ::FullIdentificationOf::convert(validator_id.clone()) + ::FullIdentificationOf::convert(validator_id.clone()) .map(|full_id| (validator_id, full_id)) .expect("failed to convert validator id to full identification")) .collect::>>(); @@ -176,7 +176,7 @@ fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< } #[cfg(test)] -fn check_events::Event>>(expected: I) { +fn check_events::Event>>(expected: I) { let events = System::::events() .into_iter() .map(|frame_system::EventRecord { event, .. }| event).collect::>(); let expected = expected.collect::>(); @@ -235,7 +235,7 @@ benchmarks! { }; assert_eq!(System::::event_count(), 0); }: { - let _ = ::ReportUnresponsiveness::report_offence( + let _ = ::ReportUnresponsiveness::report_offence( reporters.clone(), offence ); @@ -250,14 +250,14 @@ benchmarks! { .flat_map(|offender| { core::iter::once(offender.stash).chain(offender.nominator_stashes.into_iter()) }) - .map(|stash| ::Event::from( + .map(|stash| ::Event::from( StakingEvent::::Slash(stash, BalanceOf::::from(slash_amount)) )) .collect::>(); let reward_events = reporters.into_iter() .flat_map(|reporter| vec![ frame_system::Event::::NewAccount(reporter.clone()).into(), - ::Event::from( + ::Event::from( pallet_balances::Event::::Endowed(reporter, (reward_amount / r).into()) ).into() ]); @@ -272,7 +272,7 @@ benchmarks! { .chain(slash_events.into_iter().map(Into::into)) .chain(reward_events) .chain(slash_rest.into_iter().map(Into::into)) - .chain(std::iter::once(::Event::from( + .chain(std::iter::once(::Event::from( pallet_offences::Event::Offence( UnresponsivenessOffence::::ID, 0_u32.to_le_bytes().to_vec(), diff --git a/frame/proxy/README.md b/frame/proxy/README.md index 26969db6382..d85cfa7d049 100644 --- a/frame/proxy/README.md +++ b/frame/proxy/README.md @@ -6,7 +6,7 @@ The accounts to which permission is delegated may be requied to announce the act wish to execute some duration prior to execution happens. In this case, the target account may reject the announcement and in doing so, veto the execution. -- [`proxy::Trait`](https://docs.rs/pallet-proxy/latest/pallet_proxy/trait.Trait.html) +- [`proxy::Config`](https://docs.rs/pallet-proxy/latest/pallet_proxy/trait.Config.html) - [`Call`](https://docs.rs/pallet-proxy/latest/pallet_proxy/enum.Call.html) ## Overview @@ -16,6 +16,6 @@ reject the announcement and in doing so, veto the execution. ### Dispatchable Functions [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/frame/randomness-collective-flip/README.md b/frame/randomness-collective-flip/README.md index 2af18d3d2f7..9885c734d9f 100644 --- a/frame/randomness-collective-flip/README.md +++ b/frame/randomness-collective-flip/README.md @@ -22,10 +22,10 @@ the system trait. ```rust use frame_support::{decl_module, dispatch, traits::Randomness}; -pub trait Trait: frame_system::Trait {} +pub trait Config: frame_system::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn random_module_example(origin) -> dispatch::DispatchResult { let _random_value = >::random(&b"my context"[..]); diff --git a/frame/recovery/README.md b/frame/recovery/README.md index b6d3ae5acee..ff990bc97c9 100644 --- a/frame/recovery/README.md +++ b/frame/recovery/README.md @@ -1,6 +1,6 @@ # Recovery Pallet -- [`recovery::Trait`](https://docs.rs/pallet-recovery/latest/pallet_recovery/trait.Trait.html) +- [`recovery::Config`](https://docs.rs/pallet-recovery/latest/pallet_recovery/trait.Config.html) - [`Call`](https://docs.rs/pallet-recovery/latest/pallet_recovery/enum.Call.html) ## Overview diff --git a/frame/scheduler/README.md b/frame/scheduler/README.md index 47beb71e3a0..fb08297846c 100644 --- a/frame/scheduler/README.md +++ b/frame/scheduler/README.md @@ -1,7 +1,7 @@ # Scheduler A module for scheduling dispatches. -- [`scheduler::Trait`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/trait.Trait.html) +- [`scheduler::Config`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/trait.Config.html) - [`Call`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/enum.Call.html) - [`Module`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/struct.Module.html) @@ -12,7 +12,7 @@ specified block number or at a specified period. These scheduled dispatches may be named or anonymous and may be canceled. **NOTE:** The scheduled calls will be dispatched with the default filter -for the origin: namely `frame_system::Trait::BaseCallFilter` for all origin +for the origin: namely `frame_system::Config::BaseCallFilter` for all origin except root which will get no filter. And not the filter contained in origin use to call `fn schedule`. diff --git a/frame/scored-pool/README.md b/frame/scored-pool/README.md index 948d5b49772..85d20003580 100644 --- a/frame/scored-pool/README.md +++ b/frame/scored-pool/README.md @@ -20,7 +20,7 @@ time. If an entity is currently a member, this results in removal from the `Pool` and `Members`; the entity is immediately replaced by the next highest scoring candidate in the pool, if available. -- [`scored_pool::Trait`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/trait.Trait.html) +- [`scored_pool::Config`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/trait.Config.html) - [`Call`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/enum.Call.html) - [`Module`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/struct.Module.html) @@ -41,10 +41,10 @@ use frame_support::{decl_module, dispatch}; use frame_system::ensure_signed; use pallet_scored_pool::{self as scored_pool}; -pub trait Trait: scored_pool::Trait {} +pub trait Config: scored_pool::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn candidate(origin) -> dispatch::DispatchResult { let who = ensure_signed(origin)?; diff --git a/frame/session/README.md b/frame/session/README.md index 60da8958f73..f955268c21b 100644 --- a/frame/session/README.md +++ b/frame/session/README.md @@ -3,7 +3,7 @@ The Session module allows validators to manage their session keys, provides a function for changing the session length, and handles session rotation. -- [`session::Trait`](https://docs.rs/pallet-session/latest/pallet_session/trait.Trait.html) +- [`session::Config`](https://docs.rs/pallet-session/latest/pallet_session/trait.Config.html) - [`Call`](https://docs.rs/pallet-session/latest/pallet_session/enum.Call.html) - [`Module`](https://docs.rs/pallet-session/latest/pallet_session/struct.Module.html) @@ -71,7 +71,7 @@ The [Staking pallet](https://docs.rs/pallet-staking/latest/pallet_staking/) uses ```rust use pallet_session as session; -fn validators() -> Vec<::ValidatorId> { +fn validators() -> Vec<::ValidatorId> { >::validators() } ``` diff --git a/frame/session/src/historical/offchain.rs b/frame/session/src/historical/offchain.rs index 616cdede254..9bb20ababb3 100644 --- a/frame/session/src/historical/offchain.rs +++ b/frame/session/src/historical/offchain.rs @@ -189,12 +189,12 @@ mod tests { #[test] fn encode_decode_roundtrip() { use codec::{Decode, Encode}; - use super::super::super::Config as SessionTrait; - use super::super::Config as HistoricalTrait; + use super::super::super::Config as SessionConfig; + use super::super::Config as HistoricalConfig; let sample = ( - 22u32 as ::ValidatorId, - 7_777_777 as ::FullIdentification); + 22u32 as ::ValidatorId, + 7_777_777 as ::FullIdentification); let encoded = sample.encode(); let decoded = Decode::decode(&mut encoded.as_slice()).expect("Must decode"); diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs index dd6c9de9b58..f4576675c11 100644 --- a/frame/session/src/historical/onchain.rs +++ b/frame/session/src/historical/onchain.rs @@ -20,9 +20,9 @@ use codec::Encode; use sp_runtime::traits::Convert; -use super::super::Config as SessionTrait; +use super::super::Config as SessionConfig; use super::super::{Module as SessionModule, SessionIndex}; -use super::Config as HistoricalTrait; +use super::Config as HistoricalConfig; use super::shared; use sp_std::prelude::*; @@ -35,14 +35,14 @@ use sp_std::prelude::*; /// `on_initialize(..)` or `on_finalization(..)`. /// **Must** be called during the session, which validator-set is to be stored for further /// off-chain processing. Otherwise the `FullIdentification` might not be available. -pub fn store_session_validator_set_to_offchain( +pub fn store_session_validator_set_to_offchain( session_index: SessionIndex, ) { let encoded_validator_list = >::validators() .into_iter() - .filter_map(|validator_id: ::ValidatorId| { + .filter_map(|validator_id: ::ValidatorId| { let full_identification = - <::FullIdentificationOf>::convert(validator_id.clone()); + <::FullIdentificationOf>::convert(validator_id.clone()); full_identification.map(|full_identification| (validator_id, full_identification)) }) .collect::>(); @@ -57,6 +57,6 @@ pub fn store_session_validator_set_to_offchain() { +pub fn store_current_session_validator_set_to_offchain() { store_session_validator_set_to_offchain::(>::current_index()); } diff --git a/frame/society/README.md b/frame/society/README.md index 372dfe1f048..f68aeb73d42 100644 --- a/frame/society/README.md +++ b/frame/society/README.md @@ -1,6 +1,6 @@ # Society Module -- [`society::Trait`](https://docs.rs/pallet-society/latest/pallet_society/trait.Trait.html) +- [`society::Config`](https://docs.rs/pallet-society/latest/pallet_society/trait.Config.html) - [`Call`](https://docs.rs/pallet-society/latest/pallet_society/enum.Call.html) ## Overview diff --git a/frame/staking/README.md b/frame/staking/README.md index 78474ee8422..d073818d649 100644 --- a/frame/staking/README.md +++ b/frame/staking/README.md @@ -2,7 +2,7 @@ The Staking module is used to manage funds at stake by network maintainers. -- [`staking::Trait`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html) +- [`staking::Config`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html) - [`Call`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html) - [`Module`](https://docs.rs/pallet-staking/latest/pallet_staking/struct.Module.html) @@ -90,7 +90,7 @@ valid behavior_ while _punishing any misbehavior or lack of availability_. Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to the -validator as well as its nominators. Only the [`Trait::MaxNominatorRewardedPerValidator`] +validator as well as its nominators. Only the [`Config::MaxNominatorRewardedPerValidator`] biggest stakers can claim their reward. This is to limit the i/o cost to mutate storage for each nominator's account. @@ -137,10 +137,10 @@ use frame_support::{decl_module, dispatch}; use frame_system::ensure_signed; use pallet_staking::{self as staking}; -pub trait Trait: staking::Trait {} +pub trait Config: staking::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { /// Reward a validator. #[weight = 0] pub fn reward_myself(origin) -> dispatch::DispatchResult { @@ -157,7 +157,7 @@ decl_module! { ### Era payout The era payout is computed using yearly inflation curve defined at -[`T::RewardCurve`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.RewardCurve) as such: +[`T::RewardCurve`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.RewardCurve) as such: ```nocompile staker_payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year @@ -168,7 +168,7 @@ This payout is used to reward stakers as defined in next section remaining_payout = max_yearly_inflation * total_tokens / era_per_year - staker_payout ``` The remaining reward is send to the configurable end-point -[`T::RewardRemainder`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.RewardRemainder). +[`T::RewardRemainder`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.RewardRemainder). ### Reward Calculation @@ -214,7 +214,7 @@ Any funds already placed into stash can be the target of the following operation The controller account can free a portion (or all) of the funds using the [`unbond`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html#variant.unbond) call. Note that the funds are not immediately -accessible. Instead, a duration denoted by [`BondingDuration`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.BondingDuration) +accessible. Instead, a duration denoted by [`BondingDuration`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.BondingDuration) (in number of eras) must pass until the funds can actually be removed. Once the `BondingDuration` is over, the [`withdraw_unbonded`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html#variant.withdraw_unbonded) call can be used to actually withdraw the funds. diff --git a/frame/sudo/README.md b/frame/sudo/README.md index 233727ac1bd..8ac0264d458 100644 --- a/frame/sudo/README.md +++ b/frame/sudo/README.md @@ -1,6 +1,6 @@ # Sudo Module -- [`sudo::Trait`](https://docs.rs/pallet-sudo/latest/pallet_sudo/trait.Trait.html) +- [`sudo::Config`](https://docs.rs/pallet-sudo/latest/pallet_sudo/trait.Config.html) - [`Call`](https://docs.rs/pallet-sudo/latest/pallet_sudo/enum.Call.html) ## Overview @@ -38,10 +38,10 @@ This is an example of a module that exposes a privileged function: use frame_support::{decl_module, dispatch}; use frame_system::ensure_root; -pub trait Trait: frame_system::Trait {} +pub trait Config: frame_system::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn privileged_function(origin) -> dispatch::DispatchResult { ensure_root(origin)?; @@ -64,7 +64,7 @@ You need to set an initial superuser account as the sudo `key`. * [Democracy](https://docs.rs/pallet-democracy/latest/pallet_democracy/) [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html [`Origin`]: https://docs.substrate.dev/docs/substrate-types License: Apache-2.0 \ No newline at end of file diff --git a/frame/system/README.md b/frame/system/README.md index adfa7aa35dd..b2ff4009dfa 100644 --- a/frame/system/README.md +++ b/frame/system/README.md @@ -3,7 +3,7 @@ The System module provides low-level access to core types and cross-cutting utilities. It acts as the base layer for other pallets to interact with the Substrate framework components. -- [`system::Trait`](https://docs.rs/frame-system/latest/frame_system/trait.Trait.html) +- [`system::Config`](https://docs.rs/frame-system/latest/frame_system/trait.Config.html) ## Overview @@ -57,10 +57,10 @@ Import the System module and derive your module's configuration trait from the s use frame_support::{decl_module, dispatch}; use frame_system::{self as system, ensure_signed}; -pub trait Trait: system::Trait {} +pub trait Config: system::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn system_module_example(origin) -> dispatch::DispatchResult { let _sender = ensure_signed(origin)?; diff --git a/frame/timestamp/README.md b/frame/timestamp/README.md index 54ef7fa43b4..6ba03305439 100644 --- a/frame/timestamp/README.md +++ b/frame/timestamp/README.md @@ -2,7 +2,7 @@ The Timestamp module provides functionality to get and set the on-chain time. -- [`timestamp::Trait`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/trait.Trait.html) +- [`timestamp::Config`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/trait.Config.html) - [`Call`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/enum.Call.html) - [`Module`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/struct.Module.html) @@ -29,7 +29,7 @@ because of cumulative calculation errors and hence should be avoided. * `get` - Gets the current time for the current block. If this function is called prior to setting the timestamp, it will return the timestamp of the previous block. -### Trait Getters +### Config Getters * `MinimumPeriod` - Gets the minimum (and advised) period between blocks for the chain. @@ -48,10 +48,10 @@ trait from the timestamp trait. use frame_support::{decl_module, dispatch}; use frame_system::ensure_signed; -pub trait Trait: timestamp::Trait {} +pub trait Config: timestamp::Config {} decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin { #[weight = 0] pub fn get_time(origin) -> dispatch::DispatchResult { let _sender = ensure_signed(origin)?; diff --git a/frame/transaction-payment/README.md b/frame/transaction-payment/README.md index 10ad9579e92..7e95677a1b2 100644 --- a/frame/transaction-payment/README.md +++ b/frame/transaction-payment/README.md @@ -8,9 +8,9 @@ transaction to be included. This includes: chance to be included by the transaction queue. Additionally, this module allows one to configure: - - The mapping between one unit of weight to one unit of fee via [`Trait::WeightToFee`]. + - The mapping between one unit of weight to one unit of fee via [`Config::WeightToFee`]. - A means of updating the fee for the next block, via defining a multiplier, based on the final state of the chain at the end of the previous block. This can be configured via - [`Trait::FeeMultiplierUpdate`] + [`Config::FeeMultiplierUpdate`] License: Apache-2.0 \ No newline at end of file diff --git a/frame/treasury/README.md b/frame/treasury/README.md index 424b8e0eedf..b316e604f4a 100644 --- a/frame/treasury/README.md +++ b/frame/treasury/README.md @@ -3,7 +3,7 @@ The Treasury module provides a "pot" of funds that can be managed by stakeholders in the system and a structure for making spending proposals from this pot. -- [`treasury::Trait`](https://docs.rs/pallet-treasury/latest/pallet_treasury/trait.Trait.html) +- [`treasury::Config`](https://docs.rs/pallet-treasury/latest/pallet_treasury/trait.Config.html) - [`Call`](https://docs.rs/pallet-treasury/latest/pallet_treasury/enum.Call.html) ## Overview @@ -21,7 +21,7 @@ A separate subsystem exists to allow for an agile "tipping" process, whereby a r given without first having a pre-determined stakeholder group come to consensus on how much should be paid. -A group of `Tippers` is determined through the config `Trait`. After half of these have declared +A group of `Tippers` is determined through the config `Config`. After half of these have declared some amount that they believe a particular reported reason deserves, then a countdown period is entered where any remaining members can declare their tip amounts also. After the close of the countdown period, the median of all declared tips is paid to the reported beneficiary, along diff --git a/frame/utility/README.md b/frame/utility/README.md index 39639692911..df874ec1106 100644 --- a/frame/utility/README.md +++ b/frame/utility/README.md @@ -1,7 +1,7 @@ # Utility Module A stateless module with helpers for dispatch management which does no re-authentication. -- [`utility::Trait`](https://docs.rs/pallet-utility/latest/pallet_utility/trait.Trait.html) +- [`utility::Config`](https://docs.rs/pallet-utility/latest/pallet_utility/trait.Config.html) - [`Call`](https://docs.rs/pallet-utility/latest/pallet_utility/enum.Call.html) ## Overview @@ -33,6 +33,6 @@ filtered by any proxy. * `as_derivative` - Dispatch a call from a derivative signed origin. [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/frame/vesting/README.md b/frame/vesting/README.md index 921fa94a1a2..59bfdfcedd0 100644 --- a/frame/vesting/README.md +++ b/frame/vesting/README.md @@ -1,6 +1,6 @@ # Vesting Module -- [`vesting::Trait`](https://docs.rs/pallet-vesting/latest/pallet_vesting/trait.Trait.html) +- [`vesting::Config`](https://docs.rs/pallet-vesting/latest/pallet_vesting/trait.Config.html) - [`Call`](https://docs.rs/pallet-vesting/latest/pallet_vesting/enum.Call.html) ## Overview @@ -26,6 +26,6 @@ This module implements the `VestingSchedule` trait. "vested" so far. [`Call`]: ./enum.Call.html -[`Trait`]: ./trait.Trait.html +[`Config`]: ./trait.Config.html License: Apache-2.0 \ No newline at end of file diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 5839618e373..85f5a1797b1 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -410,7 +410,7 @@ fn extend_with_runtime_decl_path(mut trait_: Path) -> Path { .segments .last() .as_ref() - .expect("Config path should always contain at least one item; qed") + .expect("Trait path should always contain at least one item; qed") .ident; generate_runtime_mod_name_for_trait(trait_name) diff --git a/utils/frame/benchmarking-cli/src/template.hbs b/utils/frame/benchmarking-cli/src/template.hbs index fd066b1a3a8..c76eaad22c9 100644 --- a/utils/frame/benchmarking-cli/src/template.hbs +++ b/utils/frame/benchmarking-cli/src/template.hbs @@ -18,7 +18,7 @@ use sp_std::marker::PhantomData; /// Weight functions for {{pallet}}. pub struct WeightInfo(PhantomData); -impl {{pallet}}::WeightInfo for WeightInfo { +impl {{pallet}}::WeightInfo for WeightInfo { {{~#each benchmarks as |benchmark|}} fn {{benchmark.name~}} ( -- GitLab From dcf6a3ae9587bdf27a58eeff4bad8628c4763b38 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 30 Nov 2020 14:01:18 -0800 Subject: [PATCH 068/163] Fix CI Link Check (#7639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix trigger fingers * more * Update frame/example-offchain-worker/README.md Co-authored-by: Guillaume Thiolliere Co-authored-by: Bastian Köcher Co-authored-by: Guillaume Thiolliere --- frame/assets/README.md | 6 +++--- frame/atomic-swap/README.md | 4 ++-- frame/aura/README.md | 4 ++-- frame/balances/README.md | 4 ++-- frame/contracts/README.md | 4 ++-- frame/democracy/README.md | 4 ++-- frame/elections-phragmen/README.md | 4 ++-- frame/example-offchain-worker/README.md | 4 ++-- frame/example/README.md | 4 ++-- frame/identity/README.md | 4 ++-- frame/im-online/README.md | 4 ++-- frame/multisig/README.md | 4 ++-- frame/nicks/README.md | 4 ++-- frame/proxy/README.md | 4 ++-- frame/recovery/README.md | 4 ++-- frame/scheduler/README.md | 4 ++-- frame/scored-pool/README.md | 4 ++-- frame/session/README.md | 4 ++-- frame/society/README.md | 4 ++-- frame/staking/README.md | 10 +++++----- frame/sudo/README.md | 4 ++-- frame/system/README.md | 4 ++-- frame/timestamp/README.md | 4 ++-- frame/treasury/README.md | 4 ++-- frame/utility/README.md | 4 ++-- frame/vesting/README.md | 4 ++-- 26 files changed, 56 insertions(+), 56 deletions(-) diff --git a/frame/assets/README.md b/frame/assets/README.md index 804856f90d0..44c4eedc31b 100644 --- a/frame/assets/README.md +++ b/frame/assets/README.md @@ -11,9 +11,9 @@ with a fixed supply, including: * Asset Transfer * Asset Destruction -To use it in your runtime, you need to implement the assets [`Config`](https://docs.rs/pallet-assets/latest/pallet_assets/trait.Config.html). +To use it in your runtime, you need to implement the assets [`assets::Trait`](https://docs.rs/pallet-assets/latest/pallet_assets/trait.Trait.html). -The supported dispatchable functions are documented in the [`Call`](https://docs.rs/pallet-assets/latest/pallet_assets/enum.Call.html) enum. +The supported dispatchable functions are documented in the [`assets::Call`](https://docs.rs/pallet-assets/latest/pallet_assets/enum.Call.html) enum. ### Terminology @@ -113,4 +113,4 @@ them are violated, the behavior of this module is undefined. * [`System`](https://docs.rs/frame-system/latest/frame_system/) * [`Support`](https://docs.rs/frame-support/latest/frame_support/) -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/atomic-swap/README.md b/frame/atomic-swap/README.md index eeac282f1d5..5dd502095d7 100644 --- a/frame/atomic-swap/README.md +++ b/frame/atomic-swap/README.md @@ -2,7 +2,7 @@ A module for atomically sending funds. -- [`atomic_swap::Config`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/trait.Config.html) +- [`atomic_swap::Trait`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/trait.Trait.html) - [`Call`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/enum.Call.html) - [`Module`](https://docs.rs/pallet-atomic-swap/latest/pallet_atomic_swap/struct.Module.html) @@ -20,4 +20,4 @@ claimed within a specified duration of time, the sender may cancel it. * `claim_swap` - called by the target to approve a swap * `cancel_swap` - may be called by a sender after a specified duration -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/aura/README.md b/frame/aura/README.md index 253e0d3651c..73ed986dd73 100644 --- a/frame/aura/README.md +++ b/frame/aura/README.md @@ -1,6 +1,6 @@ # Aura Module -- [`aura::Config`](https://docs.rs/pallet-aura/latest/pallet_aura/trait.Config.html) +- [`aura::Trait`](https://docs.rs/pallet-aura/latest/pallet_aura/trait.Trait.html) - [`Module`](https://docs.rs/pallet-aura/latest/pallet_aura/struct.Module.html) ## Overview @@ -25,4 +25,4 @@ If you're interested in hacking on this module, it is useful to understand the i [`ProvideInherent`](https://docs.rs/sp-inherents/latest/sp_inherents/trait.ProvideInherent.html) and [`ProvideInherentData`](https://docs.rs/sp-inherents/latest/sp_inherents/trait.ProvideInherentData.html) to create and check inherents. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/balances/README.md b/frame/balances/README.md index 9a2f3c394c9..cbbfea75e68 100644 --- a/frame/balances/README.md +++ b/frame/balances/README.md @@ -2,7 +2,7 @@ The Balances module provides functionality for handling accounts and balances. -- [`balances::Config`](https://docs.rs/pallet-balances/latest/pallet_balances/trait.Config.html) +- [`balances::Trait`](https://docs.rs/pallet-balances/latest/pallet_balances/trait.Trait.html) - [`Call`](https://docs.rs/pallet-balances/latest/pallet_balances/enum.Call.html) - [`Module`](https://docs.rs/pallet-balances/latest/pallet_balances/struct.Module.html) @@ -119,4 +119,4 @@ The Balances module depends on the [`GenesisConfig`](https://docs.rs/pallet-bala * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/contracts/README.md b/frame/contracts/README.md index a6317d8aa24..4252bfc1d84 100644 --- a/frame/contracts/README.md +++ b/frame/contracts/README.md @@ -2,7 +2,7 @@ The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts. -- [`contract::Config`](https://docs.rs/pallet-contracts/latest/pallet_contracts/trait.Config.html) +- [`contract::Trait`](https://docs.rs/pallet-contracts/latest/pallet_contracts/trait.Trait.html) - [`Call`](https://docs.rs/pallet-contracts/latest/pallet_contracts/enum.Call.html) ## Overview @@ -61,4 +61,4 @@ WebAssembly based smart contracts in the Rust programming language. This is a wo * [Balances](https://docs.rs/pallet-balances/latest/pallet_balances/) -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/democracy/README.md b/frame/democracy/README.md index f2a8e5488df..6a390cc048e 100644 --- a/frame/democracy/README.md +++ b/frame/democracy/README.md @@ -1,6 +1,6 @@ # Democracy Pallet -- [`democracy::Config`](https://docs.rs/pallet-democracy/latest/pallet_democracy/trait.Config.html) +- [`democracy::Trait`](https://docs.rs/pallet-democracy/latest/pallet_democracy/trait.Trait.html) - [`Call`](https://docs.rs/pallet-democracy/latest/pallet_democracy/enum.Call.html) ## Overview @@ -132,4 +132,4 @@ This call can only be made by the `VetoOrigin`. - `cancel_queued` - Cancels a proposal that is queued for enactment. - `clear_public_proposal` - Removes all public proposals. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/elections-phragmen/README.md b/frame/elections-phragmen/README.md index 38f9ec7b6f3..8c5940ea2d7 100644 --- a/frame/elections-phragmen/README.md +++ b/frame/elections-phragmen/README.md @@ -60,8 +60,8 @@ being re-elected at the end of each round. ### Module Information -- [`election_sp_phragmen::Config`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Config.html) +- [`election_sp_phragmen::Trait`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/trait.Trait.html) - [`Call`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/enum.Call.html) - [`Module`](https://docs.rs/pallet-elections-phragmen/latest/pallet_elections_phragmen/struct.Module.html) -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/example-offchain-worker/README.md b/frame/example-offchain-worker/README.md index c036ec8fb19..5299027f392 100644 --- a/frame/example-offchain-worker/README.md +++ b/frame/example-offchain-worker/README.md @@ -7,7 +7,7 @@ concepts, APIs and structures common to most offchain workers. Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's documentation. -- [`pallet_example_offchain_worker::Config`](./trait.Config.html) +- [`pallet_example_offchain_worker::Trait`](./trait.Trait.html) - [`Call`](./enum.Call.html) - [`Module`](./struct.Module.html) @@ -24,4 +24,4 @@ Additional logic in OCW is put in place to prevent spamming the network with bot and unsigned transactions, and custom `UnsignedValidator` makes sure that there is only one unsigned transaction floating in the network. -License: Unlicense \ No newline at end of file +License: Unlicense diff --git a/frame/example/README.md b/frame/example/README.md index 5748169bc77..46a0d076a96 100644 --- a/frame/example/README.md +++ b/frame/example/README.md @@ -46,7 +46,7 @@ Copy and paste this template from frame/example/src/lib.rs into file // Include the following links that shows what trait needs to be implemented to use the pallet // and the supported dispatchables that are documented in the Call enum. -- \[`::Config`](https://docs.rs/pallet-example/latest/pallet_example/trait.Config.html) +- \[`::Trait`](https://docs.rs/pallet-example/latest/pallet_example/trait.Trait.html) - \[`Call`](https://docs.rs/pallet-example/latest/pallet_example/enum.Call.html) - \[`Module`](https://docs.rs/pallet-example/latest/pallet_example/struct.Module.html) @@ -235,4 +235,4 @@ pub trait Config: ::Config { } // that the implementation is based on.

-License: Unlicense \ No newline at end of file +License: Unlicense diff --git a/frame/identity/README.md b/frame/identity/README.md index 412d67ca2b8..38e16d4dd49 100644 --- a/frame/identity/README.md +++ b/frame/identity/README.md @@ -1,6 +1,6 @@ # Identity Module -- [`identity::Config`](https://docs.rs/pallet-identity/latest/pallet_identity/trait.Config.html) +- [`identity::Trait`](https://docs.rs/pallet-identity/latest/pallet_identity/trait.Trait.html) - [`Call`](https://docs.rs/pallet-identity/latest/pallet_identity/enum.Call.html) ## Overview @@ -53,4 +53,4 @@ no state-bloat attack is viable. [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/im-online/README.md b/frame/im-online/README.md index e0043970ac8..a2ed5edc906 100644 --- a/frame/im-online/README.md +++ b/frame/im-online/README.md @@ -13,7 +13,7 @@ and includes the recent best block number of the local validators chain as well as the `NetworkState`. It is submitted as an Unsigned Transaction via off-chain workers. -- [`im_online::Config`](https://docs.rs/pallet-im-online/latest/pallet_im_online/trait.Config.html) +- [`im_online::Trait`](https://docs.rs/pallet-im-online/latest/pallet_im_online/trait.Trait.html) - [`Call`](https://docs.rs/pallet-im-online/latest/pallet_im_online/enum.Call.html) - [`Module`](https://docs.rs/pallet-im-online/latest/pallet_im_online/struct.Module.html) @@ -48,4 +48,4 @@ decl_module! { This module depends on the [Session module](https://docs.rs/pallet-session/latest/pallet_session/). -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/multisig/README.md b/frame/multisig/README.md index a0851f948d1..a18ef74163d 100644 --- a/frame/multisig/README.md +++ b/frame/multisig/README.md @@ -1,7 +1,7 @@ # Multisig Module A module for doing multisig dispatch. -- [`multisig::Config`](https://docs.rs/pallet-multisig/latest/pallet_multisig/trait.Config.html) +- [`multisig::Trait`](https://docs.rs/pallet-multisig/latest/pallet_multisig/trait.Trait.html) - [`Call`](https://docs.rs/pallet-multisig/latest/pallet_multisig/enum.Call.html) ## Overview @@ -26,4 +26,4 @@ not available or desired. [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/nicks/README.md b/frame/nicks/README.md index fa6a3be0e4e..766108470be 100644 --- a/frame/nicks/README.md +++ b/frame/nicks/README.md @@ -1,6 +1,6 @@ # Nicks Module -- [`nicks::Config`](https://docs.rs/pallet-nicks/latest/pallet_nicks/trait.Config.html) +- [`nicks::Trait`](https://docs.rs/pallet-nicks/latest/pallet_nicks/trait.Trait.html) - [`Call`](https://docs.rs/pallet-nicks/latest/pallet_nicks/enum.Call.html) ## Overview @@ -22,4 +22,4 @@ have not been designed to be economically secure. Do not use this pallet as-is i [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/proxy/README.md b/frame/proxy/README.md index d85cfa7d049..20c4d2bf20b 100644 --- a/frame/proxy/README.md +++ b/frame/proxy/README.md @@ -6,7 +6,7 @@ The accounts to which permission is delegated may be requied to announce the act wish to execute some duration prior to execution happens. In this case, the target account may reject the announcement and in doing so, veto the execution. -- [`proxy::Config`](https://docs.rs/pallet-proxy/latest/pallet_proxy/trait.Config.html) +- [`proxy::Trait`](https://docs.rs/pallet-proxy/latest/pallet_proxy/trait.Trait.html) - [`Call`](https://docs.rs/pallet-proxy/latest/pallet_proxy/enum.Call.html) ## Overview @@ -18,4 +18,4 @@ reject the announcement and in doing so, veto the execution. [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/recovery/README.md b/frame/recovery/README.md index ff990bc97c9..c45df2c666a 100644 --- a/frame/recovery/README.md +++ b/frame/recovery/README.md @@ -1,6 +1,6 @@ # Recovery Pallet -- [`recovery::Config`](https://docs.rs/pallet-recovery/latest/pallet_recovery/trait.Config.html) +- [`recovery::Trait`](https://docs.rs/pallet-recovery/latest/pallet_recovery/trait.Trait.html) - [`Call`](https://docs.rs/pallet-recovery/latest/pallet_recovery/enum.Call.html) ## Overview @@ -131,4 +131,4 @@ of this pallet are: * `set_recovered` - The ROOT origin is able to skip the recovery process and directly allow one account to access another. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/scheduler/README.md b/frame/scheduler/README.md index fb08297846c..3d07818b15d 100644 --- a/frame/scheduler/README.md +++ b/frame/scheduler/README.md @@ -1,7 +1,7 @@ # Scheduler A module for scheduling dispatches. -- [`scheduler::Config`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/trait.Config.html) +- [`scheduler::Trait`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/trait.Trait.html) - [`Call`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/enum.Call.html) - [`Module`](https://docs.rs/pallet-scheduler/latest/pallet_scheduler/struct.Module.html) @@ -31,4 +31,4 @@ then those filter will not be used when dispatching the schedule call. `Vec` parameter that can be used for identification. * `cancel_named` - the named complement to the cancel function. -License: Unlicense \ No newline at end of file +License: Unlicense diff --git a/frame/scored-pool/README.md b/frame/scored-pool/README.md index 85d20003580..8f7198a5e11 100644 --- a/frame/scored-pool/README.md +++ b/frame/scored-pool/README.md @@ -20,7 +20,7 @@ time. If an entity is currently a member, this results in removal from the `Pool` and `Members`; the entity is immediately replaced by the next highest scoring candidate in the pool, if available. -- [`scored_pool::Config`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/trait.Config.html) +- [`scored_pool::Trait`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/trait.Trait.html) - [`Call`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/enum.Call.html) - [`Module`](https://docs.rs/pallet-scored-pool/latest/pallet_scored_pool/struct.Module.html) @@ -63,4 +63,4 @@ decl_module! { This module depends on the [System module](https://docs.rs/frame-system/latest/frame_system/). -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/session/README.md b/frame/session/README.md index f955268c21b..e1f8b7f8e02 100644 --- a/frame/session/README.md +++ b/frame/session/README.md @@ -3,7 +3,7 @@ The Session module allows validators to manage their session keys, provides a function for changing the session length, and handles session rotation. -- [`session::Config`](https://docs.rs/pallet-session/latest/pallet_session/trait.Config.html) +- [`session::Trait`](https://docs.rs/pallet-session/latest/pallet_session/trait.Trait.html) - [`Call`](https://docs.rs/pallet-session/latest/pallet_session/enum.Call.html) - [`Module`](https://docs.rs/pallet-session/latest/pallet_session/struct.Module.html) @@ -80,4 +80,4 @@ fn validators() -> Vec<: - [Staking](https://docs.rs/pallet-staking/latest/pallet_staking/) -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/society/README.md b/frame/society/README.md index f68aeb73d42..a25940f636d 100644 --- a/frame/society/README.md +++ b/frame/society/README.md @@ -1,6 +1,6 @@ # Society Module -- [`society::Config`](https://docs.rs/pallet-society/latest/pallet_society/trait.Config.html) +- [`society::Trait`](https://docs.rs/pallet-society/latest/pallet_society/trait.Trait.html) - [`Call`](https://docs.rs/pallet-society/latest/pallet_society/enum.Call.html) ## Overview @@ -225,4 +225,4 @@ make judgement on a suspended candidate. * `set_max_membership` - The ROOT origin can update the maximum member count for the society. The max membership count must be greater than 1. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/staking/README.md b/frame/staking/README.md index d073818d649..1f1ba3dffa8 100644 --- a/frame/staking/README.md +++ b/frame/staking/README.md @@ -2,7 +2,7 @@ The Staking module is used to manage funds at stake by network maintainers. -- [`staking::Config`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html) +- [`staking::Trait`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html) - [`Call`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html) - [`Module`](https://docs.rs/pallet-staking/latest/pallet_staking/struct.Module.html) @@ -157,7 +157,7 @@ decl_module! { ### Era payout The era payout is computed using yearly inflation curve defined at -[`T::RewardCurve`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.RewardCurve) as such: +[`T::RewardCurve`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.RewardCurve) as such: ```nocompile staker_payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year @@ -168,7 +168,7 @@ This payout is used to reward stakers as defined in next section remaining_payout = max_yearly_inflation * total_tokens / era_per_year - staker_payout ``` The remaining reward is send to the configurable end-point -[`T::RewardRemainder`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.RewardRemainder). +[`T::RewardRemainder`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.RewardRemainder). ### Reward Calculation @@ -214,7 +214,7 @@ Any funds already placed into stash can be the target of the following operation The controller account can free a portion (or all) of the funds using the [`unbond`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html#variant.unbond) call. Note that the funds are not immediately -accessible. Instead, a duration denoted by [`BondingDuration`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Config.html#associatedtype.BondingDuration) +accessible. Instead, a duration denoted by [`BondingDuration`](https://docs.rs/pallet-staking/latest/pallet_staking/trait.Trait.html#associatedtype.BondingDuration) (in number of eras) must pass until the funds can actually be removed. Once the `BondingDuration` is over, the [`withdraw_unbonded`](https://docs.rs/pallet-staking/latest/pallet_staking/enum.Call.html#variant.withdraw_unbonded) call can be used to actually withdraw the funds. @@ -246,4 +246,4 @@ The Staking module depends on the [`GenesisConfig`](https://docs.rs/pallet-staki - [Session](https://docs.rs/pallet-session/latest/pallet_session/): Used to manage sessions. Also, a list of new validators is stored in the Session module's `Validators` at the end of each era. -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/sudo/README.md b/frame/sudo/README.md index 8ac0264d458..95ca7ce88d9 100644 --- a/frame/sudo/README.md +++ b/frame/sudo/README.md @@ -1,6 +1,6 @@ # Sudo Module -- [`sudo::Config`](https://docs.rs/pallet-sudo/latest/pallet_sudo/trait.Config.html) +- [`sudo::Trait`](https://docs.rs/pallet-sudo/latest/pallet_sudo/trait.Trait.html) - [`Call`](https://docs.rs/pallet-sudo/latest/pallet_sudo/enum.Call.html) ## Overview @@ -67,4 +67,4 @@ You need to set an initial superuser account as the sudo `key`. [`Config`]: ./trait.Config.html [`Origin`]: https://docs.substrate.dev/docs/substrate-types -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/system/README.md b/frame/system/README.md index b2ff4009dfa..106a16bc209 100644 --- a/frame/system/README.md +++ b/frame/system/README.md @@ -3,7 +3,7 @@ The System module provides low-level access to core types and cross-cutting utilities. It acts as the base layer for other pallets to interact with the Substrate framework components. -- [`system::Config`](https://docs.rs/frame-system/latest/frame_system/trait.Config.html) +- [`system::Trait`](https://docs.rs/frame-system/latest/frame_system/trait.Trait.html) ## Overview @@ -72,4 +72,4 @@ decl_module! { } ``` -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/timestamp/README.md b/frame/timestamp/README.md index 6ba03305439..de1fb743922 100644 --- a/frame/timestamp/README.md +++ b/frame/timestamp/README.md @@ -2,7 +2,7 @@ The Timestamp module provides functionality to get and set the on-chain time. -- [`timestamp::Config`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/trait.Config.html) +- [`timestamp::Trait`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/trait.Trait.html) - [`Call`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/enum.Call.html) - [`Module`](https://docs.rs/pallet-timestamp/latest/pallet_timestamp/struct.Module.html) @@ -71,4 +71,4 @@ the Timestamp module for session management. * [Session](https://docs.rs/pallet-session/latest/pallet_session/) -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/treasury/README.md b/frame/treasury/README.md index b316e604f4a..c8e1a57350d 100644 --- a/frame/treasury/README.md +++ b/frame/treasury/README.md @@ -3,7 +3,7 @@ The Treasury module provides a "pot" of funds that can be managed by stakeholders in the system and a structure for making spending proposals from this pot. -- [`treasury::Config`](https://docs.rs/pallet-treasury/latest/pallet_treasury/trait.Config.html) +- [`treasury::Trait`](https://docs.rs/pallet-treasury/latest/pallet_treasury/trait.Trait.html) - [`Call`](https://docs.rs/pallet-treasury/latest/pallet_treasury/enum.Call.html) ## Overview @@ -115,4 +115,4 @@ tasks and stake the required deposit. The Treasury module depends on the [`GenesisConfig`](https://docs.rs/pallet-treasury/latest/pallet_treasury/struct.GenesisConfig.html). -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/utility/README.md b/frame/utility/README.md index df874ec1106..f7c0923cd54 100644 --- a/frame/utility/README.md +++ b/frame/utility/README.md @@ -1,7 +1,7 @@ # Utility Module A stateless module with helpers for dispatch management which does no re-authentication. -- [`utility::Config`](https://docs.rs/pallet-utility/latest/pallet_utility/trait.Config.html) +- [`utility::Trait`](https://docs.rs/pallet-utility/latest/pallet_utility/trait.Trait.html) - [`Call`](https://docs.rs/pallet-utility/latest/pallet_utility/enum.Call.html) ## Overview @@ -35,4 +35,4 @@ filtered by any proxy. [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 diff --git a/frame/vesting/README.md b/frame/vesting/README.md index 59bfdfcedd0..811b0dc4415 100644 --- a/frame/vesting/README.md +++ b/frame/vesting/README.md @@ -1,6 +1,6 @@ # Vesting Module -- [`vesting::Config`](https://docs.rs/pallet-vesting/latest/pallet_vesting/trait.Config.html) +- [`vesting::Trait`](https://docs.rs/pallet-vesting/latest/pallet_vesting/trait.Trait.html) - [`Call`](https://docs.rs/pallet-vesting/latest/pallet_vesting/enum.Call.html) ## Overview @@ -28,4 +28,4 @@ This module implements the `VestingSchedule` trait. [`Call`]: ./enum.Call.html [`Config`]: ./trait.Config.html -License: Apache-2.0 \ No newline at end of file +License: Apache-2.0 -- GitLab From ace7f47735a6cb87580513d4eaa6bc7c7c398bd4 Mon Sep 17 00:00:00 2001 From: jolestar Date: Tue, 1 Dec 2020 18:58:00 +0800 Subject: [PATCH 069/163] Fix cargo clippy warning in peerset. (#7641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix cargo clippy warning in peerset. * Update client/peerset/src/lib.rs Co-authored-by: Bastian Köcher * Apply suggestions from code review Co-authored-by: Pierre Krieger Co-authored-by: Bastian Köcher Co-authored-by: Pierre Krieger --- client/peerset/src/lib.rs | 48 ++++++++++++---------------- client/peerset/src/peersstate.rs | 8 ++--- client/peerset/tests/fuzz.rs | 4 +-- primitives/utils/src/mpsc.rs | 2 +- primitives/utils/src/status_sinks.rs | 6 ++++ 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 575743afa07..b3284533a80 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -36,7 +36,7 @@ const BANNED_THRESHOLD: i32 = 82 * (i32::min_value() / 100); /// Reputation change for a node when we get disconnected from it. const DISCONNECT_REPUTATION_CHANGE: i32 = -256; /// Reserved peers group ID -const RESERVED_NODES: &'static str = "reserved"; +const RESERVED_NODES: &str = "reserved"; /// Amount of time between the moment we disconnect from a node and the moment we remove it from /// the list. const FORGET_AFTER: Duration = Duration::from_secs(3600); @@ -87,7 +87,7 @@ impl PeersetHandle { /// Has no effect if the node was already a reserved peer. /// /// > **Note**: Keep in mind that the networking has to know an address for this node, - /// > otherwise it will not be able to connect to it. + /// > otherwise it will not be able to connect to it. pub fn add_reserved_peer(&self, peer_id: PeerId) { let _ = self.tx.unbounded_send(Action::AddReservedPeer(peer_id)); } @@ -169,7 +169,7 @@ pub struct PeersetConfig { /// List of bootstrap nodes to initialize the peer with. /// /// > **Note**: Keep in mind that the networking has to know an address for these nodes, - /// > otherwise it will not be able to connect to them. + /// > otherwise it will not be able to connect to them. pub bootnodes: Vec, /// If true, we only accept nodes in [`PeersetConfig::priority_groups`]. @@ -178,7 +178,7 @@ pub struct PeersetConfig { /// Lists of nodes we should always be connected to. /// /// > **Note**: Keep in mind that the networking has to know an address for these nodes, - /// > otherwise it will not be able to connect to them. + /// > otherwise it will not be able to connect to them. pub priority_groups: Vec<(String, HashSet)>, } @@ -430,10 +430,9 @@ impl Peerset { .get(RESERVED_NODES) .into_iter() .flatten() - .filter(move |n| { + .find(move |n| { data.peer(n).into_connected().is_none() }) - .next() .cloned() }; @@ -469,10 +468,9 @@ impl Peerset { self.priority_groups .values() .flatten() - .filter(move |n| { + .find(move |n| { data.peer(n).into_connected().is_none() }) - .next() .cloned() }; @@ -497,21 +495,17 @@ impl Peerset { } // Now, we try to connect to non-priority nodes. - loop { - // Try to grab the next node to attempt to connect to. - let next = match self.data.highest_not_connected_peer() { - Some(p) => p, - None => break, // No known node to add. - }; - + while let Some(next) = self.data.highest_not_connected_peer() { // Don't connect to nodes with an abysmal reputation. if next.reputation() < BANNED_THRESHOLD { break; } match next.try_outgoing() { - Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), - Err(_) => break, // No more slots available. + Ok(conn) => self + .message_queue + .push_back(Message::Connect(conn.into_peer_id())), + Err(_) => break, // No more slots available. } } } @@ -530,11 +524,9 @@ impl Peerset { trace!(target: "peerset", "Incoming {:?}", peer_id); self.update_time(); - if self.reserved_only { - if !self.priority_groups.get(RESERVED_NODES).map_or(false, |n| n.contains(&peer_id)) { - self.message_queue.push_back(Message::Reject(index)); - return; - } + if self.reserved_only && !self.priority_groups.get(RESERVED_NODES).map_or(false, |n| n.contains(&peer_id)) { + self.message_queue.push_back(Message::Reject(index)); + return; } let not_connected = match self.data.peer(&peer_id) { @@ -584,7 +576,7 @@ impl Peerset { /// Adds discovered peer ids to the PSM. /// /// > **Note**: There is no equivalent "expired" message, meaning that it is the responsibility - /// > of the PSM to remove `PeerId`s that fail to dial too often. + /// > of the PSM to remove `PeerId`s that fail to dial too often. pub fn discovered>(&mut self, peer_ids: I) { let mut discovered_any = false; @@ -747,12 +739,12 @@ mod tests { let (mut peerset, _handle) = Peerset::from_config(config); peerset.incoming(incoming.clone(), ii); - peerset.incoming(incoming.clone(), ii4); - peerset.incoming(incoming2.clone(), ii2); - peerset.incoming(incoming3.clone(), ii3); + peerset.incoming(incoming, ii4); + peerset.incoming(incoming2, ii2); + peerset.incoming(incoming3, ii3); assert_messages(peerset, vec![ - Message::Connect(bootnode.clone()), + Message::Connect(bootnode), Message::Accept(ii), Message::Accept(ii2), Message::Reject(ii3), @@ -772,7 +764,7 @@ mod tests { }; let (mut peerset, _) = Peerset::from_config(config); - peerset.incoming(incoming.clone(), ii); + peerset.incoming(incoming, ii); assert_messages(peerset, vec![ Message::Reject(ii), diff --git a/client/peerset/src/peersstate.rs b/client/peerset/src/peersstate.rs index 59879f629e3..19b2489eff4 100644 --- a/client/peerset/src/peersstate.rs +++ b/client/peerset/src/peersstate.rs @@ -42,8 +42,8 @@ pub struct PeersState { /// List of nodes that we know about. /// /// > **Note**: This list should really be ordered by decreasing reputation, so that we can - /// easily select the best node to connect to. As a first draft, however, we don't - /// sort, to make the logic easier. + /// easily select the best node to connect to. As a first draft, however, we don't + /// sort, to make the logic easier. nodes: HashMap, /// Number of slot-occupying nodes for which the `ConnectionState` is `In`. @@ -130,7 +130,7 @@ impl PeersState { /// Returns an object that grants access to the state of a peer. pub fn peer<'a>(&'a mut self, peer_id: &'a PeerId) -> Peer<'a> { match self.nodes.get_mut(peer_id) { - None => return Peer::Unknown(UnknownPeer { + None => Peer::Unknown(UnknownPeer { parent: self, peer_id: Cow::Borrowed(peer_id), }), @@ -585,7 +585,7 @@ mod tests { peers_state.peer(&id2).into_connected().unwrap().disconnect(); assert_eq!(peers_state.highest_not_connected_peer().map(|p| p.into_peer_id()), Some(id1.clone())); peers_state.peer(&id1).into_not_connected().unwrap().set_reputation(-100); - assert_eq!(peers_state.highest_not_connected_peer().map(|p| p.into_peer_id()), Some(id2.clone())); + assert_eq!(peers_state.highest_not_connected_peer().map(|p| p.into_peer_id()), Some(id2)); } #[test] diff --git a/client/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs index 6fa29e3d834..e02742fc40a 100644 --- a/client/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -115,8 +115,8 @@ fn test_once() { 4 => if let Some(id) = known_nodes.iter() .filter(|n| incoming_nodes.values().all(|m| m != *n) && !connected_nodes.contains(*n)) .choose(&mut rng) { - peerset.incoming(id.clone(), next_incoming_id.clone()); - incoming_nodes.insert(next_incoming_id.clone(), id.clone()); + peerset.incoming(id.clone(), next_incoming_id); + incoming_nodes.insert(next_incoming_id, id.clone()); next_incoming_id.0 += 1; } diff --git a/primitives/utils/src/mpsc.rs b/primitives/utils/src/mpsc.rs index 70baa006bdc..321ab72f0d2 100644 --- a/primitives/utils/src/mpsc.rs +++ b/primitives/utils/src/mpsc.rs @@ -63,7 +63,7 @@ mod inner { /// `UNBOUNDED_CHANNELS_COUNTER` pub fn tracing_unbounded(key: &'static str) ->(TracingUnboundedSender, TracingUnboundedReceiver) { let (s, r) = mpsc::unbounded(); - (TracingUnboundedSender(key.clone(), s), TracingUnboundedReceiver(key,r)) + (TracingUnboundedSender(key, s), TracingUnboundedReceiver(key,r)) } impl TracingUnboundedSender { diff --git a/primitives/utils/src/status_sinks.rs b/primitives/utils/src/status_sinks.rs index 65a560af4ea..6ca9452893f 100644 --- a/primitives/utils/src/status_sinks.rs +++ b/primitives/utils/src/status_sinks.rs @@ -43,6 +43,12 @@ struct YieldAfter { sender: Option>, } +impl Default for StatusSinks { + fn default() -> Self { + Self::new() + } +} + impl StatusSinks { /// Builds a new empty collection. pub fn new() -> StatusSinks { -- GitLab From b63b8643e00214f1cbe28b6ca4e804af656c9038 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Tue, 1 Dec 2020 13:50:27 +0100 Subject: [PATCH 070/163] remove unused deps pulled by parity-util-mem (#7635) * remove unused deps pulled by parity-util-mem * fix a warning about unused Cargo key --- Cargo.lock | 123 +++------------------------------------ Cargo.toml | 1 - frame/support/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 190dbaf7179..9a44096132f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,15 +79,6 @@ dependencies = [ "opaque-debug 0.3.0", ] -[[package]] -name = "ahash" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29661b60bec623f0586702976ff4d0c9942dcb6723161c2df0eea78455cfedfb" -dependencies = [ - "const-random", -] - [[package]] name = "ahash" version = "0.3.8" @@ -798,26 +789,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "const-random" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dc82c12dc2ee6e1ded861cf7d582b46f66f796d1b6c93fa28b911ead95da02" -dependencies = [ - "const-random-macro", - "proc-macro-hack", -] - -[[package]] -name = "const-random-macro" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc757bbb9544aa296c2ae00c679e81f886b37e28e59097defe0cf524306f6685" -dependencies = [ - "getrandom 0.2.0", - "proc-macro-hack", -] - [[package]] name = "const_fn" version = "0.4.3" @@ -1406,33 +1377,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ethbloom" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a6567e6fd35589fea0c63b94b4cf2e55573e413901bdbe60ab15cf0e25e5df" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473aecff686bd8e7b9db0165cbbb53562376b39bf35b427f0c60446a9e1634b0" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - [[package]] name = "event-listener" version = "2.5.1" @@ -2040,17 +1984,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "ghash" version = "0.3.0" @@ -2182,16 +2115,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" -dependencies = [ - "ahash 0.2.19", - "autocfg 0.1.7", -] - [[package]] name = "hashbrown" version = "0.8.2" @@ -2478,15 +2401,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "impl-rlp" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" -dependencies = [ - "rlp", -] - [[package]] name = "impl-serde" version = "0.3.1" @@ -3175,7 +3089,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "lru 0.6.1", + "lru", "minicbor", "rand 0.7.3", "smallvec 1.5.0", @@ -3396,15 +3310,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "lru" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c456c123957de3a220cd03786e0d86aa542a88b46029973b542f426da6ef34" -dependencies = [ - "hashbrown 0.6.3", -] - [[package]] name = "lru" version = "0.6.1" @@ -5260,10 +5165,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ "cfg-if 0.1.10", - "ethereum-types", "hashbrown 0.8.2", "impl-trait-for-tuples", - "lru 0.5.3", "parity-util-mem-derive", "parking_lot 0.10.2", "primitive-types", @@ -5684,7 +5587,6 @@ checksum = "7dd39dcacf71411ba488570da7bbc89b717225e46478b30ba99b92db6b149809" dependencies = [ "fixed-hash", "impl-codec", - "impl-rlp", "impl-serde", "uint", ] @@ -5928,7 +5830,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.15", + "getrandom", "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", @@ -5977,7 +5879,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.15", + "getrandom", ] [[package]] @@ -6133,7 +6035,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ - "getrandom 0.1.15", + "getrandom", "redox_syscall", "rust-argon2", ] @@ -6239,15 +6141,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rlp" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1190dcc8c3a512f1eef5d09bb8c84c7f39e1054e174d1795482e18f5272f2e73" -dependencies = [ - "rustc-hex", -] - [[package]] name = "rocksdb" version = "0.15.0" @@ -7096,7 +6989,7 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log", - "lru 0.6.1", + "lru", "nohash-hasher", "parity-scale-codec", "parking_lot 0.11.1", @@ -7142,7 +7035,7 @@ dependencies = [ "futures-timer 3.0.2", "libp2p", "log", - "lru 0.6.1", + "lru", "quickcheck", "rand 0.7.3", "sc-network", @@ -7578,7 +7471,7 @@ dependencies = [ "arrayref", "arrayvec 0.5.2", "curve25519-dalek 2.1.0", - "getrandom 0.1.15", + "getrandom", "merlin", "rand 0.7.3", "rand_core 0.5.1", @@ -8118,7 +8011,7 @@ version = "2.0.0" dependencies = [ "futures 0.3.8", "log", - "lru 0.6.1", + "lru", "parity-scale-codec", "parking_lot 0.10.2", "sp-api", diff --git a/Cargo.toml b/Cargo.toml index 2e3cff821e0..6a007a209f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -207,7 +207,6 @@ aesni = { opt-level = 3 } blake2 = { opt-level = 3 } blake2-rfc = { opt-level = 3 } blake2b_simd = { opt-level = 3 } -blake2s_simd = { opt-level = 3 } chacha20poly1305 = { opt-level = 3 } cranelift-codegen = { opt-level = 3 } cranelift-wasm = { opt-level = 3 } diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 1f7fe9a2025..0189dc172fb 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -35,7 +35,7 @@ smallvec = "1.4.1" [dev-dependencies] pretty_assertions = "0.6.1" frame-system = { version = "2.0.0", path = "../system" } -parity-util-mem = { version = "0.7.0", features = ["primitive-types"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } sp-api = { version = "2.0.0", default-features = false, path = "../../primitives/api" } -- GitLab From cbe1cc33bc1ee12da92440b0e753b6680b5ac5ba Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Tue, 1 Dec 2020 15:35:06 +0100 Subject: [PATCH 071/163] minor fix and improvements on localkeystore (#7626) * minor fixes and improvements on localkeystore * fixing tests * update docs --- client/keystore/src/local.rs | 50 ++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index e0b95a08d5c..a31e3e1f1e4 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -329,7 +329,7 @@ impl KeystoreInner { /// Open the store at the given path. /// /// Optionally takes a password that will be used to encrypt/decrypt the keys. - pub fn open>(path: T, password: Option) -> Result { + fn open>(path: T, password: Option) -> Result { let path = path.into(); fs::create_dir_all(&path)?; @@ -345,7 +345,7 @@ impl KeystoreInner { } /// Create a new in-memory store. - pub fn new_in_memory() -> Self { + fn new_in_memory() -> Self { Self { path: None, additional: HashMap::new(), @@ -373,8 +373,8 @@ impl KeystoreInner { /// Insert a new key with anonymous crypto. /// - /// Places it into the file system store. - pub fn insert_unknown(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<()> { + /// Places it into the file system store, if a path is configured. + fn insert_unknown(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<()> { if let Some(path) = self.key_file_path(public, key_type) { let mut file = File::create(path).map_err(Error::Io)?; serde_json::to_writer(&file, &suri).map_err(Error::Json)?; @@ -385,13 +385,16 @@ impl KeystoreInner { /// Generate a new key. /// - /// Places it into the file system store. - pub fn generate_by_type(&self, key_type: KeyTypeId) -> Result { + /// Places it into the file system store, if a path is configured. Otherwise insert + /// it into the memory cache only. + fn generate_by_type(&mut self, key_type: KeyTypeId) -> Result { let (pair, phrase, _) = Pair::generate_with_phrase(self.password()); if let Some(path) = self.key_file_path(pair.public().as_slice(), key_type) { let mut file = File::create(path)?; serde_json::to_writer(&file, &phrase)?; file.flush()?; + } else { + self.insert_ephemeral_pair(&pair, &phrase, key_type); } Ok(pair) } @@ -399,7 +402,7 @@ impl KeystoreInner { /// Create a new key from seed. /// /// Does not place it into the file system store. - pub fn insert_ephemeral_from_seed_by_type( + fn insert_ephemeral_from_seed_by_type( &mut self, seed: &str, key_type: KeyTypeId, @@ -422,7 +425,7 @@ impl KeystoreInner { } /// Get a key pair for the given public key and key type. - pub fn key_pair_by_type(&self, + fn key_pair_by_type(&self, public: &Pair::Public, key_type: KeyTypeId, ) -> Result { @@ -501,6 +504,8 @@ mod tests { str::FromStr, }; + const TEST_KEY_TYPE: KeyTypeId = KeyTypeId(*b"test"); + impl KeystoreInner { fn insert_ephemeral_from_seed(&mut self, seed: &str) -> Result { self.insert_ephemeral_from_seed_by_type::(seed, Pair::ID).map(Into::into) @@ -515,7 +520,7 @@ mod tests { }) } - fn generate(&self) -> Result { + fn generate(&mut self) -> Result { self.generate_by_type::(Pair::ID).map(Into::into) } } @@ -523,7 +528,7 @@ mod tests { #[test] fn basic_store() { let temp_dir = TempDir::new().unwrap(); - let store = KeystoreInner::open(temp_dir.path(), None).unwrap(); + let mut store = KeystoreInner::open(temp_dir.path(), None).unwrap(); assert!(store.public_keys::().unwrap().is_empty()); @@ -558,7 +563,7 @@ mod tests { fn password_being_used() { let password = String::from("password"); let temp_dir = TempDir::new().unwrap(); - let store = KeystoreInner::open( + let mut store = KeystoreInner::open( temp_dir.path(), Some(FromStr::from_str(password.as_str()).unwrap()), ).unwrap(); @@ -640,4 +645,27 @@ mod tests { SyncCryptoStore::sr25519_public_keys(&store, SR25519).is_empty(), ); } + + #[test] + fn generate_with_seed_is_not_stored() { + let temp_dir = TempDir::new().unwrap(); + let store = LocalKeystore::open(temp_dir.path(), None).unwrap(); + let _alice_tmp_key = SyncCryptoStore::sr25519_generate_new(&store, TEST_KEY_TYPE, Some("//Alice")).unwrap(); + + assert_eq!(SyncCryptoStore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 1); + + drop(store); + let store = LocalKeystore::open(temp_dir.path(), None).unwrap(); + assert_eq!(SyncCryptoStore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 0); + } + + #[test] + fn generate_can_be_fetched_in_memory() { + let store = LocalKeystore::in_memory(); + SyncCryptoStore::sr25519_generate_new(&store, TEST_KEY_TYPE, Some("//Alice")).unwrap(); + + assert_eq!(SyncCryptoStore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 1); + SyncCryptoStore::sr25519_generate_new(&store, TEST_KEY_TYPE, None).unwrap(); + assert_eq!(SyncCryptoStore::sr25519_public_keys(&store, TEST_KEY_TYPE).len(), 2); + } } -- GitLab From ba8797284effac13701b6869a42eedd3f27677c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 1 Dec 2020 19:40:53 +0100 Subject: [PATCH 072/163] Remove a stray file. (#7649) --- client/transaction-pool/graph/src/error.rs | 81 ---------------------- 1 file changed, 81 deletions(-) delete mode 100644 client/transaction-pool/graph/src/error.rs diff --git a/client/transaction-pool/graph/src/error.rs b/client/transaction-pool/graph/src/error.rs deleted file mode 100644 index 01fcb9f8dc9..00000000000 --- a/client/transaction-pool/graph/src/error.rs +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2018-2020 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 . - -//! Transaction pool errors. - -use sp_runtime::transaction_validity::{ - TransactionPriority as Priority, InvalidTransaction, UnknownTransaction, -}; - -/// Transaction pool result. -pub type Result = std::result::Result; - -/// Transaction pool error type. -#[derive(Debug, thiserror::Error, derive_more::From)] -#[allow(missing_docs)] -pub enum Error { - /// Transaction is not verifiable yet, but might be in the future. - #[error("Unknown transaction validity: {0:?}")] - UnknownTransaction(UnknownTransaction), - - #[error("Invalid transaction validity: {0:?}")] - InvalidTransaction(InvalidTransaction), - /// The transaction validity returned no "provides" tag. - /// - /// Such transactions are not accepted to the pool, since we use those tags - /// to define identity of transactions (occupance of the same "slot"). - #[error("The transaction validity returned no `provides` tags, so the pool can't identify it.")] - NoTagsProvided, - - #[error("Temporarily Banned")] - TemporarilyBanned, - - #[error("[{0:?}] Transaction is already in the pool")] - AlreadyImported(Box), - - #[error("Transaction cannot be imported due to too low priority ({0} > {1})", old, new)] - TooLowPriority { - /// Transaction already in the pool. - old: Priority, - /// Transaction entering the pool. - new: Priority - }, - - #[error("Dependency cycle detected")] - CycleDetected, - - #[error("Transaction couldn't enter the pool because of the limit.")] - ImmediatelyDropped, - - #[error("Invlaid block id: {0}")] - InvalidBlockId(String), -} - -/// Transaction pool error conversion. -pub trait IntoPoolError: ::std::error::Error + Send + Sized { - /// Try to extract original `Error` - /// - /// This implementation is optional and used only to - /// provide more descriptive error messages for end users - /// of RPC API. - fn into_pool_error(self) -> ::std::result::Result { Err(self) } -} - -impl IntoPoolError for Error { - fn into_pool_error(self) -> ::std::result::Result { Ok(self) } -} -- GitLab From f884296f7436916909025f8b43c4bbf3e60e4c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Tue, 1 Dec 2020 18:49:09 +0000 Subject: [PATCH 073/163] fork-tree: fix tree rebalancing (#7616) * fork-tree: rebalance tree when inserting inner node * fork-tree: fix tests for new rebalancing behavior * fork-tree: fix node iterator initial state * grandpa: fix tests --- client/finality-grandpa/src/authorities.rs | 5 ++- utils/fork-tree/src/lib.rs | 50 +++++++++++++++------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 2de169fc828..de14c7b3ba3 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -758,9 +758,10 @@ mod tests { authorities.add_pending_change(change_d.clone(), &static_is_descendent_of(false)).unwrap(); authorities.add_pending_change(change_e.clone(), &static_is_descendent_of(false)).unwrap(); + // ordered by subtree depth assert_eq!( authorities.pending_changes().collect::>(), - vec![&change_b, &change_a, &change_c, &change_e, &change_d], + vec![&change_a, &change_c, &change_b, &change_e, &change_d], ); } @@ -798,7 +799,7 @@ mod tests { assert_eq!( authorities.pending_changes().collect::>(), - vec![&change_b, &change_a], + vec![&change_a, &change_b], ); // finalizing "hash_c" won't enact the change signaled at "hash_a" but it will prune out "hash_b" diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index 1d01c534176..f266b642230 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -229,7 +229,10 @@ impl ForkTree where number = n; data = d; }, - None => return Ok(false), + None => { + self.rebalance(); + return Ok(false); + }, } } @@ -251,7 +254,9 @@ impl ForkTree where } fn node_iter(&self) -> impl Iterator> { - ForkTreeIterator { stack: self.roots.iter().collect() } + // we need to reverse the order of roots to maintain the expected + // ordering since the iterator uses a stack to track state. + ForkTreeIterator { stack: self.roots.iter().rev().collect() } } /// Iterates the nodes in the tree in pre-order. @@ -939,6 +944,10 @@ mod test { // — J - K // // (where N is not a part of fork tree) + // + // NOTE: the tree will get automatically rebalance on import and won't be laid out like the + // diagram above. the children will be ordered by subtree depth and the longest branches + // will be on the leftmost side of the tree. let is_descendent_of = |base: &&str, block: &&str| -> Result { let letters = vec!["B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "O"]; match (*base, *block) { @@ -1132,7 +1141,7 @@ mod test { assert_eq!( tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), - vec![("I", 4), ("L", 4)], + vec![("L", 4), ("I", 4)], ); // finalizing a node from another fork that isn't part of the tree clears the tree @@ -1180,7 +1189,7 @@ mod test { assert_eq!( tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::>(), - vec![("I", 4), ("L", 4)], + vec![("L", 4), ("I", 4)], ); assert_eq!( @@ -1354,11 +1363,11 @@ mod test { vec![ ("A", 1), ("B", 2), ("C", 3), ("D", 4), ("E", 5), - ("F", 2), + ("F", 2), ("H", 3), ("L", 4), ("M", 5), + ("O", 5), + ("I", 4), ("G", 3), - ("H", 3), ("I", 4), - ("L", 4), ("M", 5), ("O", 5), - ("J", 2), ("K", 3) + ("J", 2), ("K", 3), ], ); } @@ -1480,7 +1489,7 @@ mod test { assert_eq!( removed.map(|(hash, _, _)| hash).collect::>(), - vec!["A", "F", "G", "H", "I", "L", "M", "O", "J", "K"] + vec!["A", "F", "H", "L", "M", "O", "I", "G", "J", "K"] ); let removed = tree.prune( @@ -1545,19 +1554,30 @@ mod test { fn tree_rebalance() { let (mut tree, _) = test_fork_tree(); + // the tree is automatically rebalanced on import, therefore we should iterate in preorder + // exploring the longest forks first. check the ascii art above to understand the expected + // output below. assert_eq!( tree.iter().map(|(h, _, _)| *h).collect::>(), - vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "L", "M", "O", "J", "K"], + vec!["A", "B", "C", "D", "E", "F", "H", "L", "M", "O", "I", "G", "J", "K"], ); - // after rebalancing the tree we should iterate in preorder exploring - // the longest forks first. check the ascii art above to understand the - // expected output below. - tree.rebalance(); + // let's add a block "P" which is a descendent of block "O" + let is_descendent_of = |base: &&str, block: &&str| -> Result { + match (*base, *block) { + (b, "P") => Ok(vec!["A", "F", "L", "O"].into_iter().any(|n| n == b)), + _ => Ok(false), + } + }; + + tree.import("P", 6, (), &is_descendent_of).unwrap(); + // this should re-order the tree, since the branch "A -> B -> C -> D -> E" is no longer tied + // with 5 blocks depth. additionally "O" should be visited before "M" now, since it has one + // descendent "P" which makes that branch 6 blocks long. assert_eq!( tree.iter().map(|(h, _, _)| *h).collect::>(), - ["A", "B", "C", "D", "E", "F", "H", "L", "M", "O", "I", "G", "J", "K"] + ["A", "F", "H", "L", "O", "P", "M", "I", "G", "B", "C", "D", "E", "J", "K"] ); } } -- GitLab From e4ae38b0968f5d9eb5a896e629646d42a07277b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 2 Dec 2020 16:53:44 +0100 Subject: [PATCH 074/163] Use unreleased trybuild to fix CI (#7656) --- Cargo.lock | 3 +-- frame/support/test/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 2 +- primitives/runtime-interface/Cargo.toml | 2 +- test-utils/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a44096132f..681a65fccd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9623,8 +9623,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "trybuild" version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d30fe369fd650072b352b1a9cb9587669de6b89be3b8225544012c1c45292d" +source = "git+https://github.com/bkchr/trybuild.git?branch=bkchr-use-workspace-cargo-lock#0eaad05ba8a32a743751ff52b57a7d9f57da4869" dependencies = [ "dissimilar", "glob", diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 6d8064102c4..01484ccfb88 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -21,7 +21,7 @@ sp-inherents = { version = "2.0.0", default-features = false, path = "../../../p sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } -trybuild = "1.0.33" +trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } pretty_assertions = "0.6.1" rustversion = "1.0.0" frame-metadata = { version = "12.0.0", default-features = false, path = "../../metadata" } diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 867cdd6e57e..1110b02020b 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -21,7 +21,7 @@ sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common sc-block-builder = { version = "0.8.0", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.3.1" } sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } -trybuild = "1.0.17" +trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } rustversion = "1.0.0" [dev-dependencies] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index bc36098f05a..0138637366d 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -30,7 +30,7 @@ sp-state-machine = { version = "0.8.0", path = "../../primitives/state-machine" sp-core = { version = "2.0.0", path = "../core" } sp-io = { version = "2.0.0", path = "../io" } rustversion = "1.0.0" -trybuild = "1.0.23" +trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } [features] default = [ "std" ] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index ddadc2cb717..7606b0c1c15 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -18,4 +18,4 @@ tokio = { version = "0.2.13", features = ["macros"] } [dev-dependencies] sc-service = { version = "0.8.0", path = "../client/service" } -trybuild = { version = "1.0", features = ["diff"] } +trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock", features = [ "diff" ] } -- GitLab From 77f1089942b7f1190652887abb1246ea09dff894 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 2 Dec 2020 17:34:05 +0100 Subject: [PATCH 075/163] Show reputation changes when dropping peer (#7655) * Show reputation changes when dropping peer * Print all --- client/peerset/src/lib.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index b3284533a80..bb08bdc18e6 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -103,7 +103,7 @@ impl PeersetHandle { pub fn set_reserved_only(&self, reserved: bool) { let _ = self.tx.unbounded_send(Action::SetReservedOnly(reserved)); } - + /// Set reserved peers to the new set. pub fn set_reserved_peers(&self, peer_ids: HashSet) { let _ = self.tx.unbounded_send(Action::SetReservedPeers(peer_ids)); @@ -252,7 +252,7 @@ impl Peerset { fn on_remove_reserved_peer(&mut self, peer_id: PeerId) { self.on_remove_from_priority_group(RESERVED_NODES, peer_id); } - + fn on_set_reserved_peers(&mut self, peer_ids: HashSet) { self.on_set_priority_group(RESERVED_NODES, peer_ids); } @@ -357,8 +357,18 @@ impl Peerset { ); } }, - peersstate::Peer::NotConnected(mut peer) => peer.add_reputation(change.value), - peersstate::Peer::Unknown(peer) => peer.discover().add_reputation(change.value), + peersstate::Peer::NotConnected(mut peer) => { + trace!(target: "peerset", "Report {}: {:+} to {}. Reason: {}", + peer_id, change.value, peer.reputation(), change.reason + ); + peer.add_reputation(change.value) + }, + peersstate::Peer::Unknown(peer) => { + trace!(target: "peerset", "Discover {}: {:+}. Reason: {}", + peer_id, change.value, change.reason + ); + peer.discover().add_reputation(change.value) + }, } } @@ -555,8 +565,6 @@ impl Peerset { /// Must only be called after the PSM has either generated a `Connect` message with this /// `PeerId`, or accepted an incoming connection with this `PeerId`. pub fn dropped(&mut self, peer_id: PeerId) { - trace!(target: "peerset", "Dropping {:?}", peer_id); - // We want reputations to be up-to-date before adjusting them. self.update_time(); @@ -564,6 +572,8 @@ impl Peerset { peersstate::Peer::Connected(mut entry) => { // Decrease the node's reputation so that we don't try it again and again and again. entry.add_reputation(DISCONNECT_REPUTATION_CHANGE); + trace!(target: "peerset", "Dropping {}: {:+} to {}", + peer_id, DISCONNECT_REPUTATION_CHANGE, entry.reputation()); entry.disconnect(); } peersstate::Peer::NotConnected(_) | peersstate::Peer::Unknown(_) => -- GitLab From f4d4244ed6f09675f09c6e1afa96c2b595a689bf Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 2 Dec 2020 17:35:48 +0100 Subject: [PATCH 076/163] Remove sc_network::NetworkService::register_notifications_protocol and partially refactor Grandpa tests (#7646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove sc_network::NetworkService::register_notifications_protocol * Missing calls to .into() * Wrong crate name * [WIP] Fix Grandpa tests * One more passing * One more. Two to go. * This one was actually already passing 🎉 * Last one compiles * Progress * grandpa: fix voter_persists_its_votes test * Restore other tests * Try spawn future later Co-authored-by: André Silva --- bin/node-template/node/src/service.rs | 10 +- bin/node/cli/src/service.rs | 10 +- .../finality-grandpa/src/communication/mod.rs | 2 + .../src/communication/tests.rs | 2 - client/finality-grandpa/src/lib.rs | 25 +- client/finality-grandpa/src/tests.rs | 543 +++++++++--------- client/network-gossip/src/bridge.rs | 6 - client/network-gossip/src/lib.rs | 15 - client/network-gossip/src/state_machine.rs | 2 - client/network/README.md | 6 +- client/network/src/lib.rs | 5 +- client/network/src/service.rs | 31 +- 12 files changed, 293 insertions(+), 364 deletions(-) diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index e32ba740504..1fa1a372a05 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -79,13 +79,15 @@ pub fn new_partial(config: &Configuration) -> Result Result { +pub fn new_full(mut config: Configuration) -> Result { let sc_service::PartialComponents { client, backend, mut task_manager, import_queue, keystore_container, select_chain, transaction_pool, inherent_data_providers, other: (block_import, grandpa_link), } = new_partial(&config)?; + config.network.notifications_protocols.push(sc_finality_grandpa::GRANDPA_PROTOCOL_NAME.into()); + let (network, network_status_sinks, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -210,8 +212,6 @@ pub fn new_full(config: Configuration) -> Result { "grandpa-voter", sc_finality_grandpa::run_grandpa_voter(grandpa_config)? ); - } else { - sc_finality_grandpa::setup_disabled_grandpa(network)?; } network_starter.start_network(); @@ -219,10 +219,12 @@ pub fn new_full(config: Configuration) -> Result { } /// Builds a new service for a light client. -pub fn new_light(config: Configuration) -> Result { +pub fn new_light(mut config: Configuration) -> Result { let (client, backend, keystore_container, mut task_manager, on_demand) = sc_service::new_light_parts::(&config)?; + config.network.notifications_protocols.push(sc_finality_grandpa::GRANDPA_PROTOCOL_NAME.into()); + let select_chain = sc_consensus::LongestChain::new(backend.clone()); let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 9d7c9bb1b7a..5eb8e35e69e 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -164,7 +164,7 @@ pub struct NewFullBase { /// Creates a full service from the configuration. pub fn new_full_base( - config: Configuration, + mut config: Configuration, with_startup_data: impl FnOnce( &sc_consensus_babe::BabeBlockImport, &sc_consensus_babe::BabeLink, @@ -178,6 +178,8 @@ pub fn new_full_base( let shared_voter_state = rpc_setup; + config.network.notifications_protocols.push(grandpa::GRANDPA_PROTOCOL_NAME.into()); + let (network, network_status_sinks, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -315,8 +317,6 @@ pub fn new_full_base( "grandpa-voter", grandpa::run_grandpa_voter(grandpa_config)? ); - } else { - grandpa::setup_disabled_grandpa(network.clone())?; } network_starter.start_network(); @@ -338,7 +338,7 @@ pub fn new_full(config: Configuration) }) } -pub fn new_light_base(config: Configuration) -> Result<( +pub fn new_light_base(mut config: Configuration) -> Result<( TaskManager, RpcHandlers, Arc, Arc::Hash>>, Arc>> @@ -346,6 +346,8 @@ pub fn new_light_base(config: Configuration) -> Result<( let (client, backend, keystore_container, mut task_manager, on_demand) = sc_service::new_light_parts::(&config)?; + config.network.notifications_protocols.push(grandpa::GRANDPA_PROTOCOL_NAME.into()); + let select_chain = sc_consensus::LongestChain::new(backend.clone()); let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 038d82a8cdc..29fe8bc7471 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -68,6 +68,8 @@ mod periodic; #[cfg(test)] pub(crate) mod tests; +/// Name of the notifications protocol used by Grandpa. Must be registered towards the networking +/// in order for Grandpa to properly function. pub const GRANDPA_PROTOCOL_NAME: &'static str = "/paritytech/grandpa/1"; // cost scalars for reporting peers. diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index e1685256f7b..27a394a062b 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -62,8 +62,6 @@ impl sc_network_gossip::Network for TestNetwork { let _ = self.sender.unbounded_send(Event::WriteNotification(who, message)); } - fn register_notifications_protocol(&self, _: Cow<'static, str>) {} - fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); } diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index c5f89717a64..ced101b8c85 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -122,6 +122,7 @@ mod until_imported; mod voting_rule; pub use authorities::{SharedAuthoritySet, AuthoritySet}; +pub use communication::GRANDPA_PROTOCOL_NAME; pub use finality_proof::{FinalityProofFragment, FinalityProofProvider, StorageAndProofProvider}; pub use notification::{GrandpaJustificationSender, GrandpaJustificationStream}; pub use import::GrandpaBlockImport; @@ -652,6 +653,10 @@ pub struct GrandpaParams { /// A link to the block import worker. pub link: LinkHalf, /// The Network instance. + /// + /// It is assumed that this network will feed us Grandpa notifications. When using the + /// `sc_network` crate, it is assumed that the Grandpa notifications protocol has been passed + /// to the configuration of the networking. pub network: N, /// If supplied, can be used to hook on telemetry connection established events. pub telemetry_on_connect: Option>, @@ -1065,26 +1070,6 @@ where } } -/// When GRANDPA is not initialized we still need to register the finality -/// tracker inherent provider which might be expected by the runtime for block -/// authoring. Additionally, we register a gossip message validator that -/// discards all GRANDPA messages (otherwise, we end up banning nodes that send -/// us a `Neighbor` message, since there is no registered gossip validator for -/// the engine id defined in the message.) -pub fn setup_disabled_grandpa(network: N) -> Result<(), sp_consensus::Error> -where - N: NetworkT + Send + Clone + 'static, -{ - // We register the GRANDPA protocol so that we don't consider it an anomaly - // to receive GRANDPA messages on the network. We don't process the - // messages. - network.register_notifications_protocol( - From::from(communication::GRANDPA_PROTOCOL_NAME), - ); - - Ok(()) -} - /// Checks if this node has any available keys in the keystore for any authority id in the given /// voter set. Returns the authority id for which keys are available, or `None` if no keys are /// available. diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index ef8168e84f6..452b30941de 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -269,6 +269,52 @@ fn block_until_complete(future: impl Future + Unpin, net: &Arc impl Future { + let voters = stream::FuturesUnordered::new(); + + for (peer_id, key) in peers.iter().enumerate() { + let (keystore, _) = create_keystore(*key); + + let (net_service, link) = { + // temporary needed for some reason + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[peer_id].network_service().clone(), + link, + ) + }; + + let grandpa_params = GrandpaParams { + config: Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: Some(keystore), + name: Some(format!("peer#{}", peer_id)), + is_authority: true, + observer_enabled: true, + }, + link, + network: net_service, + telemetry_on_connect: None, + voting_rule: (), + prometheus_registry: None, + shared_voter_state: SharedVoterState::empty(), + }; + let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); + + fn assert_send(_: &T) { } + assert_send(&voter); + + voters.push(voter); + } + + voters.for_each(|_| async move {}) +} + // run the voters to completion. provide a closure to be invoked after // the voters are spawned but before blocking on them. fn run_to_completion_with( @@ -288,22 +334,9 @@ fn run_to_completion_with( wait_for.push(f); }; - let mut keystore_paths = Vec::new(); - for (peer_id, key) in peers.iter().enumerate() { - let (keystore, keystore_path) = create_keystore(*key); - keystore_paths.push(keystore_path); - + for (peer_id, _) in peers.iter().enumerate() { let highest_finalized = highest_finalized.clone(); - let (client, net_service, link) = { - let net = net.lock(); - // temporary needed for some reason - let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); - ( - net.peers[peer_id].client().clone(), - net.peers[peer_id].network_service().clone(), - link, - ) - }; + let client = net.lock().peers[peer_id].client().clone(); wait_for.push( Box::pin( @@ -319,30 +352,6 @@ fn run_to_completion_with( .map(|_| ()) ) ); - - fn assert_send(_: &T) { } - - let grandpa_params = GrandpaParams { - config: Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: Some(keystore), - name: Some(format!("peer#{}", peer_id)), - is_authority: true, - observer_enabled: true, - }, - link: link, - network: net_service, - telemetry_on_connect: None, - voting_rule: (), - prometheus_registry: None, - shared_voter_state: SharedVoterState::empty(), - }; - let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); - - assert_send(&voter); - - runtime.spawn(voter); } // wait for all finalized on each. @@ -388,6 +397,7 @@ fn finalize_3_voters_no_observers() { let voters = make_ids(peers); let mut net = GrandpaTestNet::new(TestApi::new(voters), 3); + runtime.spawn(initialize_grandpa(&mut net, peers)); net.peer(0).push_blocks(20, false); net.block_until_sync(); @@ -414,50 +424,18 @@ fn finalize_3_voters_1_full_observer() { let voters = make_ids(peers); let mut net = GrandpaTestNet::new(TestApi::new(voters), 4); - net.peer(0).push_blocks(20, false); - net.block_until_sync(); + runtime.spawn(initialize_grandpa(&mut net, peers)); - let net = Arc::new(Mutex::new(net)); - let mut finality_notifications = Vec::new(); - - let all_peers = peers.iter() - .cloned() - .map(Some) - .chain(std::iter::once(None)); - - let mut keystore_paths = Vec::new(); - - let mut voters = Vec::new(); - - for (peer_id, local_key) in all_peers.enumerate() { - let (client, net_service, link) = { - let net = net.lock(); - let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); - ( - net.peers[peer_id].client().clone(), - net.peers[peer_id].network_service().clone(), - link, - ) - }; - finality_notifications.push( - client.finality_notification_stream() - .take_while(|n| future::ready(n.header.number() < &20)) - .for_each(move |_| future::ready(())) - ); - - let keystore = if let Some(local_key) = local_key { - let (keystore, keystore_path) = create_keystore(local_key); - keystore_paths.push(keystore_path); - Some(keystore) - } else { - None - }; + runtime.spawn({ + let peer_id = 3; + let net_service = net.peers[peer_id].network_service().clone(); + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); let grandpa_params = GrandpaParams { config: Config { gossip_duration: TEST_GOSSIP_DURATION, justification_period: 32, - keystore, + keystore: None, name: Some(format!("peer#{}", peer_id)), is_authority: true, observer_enabled: true, @@ -470,11 +448,21 @@ fn finalize_3_voters_1_full_observer() { shared_voter_state: SharedVoterState::empty(), }; - voters.push(run_grandpa_voter(grandpa_params).expect("all in order with client and network")); - } + run_grandpa_voter(grandpa_params).expect("all in order with client and network") + }); - for voter in voters { - runtime.spawn(voter); + net.peer(0).push_blocks(20, false); + + let net = Arc::new(Mutex::new(net)); + let mut finality_notifications = Vec::new(); + + for peer_id in 0..4 { + let client = net.lock().peers[peer_id].client().clone(); + finality_notifications.push( + client.finality_notification_stream() + .take_while(|n| future::ready(n.header.number() < &20)) + .for_each(move |_| future::ready(())) + ); } // wait for all finalized on each. @@ -507,6 +495,13 @@ fn transition_3_voters_twice_1_full_observer() { let observer = &[Ed25519Keyring::One]; + let all_peers = peers_a.iter() + .chain(peers_b) + .chain(peers_c) + .chain(observer) + .cloned() + .collect::>(); // deduplicate + let genesis_voters = make_ids(peers_a); let api = TestApi::new(genesis_voters); @@ -514,6 +509,41 @@ fn transition_3_voters_twice_1_full_observer() { let mut runtime = Runtime::new().unwrap(); + let mut keystore_paths = Vec::new(); + let mut voters = Vec::new(); + for (peer_id, local_key) in all_peers.clone().into_iter().enumerate() { + let (keystore, keystore_path) = create_keystore(local_key); + keystore_paths.push(keystore_path); + + let (net_service, link) = { + let net = net.lock(); + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[peer_id].network_service().clone(), + link, + ) + }; + + let grandpa_params = GrandpaParams { + config: Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: Some(keystore), + name: Some(format!("peer#{}", peer_id)), + is_authority: true, + observer_enabled: true, + }, + link, + network: net_service, + telemetry_on_connect: None, + voting_rule: (), + prometheus_registry: None, + shared_voter_state: SharedVoterState::empty(), + }; + + voters.push(run_grandpa_voter(grandpa_params).expect("all in order with client and network")); + } + net.lock().peer(0).push_blocks(1, false); net.lock().block_until_sync(); @@ -579,30 +609,13 @@ fn transition_3_voters_twice_1_full_observer() { } let mut finality_notifications = Vec::new(); - let all_peers = peers_a.iter() - .chain(peers_b) - .chain(peers_c) - .chain(observer) - .cloned() - .collect::>() // deduplicate - .into_iter() - .enumerate(); - - let mut keystore_paths = Vec::new(); - for (peer_id, local_key) in all_peers { - let (keystore, keystore_path) = create_keystore(local_key); - keystore_paths.push(keystore_path); - let (client, net_service, link) = { - let net = net.lock(); - let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); - ( - net.peers[peer_id].client().clone(), - net.peers[peer_id].network_service().clone(), - link, - ) - }; + for voter in voters { + runtime.spawn(voter); + } + for (peer_id, _) in all_peers.into_iter().enumerate() { + let client = net.lock().peers[peer_id].client().clone(); finality_notifications.push( client.finality_notification_stream() .take_while(|n| future::ready(n.header.number() < &30)) @@ -615,26 +628,6 @@ fn transition_3_voters_twice_1_full_observer() { assert_eq!(set.pending_changes().count(), 0); }) ); - - let grandpa_params = GrandpaParams { - config: Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: Some(keystore), - name: Some(format!("peer#{}", peer_id)), - is_authority: true, - observer_enabled: true, - }, - link: link, - network: net_service, - telemetry_on_connect: None, - voting_rule: (), - prometheus_registry: None, - shared_voter_state: SharedVoterState::empty(), - }; - let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); - - runtime.spawn(voter); } // wait for all finalized on each. @@ -650,6 +643,7 @@ fn justification_is_generated_periodically() { let voters = make_ids(peers); let mut net = GrandpaTestNet::new(TestApi::new(voters), 3); + runtime.spawn(initialize_grandpa(&mut net, peers)); net.peer(0).push_blocks(32, false); net.block_until_sync(); @@ -673,6 +667,7 @@ fn sync_justifications_on_change_blocks() { // 4 peers, 3 of them are authorities and participate in grandpa let api = TestApi::new(voters); let mut net = GrandpaTestNet::new(api, 4); + let voters = initialize_grandpa(&mut net, peers_a); // add 20 blocks net.peer(0).push_blocks(20, false); @@ -697,6 +692,7 @@ fn sync_justifications_on_change_blocks() { } let net = Arc::new(Mutex::new(net)); + runtime.spawn(voters); run_to_completion(&mut runtime, 25, net.clone(), peers_a); // the first 3 peers are grandpa voters and therefore have already finalized @@ -734,6 +730,7 @@ fn finalizes_multiple_pending_changes_in_order() { // 6 peers, 3 of them are authorities and participate in grandpa from genesis let api = TestApi::new(genesis_voters); let mut net = GrandpaTestNet::new(api, 6); + runtime.spawn(initialize_grandpa(&mut net, all_peers)); // add 20 blocks net.peer(0).push_blocks(20, false); @@ -792,7 +789,8 @@ fn force_change_to_new_set() { let api = TestApi::new(make_ids(genesis_authorities)); let voters = make_ids(peers_a); - let net = GrandpaTestNet::new(api, 3); + let mut net = GrandpaTestNet::new(api, 3); + let voters_future = initialize_grandpa(&mut net, peers_a); let net = Arc::new(Mutex::new(net)); net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { @@ -830,6 +828,7 @@ fn force_change_to_new_set() { // it will only finalize if the forced transition happens. // we add_blocks after the voters are spawned because otherwise // the link-halves have the wrong AuthoritySet + runtime.spawn(voters_future); run_to_completion(&mut runtime, 25, net, peers_a); } @@ -937,10 +936,10 @@ fn test_bad_justification() { fn voter_persists_its_votes() { use std::sync::atomic::{AtomicUsize, Ordering}; use futures::future; - use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver}; sp_tracing::try_init_simple(); let mut runtime = Runtime::new().unwrap(); + let mut keystore_paths = Vec::new(); // we have two authorities but we'll only be running the voter for alice // we are going to be listening for the prevotes it casts @@ -949,152 +948,150 @@ fn voter_persists_its_votes() { // alice has a chain with 20 blocks let mut net = GrandpaTestNet::new(TestApi::new(voters.clone()), 2); - net.peer(0).push_blocks(20, false); - net.block_until_sync(); - - assert_eq!(net.peer(0).client().info().best_number, 20, - "Peer #{} failed to sync", 0); - - - let peer = net.peer(0); - let client = peer.client().clone(); - let net = Arc::new(Mutex::new(net)); - - // channel between the voter and the main controller. - // sending a message on the `voter_tx` restarts the voter. - let (voter_tx, voter_rx) = tracing_unbounded::<()>(""); - - let mut keystore_paths = Vec::new(); - - // startup a grandpa voter for alice but also listen for messages on a - // channel. whenever a message is received the voter is restarted. when the - // sender is dropped the voter is stopped. - { - let (keystore, keystore_path) = create_keystore(peers[0]); - keystore_paths.push(keystore_path); - - struct ResettableVoter { - voter: Pin + Send + Unpin>>, - voter_rx: TracingUnboundedReceiver<()>, - net: Arc>, - client: PeersClient, - keystore: SyncCryptoStorePtr, - } - - impl Future for ResettableVoter { - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let this = Pin::into_inner(self); - - if let Poll::Ready(()) = Pin::new(&mut this.voter).poll(cx) { - panic!("error in the voter"); - } - - match Pin::new(&mut this.voter_rx).poll_next(cx) { - Poll::Pending => return Poll::Pending, - Poll::Ready(None) => return Poll::Ready(()), - Poll::Ready(Some(())) => { - let (_block_import, _, link) = - this.net.lock() - .make_block_import::< - TransactionFor - >(this.client.clone()); - let link = link.lock().take().unwrap(); - - let grandpa_params = GrandpaParams { - config: Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: Some(this.keystore.clone()), - name: Some(format!("peer#{}", 0)), - is_authority: true, - observer_enabled: true, - }, - link, - network: this.net.lock().peers[0].network_service().clone(), - telemetry_on_connect: None, - voting_rule: VotingRulesBuilder::default().build(), - prometheus_registry: None, - shared_voter_state: SharedVoterState::empty(), - }; - - let voter = run_grandpa_voter(grandpa_params) - .expect("all in order with client and network") - .map(move |r| { - // we need to keep the block_import alive since it owns the - // sender for the voter commands channel, if that gets dropped - // then the voter will stop - drop(_block_import); - r - }); - - this.voter = Box::pin(voter); - // notify current task in order to poll the voter - cx.waker().wake_by_ref(); - } - }; - - Poll::Pending - } - } - - // we create a "dummy" voter by setting it to `pending` and triggering the `tx`. - // this way, the `ResettableVoter` will reset its `voter` field to a value ASAP. - voter_tx.unbounded_send(()).unwrap(); - runtime.spawn(ResettableVoter { - voter: Box::pin(futures::future::pending()), - voter_rx, - net: net.clone(), - client: client.clone(), - keystore, - }); - } - - let (exit_tx, exit_rx) = futures::channel::oneshot::channel::<()>(); // create the communication layer for bob, but don't start any // voter. instead we'll listen for the prevote that alice casts // and cast our own manually - { + let bob_keystore = { let (keystore, keystore_path) = create_keystore(peers[1]); keystore_paths.push(keystore_path); - + keystore + }; + let bob_network = { let config = Config { gossip_duration: TEST_GOSSIP_DURATION, justification_period: 32, - keystore: Some(keystore.clone()), + keystore: Some(bob_keystore.clone()), name: Some(format!("peer#{}", 1)), is_authority: true, observer_enabled: true, }; let set_state = { - let (_, _, link) = net.lock() + let bob_client = net.peer(1).client().clone(); + let (_, _, link) = net .make_block_import::< TransactionFor - >(client); + >(bob_client); let LinkHalf { persistent_data, .. } = link.lock().take().unwrap(); let PersistentData { set_state, .. } = persistent_data; set_state }; - let network = communication::NetworkBridge::new( - net.lock().peers[1].network_service().clone(), + communication::NetworkBridge::new( + net.peers[1].network_service().clone(), config.clone(), set_state, None, - ); + ) + }; + + // spawn two voters for alice. + // half-way through the test, we stop one and start the other. + let (alice_voter1, abort) = future::abortable({ + let (keystore, _) = create_keystore(peers[0]); + + let (net_service, link) = { + // temporary needed for some reason + let link = net.peers[0].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[0].network_service().clone(), + link, + ) + }; + + let grandpa_params = GrandpaParams { + config: Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: Some(keystore), + name: Some(format!("peer#{}", 0)), + is_authority: true, + observer_enabled: true, + }, + link, + network: net_service, + telemetry_on_connect: None, + voting_rule: VotingRulesBuilder::default().build(), + prometheus_registry: None, + shared_voter_state: SharedVoterState::empty(), + }; + + run_grandpa_voter(grandpa_params).expect("all in order with client and network") + }); + + fn alice_voter2( + peers: &[Ed25519Keyring], + net: Arc>, + ) -> impl Future + Unpin + Send + 'static { + let (keystore, _) = create_keystore(peers[0]); + let mut net = net.lock(); + + // we add a new peer to the test network and we'll use + // the network service of this new peer + net.add_full_peer(); + let net_service = net.peers[2].network_service().clone(); + // but we'll reuse the client from the first peer (alice_voter1) + // since we want to share the same database, so that we can + // read the persisted state after aborting alice_voter1. + let alice_client = net.peer(0).client().clone(); + + let (_block_import, _, link) = net + .make_block_import::< + TransactionFor + >(alice_client); + let link = link.lock().take().unwrap(); + + let grandpa_params = GrandpaParams { + config: Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: Some(keystore), + name: Some(format!("peer#{}", 0)), + is_authority: true, + observer_enabled: true, + }, + link, + network: net_service, + telemetry_on_connect: None, + voting_rule: VotingRulesBuilder::default().build(), + prometheus_registry: None, + shared_voter_state: SharedVoterState::empty(), + }; + + run_grandpa_voter(grandpa_params) + .expect("all in order with client and network") + .map(move |r| { + // we need to keep the block_import alive since it owns the + // sender for the voter commands channel, if that gets dropped + // then the voter will stop + drop(_block_import); + r + }) + }; + + runtime.spawn(alice_voter1); + + net.peer(0).push_blocks(20, false); + net.block_until_sync(); + + assert_eq!(net.peer(0).client().info().best_number, 20, + "Peer #{} failed to sync", 0); + + let net = Arc::new(Mutex::new(net)); - let (round_rx, round_tx) = network.round_communication( - Some((peers[1].public().into(), keystore).into()), + let (exit_tx, exit_rx) = futures::channel::oneshot::channel::<()>(); + + { + let (round_rx, round_tx) = bob_network.round_communication( + Some((peers[1].public().into(), bob_keystore).into()), communication::Round(1), communication::SetId(0), Arc::new(VoterSet::new(voters).unwrap()), HasVoted::No, ); - runtime.spawn(network); + runtime.spawn(bob_network); let round_tx = Arc::new(Mutex::new(round_tx)); let exit_tx = Arc::new(Mutex::new(Some(exit_tx))); @@ -1102,13 +1099,15 @@ fn voter_persists_its_votes() { let net = net.clone(); let state = Arc::new(AtomicUsize::new(0)); + let runtime_handle = runtime.handle().clone(); runtime.spawn(round_rx.for_each(move |signed| { let net2 = net.clone(); let net = net.clone(); - let voter_tx = voter_tx.clone(); + let abort = abort.clone(); let round_tx = round_tx.clone(); let state = state.clone(); let exit_tx = exit_tx.clone(); + let runtime_handle = runtime_handle.clone(); async move { if state.compare_and_swap(0, 1, Ordering::SeqCst) == 0 { @@ -1120,7 +1119,7 @@ fn voter_persists_its_votes() { // its chain has 20 blocks and the voter targets 3/4 of the // unfinalized chain, so the vote should be for block 15 - assert!(prevote.target_number == 15); + assert_eq!(prevote.target_number, 15); // we push 20 more blocks to alice's chain net.lock().peer(0).push_blocks(20, false); @@ -1143,7 +1142,8 @@ fn voter_persists_its_votes() { net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap(); // we restart alice's voter - voter_tx.unbounded_send(()).unwrap(); + abort.abort(); + runtime_handle.spawn(alice_voter2(peers, net.clone())); // and we push our own prevote for block 30 let prevote = finality_grandpa::Prevote { @@ -1200,6 +1200,19 @@ fn finalize_3_voters_1_light_observer() { let voters = make_ids(authorities); let mut net = GrandpaTestNet::new(TestApi::new(voters), 4); + let voters = initialize_grandpa(&mut net, authorities); + let observer = observer::run_grandpa_observer( + Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore: None, + name: Some("observer".to_string()), + is_authority: false, + observer_enabled: true, + }, + net.peers[3].data.lock().take().expect("link initialized at startup; qed"), + net.peers[3].network_service().clone(), + ).unwrap(); net.peer(0).push_blocks(20, false); net.block_until_sync(); @@ -1209,32 +1222,10 @@ fn finalize_3_voters_1_light_observer() { } let net = Arc::new(Mutex::new(net)); - let link = net.lock().peer(3).data.lock().take().expect("link initialized on startup; qed"); - - let finality_notifications = net.lock().peer(3).client().finality_notification_stream() - .take_while(|n| { - future::ready(n.header.number() < &20) - }) - .collect::>(); - - run_to_completion_with(&mut runtime, 20, net.clone(), authorities, |executor| { - executor.spawn( - observer::run_grandpa_observer( - Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: None, - name: Some("observer".to_string()), - is_authority: false, - observer_enabled: true, - }, - link, - net.lock().peers[3].network_service().clone(), - ).unwrap() - ); - Some(Box::pin(finality_notifications.map(|_| ()))) - }); + runtime.spawn(voters); + runtime.spawn(observer); + run_to_completion(&mut runtime, 20, net.clone(), authorities); } #[test] @@ -1245,9 +1236,7 @@ fn voter_catches_up_to_latest_round_when_behind() { let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers); - let mut net = GrandpaTestNet::new(TestApi::new(voters), 3); - net.peer(0).push_blocks(50, false); - net.block_until_sync(); + let net = GrandpaTestNet::new(TestApi::new(voters), 2); let net = Arc::new(Mutex::new(net)); let mut finality_notifications = Vec::new(); @@ -1300,6 +1289,9 @@ fn voter_catches_up_to_latest_round_when_behind() { runtime.spawn(voter); } + net.lock().peer(0).push_blocks(50, false); + net.lock().block_until_sync(); + // wait for them to finalize block 50. since they'll vote on 3/4 of the // unfinalized chain it will take at least 4 rounds to do it. let wait_for_finality = ::futures::future::join_all(finality_notifications); @@ -1311,18 +1303,15 @@ fn voter_catches_up_to_latest_round_when_behind() { let runtime = runtime.handle().clone(); wait_for_finality.then(move |_| { - let peer_id = 2; + net.lock().add_full_peer(); + let link = { let net = net.lock(); - let mut link = net.peers[peer_id].data.lock(); + let mut link = net.peers[2].data.lock(); link.take().expect("link initialized at startup; qed") }; - let set_state = link.persistent_data.set_state.clone(); - - let voter = voter(None, peer_id, link, net); - - runtime.spawn(voter); + runtime.spawn(voter(None, 2, link, net.clone())); let start_time = std::time::Instant::now(); let timeout = Duration::from_secs(5 * 60); diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 98ada69590f..4deaad6d748 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -72,11 +72,7 @@ impl GossipEngine { validator: Arc>, ) -> Self where B: 'static { let protocol = protocol.into(); - - // We grab the event stream before registering the notifications protocol, otherwise we - // might miss events. let network_event_stream = network.event_stream(); - network.register_notifications_protocol(protocol.clone()); GossipEngine { state_machine: ConsensusGossip::new(validator, protocol.clone()), @@ -335,8 +331,6 @@ mod tests { unimplemented!(); } - fn register_notifications_protocol(&self, _: Cow<'static, str>) {} - fn announce(&self, _: B::Hash, _: Vec) { unimplemented!(); } diff --git a/client/network-gossip/src/lib.rs b/client/network-gossip/src/lib.rs index 09e946d1a1e..2b333610223 100644 --- a/client/network-gossip/src/lib.rs +++ b/client/network-gossip/src/lib.rs @@ -81,14 +81,6 @@ pub trait Network { /// Send a notification to a peer. fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec); - /// Registers a notifications protocol. - /// - /// See the documentation of [`NetworkService:register_notifications_protocol`] for more information. - fn register_notifications_protocol( - &self, - protocol: Cow<'static, str>, - ); - /// Notify everyone we're connected to that we have the given block. /// /// Note: this method isn't strictly related to gossiping and should eventually be moved @@ -113,13 +105,6 @@ impl Network for Arc> { NetworkService::write_notification(self, who, protocol, message) } - fn register_notifications_protocol( - &self, - protocol: Cow<'static, str>, - ) { - NetworkService::register_notifications_protocol(self, protocol) - } - fn announce(&self, block: B::Hash, associated_data: Vec) { NetworkService::announce_block(self, block, associated_data) } diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 8bd6d9df019..88f9d48375d 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -503,8 +503,6 @@ mod tests { unimplemented!(); } - fn register_notifications_protocol(&self, _: Cow<'static, str>) {} - fn announce(&self, _: B::Hash, _: Vec) { unimplemented!(); } diff --git a/client/network/README.md b/client/network/README.md index e0bd691043b..914720f53e2 100644 --- a/client/network/README.md +++ b/client/network/README.md @@ -120,8 +120,8 @@ bytes. block announces are pushed to other nodes. The handshake is empty on both sides. The message format is a SCALE-encoded tuple containing a block header followed with an opaque list of bytes containing some data associated with this block announcement, e.g. a candidate message. -- Notifications protocols that are registered using the `register_notifications_protocol` -method. For example: `/paritytech/grandpa/1`. See below for more information. +- Notifications protocols that are registered using `NetworkConfiguration::notifications_protocols`. +For example: `/paritytech/grandpa/1`. See below for more information. ## The legacy Substrate substream @@ -223,4 +223,4 @@ dispatching a background task with the [`NetworkWorker`]. More precise usage details are still being worked on and will likely change in the future. -License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file +License: GPL-3.0-or-later WITH Classpath-exception-2.0 diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index 91ea49bce76..fb65c754d79 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -141,8 +141,9 @@ //! block announces are pushed to other nodes. The handshake is empty on both sides. The message //! format is a SCALE-encoded tuple containing a block header followed with an opaque list of //! bytes containing some data associated with this block announcement, e.g. a candidate message. -//! - Notifications protocols that are registered using the `register_notifications_protocol` -//! method. For example: `/paritytech/grandpa/1`. See below for more information. +//! - Notifications protocols that are registered using +//! `NetworkConfiguration::notifications_protocols`. For example: `/paritytech/grandpa/1`. See +//! below for more information. //! //! ## The legacy Substrate substream //! diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 8c0dbd7eec6..b6f162affd6 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -656,7 +656,7 @@ impl NetworkService { /// > between the remote voluntarily closing a substream or a network error /// > preventing the message from being delivered. /// - /// The protocol must have been registered with `register_notifications_protocol` or + /// The protocol must have been registered with /// [`NetworkConfiguration::notifications_protocols`](crate::config::NetworkConfiguration::notifications_protocols). /// pub fn write_notification(&self, target: PeerId, protocol: Cow<'static, str>, message: Vec) { @@ -717,7 +717,7 @@ impl NetworkService { /// return an error. It is however possible for the entire connection to be abruptly closed, /// in which case enqueued notifications will be lost. /// - /// The protocol must have been registered with `register_notifications_protocol` or + /// The protocol must have been registered with /// [`NetworkConfiguration::notifications_protocols`](crate::config::NetworkConfiguration::notifications_protocols). /// /// # Usage @@ -844,28 +844,6 @@ impl NetworkService { } } - /// Registers a new notifications protocol. - /// - /// After a protocol has been registered, you can call `write_notifications`. - /// - /// **Important**: This method is a work-around, and you are instead strongly encouraged to - /// pass the protocol in the `NetworkConfiguration::notifications_protocols` list instead. - /// If you have no other choice but to use this method, you are very strongly encouraged to - /// call it very early on. Any connection open will retain the protocols that were registered - /// then, and not any new one. - /// - /// Please call `event_stream` before registering a protocol, otherwise you may miss events - /// about the protocol that you have registered. - // TODO: remove this method after https://github.com/paritytech/substrate/issues/6827 - pub fn register_notifications_protocol( - &self, - protocol_name: impl Into>, - ) { - let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::RegisterNotifProtocol { - protocol_name: protocol_name.into(), - }); - } - /// You may call this when new transactons are imported by the transaction pool. /// /// All transactions will be fetched from the `TransactionPool` that was passed at @@ -1222,9 +1200,6 @@ enum ServiceToWorkerMsg { request: Vec, pending_response: oneshot::Sender, RequestFailure>>, }, - RegisterNotifProtocol { - protocol_name: Cow<'static, str>, - }, DisconnectPeer(PeerId), NewBestBlockImported(B::Hash, NumberFor), } @@ -1359,8 +1334,6 @@ impl Future for NetworkWorker { }, } }, - ServiceToWorkerMsg::RegisterNotifProtocol { protocol_name } => - this.network_service.register_notifications_protocol(protocol_name), ServiceToWorkerMsg::DisconnectPeer(who) => this.network_service.user_protocol_mut().disconnect_peer(&who), ServiceToWorkerMsg::NewBestBlockImported(hash, number) => -- GitLab From a364e27d6e3971d756d28435efc468d95add52d3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 2 Dec 2020 18:45:49 +0100 Subject: [PATCH 077/163] *: Update to libp2p v0.31.2 (#7658) --- Cargo.lock | 12 ++++++------ client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 ++-- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 681a65fccd9..b3ad559ff5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2780,9 +2780,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.31.1" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24966e73cc5624a6cf14b025365f67cb6da436b4d6337ed84d198063ba74451d" +checksum = "724846a3194368fefcac7ebdab12e01b8ac382e3efe399ddbd28851ab34f396f" dependencies = [ "atomic", "bytes 0.5.6", @@ -2818,9 +2818,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d92fab5df60c9705e05750d9ecee6a5af15aed1e3fa86e09fd3dd07ec5dc8e" +checksum = "cc9c96d3a606a696a3a6c0ad3c3352c57bda2082ec9090930f1bd9daf787039f" dependencies = [ "asn1_der", "bs58", @@ -3571,9 +3571,9 @@ checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" [[package]] name = "multistream-select" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e19fd46149acdd3600780ebaa09f6ae4e7f2ddbafec64aab54cf75aafd1746" +checksum = "dda822043bba2d6da31c4e14041f9794f8fb130a5959289038d0b809d8888614" dependencies = [ "bytes 0.5.6", "futures 0.3.8", diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 0d2a254c6b1..4cd2dae1388 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -23,7 +23,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.31.1", default-features = false, features = ["kad"] } +libp2p = { version = "0.31.2", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 45312202e86..ef9de997162 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -21,7 +21,7 @@ ansi_term = "0.12.1" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.31.1" +libp2p = "0.31.2" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index edd993ce505..bbbb83f2061 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.31.2", default-features = false } log = "0.4.8" lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 123ef6ddbc7..0b8d3da928f 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -64,13 +64,13 @@ wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.31.1" +version = "0.31.2" default-features = false features = ["identify", "kad", "mdns-async-std", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.31.2", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 84fc5e2ef78..9640ca9ae8c 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.31.2", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 8ec83b6fd64..d3f782bb945 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.31.2", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index a91d55e0c06..58f2a066293 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.5" -libp2p = { version = "0.31.1", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.31.2", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index a76abfcea36..375e976ce5b 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.31.2", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } -- GitLab From 9f57f27c702181bfb5d3a12a2bd80247becdd173 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 3 Dec 2020 11:51:08 +0100 Subject: [PATCH 078/163] Refactor `StorageInstance` trait to be usable more easily (#7659) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor StorageInstance to be usable without macros * better description * update types doc * Update frame/support/src/traits.rs Co-authored-by: Bastian Köcher Co-authored-by: Bastian Köcher --- frame/support/src/storage/types/double_map.rs | 8 +++----- frame/support/src/storage/types/map.rs | 8 +++----- frame/support/src/storage/types/value.rs | 8 +++----- frame/support/src/traits.rs | 16 +++++++++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index 8e315cef85c..3e37c0522e3 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -34,7 +34,7 @@ use sp_std::vec::Vec; /// /// Each value is stored at: /// ```nocompile -/// Twox128(::name()) +/// Twox128(Prefix::pallet_prefix()) /// ++ Twox128(Prefix::STORAGE_PREFIX) /// ++ Hasher1(encode(key1)) /// ++ Hasher2(encode(key2)) @@ -68,8 +68,7 @@ where type Hasher1 = Hasher1; type Hasher2 = Hasher2; fn module_prefix() -> &'static [u8] { - ::name::() - .expect("Every active pallet has a name in the runtime; qed").as_bytes() + Prefix::pallet_prefix().as_bytes() } fn storage_prefix() -> &'static [u8] { Prefix::STORAGE_PREFIX.as_bytes() @@ -415,8 +414,7 @@ mod test { struct Prefix; impl StorageInstance for Prefix { - type Pallet = (); - type PalletInfo = (); + fn pallet_prefix() -> &'static str { "test" } const STORAGE_PREFIX: &'static str = "foo"; } diff --git a/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index d28b7dbaa7e..64f9ff4b052 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -33,7 +33,7 @@ use sp_std::prelude::*; /// /// Each value is stored at: /// ```nocompile -/// Twox128(::name()) +/// Twox128(Prefix::pallet_prefix()) /// ++ Twox128(Prefix::STORAGE_PREFIX) /// ++ Hasher1(encode(key)) /// ``` @@ -60,8 +60,7 @@ where type Query = QueryKind::Query; type Hasher = Hasher; fn module_prefix() -> &'static [u8] { - ::name::() - .expect("Every active pallet has a name in the runtime; qed").as_bytes() + Prefix::pallet_prefix().as_bytes() } fn storage_prefix() -> &'static [u8] { Prefix::STORAGE_PREFIX.as_bytes() @@ -318,8 +317,7 @@ mod test { struct Prefix; impl StorageInstance for Prefix { - type Pallet = (); - type PalletInfo = (); + fn pallet_prefix() -> &'static str { "test" } const STORAGE_PREFIX: &'static str = "foo"; } diff --git a/frame/support/src/storage/types/value.rs b/frame/support/src/storage/types/value.rs index da80963b28f..649b7b9fd27 100644 --- a/frame/support/src/storage/types/value.rs +++ b/frame/support/src/storage/types/value.rs @@ -31,7 +31,7 @@ use frame_metadata::{DefaultByteGetter, StorageEntryModifier}; /// /// Each value is stored at: /// ```nocompile -/// Twox128(::name()) ++ Twox128(Prefix::STORAGE_PREFIX) +/// Twox128(Prefix::pallet_prefix()) ++ Twox128(Prefix::STORAGE_PREFIX) /// ``` pub struct StorageValue( core::marker::PhantomData<(Prefix, Value, QueryKind, OnEmpty)> @@ -47,8 +47,7 @@ where { type Query = QueryKind::Query; fn module_prefix() -> &'static [u8] { - ::name::() - .expect("Every active pallet has a name in the runtime; qed").as_bytes() + Prefix::pallet_prefix().as_bytes() } fn storage_prefix() -> &'static [u8] { Prefix::STORAGE_PREFIX.as_bytes() @@ -201,8 +200,7 @@ mod test { struct Prefix; impl StorageInstance for Prefix { - type Pallet = (); - type PalletInfo = (); + fn pallet_prefix() -> &'static str { "test" } const STORAGE_PREFIX: &'static str = "foo"; } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 19c23a464db..1bbcd87cc2e 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1731,13 +1731,19 @@ pub trait Instance: 'static { const PREFIX: &'static str; } -/// An instance of a storage. +/// An instance of a storage in a pallet. /// -/// It is required the the couple `(PalletInfo::name(), STORAGE_PREFIX)` is unique. -/// Any storage with same couple will collide. +/// Define an instance for an individual storage inside a pallet. +/// The pallet prefix is used to isolate the storage between pallets, and the storage prefix is +/// used to isolate storages inside a pallet. +/// +/// NOTE: These information can be used to define storages in pallet such as a `StorageMap` which +/// can use keys after `twox_128(pallet_prefix())++twox_128(STORAGE_PREFIX)` pub trait StorageInstance { - type Pallet: 'static; - type PalletInfo: PalletInfo; + /// Prefix of a pallet to isolate it from other pallets. + fn pallet_prefix() -> &'static str; + + /// Prefix given to a storage to isolate from other storages in the pallet. const STORAGE_PREFIX: &'static str; } -- GitLab From fbd21bdc208d33efd009964f84248c384b2f76d2 Mon Sep 17 00:00:00 2001 From: LusWar Date: Thu, 3 Dec 2020 19:22:03 +0800 Subject: [PATCH 079/163] Update ss58 registry for Phala network (#7654) --- ss58-registry.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ss58-registry.json b/ss58-registry.json index 80d600ed593..8c7110060ba 100644 --- a/ss58-registry.json +++ b/ss58-registry.json @@ -257,10 +257,10 @@ "prefix": 30, "network": "phala", "displayName": "Phala Network", - "symbols": null, - "decimals": null, + "symbols": ["PHA"], + "decimals": [12], "standardAccount": "*25519", - "website": null + "website": "https://phala.network" }, { "prefix": 32, -- GitLab From 675cbe9ac507a4f75bd0105ce02b00b772140c6b Mon Sep 17 00:00:00 2001 From: Krishna Singh Date: Thu, 3 Dec 2020 18:14:53 +0530 Subject: [PATCH 080/163] Changed map to filter map so that Phragmen ignores empty voters (#7378) * Changed map to filter map so that Phragmen ignores empty voters * Resolve flaws and added test case * Updated test --- primitives/npos-elections/src/lib.rs | 18 ++++++++---- primitives/npos-elections/src/tests.rs | 40 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/primitives/npos-elections/src/lib.rs b/primitives/npos-elections/src/lib.rs index 11951d20659..d82839f0208 100644 --- a/primitives/npos-elections/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -629,7 +629,7 @@ pub(crate) fn setup_inputs( }) .collect::>>(); - let voters = initial_voters.into_iter().map(|(who, voter_stake, votes)| { + let voters = initial_voters.into_iter().filter_map(|(who, voter_stake, votes)| { let mut edges: Vec> = Vec::with_capacity(votes.len()); for v in votes { if edges.iter().any(|e| e.who == v) { @@ -650,12 +650,18 @@ pub(crate) fn setup_inputs( ); } // else {} would be wrong votes. We don't really care about it. } - Voter { - who, - edges: edges, - budget: voter_stake.into(), - load: Rational128::zero(), + if edges.is_empty() { + None + } + else { + Some(Voter { + who, + edges: edges, + budget: voter_stake.into(), + load: Rational128::zero(), + }) } + }).collect::>(); (candidates, voters,) diff --git a/primitives/npos-elections/src/tests.rs b/primitives/npos-elections/src/tests.rs index dc7a1a5fdfb..79f95a469ad 100644 --- a/primitives/npos-elections/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -72,6 +72,46 @@ fn float_phragmen_poc_works() { ); } +#[test] +fn phragmen_core_test_without_edges() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, 10, vec![]), + (20, 20, vec![]), + (30, 30, vec![]), + ]; + + let (candidates, voters) = setup_inputs(candidates, voters); + + assert_eq!( + voters + .iter() + .map(|v| ( + v.who, + v.budget, + (v.edges.iter().map(|e| (e.who, e.weight)).collect::>()), + )) + .collect::>(), + vec![] + ); + + assert_eq!( + candidates + .iter() + .map(|c_ptr| ( + c_ptr.borrow().who, + c_ptr.borrow().elected, + c_ptr.borrow().round, + c_ptr.borrow().backed_stake, + )).collect::>(), + vec![ + (1, false, 0, 0), + (2, false, 0, 0), + (3, false, 0, 0), + ] + ); +} + #[test] fn phragmen_core_poc_works() { let candidates = vec![1, 2, 3]; -- GitLab From 0dfdc328fa2b9514847b354e6968553a9e29d61e Mon Sep 17 00:00:00 2001 From: mattrutherford <44339188+mattrutherford@users.noreply.github.com> Date: Thu, 3 Dec 2020 13:17:44 +0000 Subject: [PATCH 081/163] RPC to allow setting the log filter (#7474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add filter reload handle * add RPC, move logging module from cli to tracing * remove dup fn * working example * Update client/rpc-api/src/system/mod.rs Co-authored-by: Pierre Krieger * Prefer "set" to "reload" * Re-enable the commented out features of the logger * Remove duplicate code * cleanup * unneeded lvar * Bump to latest patch release * Add new CLI option to disable log filter reloading, Move profiling CLI options to SharedParams * Apply suggestions from code review Co-authored-by: Bastian Köcher * Applied suggestions from reviews * Fix calls to init_logger() * Handle errors when parsing logging directives * Deny `system_setLogFilter` RPC by default * One more time * Don't ignore parse errors for log directives set via CLI or RPC * Improve docs * Apply suggestions from code review Co-authored-by: Bastian Köcher * Update client/cli/src/config.rs Co-authored-by: Bastian Köcher * fix merge errors * include default directives with system_setLogFilter RPC, implement system_rawSetLogFilter RPC to exclude defaults * docs etc... * update test * refactor: rename fn * Add a test for system_set_log_filter – NOTE: the code should likely change to return an error when bad directives are passed * Update client/cli/src/lib.rs Co-authored-by: Bastian Köcher * Address review grumbles * Add doc note on panicking behaviour * print all invalid directives before panic * change RPCs to: addLogFilter and resetLogFilter * make CLI log directives default * add comments * restore previous behaviour to panic when hard-coded directives are invalid * change/refactor directive parsing * fix line width * add test for log filter reloading * Apply suggestions from code review Co-authored-by: Bastian Köcher * finish up suggestions from code review * improve test * change expect message * change fn name * Apply suggestions from code review Co-authored-by: Bastian Köcher * Apply suggestions from code review Co-authored-by: Bastian Köcher * add docs, remove unused fn * propagate Err on invalid log directive * Update tracing-subscriber version * Improve docs for `disable_log_reloading` CLI param Co-authored-by: Matt Co-authored-by: David Co-authored-by: Pierre Krieger Co-authored-by: Bastian Köcher --- Cargo.lock | 8 +- client/cli/Cargo.toml | 5 +- client/cli/src/config.rs | 28 ++++--- client/cli/src/lib.rs | 110 ++++++++++++++++--------- client/cli/src/params/import_params.rs | 25 +----- client/cli/src/params/shared_params.rs | 38 +++++++++ client/executor/Cargo.toml | 2 +- client/rpc-api/src/system/mod.rs | 14 ++++ client/rpc/Cargo.toml | 2 + client/rpc/src/system/mod.rs | 11 +++ client/rpc/src/system/tests.rs | 83 ++++++++++++++++++- client/service/src/config.rs | 2 + client/service/test/src/lib.rs | 1 + client/tracing/Cargo.toml | 7 +- client/tracing/src/lib.rs | 109 ++++++++++++++++++++++-- client/{cli => tracing}/src/logging.rs | 14 ++-- primitives/tracing/Cargo.toml | 2 +- utils/browser/src/lib.rs | 1 + 18 files changed, 365 insertions(+), 97 deletions(-) rename client/{cli => tracing}/src/logging.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index b3ad559ff5e..eb98e96a889 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6389,7 +6389,6 @@ dependencies = [ "fdlimit", "futures 0.3.8", "hex", - "lazy_static", "libp2p", "log", "names", @@ -7139,11 +7138,13 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.2", "sc-block-builder", + "sc-cli", "sc-client-api", "sc-executor", "sc-keystore", "sc-network", "sc-rpc-api", + "sc-tracing", "sc-transaction-pool", "serde_json", "sp-api", @@ -7381,9 +7382,13 @@ dependencies = [ name = "sc-tracing" version = "2.0.0" dependencies = [ + "ansi_term 0.12.1", "erased-serde", + "lazy_static", "log", + "once_cell", "parking_lot 0.10.2", + "regex", "rustc-hash", "sc-telemetry", "serde", @@ -7392,6 +7397,7 @@ dependencies = [ "sp-tracing", "tracing", "tracing-core", + "tracing-log", "tracing-subscriber", ] diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index ef9de997162..f323f1940b1 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -16,8 +16,6 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4.11" atty = "0.2.13" regex = "1.4.2" -lazy_static = "1.4.0" -ansi_term = "0.12.1" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" @@ -47,7 +45,7 @@ chrono = "0.4.10" serde = "1.0.111" tracing = "0.1.22" tracing-log = "0.1.1" -tracing-subscriber = "0.2.10" +tracing-subscriber = "0.2.15" sc-cli-proc-macro = { version = "2.0.0", path = "./proc-macro" } thiserror = "1.0.21" @@ -56,6 +54,7 @@ rpassword = "5.0.0" [dev-dependencies] tempfile = "3.1.0" +ansi_term = "0.12.1" [features] wasmtime = [ diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index ab7a335c1ce..e4411e49408 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -408,22 +408,18 @@ pub trait CliConfiguration: Sized { /// Get the tracing targets from the current object (if any) /// - /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// By default this is retrieved from [`SharedParams`] if it is available. Otherwise its /// `None`. fn tracing_targets(&self) -> Result> { - Ok(self.import_params() - .map(|x| x.tracing_targets()) - .unwrap_or_else(|| Default::default())) + Ok(self.shared_params().tracing_targets()) } /// Get the TracingReceiver value from the current object /// - /// By default this is retrieved from `ImportParams` if it is available. Otherwise its + /// By default this is retrieved from [`SharedParams`] if it is available. Otherwise its /// `TracingReceiver::default()`. fn tracing_receiver(&self) -> Result { - Ok(self.import_params() - .map(|x| x.tracing_receiver()) - .unwrap_or_default()) + Ok(self.shared_params().tracing_receiver()) } /// Get the node key from the current object @@ -519,6 +515,7 @@ pub trait CliConfiguration: Sized { dev_key_seed: self.dev_key_seed(is_dev)?, tracing_targets: self.tracing_targets()?, tracing_receiver: self.tracing_receiver()?, + disable_log_reloading: self.is_log_filter_reloading_disabled()?, chain_spec, max_runtime_instances, announce_block: self.announce_block()?, @@ -538,6 +535,11 @@ pub trait CliConfiguration: Sized { Ok(self.shared_params().log_filters().join(",")) } + /// Is log reloading disabled (enabled by default) + fn is_log_filter_reloading_disabled(&self) -> Result { + Ok(self.shared_params().is_log_filter_reloading_disabled()) + } + /// Initialize substrate. This must be done only once per process. /// /// This method: @@ -549,12 +551,16 @@ pub trait CliConfiguration: Sized { let logger_pattern = self.log_filters()?; let tracing_receiver = self.tracing_receiver()?; let tracing_targets = self.tracing_targets()?; + let disable_log_reloading = self.is_log_filter_reloading_disabled()?; sp_panic_handler::set(&C::support_url(), &C::impl_version()); - if let Err(e) = init_logger(&logger_pattern, tracing_receiver, tracing_targets) { - log::warn!("💬 Problem initializing global logging framework: {:}", e) - } + init_logger( + &logger_pattern, + tracing_receiver, + tracing_targets, + disable_log_reloading, + )?; if let Some(new_limit) = fdlimit::raise_fd_limit() { if new_limit < RECOMMENDED_OPEN_FILE_DESCRIPTOR_LIMIT { diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index b543f80a9d3..80882924bd3 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -27,7 +27,6 @@ pub mod arg_enums; mod commands; mod config; mod error; -mod logging; mod params; mod runner; @@ -48,8 +47,13 @@ use structopt::{ StructOpt, }; use tracing_subscriber::{ - filter::Directive, fmt::time::ChronoLocal, layer::SubscriberExt, FmtSubscriber, Layer, + fmt::time::ChronoLocal, + EnvFilter, + FmtSubscriber, + Layer, + layer::SubscriberExt, }; +pub use sc_tracing::logging; pub use logging::PREFIX_LOG_SPAN; #[doc(hidden)] @@ -243,12 +247,16 @@ pub fn init_logger( pattern: &str, tracing_receiver: sc_tracing::TracingReceiver, profiling_targets: Option, + disable_log_reloading: bool, ) -> std::result::Result<(), String> { - fn parse_directives(dirs: impl AsRef) -> Vec { - dirs.as_ref() - .split(',') - .filter_map(|s| s.parse().ok()) - .collect() + use sc_tracing::parse_default_directive; + + // Accept all valid directives and print invalid ones + fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> std::result::Result { + for dir in dirs.split(',') { + env_filter = env_filter.add_directive(parse_default_directive(&dir)?); + } + Ok(env_filter) } if let Err(e) = tracing_log::LogTracer::init() { @@ -257,33 +265,35 @@ pub fn init_logger( )) } - let mut env_filter = tracing_subscriber::EnvFilter::default() + // Initialize filter - ensure to use `parse_default_directive` for any defaults to persist + // after log filter reloading by RPC + let mut env_filter = EnvFilter::default() + // Enable info + .add_directive(parse_default_directive("info") + .expect("provided directive is valid")) // Disable info logging by default for some modules. - .add_directive("ws=off".parse().expect("provided directive is valid")) - .add_directive("yamux=off".parse().expect("provided directive is valid")) - .add_directive("cranelift_codegen=off".parse().expect("provided directive is valid")) + .add_directive(parse_default_directive("ws=off") + .expect("provided directive is valid")) + .add_directive(parse_default_directive("yamux=off") + .expect("provided directive is valid")) + .add_directive(parse_default_directive("cranelift_codegen=off") + .expect("provided directive is valid")) // Set warn logging by default for some modules. - .add_directive("cranelift_wasm=warn".parse().expect("provided directive is valid")) - .add_directive("hyper=warn".parse().expect("provided directive is valid")) - // Enable info for others. - .add_directive(tracing_subscriber::filter::LevelFilter::INFO.into()); + .add_directive(parse_default_directive("cranelift_wasm=warn") + .expect("provided directive is valid")) + .add_directive(parse_default_directive("hyper=warn") + .expect("provided directive is valid")); if let Ok(lvl) = std::env::var("RUST_LOG") { if lvl != "" { - // We're not sure if log or tracing is available at this moment, so silently ignore the - // parse error. - for directive in parse_directives(lvl) { - env_filter = env_filter.add_directive(directive); - } + env_filter = parse_user_directives(env_filter, &lvl)?; } } if pattern != "" { // We're not sure if log or tracing is available at this moment, so silently ignore the // parse error. - for directive in parse_directives(pattern) { - env_filter = env_filter.add_directive(directive); - } + env_filter = parse_user_directives(env_filter, pattern)?; } // If we're only logging `INFO` entries then we'll use a simplified logging format. @@ -293,19 +303,16 @@ pub fn init_logger( }; // Always log the special target `sc_tracing`, overrides global level. + // Required because profiling traces are emitted via `sc_tracing` // NOTE: this must be done after we check the `max_level_hint` otherwise // it is always raised to `TRACE`. env_filter = env_filter.add_directive( - "sc_tracing=trace" - .parse() - .expect("provided directive is valid"), + parse_default_directive("sc_tracing=trace").expect("provided directive is valid") ); // Make sure to include profiling targets in the filter if let Some(profiling_targets) = profiling_targets.clone() { - for directive in parse_directives(profiling_targets) { - env_filter = env_filter.add_directive(directive); - } + env_filter = parse_user_directives(env_filter, &profiling_targets)?; } let enable_color = atty::is(atty::Stream::Stderr); @@ -315,22 +322,42 @@ pub fn init_logger( "%Y-%m-%d %H:%M:%S%.3f".to_string() }); - let subscriber = FmtSubscriber::builder() + let subscriber_builder = FmtSubscriber::builder() .with_env_filter(env_filter) - .with_writer(std::io::stderr) + .with_writer(std::io::stderr as _) .event_format(logging::EventFormat { timer, + enable_color, display_target: !simple, display_level: !simple, display_thread_name: !simple, - enable_color, - }) - .finish() - .with(logging::NodeNameLayer); + }); + if disable_log_reloading { + let subscriber = subscriber_builder + .finish() + .with(logging::NodeNameLayer); + initialize_tracing(subscriber, tracing_receiver, profiling_targets) + } else { + let subscriber_builder = subscriber_builder.with_filter_reloading(); + let handle = subscriber_builder.reload_handle(); + sc_tracing::set_reload_handle(handle); + let subscriber = subscriber_builder + .finish() + .with(logging::NodeNameLayer); + initialize_tracing(subscriber, tracing_receiver, profiling_targets) + } +} +fn initialize_tracing( + subscriber: S, + tracing_receiver: sc_tracing::TracingReceiver, + profiling_targets: Option, +) -> std::result::Result<(), String> +where + S: tracing::Subscriber + Send + Sync + 'static, +{ if let Some(profiling_targets) = profiling_targets { let profiling = sc_tracing::ProfilingLayer::new(tracing_receiver, &profiling_targets); - if let Err(e) = tracing::subscriber::set_global_default(subscriber.with(profiling)) { return Err(format!( "Registering Substrate tracing subscriber failed: {:}!", e @@ -339,7 +366,7 @@ pub fn init_logger( } else { if let Err(e) = tracing::subscriber::set_global_default(subscriber) { return Err(format!( - "Registering Substrate tracing subscriber failed: {:}!", e + "Registering Substrate tracing subscriber failed: {:}!", e )) } } @@ -356,7 +383,7 @@ mod tests { #[test] fn test_logger_filters() { let test_pattern = "afg=debug,sync=trace,client=warn,telemetry,something-with-dash=error"; - init_logger(&test_pattern, Default::default(), Default::default()).unwrap(); + init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); tracing::dispatcher::get_default(|dispatcher| { let test_filter = |target, level| { @@ -415,7 +442,7 @@ mod tests { fn log_something_with_dash_target_name() { if env::var("ENABLE_LOGGING").is_ok() { let test_pattern = "test-target=info"; - init_logger(&test_pattern, Default::default(), Default::default()).unwrap(); + init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); log::info!(target: "test-target", "{}", EXPECTED_LOG_MESSAGE); } @@ -450,7 +477,8 @@ mod tests { #[test] fn prefix_in_log_lines_entrypoint() { if env::var("ENABLE_LOGGING").is_ok() { - init_logger("", Default::default(), Default::default()).unwrap(); + let test_pattern = "test-target=info"; + init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); prefix_in_log_lines_process(); } } @@ -466,7 +494,7 @@ mod tests { #[test] fn do_not_write_with_colors_on_tty_entrypoint() { if env::var("ENABLE_LOGGING").is_ok() { - init_logger("", Default::default(), Default::default()).unwrap(); + init_logger("", Default::default(), Default::default(), false).unwrap(); log::info!("{}", ansi_term::Colour::Yellow.paint(EXPECTED_LOG_MESSAGE)); } } diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index 1efd4383432..376a72b8421 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::arg_enums::{ - ExecutionStrategy, TracingReceiver, WasmExecutionMethod, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, + ExecutionStrategy, WasmExecutionMethod, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, DEFAULT_EXECUTION_IMPORT_BLOCK, DEFAULT_EXECUTION_IMPORT_BLOCK_VALIDATOR, DEFAULT_EXECUTION_OFFCHAIN_WORKER, DEFAULT_EXECUTION_OTHER, DEFAULT_EXECUTION_SYNCING, }; @@ -73,32 +73,9 @@ pub struct ImportParams { default_value = "67108864" )] pub state_cache_size: usize, - - /// Comma separated list of targets for tracing. - #[structopt(long = "tracing-targets", value_name = "TARGETS")] - pub tracing_targets: Option, - - /// Receiver to process tracing messages. - #[structopt( - long = "tracing-receiver", - value_name = "RECEIVER", - possible_values = &TracingReceiver::variants(), - case_insensitive = true, - default_value = "Log" - )] - pub tracing_receiver: TracingReceiver, } impl ImportParams { - /// Receiver to process tracing messages. - pub fn tracing_receiver(&self) -> sc_service::TracingReceiver { - self.tracing_receiver.clone().into() - } - - /// Comma separated list of targets for tracing. - pub fn tracing_targets(&self) -> Option { - self.tracing_targets.clone() - } /// Specify the state cache size. pub fn state_cache_size(&self) -> usize { diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index 3276e5b7c4b..52b1488ea9c 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -19,6 +19,7 @@ use sc_service::config::BasePath; use std::path::PathBuf; use structopt::StructOpt; +use crate::arg_enums::TracingReceiver; /// Shared parameters used by all `CoreParams`. #[derive(Debug, StructOpt)] @@ -44,6 +45,28 @@ pub struct SharedParams { /// By default, all targets log `info`. The global log level can be set with -l. #[structopt(short = "l", long, value_name = "LOG_PATTERN")] pub log: Vec, + + /// Disable feature to dynamically update and reload the log filter. + /// + /// By default this feature is enabled, however it leads to a small performance decrease. + /// The `system_addLogFilter` and `system_resetLogFilter` RPCs will have no effect with this + /// option set. + #[structopt(long = "disable-log-reloading")] + pub disable_log_reloading: bool, + + /// Sets a custom profiling filter. Syntax is the same as for logging: = + #[structopt(long = "tracing-targets", value_name = "TARGETS")] + pub tracing_targets: Option, + + /// Receiver to process tracing messages. + #[structopt( + long = "tracing-receiver", + value_name = "RECEIVER", + possible_values = &TracingReceiver::variants(), + case_insensitive = true, + default_value = "Log" + )] + pub tracing_receiver: TracingReceiver, } impl SharedParams { @@ -75,4 +98,19 @@ impl SharedParams { pub fn log_filters(&self) -> &[String] { &self.log } + + /// Is log reloading disabled + pub fn is_log_filter_reloading_disabled(&self) -> bool { + self.disable_log_reloading + } + + /// Receiver to process tracing messages. + pub fn tracing_receiver(&self) -> sc_service::TracingReceiver { + self.tracing_receiver.clone().into() + } + + /// Comma separated list of targets for tracing. + pub fn tracing_targets(&self) -> Option { + self.tracing_targets.clone() + } } diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 803a49d1dea..c5ce4b86e12 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -49,7 +49,7 @@ sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" } sc-tracing = { version = "2.0.0", path = "../tracing" } tracing = "0.1.22" -tracing-subscriber = "0.2.10" +tracing-subscriber = "0.2.15" [features] default = [ "std" ] diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index fbeec23ea50..f05f1fada90 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -108,4 +108,18 @@ pub trait SystemApi { /// known block. #[rpc(name = "system_syncState", returns = "SyncState")] fn system_sync_state(&self) -> Receiver>; + + /// Adds the supplied directives to the current log filter + /// + /// The syntax is identical to the CLI `=`: + /// + /// `sync=debug,state=trace` + #[rpc(name = "system_addLogFilter", returns = "()")] + fn system_add_log_filter(&self, directives: String) + -> Result<(), jsonrpc_core::Error>; + + /// Resets the log filter to Substrate defaults + #[rpc(name = "system_resetLogFilter", returns = "()")] + fn system_reset_log_filter(&self) + -> Result<(), jsonrpc_core::Error>; } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 0af880f4330..e68ac6e4e91 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -37,6 +37,7 @@ sc-block-builder = { version = "0.8.0", path = "../../client/block-builder" } sc-keystore = { version = "2.0.0", path = "../keystore" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sc-tracing = { version = "2.0.0", path = "../../client/tracing" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" lazy_static = { version = "1.4.0", optional = true } @@ -50,6 +51,7 @@ sp-io = { version = "2.0.0", path = "../../primitives/io" } substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } tokio = "0.1.22" sc-transaction-pool = { version = "2.0.0", path = "../transaction-pool" } +sc-cli = { version = "0.8.0", path = "../cli" } [features] test-helpers = ["lazy_static"] diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 17fb6b77a57..f1ebf5f702a 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -197,4 +197,15 @@ impl SystemApi::Number> for Sy let _ = self.send_back.unbounded_send(Request::SyncState(tx)); Receiver(Compat::new(rx)) } + + fn system_add_log_filter(&self, directives: String) -> std::result::Result<(), rpc::Error> { + self.deny_unsafe.check_if_safe()?; + sc_tracing::add_directives(&directives); + sc_tracing::reload_filter().map_err(|_e| rpc::Error::internal_error()) + } + + fn system_reset_log_filter(&self)-> std::result::Result<(), rpc::Error> { + self.deny_unsafe.check_if_safe()?; + sc_tracing::reset_log_filter().map_err(|_e| rpc::Error::internal_error()) + } } diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index 61f1940dc20..fa3574e9dae 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -24,7 +24,10 @@ use substrate_test_runtime_client::runtime::Block; use assert_matches::assert_matches; use futures::prelude::*; use sp_utils::mpsc::tracing_unbounded; -use std::thread; +use std::{ + process::{Stdio, Command}, env, io::{BufReader, BufRead, Write}, + sync::{Arc, Mutex}, thread, time::Duration +}; struct Status { pub peers: usize, @@ -333,3 +336,81 @@ fn system_network_remove_reserved() { assert_eq!(runtime.block_on(good_fut), Ok(())); assert!(runtime.block_on(bad_fut).is_err()); } + +#[test] +fn test_add_reset_log_filter() { + const EXPECTED_BEFORE_ADD: &'static str = "EXPECTED_BEFORE_ADD"; + const EXPECTED_AFTER_ADD: &'static str = "EXPECTED_AFTER_ADD"; + + // Enter log generation / filter reload + if std::env::var("TEST_LOG_FILTER").is_ok() { + sc_cli::init_logger("test_before_add=debug", Default::default(), Default::default(), false).unwrap(); + for line in std::io::stdin().lock().lines() { + let line = line.expect("Failed to read bytes"); + if line.contains("add_reload") { + assert!(api(None).system_add_log_filter("test_after_add".to_owned()).is_ok(), "`system_add_log_filter` failed"); + } else if line.contains("reset") { + assert!(api(None).system_reset_log_filter().is_ok(), "`system_reset_log_filter` failed"); + } else if line.contains("exit") { + return; + } + log::debug!(target: "test_before_add", "{}", EXPECTED_BEFORE_ADD); + log::debug!(target: "test_after_add", "{}", EXPECTED_AFTER_ADD); + } + } + + // Call this test again to enter the log generation / filter reload block + let test_executable = env::current_exe().expect("Unable to get current executable!"); + let mut child_process = Command::new(test_executable) + .env("TEST_LOG_FILTER", "1") + .args(&["--nocapture", "test_add_reset_log_filter"]) + .stdin(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + let child_stderr = child_process.stderr.take().expect("Could not get child stderr"); + let mut child_out = BufReader::new(child_stderr); + let mut child_in = child_process.stdin.take().expect("Could not get child stdin"); + + let child_out_str = Arc::new(Mutex::new(String::new())); + let shared = child_out_str.clone(); + + let _handle = thread::spawn(move || { + let mut line = String::new(); + while let Ok(_) = child_out.read_line(&mut line) { + shared.lock().unwrap().push_str(&line); + line.clear(); + } + }); + + // Initiate logs loop in child process + child_in.write(b"\n").unwrap(); + thread::sleep(Duration::from_millis(100)); + let test1_str = child_out_str.lock().unwrap().clone(); + // Assert that only the first target is present + assert!(test1_str.contains(EXPECTED_BEFORE_ADD)); + assert!(!test1_str.contains(EXPECTED_AFTER_ADD)); + child_out_str.lock().unwrap().clear(); + + // Initiate add directive & reload in child process + child_in.write(b"add_reload\n").unwrap(); + thread::sleep(Duration::from_millis(100)); + let test2_str = child_out_str.lock().unwrap().clone(); + // Assert that both targets are now present + assert!(test2_str.contains(EXPECTED_BEFORE_ADD)); + assert!(test2_str.contains(EXPECTED_AFTER_ADD)); + child_out_str.lock().unwrap().clear(); + + // Initiate logs filter reset in child process + child_in.write(b"reset\n").unwrap(); + thread::sleep(Duration::from_millis(100)); + let test3_str = child_out_str.lock().unwrap().clone(); + // Assert that only the first target is present as it was initially + assert!(test3_str.contains(EXPECTED_BEFORE_ADD)); + assert!(!test3_str.contains(EXPECTED_AFTER_ADD)); + + // Return from child process + child_in.write(b"exit\n").unwrap(); + assert!(child_process.wait().expect("Error waiting for child process").success()); +} diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 0caf05b2485..20a4995bbc7 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -103,6 +103,8 @@ pub struct Configuration { pub dev_key_seed: Option, /// Tracing targets pub tracing_targets: Option, + /// Is log filter reloading disabled + pub disable_log_reloading: bool, /// Tracing receiver pub tracing_receiver: sc_tracing::TracingReceiver, /// The size of the instances cache. diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 28930473f0a..cfcf7e9ab38 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -274,6 +274,7 @@ fn node_config, + W = fn() -> std::io::Stderr +> = layer::Layered, Registry>; + +// Handle to reload the tracing log filter +static FILTER_RELOAD_HANDLE: OnceCell> = OnceCell::new(); +// Directives that are defaulted to when resetting the log filter +static DEFAULT_DIRECTIVES: OnceCell>> = OnceCell::new(); +// Current state of log filter +static CURRENT_DIRECTIVES: OnceCell>> = OnceCell::new(); + +/// Initialize FILTER_RELOAD_HANDLE, only possible once +pub fn set_reload_handle(handle: Handle) { + let _ = FILTER_RELOAD_HANDLE.set(handle); +} + +/// Add log filter directive(s) to the defaults +/// +/// The syntax is identical to the CLI `=`: +/// +/// `sync=debug,state=trace` +pub fn add_default_directives(directives: &str) { + DEFAULT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().push(directives.to_owned()); + add_directives(directives); +} + +/// Add directives to current directives +pub fn add_directives(directives: &str) { + CURRENT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().push(directives.to_owned()); +} + +/// Reload the logging filter with the supplied directives added to the existing directives +pub fn reload_filter() -> Result<(), String> { + let mut env_filter = EnvFilter::default(); + if let Some(current_directives) = CURRENT_DIRECTIVES.get() { + // Use join and then split in case any directives added together + for directive in current_directives.lock().join(",").split(',').map(|d| d.parse()) { + match directive { + Ok(dir) => env_filter = env_filter.add_directive(dir), + Err(invalid_directive) => { + log::warn!( + target: "tracing", + "Unable to parse directive while setting log filter: {:?}", + invalid_directive, + ); + } + } + } + } + env_filter = env_filter.add_directive( + "sc_tracing=trace" + .parse() + .expect("provided directive is valid"), + ); + log::debug!(target: "tracing", "Reloading log filter with: {}", env_filter); + FILTER_RELOAD_HANDLE.get() + .ok_or("No reload handle present".to_string())? + .reload(env_filter) + .map_err(|e| format!("{}", e)) +} + +/// Resets the log filter back to the original state when the node was started. +/// +/// Includes substrate defaults and CLI supplied directives. +pub fn reset_log_filter() -> Result<(), String> { + *CURRENT_DIRECTIVES + .get_or_init(|| Mutex::new(Vec::new())).lock() = + DEFAULT_DIRECTIVES.get_or_init(|| Mutex::new(Vec::new())).lock().clone(); + reload_filter() +} + +/// Parse `Directive` and add to default directives if successful. +/// +/// Ensures the supplied directive will be restored when resetting the log filter. +pub fn parse_default_directive(directive: &str) -> Result { + let dir = directive + .parse() + .map_err(|_| format!("Unable to parse directive: {}", directive))?; + add_default_directives(directive); + Ok(dir) +} + /// Responsible for assigning ids to new spans, which are not re-used. pub struct ProfilingLayer { targets: Vec<(String, Level)>, @@ -231,15 +330,13 @@ impl ProfilingLayer { /// either with a level, eg: "pallet=trace" /// or without: "pallet" in which case the level defaults to `trace`. /// wasm_tracing indicates whether to enable wasm traces - pub fn new_with_handler(trace_handler: Box, targets: &str) - -> Self - { + pub fn new_with_handler(trace_handler: Box, targets: &str) -> Self { let targets: Vec<_> = targets.split(',').map(|s| parse_target(s)).collect(); Self { targets, trace_handler, span_data: Mutex::new(FxHashMap::default()), - current_span: Default::default() + current_span: Default::default(), } } @@ -461,7 +558,7 @@ mod tests { }; let layer = ProfilingLayer::new_with_handler( Box::new(handler), - "test_target" + "test_target", ); let subscriber = tracing_subscriber::fmt().finish().with(layer); (subscriber, spans, events) diff --git a/client/cli/src/logging.rs b/client/tracing/src/logging.rs similarity index 97% rename from client/cli/src/logging.rs rename to client/tracing/src/logging.rs index ffb4c3dfaaf..370b09f781b 100644 --- a/client/cli/src/logging.rs +++ b/client/tracing/src/logging.rs @@ -79,12 +79,12 @@ impl<'a> MaybeColorWriter<'a> { } } -pub(crate) struct EventFormat { - pub(crate) timer: T, - pub(crate) display_target: bool, - pub(crate) display_level: bool, - pub(crate) display_thread_name: bool, - pub(crate) enable_color: bool, +pub struct EventFormat { + pub timer: T, + pub display_target: bool, + pub display_level: bool, + pub display_thread_name: bool, + pub enable_color: bool, } // NOTE: the following code took inspiration from tracing-subscriber @@ -147,7 +147,7 @@ where } } -pub(crate) struct NodeNameLayer; +pub struct NodeNameLayer; impl Layer for NodeNameLayer where diff --git a/primitives/tracing/Cargo.toml b/primitives/tracing/Cargo.toml index ba370f46b9b..c6d4d7b4cac 100644 --- a/primitives/tracing/Cargo.toml +++ b/primitives/tracing/Cargo.toml @@ -23,7 +23,7 @@ codec = { version = "1.3.1", package = "parity-scale-codec", default-features = tracing = { version = "0.1.22", default-features = false } tracing-core = { version = "0.1.17", default-features = false } log = { version = "0.4.8", optional = true } -tracing-subscriber = { version = "0.2.10", optional = true, features = ["tracing-log"] } +tracing-subscriber = { version = "0.2.15", optional = true, features = ["tracing-log"] } [features] default = [ "std" ] diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 95ec7ca19c9..bffd9fbedb2 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -105,6 +105,7 @@ where informant_output_format: sc_informant::OutputFormat { enable_color: false, }, + disable_log_reloading: false, }; Ok(config) -- GitLab From 864ce58c1da2ea12689967cace79760f22579adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 3 Dec 2020 15:49:23 +0100 Subject: [PATCH 082/163] Use block requests to check if block responses are correct (#7653) * Use block requests to check if block responses are correct Before this pr sync relied on recently announced blocks to check if a given peer response is correct. However this could lead to situations where we requested a block from a peer and it gave us the requested, but we rejected the response because this peer never send us an announcement for the given block. See the added tests for a reproduction of the problem. With this pr, we now take the block request to check if a given response matches the request. A node should not send us a block response without a request anyway. Essentially there is still a bug, because as you see in the test, we are requesting block 2, while we already have this block imported. It even happens that we request a block from the network that we have authored. However a fix for this would require some more refactoring of the sync code. * Revert change * Give the test a proper name * Add moar logging * Move cheaper checks * Move checks to common place --- client/network/src/protocol.rs | 16 - client/network/src/protocol/sync.rs | 333 +++++++++++++++--- .../src/protocol/sync/extra_requests.rs | 1 - 3 files changed, 278 insertions(+), 72 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 9e589330b7f..52fbacd1be0 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -120,8 +120,6 @@ mod rep { pub const BAD_PROTOCOL: Rep = Rep::new_fatal("Unsupported protocol"); /// Peer role does not match (e.g. light peer connecting to another light peer). pub const BAD_ROLE: Rep = Rep::new_fatal("Unsupported role"); - /// Peer response data does not have requested bits. - pub const BAD_RESPONSE: Rep = Rep::new(-(1 << 12), "Incomplete response"); /// Peer send us a block announcement that failed at validation. pub const BAD_BLOCK_ANNOUNCEMENT: Rep = Rep::new(-(1 << 12), "Bad block announcement"); } @@ -706,20 +704,6 @@ impl Protocol { } } } else { - // Validate fields against the request. - if request.fields.contains(message::BlockAttributes::HEADER) && response.blocks.iter().any(|b| b.header.is_none()) { - self.behaviour.disconnect_peer(&peer); - self.peerset_handle.report_peer(peer, rep::BAD_RESPONSE); - trace!(target: "sync", "Missing header for a block"); - return CustomMessageOutcome::None - } - if request.fields.contains(message::BlockAttributes::BODY) && response.blocks.iter().any(|b| b.body.is_none()) { - self.behaviour.disconnect_peer(&peer); - self.peerset_handle.report_peer(peer, rep::BAD_RESPONSE); - trace!(target: "sync", "Missing body for a block"); - return CustomMessageOutcome::None - } - match self.sync.on_block_data(&peer, Some(request), response) { Ok(sync::OnBlockData::Import(origin, blocks)) => CustomMessageOutcome::BlockImport(origin, blocks), diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index ced789446da..380cec244cc 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -34,8 +34,8 @@ use sp_consensus::{BlockOrigin, BlockStatus, block_validation::{BlockAnnounceValidator, Validation}, import_queue::{IncomingBlock, BlockImportResult, BlockImportError} }; -use crate::{ - protocol::message::{self, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, Roles}, +use crate::protocol::message::{ + self, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse, Roles, }; use either::Either; use extra_requests::ExtraRequests; @@ -44,12 +44,14 @@ use log::{debug, trace, warn, info, error}; use sp_runtime::{ Justification, generic::BlockId, - traits::{Block as BlockT, Header, NumberFor, Zero, One, CheckedSub, SaturatedConversion, Hash, HashFor} + traits::{ + Block as BlockT, Header as HeaderT, NumberFor, Zero, One, CheckedSub, SaturatedConversion, + Hash, HashFor, + }, }; use sp_arithmetic::traits::Saturating; use std::{ - fmt, ops::Range, collections::{HashMap, hash_map::Entry, HashSet, VecDeque}, - sync::Arc, pin::Pin, + fmt, ops::Range, collections::{HashMap, hash_map::Entry, HashSet}, sync::Arc, pin::Pin, }; use futures::{task::Poll, Future, stream::FuturesUnordered, FutureExt, StreamExt}; @@ -83,9 +85,6 @@ const MAX_CONCURRENT_BLOCK_ANNOUNCE_VALIDATIONS_PER_PEER: usize = 4; /// so far behind. const MAJOR_SYNC_BLOCKS: u8 = 5; -/// Number of recently announced blocks to track for each peer. -const ANNOUNCE_HISTORY_SIZE: usize = 64; - mod rep { use sc_peerset::ReputationChange as Rep; /// Reputation change when a peer sent us a message that led to a @@ -108,14 +107,17 @@ mod rep { /// Peer did not provide us with advertised block data. pub const NO_BLOCK: Rep = Rep::new(-(1 << 29), "No requested block data"); - /// Reputation change for peers which send us a known block. - pub const KNOWN_BLOCK: Rep = Rep::new(-(1 << 29), "Duplicate block"); + /// Reputation change for peers which send us non-requested block data. + pub const NOT_REQUESTED: Rep = Rep::new(-(1 << 29), "Not requested block data"); /// Reputation change for peers which send us a block with bad justifications. pub const BAD_JUSTIFICATION: Rep = Rep::new(-(1 << 16), "Bad justification"); /// Reputation change when a peer sent us invlid ancestry result. pub const UNKNOWN_ANCESTOR:Rep = Rep::new(-(1 << 16), "DB Error"); + + /// Peer response data does not have requested bits. + pub const BAD_RESPONSE: Rep = Rep::new(-(1 << 12), "Incomplete response"); } enum PendingRequests { @@ -219,9 +221,6 @@ pub struct PeerSync { /// The state of syncing this peer is in for us, generally categories /// into `Available` or "busy" with something as defined by `PeerSyncState`. pub state: PeerSyncState, - /// A queue of blocks that this peer has announced to us, should only - /// contain `ANNOUNCE_HISTORY_SIZE` entries. - pub recently_announced: VecDeque } /// The sync status of a peer we are trying to sync with @@ -514,7 +513,6 @@ impl ChainSync { best_hash, best_number, state: PeerSyncState::Available, - recently_announced: Default::default() }); return Ok(None) } @@ -527,7 +525,6 @@ impl ChainSync { best_hash, best_number, state: PeerSyncState::Available, - recently_announced: Default::default(), }); self.pending_requests.add(&who); return Ok(None) @@ -551,7 +548,6 @@ impl ChainSync { start: self.best_queued_number, state: AncestorSearchState::ExponentialBackoff(One::one()), }, - recently_announced: Default::default() }); Ok(Some(ancestry_request::(common_best))) @@ -563,7 +559,6 @@ impl ChainSync { best_hash, best_number, state: PeerSyncState::Available, - recently_announced: Default::default(), }); self.pending_requests.add(&who); Ok(None) @@ -751,13 +746,13 @@ impl ChainSync { blocks.reverse() } self.pending_requests.add(who); - if request.is_some() { + if let Some(request) = request { match &mut peer.state { PeerSyncState::DownloadingNew(start_block) => { self.blocks.clear_peer_download(who); let start_block = *start_block; peer.state = PeerSyncState::Available; - validate_blocks::(&blocks, who)?; + validate_blocks::(&blocks, who, Some(request))?; self.blocks.insert(start_block, blocks, who.clone()); self.blocks .drain(self.best_queued_number + One::one()) @@ -780,7 +775,7 @@ impl ChainSync { debug!(target: "sync", "Empty block response from {}", who); return Err(BadPeer(who.clone(), rep::NO_BLOCK)); } - validate_blocks::(&blocks, who)?; + validate_blocks::(&blocks, who, Some(request))?; blocks.into_iter().map(|b| { IncomingBlock { hash: b.hash, @@ -864,7 +859,7 @@ impl ChainSync { } } else { // When request.is_none() this is a block announcement. Just accept blocks. - validate_blocks::(&blocks, who)?; + validate_blocks::(&blocks, who, None)?; blocks.into_iter().map(|b| { IncomingBlock { hash: b.hash, @@ -878,40 +873,30 @@ impl ChainSync { }).collect() } } else { - Vec::new() + // We don't know of this peer, so we also did not request anything from it. + return Err(BadPeer(who.clone(), rep::NOT_REQUESTED)); }; - // When doing initial sync we don't request blocks in parallel. - // So the only way this can happen is when peers lie about the - // common block. - let is_recent = new_blocks.first() - .map(|block| { - self.peers.iter().any(|(_, peer)| peer.recently_announced.contains(&block.hash)) - }) - .unwrap_or(false); - - if !is_recent && new_blocks.last().map_or(false, |b| self.is_known(&b.hash)) { - // When doing initial sync we don't request blocks in parallel. - // So the only way this can happen is when peers lie about the - // common block. - debug!(target: "sync", "Ignoring known blocks from {}", who); - return Err(BadPeer(who.clone(), rep::KNOWN_BLOCK)); - } let orig_len = new_blocks.len(); new_blocks.retain(|b| !self.queue_blocks.contains(&b.hash)); if new_blocks.len() != orig_len { debug!(target: "sync", "Ignoring {} blocks that are already queued", orig_len - new_blocks.len()); } - let origin = - if is_recent { - BlockOrigin::NetworkBroadcast - } else { - BlockOrigin::NetworkInitialSync - }; + let origin = if self.status().state != SyncState::Downloading { + BlockOrigin::NetworkBroadcast + } else { + BlockOrigin::NetworkInitialSync + }; if let Some((h, n)) = new_blocks.last().and_then(|b| b.header.as_ref().map(|h| (&b.hash, *h.number()))) { - trace!(target:"sync", "Accepted {} blocks ({:?}) with origin {:?}", new_blocks.len(), h, origin); + trace!( + target:"sync", + "Accepted {} blocks ({:?}) with origin {:?}", + new_blocks.len(), + h, + origin, + ); self.on_block_queued(h, n) } @@ -1320,11 +1305,6 @@ impl ChainSync { return PollBlockAnnounceValidation::Nothing { is_best, who, header } }; - while peer.recently_announced.len() >= ANNOUNCE_HISTORY_SIZE { - peer.recently_announced.pop_front(); - } - peer.recently_announced.push_back(hash.clone()); - if is_best { // update their best block peer.best_number = number; @@ -1600,8 +1580,7 @@ fn fork_sync_request( finalized: NumberFor, attributes: &message::BlockAttributes, check_block: impl Fn(&B::Hash) -> BlockStatus, -) -> Option<(B::Hash, BlockRequest)> -{ +) -> Option<(B::Hash, BlockRequest)> { targets.retain(|hash, r| { if r.number <= finalized { trace!(target: "sync", "Removed expired fork sync request {:?} (#{})", hash, r.number); @@ -1654,7 +1633,75 @@ fn is_descendent_of(client: &T, base: &Block::Hash, block: &Block::Has Ok(ancestor.hash == *base) } -fn validate_blocks(blocks: &Vec>, who: &PeerId) -> Result<(), BadPeer> { +/// Validate that the given `blocks` are correct. +/// +/// It is expected that `blocks` are in asending order. +fn validate_blocks( + blocks: &Vec>, + who: &PeerId, + request: Option>, +) -> Result<(), BadPeer> { + if let Some(request) = request { + if Some(blocks.len() as _) > request.max { + debug!( + target: "sync", + "Received more blocks than requested from {}. Expected in maximum {:?}, got {}.", + who, + request.max, + blocks.len(), + ); + + return Err(BadPeer(who.clone(), rep::NOT_REQUESTED)) + } + + let block_header = if request.direction == message::Direction::Descending { + blocks.last() + } else { + blocks.first() + }.and_then(|b| b.header.as_ref()); + + let expected_block = block_header.as_ref() + .map_or(false, |h| match request.from { + message::FromBlock::Hash(hash) => h.hash() == hash, + message::FromBlock::Number(n) => h.number() == &n, + }); + + if !expected_block { + debug!( + target: "sync", + "Received block that was not requested. Requested {:?}, got {:?}.", + request.from, + block_header, + ); + + return Err(BadPeer(who.clone(), rep::NOT_REQUESTED)) + } + + if request.fields.contains(message::BlockAttributes::HEADER) + && blocks.iter().any(|b| b.header.is_none()) + { + trace!( + target: "sync", + "Missing requested header for a block in response from {}.", + who, + ); + + return Err(BadPeer(who.clone(), rep::BAD_RESPONSE)) + } + + if request.fields.contains(message::BlockAttributes::BODY) + && blocks.iter().any(|b| b.body.is_none()) + { + trace!( + target: "sync", + "Missing requested body for a block in response from {}.", + who, + ); + + return Err(BadPeer(who.clone(), rep::BAD_RESPONSE)) + } + } + for b in blocks { if let Some(header) = &b.header { let hash = header.hash(); @@ -1685,20 +1732,23 @@ fn validate_blocks(blocks: &Vec>, who: } } } + Ok(()) } #[cfg(test)] mod test { - use super::message::FromBlock; + use super::message::{FromBlock, BlockState, BlockData}; use super::*; use sc_block_builder::BlockBuilderProvider; use sp_blockchain::HeaderBackend; use sp_consensus::block_validation::DefaultBlockAnnounceValidator; use substrate_test_runtime_client::{ - runtime::{Block, Hash}, + runtime::{Block, Hash, Header}, ClientBlockImportExt, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, + BlockBuilderExt, }; + use futures::{future::poll_fn, executor::block_on}; #[test] fn processes_empty_response_on_justification_request_for_unknown_block() { @@ -1846,4 +1896,177 @@ mod test { PeerSyncState::DownloadingJustification(b1_hash), ); } + + /// Send a block annoucnement for the given `header`. + fn send_block_announce( + header: Header, + peer_id: &PeerId, + sync: &mut ChainSync, + ) { + let block_annnounce = BlockAnnounce { + header: header.clone(), + state: Some(BlockState::Best), + data: Some(Vec::new()), + }; + + sync.push_block_announce_validation( + peer_id.clone(), + header.hash(), + block_annnounce, + true, + ); + + // Poll until we have procssed the block announcement + block_on(poll_fn(|cx| loop { + if sync.poll_block_announce_validation(cx).is_pending() { + break Poll::Ready(()) + } + })) + } + + /// Create a block response from the given `blocks`. + fn create_block_response(blocks: Vec) -> BlockResponse { + BlockResponse:: { + id: 0, + blocks: blocks.into_iter().map(|b| + BlockData:: { + hash: b.hash(), + header: Some(b.header().clone()), + body: Some(b.deconstruct().1), + receipt: None, + message_queue: None, + justification: None, + } + ).collect(), + } + } + + /// Get a block request from `sync` and check that is matches the expected request. + fn get_block_request( + sync: &mut ChainSync, + from: message::FromBlock, + max: u32, + peer: &PeerId, + ) -> BlockRequest { + let requests = sync.block_requests().collect::>(); + assert_eq!(1, requests.len()); + assert_eq!(peer, requests[0].0); + + let request = requests[0].1.clone(); + + assert_eq!(from, request.from); + assert_eq!(Some(max), request.max); + request + } + + /// This test is a regression test as observed on a real network. + /// + /// The node is connected to multiple peers. Both of these peers are having a best block (1) that + /// is below our best block (3). Now peer 2 announces a fork of block 3 that we will + /// request from peer 2. After imporitng the fork, peer 2 and then peer 1 will announce block 4. + /// But as peer 1 in our view is still at block 1, we will request block 2 (which we already have) + /// from it. In the meanwhile peer 2 sends us block 4 and 3 and we send another request for block + /// 2 to peer 2. Peer 1 answers with block 2 and then peer 2. This will need to succeed, as we + /// have requested block 2 from both peers. + #[test] + fn do_not_report_peer_on_block_response_for_block_request() { + sp_tracing::try_init_simple(); + + let mut client = Arc::new(TestClientBuilder::new().build()); + let info = client.info(); + + let mut sync = ChainSync::new( + Roles::AUTHORITY, + client.clone(), + &info, + Box::new(DefaultBlockAnnounceValidator), + 5, + ); + + let peer_id1 = PeerId::random(); + let peer_id2 = PeerId::random(); + + let mut client2 = client.clone(); + let mut build_block = || { + let block = client2.new_block(Default::default()).unwrap().build().unwrap().block; + client2.import(BlockOrigin::Own, block.clone()).unwrap(); + + block + }; + + let mut client2 = client.clone(); + let mut build_block_at = |at, import| { + let mut block_builder = client2.new_block_at(&BlockId::Hash(at), Default::default(), false) + .unwrap(); + // Make sure we generate a different block as fork + block_builder.push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])).unwrap(); + + let block = block_builder.build().unwrap().block; + + if import { + client2.import(BlockOrigin::Own, block.clone()).unwrap(); + } + + block + }; + + let block1 = build_block(); + let block2 = build_block(); + let block3 = build_block(); + let block3_fork = build_block_at(block2.hash(), false); + + // Add two peers which are on block 1. + sync.new_peer(peer_id1.clone(), block1.hash(), 1).unwrap(); + sync.new_peer(peer_id2.clone(), block1.hash(), 1).unwrap(); + + // Tell sync that our best block is 3. + sync.update_chain_info(&block3.hash(), 3); + + // There should be no requests. + assert!(sync.block_requests().collect::>().is_empty()); + + // Let peer2 announce a fork of block 3 + send_block_announce(block3_fork.header().clone(), &peer_id2, &mut sync); + + // Import and tell sync that we now have the fork. + client.import(BlockOrigin::Own, block3_fork.clone()).unwrap(); + sync.update_chain_info(&block3_fork.hash(), 3); + + let block4 = build_block_at(block3_fork.hash(), false); + + // Let peer2 announce block 4 and check that sync wants to get the block. + send_block_announce(block4.header().clone(), &peer_id2, &mut sync); + + let request = get_block_request(&mut sync, FromBlock::Hash(block4.hash()), 2, &peer_id2); + + // Peer1 announces the same block, but as the common block is still `1`, sync will request + // block 2 again. + send_block_announce(block4.header().clone(), &peer_id1, &mut sync); + + let request2 = get_block_request(&mut sync, FromBlock::Number(2), 1, &peer_id1); + + let response = create_block_response(vec![block4.clone(), block3_fork.clone()]); + let res = sync.on_block_data(&peer_id2, Some(request), response).unwrap(); + + // We should not yet import the blocks, because there is still an open request for fetching + // block `2` which blocks the import. + assert!(matches!(res, OnBlockData::Import(_, blocks) if blocks.is_empty())); + + let request3 = get_block_request(&mut sync, FromBlock::Number(2), 1, &peer_id2); + + let response = create_block_response(vec![block2.clone()]); + let res = sync.on_block_data(&peer_id1, Some(request2), response).unwrap(); + assert!( + matches!( + res, + OnBlockData::Import(_, blocks) + if blocks.iter().all(|b| [2, 3, 4].contains(b.header.as_ref().unwrap().number())) + ) + ); + + let response = create_block_response(vec![block2.clone()]); + let res = sync.on_block_data(&peer_id2, Some(request3), response).unwrap(); + // Nothing to import + assert!(matches!(res, OnBlockData::Import(_, blocks) if blocks.is_empty())); + } } diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 79f10c4a3bf..7a7198aa7a0 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -549,7 +549,6 @@ mod tests { best_hash: Hash::random(), best_number: g.gen(), state: ArbitraryPeerSyncState::arbitrary(g).0, - recently_announced: Default::default() }; ArbitraryPeerSync(ps) } -- GitLab From f73ac5eb0df68b72d42d25faf4da411f2d3581b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 3 Dec 2020 17:11:49 +0100 Subject: [PATCH 083/163] Don't panic on a sink error (#7666) --- client/rpc/src/author/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 1db90e209d0..1a2d84e4e57 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -215,7 +215,7 @@ impl AuthorApi, BlockHash

> for Author Ok(watcher) => { subscriptions.add(subscriber, move |sink| { sink - .sink_map_err(|_| unimplemented!()) + .sink_map_err(|e| log::debug!("Subscription sink failed: {:?}", e)) .send_all(Compat::new(watcher)) .map(|_| ()) }); -- GitLab From 1802283493b178d03ba3a5be697478c4978f1a17 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 4 Dec 2020 16:57:09 +0100 Subject: [PATCH 084/163] Features needed for reserve-backed stablecoins (#7152) * Features needed for reserve-backed stablecoins * Builds & tests. * Double map for an efficient destroy. * Update frame/assets/src/lib.rs Co-authored-by: Nikolay Volf * ED/zombie-count/refs Feature: ED/minimum balance enforcement Feature: enforce zombie count Feature: allow system-alive accounts to exist, but add reference * Update frame/assets/src/lib.rs Co-authored-by: Nikolay Volf * Update frame/assets/Cargo.toml Co-authored-by: Niklas Adolfsson * Docs * Some tests * More tests * Allow for max_zombies to be adjusted * Test for set_max_zombies * Tests and a couple of fixes * First few benchmarks * Benchmarks. * Fix error message in test * Fixes * Fixes * Fixes * cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_assets * Update frame/assets/src/lib.rs Co-authored-by: Guillaume Thiolliere * Fixes * Fixes * Fixes * cargo run --release --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml -- benchmark --chain dev --steps 50 --repeat 20 --extrinsic * --execution=wasm --wasm-execution=compiled --output ./bin/node/runtime/src/weights --header ./HEADER --pallet pallet_assets * Fixes * Update default weight * Add proper verification to benchmarks * minor improvements to tests * Update frame/assets/src/benchmarking.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fix * New weights system * fix compile * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_assets --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/assets/src/weights.rs --template=./.maintain/frame-weight-template.hbs Co-authored-by: Nikolay Volf Co-authored-by: Niklas Adolfsson Co-authored-by: Parity Benchmarking Bot Co-authored-by: Guillaume Thiolliere Co-authored-by: Shawn Tabrizi Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- Cargo.lock | 3 + bin/node/runtime/Cargo.toml | 3 + bin/node/runtime/src/lib.rs | 18 + frame/assets/Cargo.toml | 10 + frame/assets/src/benchmarking.rs | 298 +++++++ frame/assets/src/lib.rs | 1244 +++++++++++++++++++++++++----- frame/assets/src/weights.rs | 207 +++++ frame/balances/src/lib.rs | 2 +- frame/balances/src/tests.rs | 2 +- frame/system/src/lib.rs | 4 + 10 files changed, 1612 insertions(+), 179 deletions(-) create mode 100644 frame/assets/src/benchmarking.rs create mode 100644 frame/assets/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index eb98e96a889..13bc6ca0ebc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3895,6 +3895,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "hex-literal", "node-primitives", + "pallet-assets", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", @@ -4228,8 +4229,10 @@ dependencies = [ name = "pallet-assets" version = "2.0.0" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "pallet-balances", "parity-scale-codec", "serde", "sp-core", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index eabc9f61c62..7d4cf5588e3 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -43,6 +43,7 @@ frame-support = { version = "2.0.0", default-features = false, path = "../../../ frame-system = { version = "2.0.0", default-features = false, path = "../../../frame/system" } frame-system-benchmarking = { version = "2.0.0", default-features = false, path = "../../../frame/system/benchmarking", optional = true } frame-system-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-assets = { version = "2.0.0", default-features = false, path = "../../../frame/assets" } pallet-authority-discovery = { version = "2.0.0", default-features = false, path = "../../../frame/authority-discovery" } pallet-authorship = { version = "2.0.0", default-features = false, path = "../../../frame/authorship" } pallet-babe = { version = "2.0.0", default-features = false, path = "../../../frame/babe" } @@ -89,6 +90,7 @@ default = ["std"] with-tracing = [ "frame-executive/with-tracing" ] std = [ "sp-authority-discovery/std", + "pallet-assets/std", "pallet-authority-discovery/std", "pallet-authorship/std", "sp-consensus-babe/std", @@ -147,6 +149,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", "pallet-babe/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index be3783cd7ca..285f37889ae 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -892,6 +892,22 @@ impl pallet_vesting::Config for Runtime { type WeightInfo = pallet_vesting::weights::SubstrateWeight; } +parameter_types! { + pub const AssetDepositBase: Balance = 100 * DOLLARS; + pub const AssetDepositPerZombie: Balance = 1 * DOLLARS; +} + +impl pallet_assets::Config for Runtime { + type Event = Event; + type Balance = u64; + type AssetId = u32; + type Currency = Balances; + type ForceOrigin = EnsureRoot; + type AssetDepositBase = AssetDepositBase; + type AssetDepositPerZombie = AssetDepositPerZombie; + type WeightInfo = pallet_assets::weights::SubstrateWeight; +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -929,6 +945,7 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, + Assets: pallet_assets::{Module, Call, Storage, Event}, } ); @@ -1195,6 +1212,7 @@ impl_runtime_apis! { let mut batches = Vec::::new(); let params = (&config, &whitelist); + add_benchmark!(params, batches, pallet_assets, Assets); add_benchmark!(params, batches, pallet_babe, Babe); add_benchmark!(params, batches, pallet_balances, Balances); add_benchmark!(params, batches, pallet_collective, Council); diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index d1742e567cf..380b561dba4 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -15,24 +15,34 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } # Needed for various traits. In our case, `OnFinalize`. sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. frame-support = { version = "2.0.0", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. frame-system = { version = "2.0.0", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] sp-core = { version = "2.0.0", path = "../../primitives/core" } sp-std = { version = "2.0.0", path = "../../primitives/std" } sp-io = { version = "2.0.0", path = "../../primitives/io" } +pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } [features] default = ["std"] std = [ "serde", "codec/std", + "sp-std/std", "sp-runtime/std", "frame-support/std", "frame-system/std", + "frame-benchmarking/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "sp-runtime/runtime-benchmarks", + "frame-system/runtime-benchmarks", ] diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs new file mode 100644 index 00000000000..cecb2ccae58 --- /dev/null +++ b/frame/assets/src/benchmarking.rs @@ -0,0 +1,298 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Assets pallet benchmarking. + +use super::*; +use sp_std::prelude::*; +use sp_runtime::traits::Bounded; +use frame_system::RawOrigin as SystemOrigin; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; + +use crate::Module as Assets; + +const SEED: u32 = 0; + +fn create_default_asset(max_zombies: u32) + -> (T::AccountId, ::Source) +{ + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + let root = SystemOrigin::Root.into(); + assert!(Assets::::force_create( + root, + Default::default(), + caller_lookup.clone(), + max_zombies, + 1u32.into(), + ).is_ok()); + (caller, caller_lookup) +} + +fn create_default_minted_asset(max_zombies: u32, amount: T::Balance) + -> (T::AccountId, ::Source) +{ + let (caller, caller_lookup) = create_default_asset::(max_zombies); + assert!(Assets::::mint( + SystemOrigin::Signed(caller.clone()).into(), + Default::default(), + caller_lookup.clone(), + amount, + ).is_ok()); + (caller, caller_lookup) +} + +fn add_zombies(minter: T::AccountId, n: u32) { + let origin = SystemOrigin::Signed(minter); + for i in 0..n { + let target = account("zombie", i, SEED); + let target_lookup = T::Lookup::unlookup(target); + assert!(Assets::::mint(origin.clone().into(), Default::default(), target_lookup, 100u32.into()).is_ok()); + } +} + +fn assert_last_event(generic_event: ::Event) { + let events = frame_system::Module::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +benchmarks! { + _ { } + + create { + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, 1, 1u32.into()) + verify { + assert_last_event::(RawEvent::Created(Default::default(), caller.clone(), caller).into()); + } + + force_create { + let caller: T::AccountId = whitelisted_caller(); + let caller_lookup = T::Lookup::unlookup(caller.clone()); + }: _(SystemOrigin::Root, Default::default(), caller_lookup, 1, 1u32.into()) + verify { + assert_last_event::(RawEvent::ForceCreated(Default::default(), caller).into()); + } + + destroy { + let z in 0 .. 10_000; + let (caller, _) = create_default_asset::(10_000); + add_zombies::(caller.clone(), z); + }: _(SystemOrigin::Signed(caller), Default::default(), 10_000) + verify { + assert_last_event::(RawEvent::Destroyed(Default::default()).into()); + } + + force_destroy { + let z in 0 .. 10_000; + let (caller, _) = create_default_asset::(10_000); + add_zombies::(caller.clone(), z); + }: _(SystemOrigin::Root, Default::default(), 10_000) + verify { + assert_last_event::(RawEvent::Destroyed(Default::default()).into()); + } + + mint { + let (caller, caller_lookup) = create_default_asset::(10); + let amount = T::Balance::from(100u32); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, amount) + verify { + assert_last_event::(RawEvent::Issued(Default::default(), caller, amount).into()); + } + + burn { + let amount = T::Balance::from(100u32); + let (caller, caller_lookup) = create_default_minted_asset::(10, amount); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, amount) + verify { + assert_last_event::(RawEvent::Burned(Default::default(), caller, amount).into()); + } + + transfer { + let amount = T::Balance::from(100u32); + let (caller, caller_lookup) = create_default_minted_asset::(10, amount); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), target_lookup, amount) + verify { + assert_last_event::(RawEvent::Transferred(Default::default(), caller, target, amount).into()); + } + + force_transfer { + let amount = T::Balance::from(100u32); + let (caller, caller_lookup) = create_default_minted_asset::(10, amount); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, target_lookup, amount) + verify { + assert_last_event::(RawEvent::ForceTransferred(Default::default(), caller, target, amount).into()); + } + + freeze { + let (caller, caller_lookup) = create_default_minted_asset::(10, 100u32.into()); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup) + verify { + assert_last_event::(RawEvent::Frozen(Default::default(), caller).into()); + } + + thaw { + let (caller, caller_lookup) = create_default_minted_asset::(10, 100u32.into()); + assert!(Assets::::freeze( + SystemOrigin::Signed(caller.clone()).into(), + Default::default(), + caller_lookup.clone() + ).is_ok()); + }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup) + verify { + assert_last_event::(RawEvent::Thawed(Default::default(), caller).into()); + } + + transfer_ownership { + let (caller, _) = create_default_asset::(10); + let target: T::AccountId = account("target", 0, SEED); + let target_lookup = T::Lookup::unlookup(target.clone()); + }: _(SystemOrigin::Signed(caller), Default::default(), target_lookup) + verify { + assert_last_event::(RawEvent::OwnerChanged(Default::default(), target).into()); + } + + set_team { + let (caller, _) = create_default_asset::(10); + let target0 = T::Lookup::unlookup(account("target", 0, SEED)); + let target1 = T::Lookup::unlookup(account("target", 1, SEED)); + let target2 = T::Lookup::unlookup(account("target", 2, SEED)); + }: _(SystemOrigin::Signed(caller), Default::default(), target0.clone(), target1.clone(), target2.clone()) + verify { + assert_last_event::(RawEvent::TeamChanged( + Default::default(), + account("target", 0, SEED), + account("target", 1, SEED), + account("target", 2, SEED), + ).into()); + } + + set_max_zombies { + let (caller, _) = create_default_asset::(10); + let max_zombies: u32 = 100; + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: _(SystemOrigin::Signed(caller), Default::default(), max_zombies) + verify { + assert_last_event::(RawEvent::MaxZombiesChanged(Default::default(), max_zombies).into()); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + + #[test] + fn create() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_create::().is_ok()); + }); + } + + #[test] + fn force_create() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_force_create::().is_ok()); + }); + } + + #[test] + fn destroy() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_destroy::().is_ok()); + }); + } + + #[test] + fn force_destroy() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_force_destroy::().is_ok()); + }); + } + + #[test] + fn mint() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_mint::().is_ok()); + }); + } + + #[test] + fn burn() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_burn::().is_ok()); + }); + } + + #[test] + fn transfer() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_transfer::().is_ok()); + }); + } + + #[test] + fn force_transfer() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_force_transfer::().is_ok()); + }); + } + + #[test] + fn freeze() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_freeze::().is_ok()); + }); + } + + #[test] + fn thaw() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_thaw::().is_ok()); + }); + } + + #[test] + fn transfer_ownership() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_transfer_ownership::().is_ok()); + }); + } + + #[test] + fn set_team() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_set_team::().is_ok()); + }); + } + + #[test] + fn set_max_zombies() { + new_test_ext().execute_with(|| { + assert!(test_benchmark_set_max_zombies::().is_ok()); + }); + } +} diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 9ed442aada3..630f4fcc317 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -24,9 +24,10 @@ //! The Assets module provides functionality for asset management of fungible asset classes //! with a fixed supply, including: //! -//! * Asset Issuance -//! * Asset Transfer -//! * Asset Destruction +//! * Asset Issuance (Minting) +//! * Asset Transferal +//! * Asset Freezing +//! * Asset Destruction (Burning) //! //! To use it in your runtime, you need to implement the assets [`Config`](./trait.Config.html). //! @@ -34,31 +35,61 @@ //! //! ### Terminology //! -//! * **Asset issuance:** The creation of a new asset, whose total supply will belong to the -//! account that issues the asset. -//! * **Asset transfer:** The action of transferring assets from one account to another. -//! * **Asset destruction:** The process of an account removing its entire holding of an asset. -//! * **Fungible asset:** An asset whose units are interchangeable. -//! * **Non-fungible asset:** An asset for which each unit has unique characteristics. +//! * **Admin**: An account ID uniquely privileged to be able to unfreeze (thaw) an account and it's +//! assets, as well as forcibly transfer a particular class of assets between arbitrary accounts +//! and reduce the balance of a particular class of assets of arbitrary accounts. +//! * **Asset issuance/minting**: The creation of a new asset, whose total supply will belong to the +//! account that issues the asset. This is a privileged operation. +//! * **Asset transfer**: The reduction of the balance of an asset of one account with the +//! corresponding increase in the balance of another. +//! * **Asset destruction**: The process of reduce the balance of an asset of one account. This is +//! a privileged operation. +//! * **Fungible asset**: An asset whose units are interchangeable. +//! * **Issuer**: An account ID uniquely privileged to be able to mint a particular class of assets. +//! * **Freezer**: An account ID uniquely privileged to be able to freeze an account from +//! transferring a particular class of assets. +//! * **Freezing**: Removing the possibility of an unpermissioned transfer of an asset from a +//! particular account. +//! * **Non-fungible asset**: An asset for which each unit has unique characteristics. +//! * **Owner**: An account ID uniquely privileged to be able to destroy a particular asset class, +//! or to set the Issuer, Freezer or Admin of that asset class. +//! * **Zombie**: An account which has a balance of some assets in this pallet, but no other +//! footprint on-chain, in particular no account managed in the `frame_system` pallet. //! //! ### Goals //! //! The assets system in Substrate is designed to make the following possible: //! -//! * Issue a unique asset to its creator's account. +//! * Issue a new assets in a permissioned or permissionless way, if permissionless, then with a +//! deposit required. +//! * Allow accounts to hold these assets without otherwise existing on-chain (*zombies*). //! * Move assets between accounts. -//! * Remove an account's balance of an asset when requested by that account's owner and update -//! the asset's total supply. +//! * Update the asset's total supply. +//! * Allow administrative activities by specially privileged accounts including freezing account +//! balances and minting/burning assets. //! //! ## Interface //! -//! ### Dispatchable Functions +//! ### Permissionless Functions //! -//! * `issue` - Issues the total supply of a new fungible asset to the account of the caller of the function. -//! * `transfer` - Transfers an `amount` of units of fungible asset `id` from the balance of -//! the function caller's account (`origin`) to a `target` account. -//! * `destroy` - Destroys the entire holding of a fungible asset `id` associated with the account -//! that called the function. +//! * `create`: Creates a new asset class, taking the required deposit. +//! * `transfer`: Transfer sender's assets to another account. +//! +//! ### Permissioned Functions +//! +//! * `force_create`: Creates a new asset class without taking any deposit. +//! * `force_destroy`: Destroys an asset class. +//! +//! ### Privileged Functions +//! * `destroy`: Destroys an entire asset class; called by the asset class's Owner. +//! * `mint`: Increases the asset balance of an account; called by the asset class's Issuer. +//! * `burn`: Decreases the asset balance of an account; called by the asset class's Admin. +//! * `force_transfer`: Transfers between arbitrary accounts; called by the asset class's Admin. +//! * `freeze`: Disallows further `transfer`s from an account; called by the asset class's Freezer. +//! * `thaw`: Allows further `transfer`s from an account; called by the asset class's Admin. +//! * `transfer_ownership`: Changes an asset class's Owner; called by the asset class's Owner. +//! * `set_team`: Changes an asset class's Admin, Freezer and Issuer; called by the asset class's +//! Owner. //! //! Please refer to the [`Call`](./enum.Call.html) enum and its associated variants for documentation on each function. //! @@ -70,61 +101,6 @@ //! //! Please refer to the [`Module`](./struct.Module.html) struct for details on publicly available functions. //! -//! ## Usage -//! -//! The following example shows how to use the Assets module in your runtime by exposing public functions to: -//! -//! * Issue a new fungible asset for a token distribution event (airdrop). -//! * Query the fungible asset holding balance of an account. -//! * Query the total supply of a fungible asset that has been issued. -//! -//! ### Prerequisites -//! -//! Import the Assets module and types and derive your runtime's configuration traits from the Assets module trait. -//! -//! ### Simple Code Snippet -//! -//! ```rust,ignore -//! use pallet_assets as assets; -//! use frame_support::{decl_module, dispatch, ensure}; -//! use frame_system::ensure_signed; -//! -//! pub trait Config: assets::Config { } -//! -//! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { -//! pub fn issue_token_airdrop(origin) -> dispatch::DispatchResult { -//! let sender = ensure_signed(origin).map_err(|e| e.as_str())?; -//! -//! const ACCOUNT_ALICE: u64 = 1; -//! const ACCOUNT_BOB: u64 = 2; -//! const COUNT_AIRDROP_RECIPIENTS: u64 = 2; -//! const TOKENS_FIXED_SUPPLY: u64 = 100; -//! -//! ensure!(!COUNT_AIRDROP_RECIPIENTS.is_zero(), "Divide by zero error."); -//! -//! let asset_id = Self::next_asset_id(); -//! -//! >::mutate(|asset_id| *asset_id += 1); -//! >::insert((asset_id, &ACCOUNT_ALICE), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS); -//! >::insert((asset_id, &ACCOUNT_BOB), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS); -//! >::insert(asset_id, TOKENS_FIXED_SUPPLY); -//! -//! Self::deposit_event(RawEvent::Issued(asset_id, sender, TOKENS_FIXED_SUPPLY)); -//! Ok(()) -//! } -//! } -//! } -//! ``` -//! -//! ## Assumptions -//! -//! Below are assumptions that must be held when using this module. If any of -//! them are violated, the behavior of this module is undefined. -//! -//! * The total count of assets should be less than -//! `Config::AssetId::max_value()`. -//! //! ## Related Modules //! //! * [`System`](../frame_system/index.html) @@ -133,10 +109,23 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; -use sp_runtime::traits::{Member, AtLeast32Bit, AtLeast32BitUnsigned, Zero, StaticLookup}; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +pub mod weights; + +use sp_std::{fmt::Debug}; +use sp_runtime::{RuntimeDebug, traits::{ + Member, AtLeast32BitUnsigned, Zero, StaticLookup, Saturating, CheckedSub, CheckedAdd +}}; +use codec::{Encode, Decode, HasCompact}; +use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, + traits::{Currency, ReservableCurrency, EnsureOrigin, Get, BalanceStatus::Reserved}, + dispatch::{DispatchResult, DispatchError}, +}; use frame_system::ensure_signed; -use sp_runtime::traits::One; +pub use weights::WeightInfo; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// The module configuration trait. pub trait Config: frame_system::Config { @@ -147,80 +136,82 @@ pub trait Config: frame_system::Config { type Balance: Member + Parameter + AtLeast32BitUnsigned + Default + Copy; /// The arithmetic type of asset identifier. - type AssetId: Parameter + AtLeast32Bit + Default + Copy; -} + type AssetId: Member + Parameter + Default + Copy + HasCompact; -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; + /// The currency mechanism. + type Currency: ReservableCurrency; - fn deposit_event() = default; - /// Issue a new class of fungible assets. There are, and will only ever be, `total` - /// such assets and they'll all belong to the `origin` initially. It will have an - /// identifier `AssetId` instance: this will be specified in the `Issued` event. - /// - /// # - /// - `O(1)` - /// - 1 storage mutation (codec `O(1)`). - /// - 2 storage writes (condec `O(1)`). - /// - 1 event. - /// # - #[weight = 0] - fn issue(origin, #[compact] total: T::Balance) { - let origin = ensure_signed(origin)?; + /// The origin which may forcibly create or destroy an asset. + type ForceOrigin: EnsureOrigin; - let id = Self::next_asset_id(); - >::mutate(|id| *id += One::one()); + /// The basic amount of funds that must be reserved when creating a new asset class. + type AssetDepositBase: Get>; - >::insert((id, &origin), total); - >::insert(id, total); + /// The additional funds that must be reserved for every zombie account that an asset class + /// supports. + type AssetDepositPerZombie: Get>; - Self::deposit_event(RawEvent::Issued(id, origin, total)); - } + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; +} - /// Move some assets from one holder to another. - /// - /// # - /// - `O(1)` - /// - 1 static lookup - /// - 2 storage mutations (codec `O(1)`). - /// - 1 event. - /// # - #[weight = 0] - fn transfer(origin, - #[compact] id: T::AssetId, - target: ::Source, - #[compact] amount: T::Balance - ) { - let origin = ensure_signed(origin)?; - let origin_account = (id, origin.clone()); - let origin_balance = >::get(&origin_account); - let target = T::Lookup::lookup(target)?; - ensure!(!amount.is_zero(), Error::::AmountZero); - ensure!(origin_balance >= amount, Error::::BalanceLow); +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] +pub struct AssetDetails< + Balance: Encode + Decode + Clone + Debug + Eq + PartialEq, + AccountId: Encode + Decode + Clone + Debug + Eq + PartialEq, + DepositBalance: Encode + Decode + Clone + Debug + Eq + PartialEq, +> { + /// Can change `owner`, `issuer`, `freezer` and `admin` accounts. + owner: AccountId, + /// Can mint tokens. + issuer: AccountId, + /// Can thaw tokens, force transfers and burn tokens from any account. + admin: AccountId, + /// Can freeze tokens. + freezer: AccountId, + /// The total supply across all accounts. + supply: Balance, + /// The balance deposited for this asset. + /// + /// This pays for the data stored here together with any virtual accounts. + deposit: DepositBalance, + /// The number of balance-holding accounts that this asset may have, excluding those that were + /// created when they had a system-level ED. + max_zombies: u32, + /// The ED for virtual accounts. + min_balance: Balance, + /// The current number of zombie accounts. + zombies: u32, + /// The total number of accounts. + accounts: u32, +} - Self::deposit_event(RawEvent::Transferred(id, origin, target.clone(), amount)); - >::insert(origin_account, origin_balance - amount); - >::mutate((id, target), |balance| *balance += amount); - } +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)] +pub struct AssetBalance< + Balance: Encode + Decode + Clone + Debug + Eq + PartialEq, +> { + /// The balance. + balance: Balance, + /// Whether the account is frozen. + is_frozen: bool, + /// Whether the account is a zombie. If not, then it has a reference. + is_zombie: bool, +} - /// Destroy any assets of `id` owned by `origin`. - /// - /// # - /// - `O(1)` - /// - 1 storage mutation (codec `O(1)`). - /// - 1 storage deletion (codec `O(1)`). - /// - 1 event. - /// # - #[weight = 0] - fn destroy(origin, #[compact] id: T::AssetId) { - let origin = ensure_signed(origin)?; - let balance = >::take((id, &origin)); - ensure!(!balance.is_zero(), Error::::BalanceZero); +decl_storage! { + trait Store for Module as Assets { + /// Details of an asset. + Asset: map hasher(blake2_128_concat) T::AssetId => Option, + >>; - >::mutate(id, |total_supply| *total_supply -= balance); - Self::deposit_event(RawEvent::Destroyed(id, origin, balance)); - } + /// The number of units of assets held by any given account. + Account: double_map + hasher(blake2_128_concat) T::AssetId, + hasher(blake2_128_concat) T::AccountId + => AssetBalance; } } @@ -230,36 +221,620 @@ decl_event! { ::Balance, ::AssetId, { + /// Some asset class was created. \[asset_id, creator, owner\] + Created(AssetId, AccountId, AccountId), /// Some assets were issued. \[asset_id, owner, total_supply\] Issued(AssetId, AccountId, Balance), /// Some assets were transferred. \[asset_id, from, to, amount\] Transferred(AssetId, AccountId, AccountId, Balance), /// Some assets were destroyed. \[asset_id, owner, balance\] - Destroyed(AssetId, AccountId, Balance), + Burned(AssetId, AccountId, Balance), + /// The management team changed \[asset_id, issuer, admin, freezer\] + TeamChanged(AssetId, AccountId, AccountId, AccountId), + /// The owner changed \[asset_id, owner\] + OwnerChanged(AssetId, AccountId), + /// Some assets was transferred by an admin. \[asset_id, from, to, amount\] + ForceTransferred(AssetId, AccountId, AccountId, Balance), + /// Some account `who` was frozen. \[asset_id, who\] + Frozen(AssetId, AccountId), + /// Some account `who` was thawed. \[asset_id, who\] + Thawed(AssetId, AccountId), + /// An asset class was destroyed. + Destroyed(AssetId), + /// Some asset class was force-created. \[asset_id, owner\] + ForceCreated(AssetId, AccountId), + /// The maximum amount of zombies allowed has changed. \[asset_id, max_zombies\] + MaxZombiesChanged(AssetId, u32), } } decl_error! { pub enum Error for Module { - /// Transfer amount should be non-zero + /// Transfer amount should be non-zero. AmountZero, - /// Account balance must be greater than or equal to the transfer amount + /// Account balance must be greater than or equal to the transfer amount. BalanceLow, - /// Balance should be non-zero + /// Balance should be non-zero. BalanceZero, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Too many zombie accounts in use. + TooManyZombies, + /// Attempt to destroy an asset class when non-zombie, reference-bearing accounts exist. + RefsLeft, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// A mint operation lead to an overflow. + Overflow, } } -decl_storage! { - trait Store for Module as Assets { - /// The number of units of assets held by any given account. - Balances: map hasher(blake2_128_concat) (T::AssetId, T::AccountId) => T::Balance; - /// The next asset identifier up for grabs. - NextAssetId get(fn next_asset_id): T::AssetId; - /// The total unit supply of an asset. +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + fn deposit_event() = default; + + /// Issue a new class of fungible assets from a public origin. + /// + /// This new asset class has no assets initially. + /// + /// The origin must be Signed and the sender must have sufficient funds free. + /// + /// Funds of sender are reserved according to the formula: + /// `AssetDepositBase + AssetDepositPerZombie * max_zombies`. + /// + /// Parameters: + /// - `id`: The identifier of the new asset. This must not be currently in use to identify + /// an existing asset. + /// - `owner`: The owner of this class of assets. The owner has full superuser permissions + /// over this asset, but may later change and configure the permissions using `transfer_ownership` + /// and `set_team`. + /// - `max_zombies`: The total number of accounts which may hold assets in this class yet + /// have no existential deposit. + /// - `min_balance`: The minimum balance of this new asset that any single account must + /// have. If an account's balance is reduced below this, then it collapses to zero. + /// + /// Emits `Created` event when successful. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::create()] + fn create(origin, + #[compact] id: T::AssetId, + admin: ::Source, + max_zombies: u32, + min_balance: T::Balance, + ) { + let owner = ensure_signed(origin)?; + let admin = T::Lookup::lookup(admin)?; + + ensure!(!Asset::::contains_key(id), Error::::InUse); + ensure!(!min_balance.is_zero(), Error::::MinBalanceZero); + + let deposit = T::AssetDepositPerZombie::get() + .saturating_mul(max_zombies.into()) + .saturating_add(T::AssetDepositBase::get()); + T::Currency::reserve(&owner, deposit)?; + + Asset::::insert(id, AssetDetails { + owner: owner.clone(), + issuer: admin.clone(), + admin: admin.clone(), + freezer: admin.clone(), + supply: Zero::zero(), + deposit, + max_zombies, + min_balance, + zombies: Zero::zero(), + accounts: Zero::zero(), + }); + Self::deposit_event(RawEvent::Created(id, owner, admin)); + } + + /// Issue a new class of fungible assets from a privileged origin. + /// + /// This new asset class has no assets initially. + /// + /// The origin must conform to `ForceOrigin`. + /// + /// Unlike `create`, no funds are reserved. + /// + /// - `id`: The identifier of the new asset. This must not be currently in use to identify + /// an existing asset. + /// - `owner`: The owner of this class of assets. The owner has full superuser permissions + /// over this asset, but may later change and configure the permissions using `transfer_ownership` + /// and `set_team`. + /// - `max_zombies`: The total number of accounts which may hold assets in this class yet + /// have no existential deposit. + /// - `min_balance`: The minimum balance of this new asset that any single account must + /// have. If an account's balance is reduced below this, then it collapses to zero. + /// + /// Emits `ForceCreated` event when successful. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::force_create()] + fn force_create(origin, + #[compact] id: T::AssetId, + owner: ::Source, + #[compact] max_zombies: u32, + #[compact] min_balance: T::Balance, + ) { + T::ForceOrigin::ensure_origin(origin)?; + let owner = T::Lookup::lookup(owner)?; + + ensure!(!Asset::::contains_key(id), Error::::InUse); + ensure!(!min_balance.is_zero(), Error::::MinBalanceZero); + + Asset::::insert(id, AssetDetails { + owner: owner.clone(), + issuer: owner.clone(), + admin: owner.clone(), + freezer: owner.clone(), + supply: Zero::zero(), + deposit: Zero::zero(), + max_zombies, + min_balance, + zombies: Zero::zero(), + accounts: Zero::zero(), + }); + Self::deposit_event(RawEvent::ForceCreated(id, owner)); + } + + /// Destroy a class of fungible assets owned by the sender. + /// + /// The origin must be Signed and the sender must be the owner of the asset `id`. + /// + /// - `id`: The identifier of the asset to be destroyed. This must identify an existing + /// asset. + /// + /// Emits `Destroyed` event when successful. + /// + /// Weight: `O(z)` where `z` is the number of zombie accounts. + #[weight = T::WeightInfo::destroy(*zombies_witness)] + fn destroy(origin, + #[compact] id: T::AssetId, + #[compact] zombies_witness: u32, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + + Asset::::try_mutate_exists(id, |maybe_details| { + let details = maybe_details.take().ok_or(Error::::Unknown)?; + ensure!(details.owner == origin, Error::::NoPermission); + ensure!(details.accounts == details.zombies, Error::::RefsLeft); + ensure!(details.zombies <= zombies_witness, Error::::BadWitness); + T::Currency::unreserve(&details.owner, details.deposit); + + *maybe_details = None; + Account::::remove_prefix(&id); + Self::deposit_event(RawEvent::Destroyed(id)); + Ok(()) + }) + } + + /// Destroy a class of fungible assets. + /// + /// The origin must conform to `ForceOrigin`. + /// + /// - `id`: The identifier of the asset to be destroyed. This must identify an existing + /// asset. + /// + /// Emits `Destroyed` event when successful. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::force_destroy(*zombies_witness)] + fn force_destroy(origin, + #[compact] id: T::AssetId, + #[compact] zombies_witness: u32, + ) -> DispatchResult { + T::ForceOrigin::ensure_origin(origin)?; + + Asset::::try_mutate_exists(id, |maybe_details| { + let details = maybe_details.take().ok_or(Error::::Unknown)?; + ensure!(details.accounts == details.zombies, Error::::RefsLeft); + ensure!(details.zombies <= zombies_witness, Error::::BadWitness); + T::Currency::unreserve(&details.owner, details.deposit); + + *maybe_details = None; + Account::::remove_prefix(&id); + Self::deposit_event(RawEvent::Destroyed(id)); + Ok(()) + }) + } + + /// Mint assets of a particular class. + /// + /// The origin must be Signed and the sender must be the Issuer of the asset `id`. + /// + /// - `id`: The identifier of the asset to have some amount minted. + /// - `beneficiary`: The account to be credited with the minted assets. + /// - `amount`: The amount of the asset to be minted. + /// + /// Emits `Destroyed` event when successful. + /// + /// Weight: `O(1)` + /// Modes: Pre-existing balance of `beneficiary`; Account pre-existence of `beneficiary`. + #[weight = T::WeightInfo::mint()] + fn mint(origin, + #[compact] id: T::AssetId, + beneficiary: ::Source, + #[compact] amount: T::Balance + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + let beneficiary = T::Lookup::lookup(beneficiary)?; + + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + + ensure!(&origin == &details.issuer, Error::::NoPermission); + details.supply = details.supply.checked_add(&amount).ok_or(Error::::Overflow)?; + + Account::::try_mutate(id, &beneficiary, |t| -> DispatchResult { + let new_balance = t.balance.saturating_add(amount); + ensure!(new_balance >= details.min_balance, Error::::BalanceLow); + if t.balance.is_zero() { + t.is_zombie = Self::new_account(&beneficiary, details)?; + } + t.balance = new_balance; + Ok(()) + })?; + Self::deposit_event(RawEvent::Issued(id, beneficiary, amount)); + Ok(()) + }) + } + + /// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. + /// + /// Origin must be Signed and the sender should be the Manager of the asset `id`. + /// + /// Bails with `BalanceZero` if the `who` is already dead. + /// + /// - `id`: The identifier of the asset to have some amount burned. + /// - `who`: The account to be debited from. + /// - `amount`: The maximum amount by which `who`'s balance should be reduced. + /// + /// Emits `Burned` with the actual amount burned. If this takes the balance to below the + /// minimum for the asset, then the amount burned is increased to take it to zero. + /// + /// Weight: `O(1)` + /// Modes: Post-existence of `who`; Pre & post Zombie-status of `who`. + #[weight = T::WeightInfo::burn()] + fn burn(origin, + #[compact] id: T::AssetId, + who: ::Source, + #[compact] amount: T::Balance + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + let who = T::Lookup::lookup(who)?; + + Asset::::try_mutate(id, |maybe_details| { + let d = maybe_details.as_mut().ok_or(Error::::Unknown)?; + ensure!(&origin == &d.admin, Error::::NoPermission); + + let burned = Account::::try_mutate_exists( + id, + &who, + |maybe_account| -> Result { + let mut account = maybe_account.take().ok_or(Error::::BalanceZero)?; + let mut burned = amount.min(account.balance); + account.balance -= burned; + *maybe_account = if account.balance < d.min_balance { + burned += account.balance; + Self::dead_account(&who, d, account.is_zombie); + None + } else { + Some(account) + }; + Ok(burned) + } + )?; + + d.supply = d.supply.saturating_sub(burned); + + Self::deposit_event(RawEvent::Burned(id, who, burned)); + Ok(()) + }) + } + + /// Move some assets from the sender account to another. + /// + /// Origin must be Signed. + /// + /// - `id`: The identifier of the asset to have some amount transferred. + /// - `target`: The account to be credited. + /// - `amount`: The amount by which the sender's balance of assets should be reduced and + /// `target`'s balance increased. The amount actually transferred may be slightly greater in + /// the case that the transfer would otherwise take the sender balance above zero but below + /// the minimum balance. Must be greater than zero. + /// + /// Emits `Transferred` with the actual amount transferred. If this takes the source balance + /// to below the minimum for the asset, then the amount transferred is increased to take it + /// to zero. + /// + /// Weight: `O(1)` + /// Modes: Pre-existence of `target`; Post-existence of sender; Prior & post zombie-status + /// of sender; Account pre-existence of `target`. + #[weight = T::WeightInfo::transfer()] + fn transfer(origin, + #[compact] id: T::AssetId, + target: ::Source, + #[compact] amount: T::Balance + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + ensure!(!amount.is_zero(), Error::::AmountZero); + + let mut origin_account = Account::::get(id, &origin); + ensure!(!origin_account.is_frozen, Error::::Frozen); + origin_account.balance = origin_account.balance.checked_sub(&amount) + .ok_or(Error::::BalanceLow)?; + + let dest = T::Lookup::lookup(target)?; + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + + if dest == origin { + return Ok(()) + } + + let mut amount = amount; + if origin_account.balance < details.min_balance { + amount += origin_account.balance; + origin_account.balance = Zero::zero(); + } + + Account::::try_mutate(id, &dest, |a| -> DispatchResult { + let new_balance = a.balance.saturating_add(amount); + ensure!(new_balance >= details.min_balance, Error::::BalanceLow); + if a.balance.is_zero() { + a.is_zombie = Self::new_account(&dest, details)?; + } + a.balance = new_balance; + Ok(()) + })?; + + match origin_account.balance.is_zero() { + false => { + Self::dezombify(&origin, details, &mut origin_account.is_zombie); + Account::::insert(id, &origin, &origin_account) + } + true => { + Self::dead_account(&origin, details, origin_account.is_zombie); + Account::::remove(id, &origin); + } + } + + Self::deposit_event(RawEvent::Transferred(id, origin, dest, amount)); + Ok(()) + }) + } + + /// Move some assets from one account to another. + /// + /// Origin must be Signed and the sender should be the Admin of the asset `id`. + /// + /// - `id`: The identifier of the asset to have some amount transferred. + /// - `source`: The account to be debited. + /// - `dest`: The account to be credited. + /// - `amount`: The amount by which the `source`'s balance of assets should be reduced and + /// `dest`'s balance increased. The amount actually transferred may be slightly greater in + /// the case that the transfer would otherwise take the `source` balance above zero but + /// below the minimum balance. Must be greater than zero. + /// + /// Emits `Transferred` with the actual amount transferred. If this takes the source balance + /// to below the minimum for the asset, then the amount transferred is increased to take it + /// to zero. + /// + /// Weight: `O(1)` + /// Modes: Pre-existence of `dest`; Post-existence of `source`; Prior & post zombie-status + /// of `source`; Account pre-existence of `dest`. + #[weight = T::WeightInfo::force_transfer()] + fn force_transfer(origin, + #[compact] id: T::AssetId, + source: ::Source, + dest: ::Source, + #[compact] amount: T::Balance, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + + let source = T::Lookup::lookup(source)?; + let mut source_account = Account::::get(id, &source); + let mut amount = amount.min(source_account.balance); + ensure!(!amount.is_zero(), Error::::AmountZero); + + let dest = T::Lookup::lookup(dest)?; + if dest == source { + return Ok(()) + } + + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + ensure!(&origin == &details.admin, Error::::NoPermission); + + source_account.balance -= amount; + if source_account.balance < details.min_balance { + amount += source_account.balance; + source_account.balance = Zero::zero(); + } + + Account::::try_mutate(id, &dest, |a| -> DispatchResult { + let new_balance = a.balance.saturating_add(amount); + ensure!(new_balance >= details.min_balance, Error::::BalanceLow); + if a.balance.is_zero() { + a.is_zombie = Self::new_account(&dest, details)?; + } + a.balance = new_balance; + Ok(()) + })?; + + match source_account.balance.is_zero() { + false => { + Self::dezombify(&source, details, &mut source_account.is_zombie); + Account::::insert(id, &source, &source_account) + } + true => { + Self::dead_account(&source, details, source_account.is_zombie); + Account::::remove(id, &source); + } + } + + Self::deposit_event(RawEvent::ForceTransferred(id, source, dest, amount)); + Ok(()) + }) + } + + /// Disallow further unprivileged transfers from an account. + /// + /// Origin must be Signed and the sender should be the Freezer of the asset `id`. + /// + /// - `id`: The identifier of the asset to be frozen. + /// - `who`: The account to be frozen. + /// + /// Emits `Frozen`. /// - /// TWOX-NOTE: `AssetId` is trusted, so this is safe. - TotalSupply: map hasher(twox_64_concat) T::AssetId => T::Balance; + /// Weight: `O(1)` + #[weight = T::WeightInfo::freeze()] + fn freeze(origin, #[compact] id: T::AssetId, who: ::Source) { + let origin = ensure_signed(origin)?; + + let d = Asset::::get(id).ok_or(Error::::Unknown)?; + ensure!(&origin == &d.freezer, Error::::NoPermission); + let who = T::Lookup::lookup(who)?; + ensure!(Account::::contains_key(id, &who), Error::::BalanceZero); + + Account::::mutate(id, &who, |a| a.is_frozen = true); + + Self::deposit_event(Event::::Frozen(id, who)); + } + + /// Allow unprivileged transfers from an account again. + /// + /// Origin must be Signed and the sender should be the Admin of the asset `id`. + /// + /// - `id`: The identifier of the asset to be frozen. + /// - `who`: The account to be unfrozen. + /// + /// Emits `Thawed`. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::thaw()] + fn thaw(origin, #[compact] id: T::AssetId, who: ::Source) { + let origin = ensure_signed(origin)?; + + let details = Asset::::get(id).ok_or(Error::::Unknown)?; + ensure!(&origin == &details.admin, Error::::NoPermission); + let who = T::Lookup::lookup(who)?; + ensure!(Account::::contains_key(id, &who), Error::::BalanceZero); + + Account::::mutate(id, &who, |a| a.is_frozen = false); + + Self::deposit_event(Event::::Thawed(id, who)); + } + + /// Change the Owner of an asset. + /// + /// Origin must be Signed and the sender should be the Owner of the asset `id`. + /// + /// - `id`: The identifier of the asset to be frozen. + /// - `owner`: The new Owner of this asset. + /// + /// Emits `OwnerChanged`. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::transfer_ownership()] + fn transfer_ownership(origin, + #[compact] id: T::AssetId, + owner: ::Source, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + let owner = T::Lookup::lookup(owner)?; + + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + ensure!(&origin == &details.owner, Error::::NoPermission); + if details.owner == owner { return Ok(()) } + + // Move the deposit to the new owner. + T::Currency::repatriate_reserved(&details.owner, &owner, details.deposit, Reserved)?; + + details.owner = owner.clone(); + + Self::deposit_event(RawEvent::OwnerChanged(id, owner)); + Ok(()) + }) + } + + /// Change the Issuer, Admin and Freezer of an asset. + /// + /// Origin must be Signed and the sender should be the Owner of the asset `id`. + /// + /// - `id`: The identifier of the asset to be frozen. + /// - `issuer`: The new Issuer of this asset. + /// - `admin`: The new Admin of this asset. + /// - `freezer`: The new Freezer of this asset. + /// + /// Emits `TeamChanged`. + /// + /// Weight: `O(1)` + #[weight = T::WeightInfo::set_team()] + fn set_team(origin, + #[compact] id: T::AssetId, + issuer: ::Source, + admin: ::Source, + freezer: ::Source, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + let issuer = T::Lookup::lookup(issuer)?; + let admin = T::Lookup::lookup(admin)?; + let freezer = T::Lookup::lookup(freezer)?; + + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + ensure!(&origin == &details.owner, Error::::NoPermission); + + details.issuer = issuer.clone(); + details.admin = admin.clone(); + details.freezer = freezer.clone(); + + Self::deposit_event(RawEvent::TeamChanged(id, issuer, admin, freezer)); + Ok(()) + }) + } + + #[weight = T::WeightInfo::set_max_zombies()] + fn set_max_zombies(origin, + #[compact] id: T::AssetId, + #[compact] max_zombies: u32, + ) -> DispatchResult { + let origin = ensure_signed(origin)?; + + Asset::::try_mutate(id, |maybe_details| { + let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + ensure!(&origin == &details.owner, Error::::NoPermission); + ensure!(max_zombies >= details.zombies, Error::::TooManyZombies); + + let new_deposit = T::AssetDepositPerZombie::get() + .saturating_mul(max_zombies.into()) + .saturating_add(T::AssetDepositBase::get()); + + if new_deposit > details.deposit { + T::Currency::reserve(&origin, new_deposit - details.deposit)?; + } else { + T::Currency::unreserve(&origin, details.deposit - new_deposit); + } + + details.max_zombies = max_zombies; + + Self::deposit_event(RawEvent::MaxZombiesChanged(id, max_zombies)); + Ok(()) + }) + } } } @@ -269,12 +844,60 @@ impl Module { /// Get the asset `id` balance of `who`. pub fn balance(id: T::AssetId, who: T::AccountId) -> T::Balance { - >::get((id, who)) + Account::::get(id, who).balance } /// Get the total supply of an asset `id`. pub fn total_supply(id: T::AssetId) -> T::Balance { - >::get(id) + Asset::::get(id).map(|x| x.supply).unwrap_or_else(Zero::zero) + } + + /// Check the number of zombies allow yet for an asset. + pub fn zombie_allowance(id: T::AssetId) -> u32 { + Asset::::get(id).map(|x| x.max_zombies - x.zombies).unwrap_or_else(Zero::zero) + } + + fn new_account( + who: &T::AccountId, + d: &mut AssetDetails>, + ) -> Result { + let accounts = d.accounts.checked_add(1).ok_or(Error::::Overflow)?; + let r = Ok(if frame_system::Module::::account_exists(who) { + frame_system::Module::::inc_ref(who); + false + } else { + ensure!(d.zombies < d.max_zombies, Error::::TooManyZombies); + d.zombies += 1; + true + }); + d.accounts = accounts; + r + } + + /// If `who`` exists in system and it's a zombie, dezombify it. + fn dezombify( + who: &T::AccountId, + d: &mut AssetDetails>, + is_zombie: &mut bool, + ) { + if *is_zombie && frame_system::Module::::account_exists(who) { + frame_system::Module::::inc_ref(who); + *is_zombie = false; + d.zombies = d.zombies.saturating_sub(1); + } + } + + fn dead_account( + who: &T::AccountId, + d: &mut AssetDetails>, + is_zombie: bool, + ) { + if is_zombie { + d.zombies = d.zombies.saturating_sub(1); + } else { + frame_system::Module::::dec_ref(who); + } + d.accounts = d.accounts.saturating_sub(1); } } @@ -282,10 +905,25 @@ impl Module { mod tests { use super::*; - use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, weights::Weight}; + use frame_support::{ + impl_outer_origin, impl_outer_event, assert_ok, assert_noop, parameter_types, + weights::Weight + }; use sp_core::H256; use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + mod pallet_assets { + pub use crate::Event; + } + + impl_outer_event! { + pub enum Event for Test { + frame_system, + pallet_balances, + pallet_assets, + } + } + impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } @@ -309,7 +947,7 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); @@ -320,34 +958,199 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); - type AccountData = (); + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); } + + parameter_types! { + pub const ExistentialDeposit: u64 = 1; + } + + impl pallet_balances::Config for Test { + type MaxLocks = (); + type Balance = u64; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + } + + parameter_types! { + pub const AssetDepositBase: u64 = 1; + pub const AssetDepositPerZombie: u64 = 1; + } + impl Config for Test { - type Event = (); + type Currency = Balances; + type Event = Event; type Balance = u64; type AssetId = u32; + type ForceOrigin = frame_system::EnsureRoot; + type AssetDepositBase = AssetDepositBase; + type AssetDepositPerZombie = AssetDepositPerZombie; + type WeightInfo = (); } + type System = frame_system::Module; + type Balances = pallet_balances::Module; type Assets = Module; - fn new_test_ext() -> sp_io::TestExternalities { + pub(crate) fn new_test_ext() -> sp_io::TestExternalities { frame_system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] - fn issuing_asset_units_to_issuer_should_work() { + fn basic_minting_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); + assert_ok!(Assets::mint(Origin::signed(1), 0, 2, 100)); + assert_eq!(Assets::balance(0, 2), 100); + }); + } + + #[test] + fn lifecycle_should_work() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1)); + assert_eq!(Balances::reserved_balance(&1), 11); + + assert_ok!(Assets::destroy(Origin::signed(1), 0, 100)); + assert_eq!(Balances::reserved_balance(&1), 0); + + assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1)); + assert_eq!(Balances::reserved_balance(&1), 11); + + assert_ok!(Assets::force_destroy(Origin::root(), 0, 100)); + assert_eq!(Balances::reserved_balance(&1), 0); + }); + } + + #[test] + fn destroy_with_non_zombies_should_not_work() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_noop!(Assets::destroy(Origin::signed(1), 0, 100), Error::::RefsLeft); + assert_noop!(Assets::force_destroy(Origin::root(), 0, 100), Error::::RefsLeft); + assert_ok!(Assets::burn(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::destroy(Origin::signed(1), 0, 100)); + }); + } + + #[test] + fn destroy_with_bad_witness_should_not_work() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 10, 100)); + assert_noop!(Assets::destroy(Origin::signed(1), 0, 0), Error::::BadWitness); + assert_noop!(Assets::force_destroy(Origin::root(), 0, 0), Error::::BadWitness); + }); + } + + #[test] + fn max_zombies_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 2, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 0, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + + assert_eq!(Assets::zombie_allowance(0), 0); + assert_noop!(Assets::mint(Origin::signed(1), 0, 2, 100), Error::::TooManyZombies); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 50), Error::::TooManyZombies); + assert_noop!(Assets::force_transfer(Origin::signed(1), 0, 1, 2, 50), Error::::TooManyZombies); + + Balances::make_free_balance_be(&3, 100); + assert_ok!(Assets::mint(Origin::signed(1), 0, 3, 100)); + + assert_ok!(Assets::transfer(Origin::signed(0), 0, 1, 100)); + assert_eq!(Assets::zombie_allowance(0), 1); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); + }); + } + + #[test] + fn resetting_max_zombies_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 2, 1)); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 2, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 3, 100)); + + assert_eq!(Assets::zombie_allowance(0), 0); + + assert_noop!(Assets::set_max_zombies(Origin::signed(1), 0, 1), Error::::TooManyZombies); + + assert_ok!(Assets::set_max_zombies(Origin::signed(1), 0, 3)); + assert_eq!(Assets::zombie_allowance(0), 1); + }); + } + + #[test] + fn dezombifying_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 10)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_eq!(Assets::zombie_allowance(0), 9); + + // introduce a bit of balance for account 2. + Balances::make_free_balance_be(&2, 100); + + // transfer 25 units, nothing changes. + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 25)); + assert_eq!(Assets::zombie_allowance(0), 9); + + // introduce a bit of balance; this will create the account. + Balances::make_free_balance_be(&1, 100); + + // now transferring 25 units will create it. + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 25)); + assert_eq!(Assets::zombie_allowance(0), 10); + }); + } + + #[test] + fn min_balance_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 10)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_eq!(Asset::::get(0).unwrap().accounts, 1); + + // Cannot create a new account with a balance that is below minimum... + assert_noop!(Assets::mint(Origin::signed(1), 0, 2, 9), Error::::BalanceLow); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 9), Error::::BalanceLow); + assert_noop!(Assets::force_transfer(Origin::signed(1), 0, 1, 2, 9), Error::::BalanceLow); + + // When deducting from an account to below minimum, it should be reaped. + + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 91)); + assert!(Assets::balance(0, 1).is_zero()); + assert_eq!(Assets::balance(0, 2), 100); + assert_eq!(Asset::::get(0).unwrap().accounts, 1); + + assert_ok!(Assets::force_transfer(Origin::signed(1), 0, 2, 1, 91)); + assert!(Assets::balance(0, 2).is_zero()); + assert_eq!(Assets::balance(0, 1), 100); + assert_eq!(Asset::::get(0).unwrap().accounts, 1); + + assert_ok!(Assets::burn(Origin::signed(1), 0, 1, 91)); + assert!(Assets::balance(0, 1).is_zero()); + assert_eq!(Asset::::get(0).unwrap().accounts, 0); }); } #[test] fn querying_total_supply_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); assert_eq!(Assets::balance(0, 1), 50); @@ -356,15 +1159,16 @@ mod tests { assert_eq!(Assets::balance(0, 1), 50); assert_eq!(Assets::balance(0, 2), 19); assert_eq!(Assets::balance(0, 3), 31); - assert_ok!(Assets::destroy(Origin::signed(3), 0)); + assert_ok!(Assets::burn(Origin::signed(1), 0, 3, u64::max_value())); assert_eq!(Assets::total_supply(0), 69); }); } #[test] - fn transferring_amount_above_available_balance_should_work() { + fn transferring_amount_below_available_balance_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); assert_eq!(Assets::balance(0, 1), 50); @@ -372,24 +1176,106 @@ mod tests { }); } + #[test] + fn transferring_frozen_balance_should_not_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_ok!(Assets::freeze(Origin::signed(1), 0, 1)); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 50), Error::::Frozen); + assert_ok!(Assets::thaw(Origin::signed(1), 0, 1)); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); + }); + } + + #[test] + fn origin_guards_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_noop!(Assets::transfer_ownership(Origin::signed(2), 0, 2), Error::::NoPermission); + assert_noop!(Assets::set_team(Origin::signed(2), 0, 2, 2, 2), Error::::NoPermission); + assert_noop!(Assets::freeze(Origin::signed(2), 0, 1), Error::::NoPermission); + assert_noop!(Assets::thaw(Origin::signed(2), 0, 2), Error::::NoPermission); + assert_noop!(Assets::mint(Origin::signed(2), 0, 2, 100), Error::::NoPermission); + assert_noop!(Assets::burn(Origin::signed(2), 0, 1, 100), Error::::NoPermission); + assert_noop!(Assets::force_transfer(Origin::signed(2), 0, 1, 2, 100), Error::::NoPermission); + assert_noop!(Assets::set_max_zombies(Origin::signed(2), 0, 11), Error::::NoPermission); + assert_noop!(Assets::destroy(Origin::signed(2), 0, 100), Error::::NoPermission); + }); + } + + #[test] + fn transfer_owner_should_work() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&1, 100); + Balances::make_free_balance_be(&2, 1); + assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1)); + + assert_eq!(Balances::reserved_balance(&1), 11); + + assert_ok!(Assets::transfer_ownership(Origin::signed(1), 0, 2)); + assert_eq!(Balances::reserved_balance(&2), 11); + assert_eq!(Balances::reserved_balance(&1), 0); + + assert_noop!(Assets::transfer_ownership(Origin::signed(1), 0, 1), Error::::NoPermission); + + assert_ok!(Assets::transfer_ownership(Origin::signed(2), 0, 1)); + assert_eq!(Balances::reserved_balance(&1), 11); + assert_eq!(Balances::reserved_balance(&2), 0); + }); + } + + #[test] + fn set_team_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::set_team(Origin::signed(1), 0, 2, 3, 4)); + + assert_ok!(Assets::mint(Origin::signed(2), 0, 2, 100)); + assert_ok!(Assets::freeze(Origin::signed(4), 0, 2)); + assert_ok!(Assets::thaw(Origin::signed(3), 0, 2)); + assert_ok!(Assets::force_transfer(Origin::signed(3), 0, 2, 3, 100)); + assert_ok!(Assets::burn(Origin::signed(3), 0, 3, 100)); + }); + } + + #[test] + fn transferring_to_frozen_account_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 2, 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_eq!(Assets::balance(0, 2), 100); + assert_ok!(Assets::freeze(Origin::signed(1), 0, 2)); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); + assert_eq!(Assets::balance(0, 2), 150); + }); + } + #[test] fn transferring_amount_more_than_available_balance_should_not_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); assert_eq!(Assets::balance(0, 1), 50); assert_eq!(Assets::balance(0, 2), 50); - assert_ok!(Assets::destroy(Origin::signed(1), 0)); + assert_ok!(Assets::burn(Origin::signed(1), 0, 1, u64::max_value())); assert_eq!(Assets::balance(0, 1), 0); assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::::BalanceLow); + assert_noop!(Assets::transfer(Origin::signed(2), 0, 1, 51), Error::::BalanceLow); }); } #[test] fn transferring_less_than_one_unit_should_not_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), Error::::AmountZero); }); @@ -398,27 +1284,31 @@ mod tests { #[test] fn transferring_more_units_than_total_supply_should_not_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), Error::::BalanceLow); }); } #[test] - fn destroying_asset_balance_with_positive_balance_should_work() { + fn burning_asset_balance_with_positive_balance_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); - assert_ok!(Assets::destroy(Origin::signed(1), 0)); + assert_ok!(Assets::burn(Origin::signed(1), 0, 1, u64::max_value())); + assert_eq!(Assets::balance(0, 1), 0); }); } #[test] - fn destroying_asset_balance_with_zero_balance_should_not_work() { + fn burning_asset_balance_with_zero_balance_should_not_work() { new_test_ext().execute_with(|| { - assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 2), 0); - assert_noop!(Assets::destroy(Origin::signed(2), 0), Error::::BalanceZero); + assert_noop!(Assets::burn(Origin::signed(1), 0, 2, u64::max_value()), Error::::BalanceZero); }); } } diff --git a/frame/assets/src/weights.rs b/frame/assets/src/weights.rs new file mode 100644 index 00000000000..f6408e527f5 --- /dev/null +++ b/frame/assets/src/weights.rs @@ -0,0 +1,207 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Autogenerated weights for pallet_assets +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 +//! DATE: 2020-12-03, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_assets +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/assets/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_assets. +pub trait WeightInfo { + fn create() -> Weight; + fn force_create() -> Weight; + fn destroy(z: u32, ) -> Weight; + fn force_destroy(z: u32, ) -> Weight; + fn mint() -> Weight; + fn burn() -> Weight; + fn transfer() -> Weight; + fn force_transfer() -> Weight; + fn freeze() -> Weight; + fn thaw() -> Weight; + fn transfer_ownership() -> Weight; + fn set_team() -> Weight; + fn set_max_zombies() -> Weight; +} + +/// Weights for pallet_assets using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn create() -> Weight { + (58_077_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn force_create() -> Weight { + (30_497_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn destroy(z: u32, ) -> Weight { + (0 as Weight) + .saturating_add((1_153_000 as Weight).saturating_mul(z as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight))) + } + fn force_destroy(z: u32, ) -> Weight { + (0 as Weight) + .saturating_add((1_153_000 as Weight).saturating_mul(z as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight))) + } + fn mint() -> Weight { + (45_600_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn burn() -> Weight { + (40_143_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn transfer() -> Weight { + (58_903_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn force_transfer() -> Weight { + (59_025_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn freeze() -> Weight { + (43_308_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn thaw() -> Weight { + (43_383_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn transfer_ownership() -> Weight { + (31_380_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn set_team() -> Weight { + (32_049_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn set_max_zombies() -> Weight { + (57_745_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn create() -> Weight { + (58_077_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn force_create() -> Weight { + (30_497_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn destroy(z: u32, ) -> Weight { + (0 as Weight) + .saturating_add((1_153_000 as Weight).saturating_mul(z as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight))) + } + fn force_destroy(z: u32, ) -> Weight { + (0 as Weight) + .saturating_add((1_153_000 as Weight).saturating_mul(z as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight))) + } + fn mint() -> Weight { + (45_600_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn burn() -> Weight { + (40_143_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn transfer() -> Weight { + (58_903_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn force_transfer() -> Weight { + (59_025_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn freeze() -> Weight { + (43_308_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn thaw() -> Weight { + (43_383_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn transfer_ownership() -> Weight { + (31_380_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn set_team() -> Weight { + (32_049_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn set_max_zombies() -> Weight { + (57_745_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } +} diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 1f119dad76f..2852fbb953f 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -409,7 +409,7 @@ decl_storage! { for (_, balance) in &config.balances { assert!( *balance >= >::ExistentialDeposit::get(), - "the balance of any account should always be more than existential deposit.", + "the balance of any account should always be at least the existential deposit.", ) } for &(ref who, free) in config.balances.iter() { diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index beaf2e2c223..9a7e7ccb268 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -630,7 +630,7 @@ macro_rules! decl_tests { } #[test] - #[should_panic = "the balance of any account should always be more than existential deposit."] + #[should_panic = "the balance of any account should always be at least the existential deposit."] fn cannot_set_genesis_value_below_ed() { ($existential_deposit).with(|v| *v.borrow_mut() = 11); let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index af185139fb6..3c13ac55397 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -903,6 +903,10 @@ impl Module { Self::deposit_event_indexed(&[], event.into()); } + pub fn account_exists(who: &T::AccountId) -> bool { + Account::::contains_key(who) + } + /// Increment the reference counter on an account. pub fn inc_ref(who: &T::AccountId) { Account::::mutate(who, |a| a.refcount = a.refcount.saturating_add(1)); -- GitLab From 39278096356942a087213b0f21c976ac100cb8f8 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 4 Dec 2020 13:09:19 -0800 Subject: [PATCH 085/163] Add Standard Error to Weight Template (#7652) * Add standard error to weight template * fix test compile --- .maintain/frame-weight-template.hbs | 2 + utils/frame/benchmarking-cli/src/template.hbs | 1 + utils/frame/benchmarking-cli/src/writer.rs | 80 +++++++++++++------ 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/.maintain/frame-weight-template.hbs b/.maintain/frame-weight-template.hbs index 6e555da968d..76f89eafbae 100644 --- a/.maintain/frame-weight-template.hbs +++ b/.maintain/frame-weight-template.hbs @@ -54,6 +54,7 @@ impl WeightInfo for SubstrateWeight { ) -> Weight { ({{underscore benchmark.base_weight}} as Weight) {{~#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)) {{~/each}} {{~#if (ne benchmark.base_reads "0")}} @@ -82,6 +83,7 @@ impl WeightInfo for () { ) -> Weight { ({{underscore benchmark.base_weight}} as Weight) {{~#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)) {{~/each}} {{~#if (ne benchmark.base_reads "0")}} diff --git a/utils/frame/benchmarking-cli/src/template.hbs b/utils/frame/benchmarking-cli/src/template.hbs index c76eaad22c9..0ff6144214d 100644 --- a/utils/frame/benchmarking-cli/src/template.hbs +++ b/utils/frame/benchmarking-cli/src/template.hbs @@ -27,6 +27,7 @@ impl {{pallet}}::WeightInfo for WeightInfo { ) -> Weight { ({{underscore benchmark.base_weight}} as Weight) {{~#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)) {{~/each}} {{~#if (ne benchmark.base_reads "0")}} diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs index 61423000231..efa356a0fa0 100644 --- a/utils/frame/benchmarking-cli/src/writer.rs +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -84,6 +84,8 @@ struct ComponentSlope { name: String, #[serde(serialize_with = "string_serialize")] slope: u128, + #[serde(serialize_with = "string_serialize")] + error: u128, } // Small helper to create an `io::Error` from a string. @@ -145,27 +147,45 @@ fn get_benchmark_data(batch: &BenchmarkBatch) -> BenchmarkData { let mut used_reads = Vec::new(); let mut used_writes = Vec::new(); - extrinsic_time.slopes.into_iter().zip(extrinsic_time.names.iter()).for_each(|(slope, name)| { - if !slope.is_zero() { - if !used_components.contains(&name) { used_components.push(name); } - used_extrinsic_time.push(ComponentSlope { - name: name.clone(), - slope: slope.saturating_mul(1000), - }); - } - }); - reads.slopes.into_iter().zip(reads.names.iter()).for_each(|(slope, name)| { - if !slope.is_zero() { - if !used_components.contains(&name) { used_components.push(name); } - used_reads.push(ComponentSlope { name: name.clone(), slope }); - } - }); - writes.slopes.into_iter().zip(writes.names.iter()).for_each(|(slope, name)| { - if !slope.is_zero() { - if !used_components.contains(&name) { used_components.push(name); } - used_writes.push(ComponentSlope { name: name.clone(), slope }); - } - }); + extrinsic_time.slopes.into_iter() + .zip(extrinsic_time.names.iter()) + .zip(extrinsic_time.model.unwrap().se.regressor_values.iter()) + .for_each(|((slope, name), error)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_extrinsic_time.push(ComponentSlope { + name: name.clone(), + slope: slope.saturating_mul(1000), + error: (*error as u128).saturating_mul(1000), + }); + } + }); + reads.slopes.into_iter() + .zip(reads.names.iter()) + .zip(reads.model.unwrap().se.regressor_values.iter()) + .for_each(|((slope, name), error)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_reads.push(ComponentSlope { + name: name.clone(), + slope, + error: *error as u128, + }); + } + }); + writes.slopes.into_iter() + .zip(writes.names.iter()) + .zip(writes.model.unwrap().se.regressor_values.iter()) + .for_each(|((slope, name), error)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_writes.push(ComponentSlope { + name: name.clone(), + slope, + error: *error as u128, + }); + } + }); // This puts a marker on any component which is entirely unused in the weight formula. let components = batch.results[0].components @@ -379,18 +399,30 @@ mod test { assert_eq!(benchmark.base_weight, base * 1_000); assert_eq!( benchmark.component_weight, - vec![ComponentSlope { name: component.to_string(), slope: slope * 1_000 }] + vec![ComponentSlope { + name: component.to_string(), + slope: slope * 1_000, + error: 0, + }] ); // DB Reads/Writes are untouched assert_eq!(benchmark.base_reads, base); assert_eq!( benchmark.component_reads, - vec![ComponentSlope { name: component.to_string(), slope: slope }] + vec![ComponentSlope { + name: component.to_string(), + slope, + error: 0, + }] ); assert_eq!(benchmark.base_writes, base); assert_eq!( benchmark.component_writes, - vec![ComponentSlope { name: component.to_string(), slope: slope }] + vec![ComponentSlope { + name: component.to_string(), + slope, + error: 0, + }] ); } -- GitLab From 60387fd76dbc6d92654eee4c4d24eebac01b75db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 6 Dec 2020 15:14:19 +0100 Subject: [PATCH 086/163] Adds support for tuples in runtime-interface (#7672) --- Cargo.lock | 1 + primitives/runtime-interface/Cargo.toml | 1 + primitives/runtime-interface/src/impls.rs | 4 +++- primitives/runtime-interface/src/lib.rs | 2 +- .../runtime-interface/test-wasm/src/lib.rs | 24 +++++++++++++++++++ primitives/runtime-interface/test/src/lib.rs | 7 +++++- 6 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13bc6ca0ebc..53c42e08774 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8368,6 +8368,7 @@ dependencies = [ name = "sp-runtime-interface" version = "2.0.0" dependencies = [ + "impl-trait-for-tuples", "parity-scale-codec", "primitive-types", "rustversion", diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 0138637366d..180914e89dd 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -23,6 +23,7 @@ codec = { package = "parity-scale-codec", version = "1.3.1", default-features = static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } sp-storage = { version = "2.0.0", default-features = false, path = "../storage" } +impl-trait-for-tuples = "0.1.3" [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0", path = "test-wasm" } diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index da57cf086be..7d84085a9e4 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -365,7 +365,9 @@ impl PassBy for Option { type PassBy = Codec; } -impl PassBy for (u32, u32, u32, u32) { +#[impl_trait_for_tuples::impl_for_tuples(30)] +#[tuple_types_no_default_trait_bound] +impl PassBy for Tuple where Self: codec::Codec { type PassBy = Codec; } diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index dd625a4a253..7a7b78bc45b 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -99,7 +99,7 @@ //! | `*const T` | `u32` | `Identity` | //! | `Option` | `u64` | `let e = v.encode();`

e.len() 32bit << 32 | e.as_ptr() 32bit | //! | [`T where T: PassBy`](./pass_by#Inner) | Depends on inner | Depends on inner | -//! | [`T where T:PassBy`](./pass_by#Codec)|`u64`|v.len() 32bit << 32 |v.as_ptr() 32bit| +//! | [`T where T: PassBy`](./pass_by#Codec)|`u64`|v.len() 32bit << 32 |v.as_ptr() 32bit| //! //! `Identity` means that the value is converted directly into the corresponding FFI type. diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 6cd37a6c1d1..852be609fef 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -120,6 +120,16 @@ pub trait TestApi { fn test_versionning(&self, data: u32) -> bool { data == 42 } + + /// Returns the input values as tuple. + fn return_input_as_tuple( + a: Vec, + b: u32, + c: Option>, + d: u8, + ) -> (Vec, u32, Option>, u8) { + (a, b, c, d) + } } /// This function is not used, but we require it for the compiler to include `sp-io`. @@ -258,4 +268,18 @@ wasm_export_functions! { assert!(!test_api::test_versionning(50)); assert!(!test_api::test_versionning(102)); } + + fn test_return_input_as_tuple() { + let a = vec![1, 3, 4, 5]; + let b = 10000; + let c = Some(vec![2, 3]); + let d = 5; + + let res = test_api::return_input_as_tuple(a.clone(), b, c.clone(), d); + + assert_eq!(a, res.0); + assert_eq!(b, res.1); + assert_eq!(c, res.2); + assert_eq!(d, res.3); + } } diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index c66609daa2f..1f079e86ff3 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -208,4 +208,9 @@ fn test_tracing() { let inner = subscriber.0.lock().unwrap(); assert!(inner.spans.contains("return_input_version_1")); -} \ No newline at end of file +} + +#[test] +fn test_return_input_as_tuple() { + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_input_as_tuple"); +} -- GitLab From 9467f562ddb9c85ff78fca69d08137950b948019 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 7 Dec 2020 10:10:21 +0100 Subject: [PATCH 087/163] Fix two potential connection poisonings (#7677) --- client/network/src/protocol/generic_proto/behaviour.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 51d7252d5f9..b8b4cce0a72 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -1565,6 +1565,7 @@ impl NetworkBehaviour for GenericProto { connec_state, ConnectionState::OpeningThenClosing )); + *entry.into_mut() = PeerState::Disabled { connections, backoff_until }; } } else { error!( @@ -1652,6 +1653,7 @@ impl NetworkBehaviour for GenericProto { }; if matches!(connections[pos].1, ConnectionState::Closing) { + *entry.into_mut() = PeerState::Enabled { connections }; return; } @@ -1683,7 +1685,7 @@ impl NetworkBehaviour for GenericProto { notifications_sink: replacement_sink, }; self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); - *entry.into_mut() = PeerState::Enabled { connections, }; + *entry.into_mut() = PeerState::Enabled { connections }; } } else { -- GitLab From eaab146094360ca02538f5287abe859b2d815c3c Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 7 Dec 2020 15:04:32 +0100 Subject: [PATCH 088/163] Fix #7629 (#7680) * Fix #7629 * Update client/network/src/service.rs Co-authored-by: Max Inden Co-authored-by: Max Inden --- client/network/src/service.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index b6f162affd6..c59aeb41229 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -668,9 +668,9 @@ impl NetworkService { sink.clone() } else { // Notification silently discarded, as documented. - log::error!( + log::debug!( target: "sub-libp2p", - "Attempted to send notification on unknown protocol: {:?}", + "Attempted to send notification on missing or closed substream: {:?}", protocol, ); return; -- GitLab From f91998e175b320e73125bd82bda313f04e4a91dd Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 7 Dec 2020 16:32:16 +0100 Subject: [PATCH 089/163] Update Cargo.toml (#7627) On behalf of dependabot, because we use 1.4.x in it clashes with this. --- primitives/core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 5044a1d6691..d59bbad09e5 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -27,7 +27,7 @@ base58 = { version = "0.1.0", optional = true } rand = { version = "0.7.3", optional = true, features = ["small_rng"] } substrate-bip39 = { version = "0.4.2", optional = true } tiny-bip39 = { version = "0.8", optional = true } -regex = { version = "1.3.1", optional = true } +regex = { version = "1.4.2", optional = true } num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } secrecy = { version = "0.7.0", default-features = false } -- GitLab From ec55d650fea0b244e5481efd11b5ea2462766196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 7 Dec 2020 16:48:54 +0100 Subject: [PATCH 090/163] Make sure the companion CI test fails on any error (#7683) --- .maintain/gitlab/check_polkadot_companion_build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 4b6e45c267e..16fb2d35672 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -9,6 +9,7 @@ # polkadot companion: paritytech/polkadot#567 # +set -e github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" # use github api v3 in order to access the data without authentication -- GitLab From 163412d6cf5a2df9eed9a5f78bac54ad7ef99982 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Tue, 8 Dec 2020 10:10:46 +0100 Subject: [PATCH 091/163] implement more convertion on NumberOrHex (#7682) --- primitives/rpc/src/number.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/primitives/rpc/src/number.rs b/primitives/rpc/src/number.rs index 3d7e7475352..0a81a34db8f 100644 --- a/primitives/rpc/src/number.rs +++ b/primitives/rpc/src/number.rs @@ -18,7 +18,7 @@ //! A number type that can be serialized both as a number or a string that encodes a number in a //! string. -use std::{convert::TryFrom, fmt::Debug}; +use std::{convert::{TryFrom, TryInto}, fmt::Debug}; use serde::{Serialize, Deserialize}; use sp_core::U256; @@ -67,24 +67,27 @@ pub struct TryFromIntError(pub(crate) ()); impl TryFrom for u32 { type Error = TryFromIntError; fn try_from(num_or_hex: NumberOrHex) -> Result { - let num_or_hex = num_or_hex.into_u256(); - if num_or_hex > U256::from(u32::max_value()) { - return Err(TryFromIntError(())); - } else { - Ok(num_or_hex.as_u32()) - } + num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(())) } } impl TryFrom for u64 { type Error = TryFromIntError; fn try_from(num_or_hex: NumberOrHex) -> Result { - let num_or_hex = num_or_hex.into_u256(); - if num_or_hex > U256::from(u64::max_value()) { - return Err(TryFromIntError(())); - } else { - Ok(num_or_hex.as_u64()) - } + num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(())) + } +} + +impl TryFrom for u128 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + num_or_hex.into_u256().try_into().map_err(|_| TryFromIntError(())) + } +} + +impl From for U256 { + fn from(num_or_hex: NumberOrHex) -> U256 { + num_or_hex.into_u256() } } -- GitLab From 332399d16668a6c769f1a7db154bb9ea3b50e61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 8 Dec 2020 13:18:34 +0100 Subject: [PATCH 092/163] Streamline frame_system weight parametrization (#6629) * Basic weights builder. * Fixing WiP * Make the tests work. * Fix weights in node/runtime. * WiP. * Update pallets with new weights parameters. * Validate returns a Result now. * Count mandatory weight separately. * DRY * BREAKING: Updating state root, because of the left-over weight-tracking stuff * Update tests affected by Mandatory tracking. * Fixing tests. * Fix defaults for simple_max * Update frame/system/src/weights.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Rework the API a bit. * Fix compilation & tests. * Apply suggestions from code review Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Add extra docs & rename few things. * Fix whitespace in ASCII art. * Update frame/system/src/limits.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fix max_extrinsic calculations. * Fix conflicts. * Fix compilation. * Fix new code. * re-remove generic asset * Fix usage. * Update state root. * Update proxy. * Fix tests. * Move weights validity to integrity_test * Remove redundant BlockWeights. * Add all/non_mandatory comment * Add test. * Remove fn block_weights * Make the macro prettier. * Fix some docs. * Make max_total behave more predictabily. * Add BlockWeights to metadata. * fix balances test * Fix utility test. Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Shawn Tabrizi Co-authored-by: Benjamin Kampmann Co-authored-by: thiolliere --- .../pallets/template/src/mock.rs | 17 +- bin/node-template/runtime/src/lib.rs | 36 +- bin/node/runtime/src/impls.rs | 34 +- bin/node/runtime/src/lib.rs | 75 +-- frame/assets/src/lib.rs | 20 +- frame/atomic-swap/src/tests.rs | 20 +- frame/aura/src/mock.rs | 19 +- frame/authority-discovery/src/lib.rs | 19 +- frame/authorship/src/lib.rs | 19 +- frame/babe/src/mock.rs | 18 +- frame/balances/src/tests_composite.rs | 16 +- frame/balances/src/tests_local.rs | 16 +- frame/benchmarking/src/tests.rs | 10 +- frame/collective/src/lib.rs | 19 +- frame/contracts/src/tests.rs | 16 +- frame/democracy/src/lib.rs | 7 +- frame/democracy/src/tests.rs | 17 +- frame/elections-phragmen/src/lib.rs | 25 +- frame/elections/src/mock.rs | 18 +- frame/example-offchain-worker/src/tests.rs | 18 +- frame/example-parallel/src/tests.rs | 12 +- frame/example/src/lib.rs | 16 +- frame/executive/src/lib.rs | 62 +-- frame/grandpa/src/mock.rs | 17 +- frame/identity/src/lib.rs | 1 + frame/identity/src/tests.rs | 17 +- frame/im-online/src/mock.rs | 17 +- frame/indices/src/mock.rs | 18 +- frame/membership/src/lib.rs | 19 +- frame/multisig/src/tests.rs | 19 +- frame/nicks/src/lib.rs | 19 +- frame/node-authorization/src/lib.rs | 21 +- frame/offences/benchmarking/src/mock.rs | 15 +- frame/offences/src/mock.rs | 18 +- frame/proxy/src/lib.rs | 2 +- frame/proxy/src/tests.rs | 19 +- frame/randomness-collective-flip/src/lib.rs | 21 +- frame/recovery/src/mock.rs | 18 +- frame/scheduler/src/lib.rs | 17 +- frame/scored-pool/src/mock.rs | 21 +- frame/session/benchmarking/src/mock.rs | 10 +- frame/session/src/lib.rs | 2 +- frame/session/src/mock.rs | 19 +- frame/society/src/lib.rs | 29 +- frame/society/src/mock.rs | 18 +- frame/staking/fuzzer/src/mock.rs | 10 +- frame/staking/src/benchmarking.rs | 14 +- frame/staking/src/mock.rs | 19 +- frame/staking/src/testing_utils.rs | 2 +- frame/sudo/src/mock.rs | 17 +- frame/support/src/weights.rs | 117 +++++ .../tests/pallet_with_name_trait_is_valid.rs | 11 +- frame/system/benches/bench.rs | 21 +- frame/system/benchmarking/src/lib.rs | 8 +- frame/system/benchmarking/src/mock.rs | 10 +- frame/system/src/extensions/check_weight.rs | 286 +++++++----- frame/system/src/lib.rs | 70 ++- frame/system/src/limits.rs | 434 ++++++++++++++++++ frame/system/src/mock.rs | 37 +- frame/system/src/weight.rs | 76 --- frame/timestamp/src/lib.rs | 19 +- frame/transaction-payment/src/lib.rs | 94 ++-- frame/treasury/src/tests.rs | 19 +- frame/utility/src/tests.rs | 18 +- frame/vesting/src/lib.rs | 18 +- test-utils/runtime/src/lib.rs | 22 +- 66 files changed, 1277 insertions(+), 931 deletions(-) create mode 100644 frame/system/src/limits.rs delete mode 100644 frame/system/src/weight.rs diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 4c7c16e7f55..84af63a1c3b 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -1,8 +1,8 @@ use crate::{Module, Config}; use sp_core::H256; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, parameter_types}; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; use frame_system as system; @@ -16,13 +16,13 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } impl system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = (); type Index = u64; @@ -34,13 +34,6 @@ impl system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index a899afe9ad1..51df3dd5a3e 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -13,7 +13,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor, Saturating, + BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor, }; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -126,16 +126,16 @@ pub fn native_version() -> NativeVersion { } } +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); + parameter_types! { + pub const Version: RuntimeVersion = VERSION; pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - /// Assume 10% of weight for average on_initialize calls. - pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() - .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; - pub const Version: RuntimeVersion = VERSION; + pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights + ::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); + pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength + ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); } // Configure FRAME pallets to include in runtime. @@ -143,6 +143,10 @@ parameter_types! { impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. type BaseCallFilter = (); + /// Block & extrinsics weights: base values and limits. + type BlockWeights = BlockWeights; + /// The maximum length of a block (in bytes). + type BlockLength = BlockLength; /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. @@ -165,24 +169,8 @@ impl frame_system::Config for Runtime { type Origin = Origin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. - type MaximumBlockWeight = MaximumBlockWeight; /// The weight of database operations that the runtime can invoke. type DbWeight = RocksDbWeight; - /// The weight of the overhead invoked on the block import process, independent of the - /// extrinsics included in that block. - type BlockExecutionWeight = BlockExecutionWeight; - /// The base weight of any extrinsic processed by the runtime, independent of the - /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...) - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - /// The maximum weight that a single extrinsic of `Normal` dispatch class can have, - /// idependent of the logic of that extrinsics. (Roughly max block weight - average on - /// initialize cost). - type MaximumExtrinsicWeight = MaximumExtrinsicWeight; - /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. - type MaximumBlockLength = MaximumBlockLength; - /// Portion of the block weight that is available to all normal transactions. - type AvailableBlockRatio = AvailableBlockRatio; /// Version of the runtime. type Version = Version; /// Converts a module to the index of the module in `construct_runtime!`. diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index acd8def6835..d7910c2c63b 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -34,13 +34,15 @@ mod multiplier_tests { use crate::{ constants::{currency::*, time::*}, - TransactionPayment, MaximumBlockWeight, AvailableBlockRatio, Runtime, TargetBlockFullness, + TransactionPayment, Runtime, TargetBlockFullness, AdjustmentVariable, System, MinimumMultiplier, + RuntimeBlockWeights as BlockWeights, }; - use frame_support::weights::{Weight, WeightToFeePolynomial}; + use frame_support::weights::{Weight, WeightToFeePolynomial, DispatchClass}; - fn max() -> Weight { - AvailableBlockRatio::get() * MaximumBlockWeight::get() + fn max_normal() -> Weight { + BlockWeights::get().get(DispatchClass::Normal).max_total + .unwrap_or_else(|| BlockWeights::get().max_block) } fn min_multiplier() -> Multiplier { @@ -48,7 +50,7 @@ mod multiplier_tests { } fn target() -> Weight { - TargetBlockFullness::get() * max() + TargetBlockFullness::get() * max_normal() } // update based on runtime impl. @@ -69,7 +71,7 @@ mod multiplier_tests { let previous_float = previous_float.max(min_multiplier().into_inner() as f64 / accuracy); // maximum tx weight - let m = max() as f64; + let m = max_normal() as f64; // block weight always truncated to max weight let block_weight = (block_weight as f64).min(m); let v: f64 = AdjustmentVariable::get().to_fraction(); @@ -89,7 +91,7 @@ mod multiplier_tests { let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default().build_storage::().unwrap().into(); t.execute_with(|| { - System::set_block_limits(w, 0); + System::set_block_consumed_resources(w, 0); assertions() }); } @@ -102,8 +104,8 @@ mod multiplier_tests { (100, fm.clone()), (1000, fm.clone()), (target(), fm.clone()), - (max() / 2, fm.clone()), - (max(), fm.clone()), + (max_normal() / 2, fm.clone()), + (max_normal(), fm.clone()), ]; test_set.into_iter().for_each(|(w, fm)| { run_with_system_weight(w, || { @@ -164,7 +166,7 @@ mod multiplier_tests { #[test] fn min_change_per_day() { - run_with_system_weight(max(), || { + run_with_system_weight(max_normal(), || { let mut fm = Multiplier::one(); // See the example in the doc of `TargetedFeeAdjustment`. are at least 0.234, hence // `fm > 1.234`. @@ -182,7 +184,7 @@ mod multiplier_tests { // `cargo test congested_chain_simulation -- --nocapture` to get some insight. // almost full. The entire quota of normal transactions is taken. - let block_weight = AvailableBlockRatio::get() * max() - 100; + let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() - 100; // Default substrate weight. let tx_weight = frame_support::weights::constants::ExtrinsicBaseWeight::get(); @@ -320,15 +322,19 @@ mod multiplier_tests { 10 * mb, 2147483647, 4294967295, - MaximumBlockWeight::get() / 2, - MaximumBlockWeight::get(), + BlockWeights::get().max_block / 2, + BlockWeights::get().max_block, Weight::max_value() / 2, Weight::max_value(), ].into_iter().for_each(|i| { run_with_system_weight(i, || { let next = runtime_multiplier_update(Multiplier::one()); let truth = truth_value_update(i, Multiplier::one()); - assert_eq_error_rate!(truth, next, Multiplier::from_inner(50_000_000)); + assert_eq_error_rate!( + truth, + next, + Multiplier::from_inner(50_000_000) + ); }); }); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 285f37889ae..ea9921beeef 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -28,14 +28,17 @@ use frame_support::{ construct_runtime, parameter_types, debug, RuntimeDebug, weights::{ Weight, IdentityFee, - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, DispatchClass, }, traits::{ Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier, U128CurrencyToVote, }, }; -use frame_system::{EnsureRoot, EnsureOneOf}; +use frame_system::{ + EnsureRoot, EnsureOneOf, + limits::{BlockWeights, BlockLength} +}; use frame_support::traits::InstanceFilter; use codec::{Encode, Decode}; use sp_core::{ @@ -54,7 +57,7 @@ use sp_runtime::curve::PiecewiseLinear; use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}; use sp_runtime::traits::{ self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, - ConvertInto, OpaqueKeys, NumberFor, Saturating, + ConvertInto, OpaqueKeys, NumberFor, }; use sp_version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -141,23 +144,47 @@ impl OnUnbalanced for DealWithFees { } } -const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10); +/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers. +/// This is used to limit the maximal weight of a single extrinsic. +const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used +/// by Operational extrinsics. +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2 seconds of compute with a 6 second average block time. +const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND; + parameter_types! { pub const BlockHashCount: BlockNumber = 2400; - /// We allow for 2 seconds of compute with a 6 second average block time. - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - /// Assume 10% of weight for average on_initialize calls. - pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT) - * MaximumBlockWeight::get(); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; -} - -const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct()); + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); +} + +const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = RuntimeBlockWeights; + type BlockLength = RuntimeBlockLength; + type DbWeight = RocksDbWeight; type Origin = Origin; type Call = Call; type Index = Index; @@ -169,13 +196,6 @@ impl frame_system::Config for Runtime { type Header = generic::Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = RocksDbWeight; - type BlockExecutionWeight = BlockExecutionWeight; - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type MaximumExtrinsicWeight = MaximumExtrinsicWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; @@ -277,7 +297,8 @@ impl pallet_proxy::Config for Runtime { } parameter_types! { - pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * + RuntimeBlockWeights::get().max_block; pub const MaxScheduledPerBlock: u32 = 50; } @@ -438,9 +459,10 @@ parameter_types! { pub const MaxIterations: u32 = 10; // 0.05%. The higher the value, the more strict solution acceptance becomes. pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000); - pub OffchainSolutionWeightLimit: Weight = MaximumExtrinsicWeight::get() - .saturating_sub(BlockExecutionWeight::get()) - .saturating_sub(ExtrinsicBaseWeight::get()); + pub OffchainSolutionWeightLimit: Weight = RuntimeBlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed") + .saturating_sub(BlockExecutionWeight::get()); } impl pallet_staking::Config for Runtime { @@ -779,7 +801,8 @@ impl pallet_im_online::Config for Runtime { } parameter_types! { - pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * + RuntimeBlockWeights::get().max_block; } impl pallet_offences::Config for Runtime { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 630f4fcc317..df1cb87f75b 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -905,12 +905,9 @@ impl Module { mod tests { use super::*; - use frame_support::{ - impl_outer_origin, impl_outer_event, assert_ok, assert_noop, parameter_types, - weights::Weight - }; + use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, impl_outer_event}; use sp_core::H256; - use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod pallet_assets { pub use crate::Event; @@ -932,12 +929,12 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type Call = (); @@ -949,13 +946,6 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index 7254ceba4f6..47b5102bc56 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -2,12 +2,9 @@ use super::*; -use frame_support::{ - impl_outer_origin, parameter_types, weights::Weight, -}; +use frame_support::{impl_outer_origin, parameter_types}; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; @@ -20,12 +17,14 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -37,13 +36,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index b06a0f427f1..1fcb1c2340d 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -22,10 +22,10 @@ use crate::{Config, Module, GenesisConfig}; use sp_consensus_aura::ed25519::AuthorityId; use sp_runtime::{ - traits::IdentityLookup, Perbill, + traits::IdentityLookup, testing::{Header, UintAuthorityId}, }; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, parameter_types}; use sp_io; use sp_core::H256; @@ -39,14 +39,16 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); pub const MinimumPeriod: u64 = 1; } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -58,13 +60,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 4db7ba753cb..2d275e01bba 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -93,7 +93,7 @@ impl pallet_session::OneSessionHandler for Module { #[cfg(test)] mod tests { use super::*; - use sp_authority_discovery::{AuthorityPair}; + use sp_authority_discovery::AuthorityPair; use sp_application_crypto::Pair; use sp_core::{crypto::key_types, H256}; use sp_io::TestExternalities; @@ -101,7 +101,7 @@ mod tests { testing::{Header, UintAuthorityId}, traits::{ConvertInto, IdentityLookup, OpaqueKeys}, Perbill, KeyTypeId, }; - use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; + use frame_support::{impl_outer_origin, parameter_types}; type AuthorityDiscovery = Module; @@ -138,13 +138,15 @@ mod tests { pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = BlockNumber; @@ -156,13 +158,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 4809462db6e..b991beaaa2b 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -399,9 +399,9 @@ mod tests { use super::*; use sp_core::H256; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, testing::Header, generic::DigestItem, Perbill, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, generic::DigestItem, }; - use frame_support::{parameter_types, impl_outer_origin, ConsensusEngineId, weights::Weight}; + use frame_support::{parameter_types, impl_outer_origin, ConsensusEngineId}; impl_outer_origin!{ pub enum Origin for Test where system = frame_system {} @@ -412,13 +412,15 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -430,13 +432,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index f3d5bc092bc..8af92c79e91 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -57,16 +57,18 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const EpochDuration: u64 = 3; pub const ExpectedBlockTime: u64 = 1; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -79,13 +81,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type PalletInfo = (); type AccountData = pallet_balances::AccountData; type OnNewAccount = (); @@ -209,7 +204,8 @@ impl pallet_staking::Config for Test { } parameter_types! { - pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) + * BlockWeights::get().max_block; } impl pallet_offences::Config for Test { diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 5f0cea7c963..81c2b895273 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -20,7 +20,6 @@ #![cfg(test)] use sp_runtime::{ - Perbill, traits::IdentityLookup, testing::Header, }; @@ -52,13 +51,15 @@ impl_outer_event! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); pub static ExistentialDeposit: u64 = 0; } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -70,13 +71,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = super::AccountData; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 888b8c7d62b..c168e1d8e59 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -20,7 +20,6 @@ #![cfg(test)] use sp_runtime::{ - Perbill, traits::IdentityLookup, testing::Header, }; @@ -53,13 +52,15 @@ impl_outer_event! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); pub static ExistentialDeposit: u64 = 0; } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -71,13 +72,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = super::AccountData; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 70359f2065e..f86abebbb92 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -74,6 +74,9 @@ pub struct Test; impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -85,13 +88,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = (); - type MaximumBlockWeight = (); - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = (); - type MaximumBlockLength = (); - type AvailableBlockRatio = (); type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 11ec42f25ae..abaf579861e 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -933,27 +933,29 @@ impl< #[cfg(test)] mod tests { use super::*; - use frame_support::{Hashable, assert_ok, assert_noop, parameter_types, weights::Weight}; + use frame_support::{Hashable, assert_ok, assert_noop, parameter_types}; use frame_system::{self as system, EventRecord, Phase}; use hex_literal::hex; use sp_core::H256; use sp_runtime::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage, }; use crate as collective; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MotionDuration: u64 = 3; pub const MaxProposals: u32 = 100; pub const MaxMembers: u32 = 100; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -965,13 +967,6 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 44ddb8c2c65..c0b9b671068 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -23,7 +23,6 @@ use crate::{ use assert_matches::assert_matches; use codec::Encode; use sp_runtime::{ - Perbill, traits::{BlakeTwo256, Hash, IdentityLookup, Convert}, testing::{Header, H256}, AccountId32, @@ -105,13 +104,15 @@ pub mod test_utils { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); pub static ExistentialDeposit: u64 = 0; } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -123,13 +124,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index ce89259e55e..70383beaa06 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -1086,7 +1086,7 @@ decl_module! { } /// Enact a proposal from a referendum. For now we just make the weight be the maximum. - #[weight = T::MaximumBlockWeight::get()] + #[weight = T::BlockWeights::get().max_block] fn enact_proposal(origin, proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { ensure_root(origin)?; Self::do_enact_proposal(proposal_hash, index) @@ -1609,6 +1609,7 @@ impl Module { /// - Db reads per R: `DepositOf`, `ReferendumInfoOf` /// # fn begin_block(now: T::BlockNumber) -> Result { + let max_block_weight = T::BlockWeights::get().max_block; let mut weight = 0; // pick out another public referendum if it's time. @@ -1616,7 +1617,7 @@ impl Module { // Errors come from the queue being empty. we don't really care about that, and even if // we did, there is nothing we can do here. let _ = Self::launch_next(now); - weight = T::MaximumBlockWeight::get(); + weight = max_block_weight; } let next = Self::lowest_unbaked(); @@ -1627,7 +1628,7 @@ impl Module { for (index, info) in Self::maturing_referenda_at_inner(now, next..last).into_iter() { let approved = Self::bake_referendum(now, index, info)?; ReferendumInfoOf::::insert(index, ReferendumInfo::Finished { end: now, approved }); - weight = T::MaximumBlockWeight::get(); + weight = max_block_weight; } Ok(weight) diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 6e7b7cfcc6d..dae3a262209 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -88,12 +88,14 @@ impl Filter for BaseFilter { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1_000_000; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1_000_000); } impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -105,13 +107,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; @@ -120,7 +115,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); } parameter_types! { - pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; } impl pallet_scheduler::Config for Test { type Event = Event; diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index c4a71d6595f..db2428971cc 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -621,7 +621,7 @@ decl_module! { #[weight = if *has_replacement { T::WeightInfo::remove_member_with_replacement() } else { - T::MaximumBlockWeight::get() + T::BlockWeights::get().max_block }] fn remove_member( origin, @@ -829,7 +829,7 @@ impl Module { if !Self::term_duration().is_zero() { if (block_number % Self::term_duration()).is_zero() { Self::do_phragmen(); - return T::MaximumBlockWeight::get() + return T::BlockWeights::get().max_block; } } 0 @@ -1058,26 +1058,26 @@ impl ContainsLengthBound for Module { #[cfg(test)] mod tests { use super::*; - use frame_support::{assert_ok, assert_noop, assert_err_with_weight, parameter_types, - weights::Weight, - }; + use frame_support::{assert_ok, assert_noop, assert_err_with_weight, parameter_types}; use substrate_test_utils::assert_eq_uvec; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, BuildStorage, DispatchResult, + testing::Header, BuildStorage, DispatchResult, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections_phragmen; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -1089,13 +1089,6 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 293074469c5..482c905f89c 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -22,23 +22,24 @@ use frame_support::{ StorageValue, StorageMap, parameter_types, assert_ok, traits::{ChangeMembers, Currency, LockIdentifier}, - weights::Weight, }; use sp_core::H256; use sp_runtime::{ - Perbill, BuildStorage, testing::Header, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, + BuildStorage, testing::Header, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = Call; type Index = u64; @@ -50,13 +51,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 809e3b7ba64..196d4cac4ad 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -20,7 +20,6 @@ use std::sync::Arc; use codec::{Encode, Decode}; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, - weights::Weight, }; use sp_core::{ H256, @@ -33,7 +32,7 @@ use sp_keystore::{ testing::KeyStore, }; use sp_runtime::{ - Perbill, RuntimeAppPublic, + RuntimeAppPublic, testing::{Header, TestXt}, traits::{ BlakeTwo256, IdentityLookup, Extrinsic as ExtrinsicT, @@ -52,12 +51,14 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = (); type Index = u64; @@ -69,13 +70,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/example-parallel/src/tests.rs b/frame/example-parallel/src/tests.rs index d2c37640013..24e846c3de4 100644 --- a/frame/example-parallel/src/tests.rs +++ b/frame/example-parallel/src/tests.rs @@ -18,7 +18,7 @@ use crate::*; use codec::{Encode, Decode}; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, parameter_types}; use sp_core::H256; use sp_runtime::{ Perbill, @@ -34,8 +34,6 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } @@ -53,13 +51,9 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; + type BlockWeights = (); + type BlockLength = (); type Version = (); type AccountData = (); type OnNewAccount = (); diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index fb84a48a8d2..b3e883781f5 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -718,7 +718,6 @@ mod tests { // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; @@ -740,12 +739,14 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -757,13 +758,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index c91287df5b9..572d58d86b4 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -251,8 +251,12 @@ where weight = weight.saturating_add( as OnInitialize>::on_initialize(*block_number) ); - weight = weight.saturating_add(>::on_initialize(*block_number)) - .saturating_add(>::get()); + weight = weight.saturating_add( + >::on_initialize(*block_number) + ); + weight = weight.saturating_add( + >::get().base_block + ); >::register_extra_weight_unchecked(weight, DispatchClass::Mandatory); frame_system::Module::::note_finished_initialize(); @@ -482,7 +486,7 @@ mod tests { use super::*; use sp_core::H256; use sp_runtime::{ - generic::{Era, DigestItem}, Perbill, DispatchError, testing::{Digest, Header, Block}, + generic::{Era, DigestItem}, DispatchError, testing::{Digest, Header, Block}, traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}, transaction_validity::{ InvalidTransaction, ValidTransaction, TransactionValidityError, UnknownTransaction @@ -493,7 +497,9 @@ mod tests { weights::{Weight, RuntimeDbWeight, IdentityFee, WeightToFeePolynomial}, traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons}, }; - use frame_system::{Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo}; + use frame_system::{ + Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo, + }; use pallet_transaction_payment::CurrencyAdapter; use pallet_balances::Call as BalancesCall; use hex_literal::hex; @@ -584,11 +590,12 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const BlockExecutionWeight: Weight = 10; - pub const ExtrinsicBaseWeight: Weight = 5; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::builder() + .base_block(10) + .for_class(DispatchClass::all(), |weights| weights.base_extrinsic = 5) + .for_class(DispatchClass::non_mandatory(), |weights| weights.max_total = 1024.into()) + .build_or_panic(); pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 10, write: 100, @@ -596,6 +603,9 @@ mod tests { } impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type Call = Call; @@ -607,13 +617,6 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = DbWeight; - type BlockExecutionWeight = BlockExecutionWeight; - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = RuntimeVersion; type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; @@ -715,7 +718,8 @@ mod tests { balances: vec![(1, 211)], }.assimilate_storage(&mut t).unwrap(); let xt = TestXt::new(Call::Balances(BalancesCall::transfer(2, 69)), sign_extra(1, 0, 0)); - let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); + let weight = xt.get_dispatch_info().weight + + ::BlockWeights::get().get(DispatchClass::Normal).base_extrinsic; let fee: Balance = ::WeightToFee::calc(&weight); let mut t = sp_io::TestExternalities::new(t); @@ -749,7 +753,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("465a1569d309039bdf84b0479d28064ea29e6584584dc7d788904bb14489c6f6").into(), + state_root: hex!("6a3ad91caba5b8ac15c325a36d7568adf6a7e49321865de7527b851d870343d4").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -817,9 +821,11 @@ mod tests { let xt = TestXt::new(Call::Balances(BalancesCall::transfer(33, 0)), sign_extra(1, 0, 0)); let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; - // on_initialize weight + block execution weight - let base_block_weight = 175 + ::BlockExecutionWeight::get(); - let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get() - base_block_weight; + // on_initialize weight + base block execution weight + let block_weights = ::BlockWeights::get(); + let base_block_weight = 175 + block_weights.base_block; + let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() + - base_block_weight; let num_to_exhaust_block = limit / (encoded_len + 5); t.execute_with(|| { Executive::initialize_block(&Header::new( @@ -861,7 +867,7 @@ mod tests { let mut t = new_test_ext(1); t.execute_with(|| { // Block execution weight + on_initialize weight from custom module - let base_block_weight = 175 + ::BlockExecutionWeight::get(); + let base_block_weight = 175 + ::BlockWeights::get().base_block; Executive::initialize_block(&Header::new( 1, @@ -879,7 +885,8 @@ mod tests { assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. - let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); + let extrinsic_weight = len as Weight + ::BlockWeights + ::get().get(DispatchClass::Normal).base_extrinsic; assert_eq!( >::block_weight().total(), base_block_weight + 3 * extrinsic_weight, @@ -945,8 +952,11 @@ mod tests { Call::System(SystemCall::remark(vec![1u8])), sign_extra(1, 0, 0), ); - let weight = xt.get_dispatch_info().weight - + ::ExtrinsicBaseWeight::get(); + let weight = xt.get_dispatch_info().weight + + ::BlockWeights + ::get() + .get(DispatchClass::Normal) + .base_extrinsic; let fee: Balance = ::WeightToFee::calc(&weight); Executive::initialize_block(&Header::new( @@ -1106,7 +1116,7 @@ mod tests { let runtime_upgrade_weight = ::on_runtime_upgrade(); let frame_system_on_initialize_weight = frame_system::Module::::on_initialize(block_number); let on_initialize_weight = >::on_initialize(block_number); - let base_block_weight = ::BlockExecutionWeight::get(); + let base_block_weight = ::BlockWeights::get().base_block; // Weights are recorded correctly assert_eq!( diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index fd731c9cda3..4a5de63e839 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -74,13 +74,15 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -92,13 +94,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; @@ -224,7 +219,7 @@ impl pallet_staking::Config for Test { } parameter_types! { - pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block; } impl pallet_offences::Config for Test { diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index c0afffc0524..959107e527a 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -1134,3 +1134,4 @@ impl Module { .collect() } } + diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index aefce1f8ff6..7f3a95dcd12 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -21,13 +21,13 @@ use super::*; use sp_runtime::traits::BadOrigin; use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, + assert_ok, assert_noop, impl_outer_origin, parameter_types, ord_parameter_types, }; use sp_core::H256; use frame_system::{EnsureSignedBy, EnsureOneOf, EnsureRoot}; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, + testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; impl_outer_origin! { @@ -38,12 +38,13 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -55,13 +56,7 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 9a049a47188..0a6dc1f79c0 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -27,7 +27,7 @@ use sp_staking::{SessionIndex, offence::{ReportOffence, OffenceError}}; use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; use sp_runtime::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; use sp_core::H256; -use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; impl_outer_origin!{ pub enum Origin for Runtime {} @@ -104,13 +104,15 @@ pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -122,13 +124,6 @@ impl frame_system::Config for Runtime { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index dbbde888c16..63f0277548f 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -20,9 +20,8 @@ #![cfg(test)] use sp_runtime::testing::Header; -use sp_runtime::Perbill; use sp_core::H256; -use frame_support::{impl_outer_origin, impl_outer_event, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; use crate::{self as indices, Module, Config}; use frame_system as system; use pallet_balances as balances; @@ -44,13 +43,15 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = (); type Index = u64; @@ -62,13 +63,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 60cd7ae1eda..cfdc38752b5 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -279,11 +279,11 @@ mod tests { use super::*; use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, + assert_ok, assert_noop, impl_outer_origin, parameter_types, ord_parameter_types }; use sp_core::H256; - use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; + use sp_runtime::{traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; use frame_system::EnsureSignedBy; impl_outer_origin! { @@ -294,14 +294,16 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); pub static Members: Vec = vec![]; pub static Prime: Option = None; } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -313,13 +315,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index 6e889518434..7a959ec37f2 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -23,10 +23,10 @@ use super::*; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, - weights::Weight, impl_outer_event, traits::Filter, + impl_outer_event, traits::Filter, }; use sp_core::H256; -use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use crate as multisig; impl_outer_origin! { @@ -55,12 +55,14 @@ impl_outer_dispatch! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -72,13 +74,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index e6658025042..2b74f323d87 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -241,13 +241,13 @@ mod tests { use super::*; use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, + assert_ok, assert_noop, impl_outer_origin, parameter_types, ord_parameter_types }; use sp_core::H256; use frame_system::EnsureSignedBy; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, + testing::Header, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, }; impl_outer_origin! { @@ -258,12 +258,14 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -275,13 +277,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index df6b391cc7a..9641bea116a 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -267,7 +267,7 @@ decl_module! { pub fn reset_well_known_nodes(origin, nodes: Vec<(PeerId, T::AccountId)>) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxWellKnownNodes::get() as usize, Error::::TooManyNodes); - + Self::initialize_nodes(&nodes); Self::deposit_event(RawEvent::NodesReset(nodes)); @@ -280,7 +280,7 @@ decl_module! { #[weight = T::WeightInfo::claim_node()] pub fn claim_node(origin, node: PeerId) { let sender = ensure_signed(origin)?; - + ensure!(node.0.len() < T::MaxPeerIdLength::get() as usize, Error::::PeerIdTooLong); ensure!(!Owners::::contains_key(&node),Error::::AlreadyClaimed); @@ -433,12 +433,12 @@ mod tests { use super::*; use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, weights::Weight, + assert_ok, assert_noop, impl_outer_origin, parameter_types, ord_parameter_types, }; use frame_system::EnsureSignedBy; use sp_core::H256; - use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; + use sp_runtime::{traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; impl_outer_origin! { pub enum Origin for Test where system = frame_system {} @@ -449,12 +449,12 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Config for Test { type BaseCallFilter = (); + type DbWeight = (); + type BlockWeights = (); + type BlockLength = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -466,13 +466,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 269324033bb..e55d7ac8e3a 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -37,11 +37,15 @@ type BlockNumber = u64; type Balance = u64; parameter_types! { - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(2 * WEIGHT_PER_SECOND); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -53,18 +57,11 @@ impl frame_system::Config for Test { type Header = sp_runtime::testing::Header; type Event = Event; type BlockHashCount = (); - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type AvailableBlockRatio = (); - type MaximumBlockLength = (); type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (Balances,); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = (); type SystemWeightInfo = (); } parameter_types! { @@ -184,7 +181,7 @@ impl pallet_im_online::Config for Test { } parameter_types! { - pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * BlockWeights::get().max_block; } impl pallet_offences::Config for Test { diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 690db58a871..124b0030294 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -91,12 +91,14 @@ pub fn set_offence_weight(new: Weight) { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(2 * WEIGHT_PER_SECOND); } impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = RocksDbWeight; type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -108,13 +110,6 @@ impl frame_system::Config for Runtime { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = RocksDbWeight; - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); @@ -124,7 +119,8 @@ impl frame_system::Config for Runtime { } parameter_types! { - pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); + pub OffencesWeightSoftLimit: Weight = + Perbill::from_percent(60) * BlockWeights::get().max_block; } impl Config for Runtime { diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 3d707d23836..7a59cdc648a 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -727,6 +727,6 @@ pub mod migration { deposit, )) ); - T::MaximumBlockWeight::get() + T::BlockWeights::get().max_block } } diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index 0338b983595..08211052356 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -23,11 +23,11 @@ use super::*; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, - weights::Weight, impl_outer_event, RuntimeDebug, dispatch::DispatchError, traits::Filter, + impl_outer_event, RuntimeDebug, dispatch::DispatchError, traits::Filter, }; use codec::{Encode, Decode}; use sp_core::H256; -use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use crate as proxy; impl_outer_origin! { @@ -57,12 +57,14 @@ impl_outer_dispatch! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -74,13 +76,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index ffa4da978a8..7e0e64f3cc0 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -135,12 +135,12 @@ mod tests { use super::*; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, Header as _, IdentityLookup}, }; + use frame_system::limits; use frame_support::{ - impl_outer_origin, parameter_types, weights::Weight, traits::{Randomness, OnInitialize}, + impl_outer_origin, parameter_types, traits::{Randomness, OnInitialize}, }; #[derive(Clone, PartialEq, Eq)] @@ -152,13 +152,17 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: limits::BlockWeights = limits::BlockWeights + ::simple_max(1024); + pub BlockLength: limits::BlockLength = limits::BlockLength + ::max(2 * 1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = BlockLength; + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -170,13 +174,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 9f15f31bd42..9b991987cee 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -21,12 +21,11 @@ use super::*; use frame_support::{ impl_outer_origin, impl_outer_dispatch, impl_outer_event, parameter_types, - weights::Weight, traits::{OnInitialize, OnFinalize}, }; use sp_core::H256; use sp_runtime::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; use crate as recovery; @@ -53,13 +52,15 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = Call; type Index = u64; @@ -71,13 +72,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 4cdfe4ddf04..9f0f806233d 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -812,12 +812,14 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 2_000_000_000_000; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(2_000_000_000_000); } impl system::Config for Test { type BaseCallFilter = BaseFilter; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = RocksDbWeight; type Origin = Origin; type Call = Call; type Index = u64; @@ -829,13 +831,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = RocksDbWeight; - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); @@ -847,7 +842,7 @@ mod tests { type Event = (); } parameter_types! { - pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; pub const MaxScheduledPerBlock: u32 = 10; } ord_parameter_types! { diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 537084bb394..7d49136cef4 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -20,10 +20,10 @@ use super::*; use std::cell::RefCell; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight, ord_parameter_types}; +use frame_support::{impl_outer_origin, parameter_types, ord_parameter_types}; use sp_core::H256; use sp_runtime::{ - Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, + traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; use frame_system::EnsureSignedBy; @@ -36,13 +36,10 @@ pub struct Test; parameter_types! { pub const CandidateDeposit: u64 = 25; pub const Period: u64 = 4; - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const ExistentialDeposit: u64 = 1; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } ord_parameter_types! { pub const KickOrigin: u64 = 2; @@ -51,6 +48,9 @@ ord_parameter_types! { impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -62,13 +62,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index af3112823d9..9001dee8790 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -47,6 +47,9 @@ pub struct Test; impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -58,13 +61,6 @@ impl frame_system::Config for Test { type Header = sp_runtime::testing::Header; type Event = (); type BlockHashCount = (); - type MaximumBlockWeight = (); - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = (); - type AvailableBlockRatio = (); - type MaximumBlockLength = (); type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 40ae5bed83e..883a0cc5ab2 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -549,7 +549,7 @@ decl_module! { fn on_initialize(n: T::BlockNumber) -> Weight { if T::ShouldEndSession::should_end_session(n) { Self::rotate_session(); - T::MaximumBlockWeight::get() + T::BlockWeights::get().max_block } else { // NOTE: the non-database part of the weight for `should_end_session(n)` is // included as weight for empty block, the database part is expected to be in diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index d485565db23..0a7f89f5d57 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -19,7 +19,7 @@ use super::*; use std::cell::RefCell; -use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use frame_support::{impl_outer_origin, parameter_types}; use sp_core::{crypto::key_types::DUMMY, H256}; use sp_runtime::{ Perbill, impl_opaque_keys, @@ -165,15 +165,17 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pub struct Test; parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; pub const MinimumPeriod: u64 = 5; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -185,13 +187,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 7859f6659cf..6fe8a2673b2 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -533,7 +533,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn bid(origin, value: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::Suspended); @@ -572,7 +572,7 @@ decl_module! { /// /// Total Complexity: O(B + X) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn unbid(origin, pos: u32) -> DispatchResult { let who = ensure_signed(origin)?; @@ -642,7 +642,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn vouch(origin, who: T::AccountId, value: BalanceOf, tip: BalanceOf) -> DispatchResult { let voucher = ensure_signed(origin)?; // Check user is not suspended. @@ -683,7 +683,7 @@ decl_module! { /// /// Total Complexity: O(B) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn unvouch(origin, pos: u32) -> DispatchResult { let voucher = ensure_signed(origin)?; ensure!(Self::vouching(&voucher) == Some(VouchingStatus::Vouching), Error::::NotVouching); @@ -721,7 +721,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + C) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn vote(origin, candidate: ::Source, approve: bool) { let voter = ensure_signed(origin)?; let candidate = T::Lookup::lookup(candidate)?; @@ -752,7 +752,7 @@ decl_module! { /// /// Total Complexity: O(M + logM) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn defender_vote(origin, approve: bool) { let voter = ensure_signed(origin)?; let members = >::get(); @@ -784,7 +784,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + P + X) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] pub fn payout(origin) { let who = ensure_signed(origin)?; @@ -826,7 +826,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] fn found(origin, founder: T::AccountId, max_members: u32, rules: Vec) { T::FounderSetOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::AlreadyFounded); @@ -853,7 +853,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] fn unfound(origin) { let founder = ensure_signed(origin)?; ensure!(Founder::::get() == Some(founder.clone()), Error::::NotFounder); @@ -895,7 +895,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] fn judge_suspended_member(origin, who: T::AccountId, forgive: bool) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; ensure!(>::contains_key(&who), Error::::NotSuspended); @@ -966,7 +966,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B + X) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] fn judge_suspended_candidate(origin, who: T::AccountId, judgement: Judgement) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; if let Some((value, kind)) = >::get(&who) { @@ -1026,7 +1026,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = T::MaximumBlockWeight::get() / 10] + #[weight = T::BlockWeights::get().max_block / 10] fn set_max_members(origin, max: u32) { ensure_root(origin)?; ensure!(max > 1, Error::::MaxMembers); @@ -1038,13 +1038,14 @@ decl_module! { let mut members = vec![]; let mut weight = 0; + let weights = T::BlockWeights::get(); // Run a candidate/membership rotation if (n % T::RotationPeriod::get()).is_zero() { members = >::get(); Self::rotate_period(&mut members); - weight += T::MaximumBlockWeight::get() / 20; + weight += weights.max_block / 20; } // Run a challenge rotation @@ -1055,7 +1056,7 @@ decl_module! { } Self::rotate_challenge(&mut members); - weight += T::MaximumBlockWeight::get() / 20; + weight += weights.max_block / 20; } weight diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index d4fa1bcfbc7..6a718c21850 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -25,7 +25,6 @@ use frame_support::{ }; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; @@ -45,14 +44,11 @@ parameter_types! { pub const PeriodSpend: u64 = 1000; pub const MaxLockDuration: u64 = 100; pub const ChallengePeriod: u64 = 8; - pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const ExistentialDeposit: u64 = 1; pub const SocietyModuleId: ModuleId = ModuleId(*b"py/socie"); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } ord_parameter_types! { @@ -62,6 +58,9 @@ ord_parameter_types! { impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -73,13 +72,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type OnNewAccount = (); diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index ac9a2b23579..6f58d6a669d 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -45,11 +45,10 @@ pub struct Test; impl frame_system::Config for Test { type BaseCallFilter = (); - type Origin = Origin; + type BlockWeights = (); + type BlockLength = (); type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = (); + type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; type Call = Call; @@ -60,9 +59,6 @@ impl frame_system::Config for Test { type Header = sp_runtime::testing::Header; type Event = (); type BlockHashCount = (); - type MaximumBlockWeight = (); - type AvailableBlockRatio = (); - type MaximumBlockLength = (); type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index f6aedf760d9..d336bfd1ddd 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -521,7 +521,12 @@ benchmarks! { compact, score, size - ) = offchain_election::prepare_submission::(assignments, winners, false, T::MaximumBlockWeight::get()).unwrap(); + ) = offchain_election::prepare_submission::( + assignments, + winners, + false, + T::BlockWeights::get().max_block, + ).unwrap(); assert_eq!( winners.len(), compact.unique_targets().len(), @@ -589,7 +594,12 @@ benchmarks! { compact, score, size - ) = offchain_election::prepare_submission::(assignments, winners, false, T::MaximumBlockWeight::get()).unwrap(); + ) = offchain_election::prepare_submission::( + assignments, + winners, + false, + T::BlockWeights::get().max_block, + ).unwrap(); assert_eq!( winners.len(), compact.unique_targets().len(), diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 4bc1921c494..5deae116e5c 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -129,9 +129,10 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = frame_support::weights::constants::WEIGHT_PER_SECOND * 2; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max( + frame_support::weights::constants::WEIGHT_PER_SECOND * 2 + ); pub const MaxLocks: u32 = 1024; pub static SessionsPerEra: SessionIndex = 3; pub static ExistentialDeposit: Balance = 0; @@ -143,6 +144,9 @@ parameter_types! { impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = RocksDbWeight; type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -154,13 +158,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = MetaEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = RocksDbWeight; - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; @@ -235,7 +232,7 @@ parameter_types! { pub const MaxNominatorRewardedPerValidator: u32 = 64; pub const UnsignedPriority: u64 = 1 << 20; pub const MinSolutionScoreBump: Perbill = Perbill::zero(); - pub const OffchainSolutionWeightLimit: Weight = MaximumBlockWeight::get(); + pub OffchainSolutionWeightLimit: Weight = BlockWeights::get().max_block; } thread_local! { diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index 9b6df1f2d48..2f198166d7e 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -301,7 +301,7 @@ pub fn get_seq_phragmen_solution( assignments, winners, do_reduce, - T::MaximumBlockWeight::get(), + T::BlockWeights::get().max_block, ) .unwrap() } diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index c21f7895264..12707d3e9da 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -23,10 +23,11 @@ use frame_support::{ weights::Weight, }; use sp_core::H256; -use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use sp_io; use crate as sudo; use frame_support::traits::Filter; +use frame_system::limits; // Logger module to track execution. pub mod logger { @@ -106,9 +107,7 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: limits::BlockWeights = limits::BlockWeights::simple_max(1024); } pub struct BlockEverything; @@ -120,6 +119,9 @@ impl Filter for BlockEverything { impl frame_system::Config for Test { type BaseCallFilter = BlockEverything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Call = Call; type Index = u64; @@ -131,13 +133,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 6a62befd6d5..d4dda427ef1 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -213,6 +213,9 @@ impl Default for Pays { } /// A generalized group of dispatch types. +/// +/// NOTE whenever upgrading the enum make sure to also update +/// [DispatchClass::all] and [DispatchClass::non_mandatory] helper functions. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] @@ -242,6 +245,39 @@ impl Default for DispatchClass { } } +impl DispatchClass { + /// Returns an array containing all dispatch classes. + pub fn all() -> &'static [DispatchClass] { + &[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory] + } + + /// Returns an array of all dispatch classes except `Mandatory`. + pub fn non_mandatory() -> &'static [DispatchClass] { + &[DispatchClass::Normal, DispatchClass::Operational] + } +} + +/// A trait that represents one or many values of given type. +/// +/// Useful to accept as parameter type to let the caller pass either a single value directly +/// or an iterator. +pub trait OneOrMany { + /// The iterator type. + type Iter: Iterator; + /// Convert this item into an iterator. + fn into_iter(self) -> Self::Iter; +} + +impl OneOrMany for DispatchClass { + type Iter = sp_std::iter::Once; + fn into_iter(self) -> Self::Iter { sp_std::iter::once(self) } +} + +impl<'a> OneOrMany for &'a [DispatchClass] { + type Iter = sp_std::iter::Cloned>; + fn into_iter(self) -> Self::Iter { self.iter().cloned() } +} + /// Primitives related to priority management of Frame. pub mod priority { /// The starting point of all Operational transactions. 3/4 of u64::max_value(). @@ -695,6 +731,87 @@ impl WeightToFeePolynomial for IdentityFee where } } +/// A struct holding value for each `DispatchClass`. +#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] +pub struct PerDispatchClass { + /// Value for `Normal` extrinsics. + normal: T, + /// Value for `Operational` extrinsics. + operational: T, + /// Value for `Mandatory` extrinsics. + mandatory: T, +} + +impl PerDispatchClass { + /// Create new `PerDispatchClass` with the same value for every class. + pub fn new(val: impl Fn(DispatchClass) -> T) -> Self { + Self { + normal: val(DispatchClass::Normal), + operational: val(DispatchClass::Operational), + mandatory: val(DispatchClass::Mandatory), + } + } + + /// Get a mutable reference to current value of given class. + pub fn get_mut(&mut self, class: DispatchClass) -> &mut T { + match class { + DispatchClass::Operational => &mut self.operational, + DispatchClass::Normal => &mut self.normal, + DispatchClass::Mandatory => &mut self.mandatory, + } + } + + /// Get current value for given class. + pub fn get(&self, class: DispatchClass) -> &T { + match class { + DispatchClass::Normal => &self.normal, + DispatchClass::Operational => &self.operational, + DispatchClass::Mandatory => &self.mandatory, + } + } +} + +impl PerDispatchClass { + /// Set the value of given class. + pub fn set(&mut self, new: T, class: impl OneOrMany) { + for class in class.into_iter() { + *self.get_mut(class) = new.clone(); + } + } +} + +impl PerDispatchClass { + /// Returns the total weight consumed by all extrinsics in the block. + pub fn total(&self) -> Weight { + let mut sum = 0; + for class in DispatchClass::all() { + sum = sum.saturating_add(*self.get(*class)); + } + sum + } + + /// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`. + pub fn add(&mut self, weight: Weight, class: DispatchClass) { + let value = self.get_mut(class); + *value = value.saturating_add(weight); + } + + /// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would + /// occur. + pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> { + let value = self.get_mut(class); + *value = value.checked_add(weight).ok_or(())?; + Ok(()) + } + + /// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of + /// `Weight`. + pub fn sub(&mut self, weight: Weight, class: DispatchClass) { + let value = self.get_mut(class); + *value = value.saturating_sub(weight); + } +} + #[cfg(test)] #[allow(dead_code)] mod tests { diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs index 3bb5e0ce667..01b965f3b51 100644 --- a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -117,9 +117,6 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); } impl frame_system::Config for Runtime { @@ -135,13 +132,9 @@ mod tests { type Header = TestHeader; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; + type BlockWeights = (); + type BlockLength = (); type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index bedb99b9f89..49093174886 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -54,14 +54,22 @@ impl_outer_event! { frame_support::parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; - pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::with_sensible_defaults( + 4 * 1024 * 1024, Perbill::from_percent(75), + ); + pub BlockLength: frame_system::limits::BlockLength = + frame_system::limits::BlockLength::max_with_normal_ratio( + 4 * 1024 * 1024, Perbill::from_percent(75), + ); } #[derive(Clone, Eq, PartialEq)] pub struct Runtime; impl system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = BlockLength; + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -73,13 +81,6 @@ impl system::Config for Runtime { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index 1f543754336..ae898a6ecaa 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -25,8 +25,10 @@ use sp_std::prelude::*; use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use sp_runtime::traits::Hash; use frame_benchmarking::{benchmarks, whitelisted_caller}; -use frame_support::traits::Get; -use frame_support::storage::{self, StorageMap}; +use frame_support::{ + storage::{self, StorageMap}, + traits::Get, +}; use frame_system::{Module as System, Call, RawOrigin, DigestItemOf, AccountInfo}; mod mock; @@ -38,7 +40,7 @@ benchmarks! { _ { } remark { - let b in 0 .. T::MaximumBlockLength::get(); + let b in 0 .. T::BlockWeights::get().max_block as u32; let remark_message = vec![1; b as usize]; let caller = whitelisted_caller(); }: _(RawOrigin::Signed(caller), remark_message) diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index b6ebecc9bb0..8cfd70b2f09 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -52,6 +52,9 @@ pub struct Test; impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -63,13 +66,6 @@ impl frame_system::Config for Test { type Header = sp_runtime::testing::Header; type Event = (); type BlockHashCount = (); - type MaximumBlockWeight = (); - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = (); - type AvailableBlockRatio = (); - type MaximumBlockLength = (); type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 6dfff865d45..fc74b03a61c 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Config, Module}; +use crate::{limits::BlockWeights, Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::{SignedExtension, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Printable}, @@ -23,7 +23,7 @@ use sp_runtime::{ ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, TransactionPriority, }, - Perbill, DispatchResult, + DispatchResult, }; use frame_support::{ traits::{Get}, @@ -36,52 +36,19 @@ use frame_support::{ pub struct CheckWeight(sp_std::marker::PhantomData); impl CheckWeight where - T::Call: Dispatchable + T::Call: Dispatchable, { - /// Get the quota ratio of each dispatch class type. This indicates that all operational and mandatory - /// dispatches can use the full capacity of any resource, while user-triggered ones can consume - /// a portion. - fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill { - match class { - DispatchClass::Operational | DispatchClass::Mandatory - => ::one(), - DispatchClass::Normal => T::AvailableBlockRatio::get(), - } - } - - /// Checks if the current extrinsic does not exceed `MaximumExtrinsicWeight` limit. + /// Checks if the current extrinsic does not exceed the maximum weight a single extrinsic + /// with given `DispatchClass` can have. fn check_extrinsic_weight( info: &DispatchInfoOf, ) -> Result<(), TransactionValidityError> { - match info.class { - // Mandatory transactions are included in a block unconditionally, so - // we don't verify weight. - DispatchClass::Mandatory => Ok(()), - // Normal transactions must not exceed `MaximumExtrinsicWeight`. - DispatchClass::Normal => { - let maximum_weight = T::MaximumExtrinsicWeight::get(); - let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); - if extrinsic_weight > maximum_weight { - Err(InvalidTransaction::ExhaustsResources.into()) - } else { - Ok(()) - } - }, - // For operational transactions we make sure it doesn't exceed - // the space alloted for `Operational` class. - DispatchClass::Operational => { - let maximum_weight = T::MaximumBlockWeight::get(); - let operational_limit = - Self::get_dispatch_limit_ratio(DispatchClass::Operational) * maximum_weight; - let operational_limit = - operational_limit.saturating_sub(T::BlockExecutionWeight::get()); - let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); - if extrinsic_weight > operational_limit { - Err(InvalidTransaction::ExhaustsResources.into()) - } else { - Ok(()) - } + let max = T::BlockWeights::get().get(info.class).max_extrinsic; + match max { + Some(max) if info.weight > max => { + Err(InvalidTransaction::ExhaustsResources.into()) }, + _ => Ok(()), } } @@ -90,51 +57,10 @@ impl CheckWeight where /// Upon successes, it returns the new block weight as a `Result`. fn check_block_weight( info: &DispatchInfoOf, - ) -> Result { - let maximum_weight = T::MaximumBlockWeight::get(); - let mut all_weight = Module::::block_weight(); - match info.class { - // If we have a dispatch that must be included in the block, it ignores all the limits. - DispatchClass::Mandatory => { - let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); - all_weight.add(extrinsic_weight, DispatchClass::Mandatory); - Ok(all_weight) - }, - // If we have a normal dispatch, we follow all the normal rules and limits. - DispatchClass::Normal => { - let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; - let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) - .ok_or(InvalidTransaction::ExhaustsResources)?; - all_weight.checked_add(extrinsic_weight, DispatchClass::Normal) - .map_err(|_| InvalidTransaction::ExhaustsResources)?; - if all_weight.get(DispatchClass::Normal) > normal_limit { - Err(InvalidTransaction::ExhaustsResources.into()) - } else { - Ok(all_weight) - } - }, - // If we have an operational dispatch, allow it if we have not used our full - // "operational space" (independent of existing fullness). - DispatchClass::Operational => { - let operational_limit = Self::get_dispatch_limit_ratio(DispatchClass::Operational) * maximum_weight; - let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; - let operational_space = operational_limit.saturating_sub(normal_limit); - - let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) - .ok_or(InvalidTransaction::ExhaustsResources)?; - all_weight.checked_add(extrinsic_weight, DispatchClass::Operational) - .map_err(|_| InvalidTransaction::ExhaustsResources)?; - - // If it would fit in normally, its okay - if all_weight.total() <= maximum_weight || - // If we have not used our operational space - all_weight.get(DispatchClass::Operational) <= operational_space { - Ok(all_weight) - } else { - Err(InvalidTransaction::ExhaustsResources.into()) - } - } - } + ) -> Result { + let maximum_weight = T::BlockWeights::get(); + let all_weight = Module::::block_weight(); + calculate_consumed_weight::(maximum_weight, all_weight, info) } /// Checks if the current extrinsic can fit into the block with respect to block length limits. @@ -144,19 +70,18 @@ impl CheckWeight where info: &DispatchInfoOf, len: usize, ) -> Result { + let length_limit = T::BlockLength::get(); let current_len = Module::::all_extrinsics_len(); - let maximum_len = T::MaximumBlockLength::get(); - let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_len; let added_len = len as u32; let next_len = current_len.saturating_add(added_len); - if next_len > limit { + if next_len > *length_limit.max.get(info.class) { Err(InvalidTransaction::ExhaustsResources.into()) } else { Ok(next_len) } } - /// get the priority of an extrinsic denoted by `info`. + /// Get the priority of an extrinsic denoted by `info`. /// /// Operational transaction will be given a fixed initial amount to be fairly distinguished from /// the normal ones. @@ -213,6 +138,53 @@ impl CheckWeight where } } +pub fn calculate_consumed_weight( + maximum_weight: BlockWeights, + mut all_weight: crate::ConsumedWeight, + info: &DispatchInfoOf, +) -> Result where + Call: Dispatchable, +{ + let extrinsic_weight = info.weight.saturating_add(maximum_weight.get(info.class).base_extrinsic); + let limit_per_class = maximum_weight.get(info.class); + + // add the weight. If class is unlimited, use saturating add instead of checked one. + if limit_per_class.max_total.is_none() && limit_per_class.reserved.is_none() { + all_weight.add(extrinsic_weight, info.class) + } else { + all_weight.checked_add(extrinsic_weight, info.class) + .map_err(|_| InvalidTransaction::ExhaustsResources)?; + } + + let per_class = *all_weight.get(info.class); + + // Check if we don't exceed per-class allowance + match limit_per_class.max_total { + Some(max) if per_class > max => { + return Err(InvalidTransaction::ExhaustsResources.into()); + }, + // There is no `max_total` limit (`None`), + // or we are below the limit. + _ => {}, + } + + // In cases total block weight is exceeded, we need to fall back + // to `reserved` pool if there is any. + if all_weight.total() > maximum_weight.max_block { + match limit_per_class.reserved { + // We are over the limit in reserved pool. + Some(reserved) if per_class > reserved => { + return Err(InvalidTransaction::ExhaustsResources.into()); + } + // There is either no limit in reserved pool (`None`), + // or we are below the limit. + _ => {}, + } + } + + Ok(all_weight) +} + impl SignedExtension for CheckWeight where T::Call: Dispatchable { @@ -277,7 +249,7 @@ impl SignedExtension for CheckWeight where // to them actually being useful. Block producers are thus not allowed to include mandatory // extrinsics that result in error. if let (DispatchClass::Mandatory, Err(e)) = (info.class, result) { - "Bad mandantory".print(); + "Bad mandatory".print(); e.print(); Err(InvalidTransaction::BadMandatory)? @@ -315,12 +287,21 @@ mod tests { use frame_support::{assert_ok, assert_noop}; use frame_support::weights::{Weight, Pays}; + fn block_weights() -> crate::limits::BlockWeights { + ::BlockWeights::get() + } + fn normal_weight_limit() -> Weight { - ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() + block_weights().get(DispatchClass::Normal).max_total + .unwrap_or_else(|| block_weights().max_block) + } + + fn block_weight_limit() -> Weight { + block_weights().max_block } fn normal_length_limit() -> u32 { - ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() + *::BlockLength::get().max.get(DispatchClass::Normal) } #[test] @@ -341,7 +322,7 @@ mod tests { check(|max, len| { assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > block_weight_limit()); }); check(|max, len| { assert_ok!(CheckWeight::::do_validate(max, len)); @@ -352,7 +333,7 @@ mod tests { fn normal_extrinsic_limited_by_maximum_extrinsic_weight() { new_test_ext().execute_with(|| { let max = DispatchInfo { - weight: ::MaximumExtrinsicWeight::get() + 1, + weight: block_weights().get(DispatchClass::Normal).max_extrinsic.unwrap() + 1, class: DispatchClass::Normal, ..Default::default() }; @@ -368,13 +349,12 @@ mod tests { #[test] fn operational_extrinsic_limited_by_operational_space_limit() { new_test_ext().execute_with(|| { - let operational_limit = CheckWeight::::get_dispatch_limit_ratio( - DispatchClass::Operational - ) * ::MaximumBlockWeight::get(); - let base_weight = ::ExtrinsicBaseWeight::get(); - let block_base = ::BlockExecutionWeight::get(); + let weights = block_weights(); + let operational_limit = weights.get(DispatchClass::Operational).max_total + .unwrap_or_else(|| weights.max_block); + let base_weight = weights.get(DispatchClass::Normal).base_extrinsic; - let weight = operational_limit - base_weight - block_base; + let weight = operational_limit - base_weight; let okay = DispatchInfo { weight, class: DispatchClass::Operational, @@ -406,7 +386,7 @@ mod tests { new_test_ext().execute_with(|| { System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Normal); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > block_weight_limit()); }); } @@ -426,8 +406,8 @@ mod tests { assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(System::block_weight().total(), 768); assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(block_weight_limit(), 1024); + assert_eq!(System::block_weight().total(), block_weight_limit()); // Checking single extrinsic should not take current block weight into account. assert_eq!(CheckWeight::::check_extrinsic_weight(&rest_operational), Ok(())); }); @@ -446,8 +426,8 @@ mod tests { // Extra 15 here from block execution + base extrinsic weight assert_eq!(System::block_weight().total(), 266); assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(block_weight_limit(), 1024); + assert_eq!(System::block_weight().total(), block_weight_limit()); }); } @@ -486,7 +466,7 @@ mod tests { // given almost full block BlockWeight::mutate(|current_weight| { - current_weight.put(normal_limit, DispatchClass::Normal) + current_weight.set(normal_limit, DispatchClass::Normal) }); // will not fit. assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); @@ -552,19 +532,20 @@ mod tests { new_test_ext().execute_with(|| { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; + let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic; let medium = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get(), + weight: normal_limit - base_extrinsic, ..Default::default() }; let big = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, + weight: normal_limit - base_extrinsic + 1, ..Default::default() }; let len = 0_usize; let reset_check_weight = |i, f, s| { BlockWeight::mutate(|current_weight| { - current_weight.put(s, DispatchClass::Normal) + current_weight.set(s, DispatchClass::Normal) }); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } @@ -586,10 +567,12 @@ mod tests { pays_fee: Default::default(), }; let len = 0_usize; + let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic; // We allow 75% for normal transaction, so we put 25% - extrinsic base weight BlockWeight::mutate(|current_weight| { - current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) + current_weight.set(0, DispatchClass::Mandatory); + current_weight.set(256 - base_extrinsic, DispatchClass::Normal); }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); @@ -617,13 +600,14 @@ mod tests { let len = 0_usize; BlockWeight::mutate(|current_weight| { - current_weight.put(128, DispatchClass::Normal) + current_weight.set(0, DispatchClass::Mandatory); + current_weight.set(128, DispatchClass::Normal); }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); assert!( @@ -632,7 +616,7 @@ mod tests { ); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); }) } @@ -640,17 +624,81 @@ mod tests { #[test] fn zero_weight_extrinsic_still_has_base_weight() { new_test_ext().execute_with(|| { + let weights = block_weights(); let free = DispatchInfo { weight: 0, ..Default::default() }; let len = 0_usize; - // Initial weight from `BlockExecutionWeight` - assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); + // Initial weight from `weights.base_block` + assert_eq!( + System::block_weight().total(), + weights.base_block + ); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); assert!(r.is_ok()); assert_eq!( System::block_weight().total(), - ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() + weights.get(DispatchClass::Normal).base_extrinsic + weights.base_block ); }) } + + #[test] + fn normal_and_mandatory_tracked_separately() { + new_test_ext().execute_with(|| { + // Max block is 1024 + // Max normal is 768 (75%) + // Max mandatory is unlimited + let max_normal = DispatchInfo { weight: 753, ..Default::default() }; + let mandatory = DispatchInfo { weight: 1019, class: DispatchClass::Mandatory, ..Default::default() }; + + let len = 0_usize; + + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + assert_eq!(System::block_weight().total(), 768); + assert_ok!(CheckWeight::::do_pre_dispatch(&mandatory, len)); + assert_eq!(block_weight_limit(), 1024); + assert_eq!(System::block_weight().total(), 1024 + 768); + assert_eq!(CheckWeight::::check_extrinsic_weight(&mandatory), Ok(())); + }); + } + + #[test] + fn no_max_total_should_still_be_limited_by_max_block() { + // given + let maximum_weight = BlockWeights::builder() + .base_block(0) + .for_class(DispatchClass::non_mandatory(), |w| { + w.base_extrinsic = 0; + w.max_total = Some(20); + }) + .for_class(DispatchClass::Mandatory, |w| { + w.base_extrinsic = 0; + w.reserved = Some(5); + w.max_total = None; + }) + .build_or_panic(); + let all_weight = crate::ConsumedWeight::new(|class| match class { + DispatchClass::Normal => 10, + DispatchClass::Operational => 10, + DispatchClass::Mandatory => 0, + }); + assert_eq!(maximum_weight.max_block, all_weight.total()); + + // fits into reserved + let mandatory1 = DispatchInfo { weight: 5, class: DispatchClass::Mandatory, ..Default::default() }; + // does not fit into reserved and the block is full. + let mandatory2 = DispatchInfo { weight: 6, class: DispatchClass::Mandatory, ..Default::default() }; + + // when + let result1 = calculate_consumed_weight::<::Call>( + maximum_weight.clone(), all_weight.clone(), &mandatory1 + ); + let result2 = calculate_consumed_weight::<::Call>( + maximum_weight, all_weight, &mandatory2 + ); + + // then + assert!(result2.is_err()); + assert!(result1.is_ok()); + } } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 3c13ac55397..7273ca09aab 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -122,7 +122,7 @@ use frame_support::{ }, weights::{ Weight, RuntimeDbWeight, DispatchInfo, DispatchClass, - extract_actual_weight, + extract_actual_weight, PerDispatchClass, }, dispatch::DispatchResultWithPostInfo, }; @@ -132,15 +132,16 @@ use codec::{Encode, Decode, FullCodec, EncodeLike}; use sp_io::TestExternalities; pub mod offchain; +pub mod limits; #[cfg(test)] pub(crate) mod mock; mod extensions; -mod weight; pub mod weights; #[cfg(test)] mod tests; + pub use extensions::{ check_mortality::CheckMortality, check_genesis::CheckGenesis, check_nonce::CheckNonce, check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, @@ -160,11 +161,20 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { H::ordered_trie_root(xts) } +/// An object to track the currently used extrinsic weight in a block. +pub type ConsumedWeight = PerDispatchClass; + pub trait Config: 'static + Eq + Clone { /// The basic call filter to use in Origin. All origins are built with this filter as base, /// except Root. type BaseCallFilter: Filter; + /// Block & extrinsics weights: base values and limits. + type BlockWeights: Get; + + /// The maximum length of a block (in bytes). + type BlockLength: Get; + /// The `Origin` type used by dispatchable calls. type Origin: Into, Self::Origin>> @@ -219,31 +229,9 @@ pub trait Config: 'static + Eq + Clone { /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount: Get; - /// The maximum weight of a block. - type MaximumBlockWeight: Get; - /// The weight of runtime database operations the runtime can invoke. type DbWeight: Get; - /// The base weight of executing a block, independent of the transactions in the block. - type BlockExecutionWeight: Get; - - /// The base weight of an Extrinsic in the block, independent of the of extrinsic being executed. - type ExtrinsicBaseWeight: Get; - - /// The maximal weight of a single Extrinsic. This should be set to at most - /// `MaximumBlockWeight - AverageOnInitializeWeight`. The limit only applies to extrinsics - /// containing `Normal` dispatch class calls. - type MaximumExtrinsicWeight: Get; - - /// The maximum length of a block (in bytes). - type MaximumBlockLength: Get; - - /// The portion of the block that is available to normal transaction. The rest can only be used - /// by operational transactions. This can be applied to any resource limit managed by the system - /// module, including weight and length. - type AvailableBlockRatio: Get; - /// Get the chain's current version. type Version: Get; @@ -399,7 +387,7 @@ decl_storage! { ExtrinsicCount: Option; /// The current weight for the block. - BlockWeight get(fn block_weight): weight::ExtrinsicsWeight; + BlockWeight get(fn block_weight): ConsumedWeight; /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; @@ -519,20 +507,11 @@ decl_module! { /// The maximum number of blocks to allow in mortal eras. const BlockHashCount: T::BlockNumber = T::BlockHashCount::get(); - /// The maximum weight of a block. - const MaximumBlockWeight: Weight = T::MaximumBlockWeight::get(); - /// The weight of runtime database operations the runtime can invoke. const DbWeight: RuntimeDbWeight = T::DbWeight::get(); - /// The base weight of executing a block, independent of the transactions in the block. - const BlockExecutionWeight: Weight = T::BlockExecutionWeight::get(); - - /// The base weight of an Extrinsic in the block, independent of the of extrinsic being executed. - const ExtrinsicBaseWeight: Weight = T::ExtrinsicBaseWeight::get(); - - /// The maximum length of a block (in bytes). - const MaximumBlockLength: u32 = T::MaximumBlockLength::get(); + /// The weight configuration (limits & base values) for each class of extrinsics and block. + const BlockWeights: limits::BlockWeights = T::BlockWeights::get(); fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { @@ -540,16 +519,22 @@ decl_module! { Some(AccountInfo { nonce, refcount: rc as RefCount, data }) ); UpgradedToU32RefCount::put(true); - T::MaximumBlockWeight::get() + T::BlockWeights::get().max_block } else { 0 } } + fn integrity_test() { + T::BlockWeights::get() + .validate() + .expect("The weights are invalid."); + } + /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). - #[weight = *_ratio * T::MaximumBlockWeight::get()] + #[weight = *_ratio * T::BlockWeights::get().max_block] fn fill_block(origin, _ratio: Perbill) { ensure_root(origin)?; } @@ -590,7 +575,7 @@ decl_module! { /// The weight of this function is dependent on the runtime, but generally this is very expensive. /// We will treat this as a full block. /// # - #[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)] + #[weight = (T::BlockWeights::get().max_block, DispatchClass::Operational)] pub fn set_code(origin, code: Vec) { ensure_root(origin)?; Self::can_set_code(&code)?; @@ -607,7 +592,7 @@ decl_module! { /// - 1 event. /// The weight of this function is dependent on the runtime. We will treat this as a full block. /// # - #[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)] + #[weight = (T::BlockWeights::get().max_block, DispatchClass::Operational)] pub fn set_code_without_checks(origin, code: Vec) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); @@ -1120,9 +1105,9 @@ impl Module { /// Set the current block weight. This should only be used in some integration tests. #[cfg(any(feature = "std", test))] - pub fn set_block_limits(weight: Weight, len: usize) { + pub fn set_block_consumed_resources(weight: Weight, len: usize) { BlockWeight::mutate(|current_weight| { - current_weight.put(weight, DispatchClass::Normal) + current_weight.set(weight, DispatchClass::Normal) }); AllExtrinsicsLen::put(len as u32); } @@ -1348,7 +1333,6 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S } } - impl IsDeadAccount for Module { fn is_dead_account(who: &T::AccountId) -> bool { !Account::::contains_key(who) diff --git a/frame/system/src/limits.rs b/frame/system/src/limits.rs new file mode 100644 index 00000000000..aac347b8e65 --- /dev/null +++ b/frame/system/src/limits.rs @@ -0,0 +1,434 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! Block resource limits configuration structures. +//! +//! FRAME defines two resources that are limited within a block: +//! - Weight (execution cost/time) +//! - Length (block size) +//! +//! `frame_system` tracks consumption of each of these resources separately for each +//! `DispatchClass`. This module contains configuration object for both resources, +//! which should be passed to `frame_system` configuration when runtime is being set up. + +use frame_support::weights::{Weight, DispatchClass, constants, PerDispatchClass, OneOrMany}; +use sp_runtime::{RuntimeDebug, Perbill}; + +/// Block length limit configuration. +#[derive(RuntimeDebug, Clone)] +pub struct BlockLength { + /// Maximal total length in bytes for each extrinsic class. + /// + /// In the worst case, the total block length is going to be: + /// `MAX(max)` + pub max: PerDispatchClass, +} + +impl Default for BlockLength { + fn default() -> Self { + BlockLength::max_with_normal_ratio( + 5 * 1024 * 1024, + DEFAULT_NORMAL_RATIO, + ) + } +} + +impl BlockLength { + /// Create new `BlockLength` with `max` for every class. + pub fn max(max: u32) -> Self { + Self { + max: PerDispatchClass::new(|_| max), + } + } + + /// Create new `BlockLength` with `max` for `Operational` & `Mandatory` + /// and `normal * max` for `Normal`. + pub fn max_with_normal_ratio(max: u32, normal: Perbill) -> Self { + Self { + max: PerDispatchClass::new(|class| if class == DispatchClass::Normal { + normal * max + } else { + max + }), + } + } +} + +#[derive(Default, RuntimeDebug)] +pub struct ValidationErrors { + pub has_errors: bool, + #[cfg(feature = "std")] + pub errors: Vec, +} + +macro_rules! error_assert { + ($cond : expr, $err : expr, $format : expr $(, $params: expr )*$(,)*) => { + if !$cond { + $err.has_errors = true; + #[cfg(feature = "std")] + { $err.errors.push(format!($format $(, &$params )*)); } + } + } +} + +/// A result of validating `BlockWeights` correctness. +pub type ValidationResult = Result; + +/// A ratio of `Normal` dispatch class within block, used as default value for +/// `BlockWeight` and `BlockLength`. The `Default` impls are provided mostly for convenience +/// to use in tests. +const DEFAULT_NORMAL_RATIO: Perbill = Perbill::from_percent(75); + +/// `DispatchClass`-specific weight configuration. +#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode)] +pub struct WeightsPerClass { + /// Base weight of single extrinsic of given class. + pub base_extrinsic: Weight, + /// Maximal weight of single extrinsic. Should NOT include `base_extrinsic` cost. + /// + /// `None` indicates that this class of extrinsics doesn't have a limit. + pub max_extrinsic: Option, + /// Block maximal total weight for all extrinsics of given class. + /// + /// `None` indicates that weight sum of this class of extrinsics is not + /// restricted. Use this value carefully, since it might produce heavily oversized + /// blocks. + /// + /// In the worst case, the total weight consumed by the class is going to be: + /// `MAX(max_total) + MAX(reserved)`. + pub max_total: Option, + /// Block reserved allowance for all extrinsics of a particular class. + /// + /// Setting to `None` indicates that extrinsics of that class are allowed + /// to go over total block weight (but at most `max_total` for that class). + /// Setting to `Some(x)` guarantees that at least `x` weight of particular class + /// is processed in every block. + pub reserved: Option, +} + +/// Block weight limits & base values configuration. +/// +/// This object is responsible for defining weight limits and base weight values tracked +/// during extrinsic execution. +/// +/// Each block starts with `base_block` weight being consumed right away. Next up the +/// `on_initialize` pallet callbacks are invoked and their cost is added before any extrinsic +/// is executed. This cost is tracked as `Mandatory` dispatch class. +/// +/// | | `max_block` | | +/// | | | | +/// | | | | +/// | | | | +/// | | | #| `on_initialize` +/// | #| `base_block` | #| +/// |NOM| |NOM| +/// ||\_ Mandatory +/// |\__ Operational +/// \___ Normal +/// +/// The remaining capacity can be used to dispatch extrinsics. Note that each dispatch class +/// is being tracked separately, but the sum can't exceed `max_block` (except for `reserved`). +/// Below you can see a picture representing full block with 3 extrinsics (two `Operational` and +/// one `Normal`). Each class has it's own limit `max_total`, but also the sum cannot exceed +/// `max_block` value. +/// -- `Mandatory` limit (unlimited) +/// | # | | | +/// | # | `Ext3` | - - `Operational` limit +/// |# | `Ext2` |- - `Normal` limit +/// | # | `Ext1` | # | +/// | #| `on_initialize` | ##| +/// | #| `base_block` |###| +/// |NOM| |NOM| +/// +/// It should be obvious now that it's possible for one class to reach it's limit (say `Normal`), +/// while the block has still capacity to process more transactions (`max_block` not reached, +/// `Operational` transactions can still go in). Setting `max_total` to `None` disables the +/// per-class limit. This is generally highly recommended for `Mandatory` dispatch class, while it +/// can be dangerous for `Normal` class and should only be done with extra care and consideration. +/// +/// Often it's desirable for some class of transactions to be added to the block despite it being +/// full. For instance one might want to prevent high-priority `Normal` transactions from pushing +/// out lower-priority `Operational` transactions. In such cases you might add a `reserved` capacity +/// for given class. +/// _ +/// # \ +/// # `Ext8` - `reserved` +/// # _/ +/// | # | `Ext7 | - - `Operational` limit +/// |# | `Ext6` | | +/// |# | `Ext5` |-# - `Normal` limit +/// |# | `Ext4` |## | +/// | #| `on_initialize` |###| +/// | #| `base_block` |###| +/// |NOM| |NOM| +/// +/// In the above example, `Ext4-6` fill up the block almost up to `max_block`. `Ext7` would not fit +/// if there wasn't the extra `reserved` space for `Operational` transactions. Note that `max_total` +/// limit applies to `reserved` space as well (i.e. the sum of weights of `Ext7` & `Ext8` mustn't +/// exceed it). Setting `reserved` to `None` allows the extrinsics to always get into the block up +/// to their `max_total` limit. If `max_total` is set to `None` as well, all extrinsics witch +/// dispatchables of given class will always end up in the block (recommended for `Mandatory` +/// dispatch class). +/// +/// As a consequence of `reserved` space, total consumed block weight might exceed `max_block` +/// value, so this parameter should rather be thought of as "target block weight" than a hard limit. +#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode)] +pub struct BlockWeights { + /// Base weight of block execution. + pub base_block: Weight, + /// Maximal total weight consumed by all kinds of extrinsics (without `reserved` space). + pub max_block: Weight, + /// Weight limits for extrinsics of given dispatch class. + pub per_class: PerDispatchClass, +} + +impl Default for BlockWeights { + fn default() -> Self { + Self::with_sensible_defaults( + 1 * constants::WEIGHT_PER_SECOND, + DEFAULT_NORMAL_RATIO, + ) + } +} + +impl BlockWeights { + /// Get per-class weight settings. + pub fn get(&self, class: DispatchClass) -> &WeightsPerClass { + self.per_class.get(class) + } + + /// Verifies correctness of this `BlockWeights` object. + pub fn validate(self) -> ValidationResult { + fn or_max(w: Option) -> Weight { + w.unwrap_or_else(|| Weight::max_value()) + } + let mut error = ValidationErrors::default(); + + for class in DispatchClass::all() { + let weights = self.per_class.get(*class); + let max_for_class = or_max(weights.max_total); + let base_for_class = weights.base_extrinsic; + let reserved = or_max(weights.reserved); + // Make sure that if total is set it's greater than base_block && + // base_for_class + error_assert!( + (max_for_class > self.base_block && max_for_class > base_for_class) + || max_for_class == 0, + &mut error, + "[{:?}] {:?} (total) has to be greater than {:?} (base block) & {:?} (base extrinsic)", + class, max_for_class, self.base_block, base_for_class, + ); + // Max extrinsic can't be greater than max_for_class. + error_assert!( + weights.max_extrinsic.unwrap_or(0) <= max_for_class.saturating_sub(base_for_class), + &mut error, + "[{:?}] {:?} (max_extrinsic) can't be greater than {:?} (max for class)", + class, weights.max_extrinsic, + max_for_class.saturating_sub(base_for_class), + ); + // Max extrinsic should not be 0 + error_assert!( + weights.max_extrinsic.unwrap_or_else(|| Weight::max_value()) > 0, + &mut error, + "[{:?}] {:?} (max_extrinsic) must not be 0. Check base cost and average initialization cost.", + class, weights.max_extrinsic, + ); + // Make sure that if reserved is set it's greater than base_for_class. + error_assert!( + reserved > base_for_class || reserved == 0, + &mut error, + "[{:?}] {:?} (reserved) has to be greater than {:?} (base extrinsic) if set", + class, reserved, base_for_class, + ); + // Make sure max block is greater than max_total if it's set. + error_assert!( + self.max_block >= weights.max_total.unwrap_or(0), + &mut error, + "[{:?}] {:?} (max block) has to be greater than {:?} (max for class)", + class, self.max_block, weights.max_total, + ); + // Make sure we can fit at least one extrinsic. + error_assert!( + self.max_block > base_for_class + self.base_block, + &mut error, + "[{:?}] {:?} (max block) must fit at least one extrinsic {:?} (base weight)", + class, self.max_block, base_for_class + self.base_block, + ); + } + + if error.has_errors { + Err(error) + } else { + Ok(self) + } + } + + /// Create new weights definition, with both `Normal` and `Operational` + /// classes limited to given weight. + /// + /// Note there is no reservation for `Operational` class, so this constructor + /// is not suitable for production deployments. + pub fn simple_max(block_weight: Weight) -> Self { + Self::builder() + .base_block(0) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = 0; + }) + .for_class(DispatchClass::non_mandatory(), |weights| { + weights.max_total = block_weight.into(); + }) + .build() + .expect("We only specify max_total and leave base values as defaults; qed") + } + + /// Create a sensible default weights system given only expected maximal block weight and the + /// ratio that `Normal` extrinsics should occupy. + /// + /// Assumptions: + /// - Average block initialization is assumed to be `10%`. + /// - `Operational` transactions have reserved allowance (`1.0 - normal_ratio`) + pub fn with_sensible_defaults( + expected_block_weight: Weight, + normal_ratio: Perbill, + ) -> Self { + let normal_weight = normal_ratio * expected_block_weight; + Self::builder() + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = normal_weight.into(); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = expected_block_weight.into(); + weights.reserved = (expected_block_weight - normal_weight).into(); + }) + .avg_block_initialization(Perbill::from_percent(10)) + .build() + .expect("Sensible defaults are tested to be valid; qed") + } + + /// Start constructing new `BlockWeights` object. + /// + /// By default all kinds except of `Mandatory` extrinsics are disallowed. + pub fn builder() -> BlockWeightsBuilder { + BlockWeightsBuilder { + weights: BlockWeights { + base_block: constants::BlockExecutionWeight::get(), + max_block: 0, + per_class: PerDispatchClass::new(|class| { + let initial = if class == DispatchClass::Mandatory { None } else { Some(0) }; + WeightsPerClass { + base_extrinsic: constants::ExtrinsicBaseWeight::get(), + max_extrinsic: None, + max_total: initial, + reserved: initial, + } + }), + }, + init_cost: None, + } + } +} + +/// An opinionated builder for `Weights` object. +pub struct BlockWeightsBuilder { + weights: BlockWeights, + init_cost: Option, +} + +impl BlockWeightsBuilder { + /// Set base block weight. + pub fn base_block(mut self, base_block: Weight) -> Self { + self.weights.base_block = base_block; + self + } + + /// Average block initialization weight cost. + /// + /// This value is used to derive maximal allowed extrinsic weight for each + /// class, based on the allowance. + /// + /// This is to make sure that extrinsics don't stay forever in the pool, + /// because they could seamingly fit the block (since they are below `max_block`), + /// but the cost of calling `on_initialize` alway prevents them from being included. + pub fn avg_block_initialization(mut self, init_cost: Perbill) -> Self { + self.init_cost = Some(init_cost); + self + } + + /// Set parameters for particular class. + /// + /// Note: `None` values of `max_extrinsic` will be overwritten in `build` in case + /// `avg_block_initialization` rate is set to a non-zero value. + pub fn for_class( + mut self, + class: impl OneOrMany, + action: impl Fn(&mut WeightsPerClass), + ) -> Self { + for class in class.into_iter() { + action(self.weights.per_class.get_mut(class)); + } + self + } + + /// Construct the `BlockWeights` object. + pub fn build(self) -> ValidationResult { + // compute max extrinsic size + let Self { mut weights, init_cost } = self; + + // compute max block size. + for class in DispatchClass::all() { + weights.max_block = match weights.per_class.get(*class).max_total { + Some(max) if max > weights.max_block => max, + _ => weights.max_block, + }; + } + // compute max size of single extrinsic + if let Some(init_weight) = init_cost.map(|rate| rate * weights.max_block) { + for class in DispatchClass::all() { + let per_class = weights.per_class.get_mut(*class); + if per_class.max_extrinsic.is_none() && init_cost.is_some() { + per_class.max_extrinsic = per_class.max_total + .map(|x| x.saturating_sub(init_weight)) + .map(|x| x.saturating_sub(per_class.base_extrinsic)); + } + } + } + + // Validate the result + weights.validate() + } + + /// Construct the `BlockWeights` object or panic if it's invalid. + /// + /// This is a convenience method to be called whenever you construct a runtime. + pub fn build_or_panic(self) -> BlockWeights { + self.build().expect( + "Builder finished with `build_or_panic`; The panic is expected if runtime weights are not correct" + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn default_weights_are_valid() { + BlockWeights::default() + .validate() + .unwrap(); + } +} diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index b6e1a4f35af..1558a5ed397 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -34,12 +34,11 @@ impl_outer_origin! { #[derive(Clone, Eq, PartialEq, Debug, Default)] pub struct Test; +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +const MAX_BLOCK_WEIGHT: Weight = 1024; + parameter_types! { pub const BlockHashCount: u64 = 10; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumExtrinsicWeight: Weight = 768; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 1024; pub Version: RuntimeVersion = RuntimeVersion { spec_name: sp_version::create_runtime_str!("test"), impl_name: sp_version::create_runtime_str!("system-test"), @@ -49,12 +48,28 @@ parameter_types! { apis: sp_version::create_apis_vec!([]), transaction_version: 1, }; - pub const BlockExecutionWeight: Weight = 10; - pub const ExtrinsicBaseWeight: Weight = 5; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 10, write: 100, }; + pub RuntimeBlockWeights: limits::BlockWeights = limits::BlockWeights::builder() + .base_block(10) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = 5; + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAX_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAX_BLOCK_WEIGHT); + weights.reserved = Some( + MAX_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAX_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(Perbill::from_percent(0)) + .build_or_panic(); + pub RuntimeBlockLength: limits::BlockLength = + limits::BlockLength::max_with_normal_ratio(1024, NORMAL_DISPATCH_RATIO); } thread_local!{ @@ -82,6 +97,8 @@ impl Dispatchable for Call { impl Config for Test { type BaseCallFilter = (); + type BlockWeights = RuntimeBlockWeights; + type BlockLength = RuntimeBlockLength; type Origin = Origin; type Call = Call; type Index = u64; @@ -93,13 +110,7 @@ impl Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = DbWeight; - type BlockExecutionWeight = BlockExecutionWeight; - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type MaximumExtrinsicWeight = MaximumExtrinsicWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = Version; type PalletInfo = (); type AccountData = u32; @@ -118,7 +129,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = GenesisConfig::default().build_storage::().unwrap().into(); // Add to each test the initial weight of a block ext.execute_with(|| System::register_extra_weight_unchecked( - ::BlockExecutionWeight::get(), + ::BlockWeights::get().base_block, DispatchClass::Mandatory )); ext diff --git a/frame/system/src/weight.rs b/frame/system/src/weight.rs deleted file mode 100644 index 93295093c4f..00000000000 --- a/frame/system/src/weight.rs +++ /dev/null @@ -1,76 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 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 codec::{Encode, Decode}; -use frame_support::weights::{Weight, DispatchClass}; -use sp_runtime::RuntimeDebug; - -/// An object to track the currently used extrinsic weight in a block. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] -pub struct ExtrinsicsWeight { - normal: Weight, - operational: Weight, -} - -impl ExtrinsicsWeight { - /// Returns the total weight consumed by all extrinsics in the block. - pub fn total(&self) -> Weight { - self.normal.saturating_add(self.operational) - } - - /// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`. - pub fn add(&mut self, weight: Weight, class: DispatchClass) { - let value = self.get_mut(class); - *value = value.saturating_add(weight); - } - - /// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would - /// occur. - pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> { - let value = self.get_mut(class); - *value = value.checked_add(weight).ok_or(())?; - Ok(()) - } - - /// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of - /// `Weight`. - pub fn sub(&mut self, weight: Weight, class: DispatchClass) { - let value = self.get_mut(class); - *value = value.saturating_sub(weight); - } - - /// Get the current weight of a specific dispatch class. - pub fn get(&self, class: DispatchClass) -> Weight { - match class { - DispatchClass::Operational => self.operational, - DispatchClass::Normal | DispatchClass::Mandatory => self.normal, - } - } - - /// Get a mutable reference to the current weight of a specific dispatch class. - fn get_mut(&mut self, class: DispatchClass) -> &mut Weight { - match class { - DispatchClass::Operational => &mut self.operational, - DispatchClass::Normal | DispatchClass::Mandatory => &mut self.normal, - } - } - - /// Set the weight of a specific dispatch class. - pub fn put(&mut self, new: Weight, class: DispatchClass) { - *self.get_mut(class) = new; - } -} diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 66043cbe3aa..b62777832ab 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -292,10 +292,10 @@ impl UnixTime for Module { mod tests { use super::*; - use frame_support::{impl_outer_origin, assert_ok, parameter_types, weights::Weight}; + use frame_support::{impl_outer_origin, assert_ok, parameter_types}; use sp_io::TestExternalities; use sp_core::H256; - use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; pub fn new_test_ext() -> TestExternalities { let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -310,12 +310,14 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -327,13 +329,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = (); diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 554b2e801af..247755aa07c 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -40,7 +40,7 @@ use frame_support::{ traits::Get, weights::{ Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Pays, WeightToFeePolynomial, - WeightToFeeCoefficient, + WeightToFeeCoefficient, DispatchClass, }, dispatch::DispatchResult, }; @@ -158,14 +158,14 @@ impl Convert for TargetedFeeAdjustment::AvailableBlockRatio::get() * - ::MaximumBlockWeight::get(); - let normal_block_weight = - >::block_weight() - .get(frame_support::weights::DispatchClass::Normal) - .min(normal_max_weight); + let normal_max_weight = weights.get(DispatchClass::Normal).max_total + .unwrap_or_else(|| weights.max_block); + let current_block_weight = >::block_weight(); + let normal_block_weight = *current_block_weight + .get(DispatchClass::Normal) + .min(&normal_max_weight); let s = S::get(); let v = V::get(); @@ -257,13 +257,13 @@ decl_module! { fn integrity_test() { // given weight == u64, we build multipliers from `diff` of two weight values, which can - // at most be MaximumBlockWeight. Make sure that this can fit in a multiplier without + // at most be maximum block weight. Make sure that this can fit in a multiplier without // loss. use sp_std::convert::TryInto; assert!( ::max_value() >= Multiplier::checked_from_integer( - ::MaximumBlockWeight::get().try_into().unwrap() + T::BlockWeights::get().max_block.try_into().unwrap() ).unwrap(), ); @@ -272,9 +272,11 @@ decl_module! { // that if we collapse to minimum, the trend will be positive with a weight value // which is 1% more than the target. let min_value = T::FeeMultiplierUpdate::min(); - let mut target = - T::FeeMultiplierUpdate::target() * - (T::AvailableBlockRatio::get() * T::MaximumBlockWeight::get()); + let mut target = T::FeeMultiplierUpdate::target() * + T::BlockWeights::get().get(DispatchClass::Normal).max_total.expect( + "Setting `max_total` for `Normal` dispatch class is not compatible with \ + `transaction-payment` pallet." + ); // add 1 percent; let addition = target / 100; @@ -285,7 +287,7 @@ decl_module! { target += addition; sp_io::TestExternalities::new_empty().execute_with(|| { - >::set_block_limits(target, 0); + >::set_block_consumed_resources(target, 0); let next = T::FeeMultiplierUpdate::convert(min_value); assert!(next > min_value, "The minimum bound of the multiplier is too low. When \ block saturation is more than target by 1% and multiplier is minimal then \ @@ -357,7 +359,13 @@ impl Module where ) -> BalanceOf where T::Call: Dispatchable, { - Self::compute_fee_raw(len, info.weight, tip, info.pays_fee) + Self::compute_fee_raw( + len, + info.weight, + tip, + info.pays_fee, + info.class, + ) } /// Compute the actual post dispatch fee for a particular transaction. @@ -372,7 +380,13 @@ impl Module where ) -> BalanceOf where T::Call: Dispatchable, { - Self::compute_fee_raw(len, post_info.calc_actual_weight(info), tip, post_info.pays_fee(info)) + Self::compute_fee_raw( + len, + post_info.calc_actual_weight(info), + tip, + post_info.pays_fee(info), + info.class, + ) } fn compute_fee_raw( @@ -380,6 +394,7 @@ impl Module where weight: Weight, tip: BalanceOf, pays_fee: Pays, + class: DispatchClass, ) -> BalanceOf { if pays_fee == Pays::Yes { let len = >::from(len); @@ -394,7 +409,7 @@ impl Module where // final adjusted weight fee. let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee); - let base_fee = Self::weight_to_fee(T::ExtrinsicBaseWeight::get()); + let base_fee = Self::weight_to_fee(T::BlockWeights::get().get(class).base_extrinsic); base_fee .saturating_add(fixed_len_fee) .saturating_add(adjusted_weight_fee) @@ -407,7 +422,7 @@ impl Module where fn weight_to_fee(weight: Weight) -> BalanceOf { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. - let capped_weight = weight.min(::MaximumBlockWeight::get()); + let capped_weight = weight.min(T::BlockWeights::get().max_block); T::WeightToFee::calc(&capped_weight) } } @@ -471,8 +486,9 @@ impl ChargeTransactionPayment where /// that the transaction which consumes more resources (either length or weight) with the same /// `fee` ends up having lower priority. fn get_priority(len: usize, info: &DispatchInfoOf, final_fee: BalanceOf) -> TransactionPriority { - let weight_saturation = T::MaximumBlockWeight::get() / info.weight.max(1); - let len_saturation = T::MaximumBlockLength::get() as u64 / (len as u64).max(1); + let weight_saturation = T::BlockWeights::get().max_block / info.weight.max(1); + let max_block_length = *T::BlockLength::get().max.get(DispatchClass::Normal); + let len_saturation = max_block_length as u64 / (len as u64).max(1); let coefficient: BalanceOf = weight_saturation.min(len_saturation).saturated_into::>(); final_fee.saturating_mul(coefficient).saturated_into::() } @@ -571,6 +587,7 @@ mod tests { traits::{BlakeTwo256, IdentityLookup}, Perbill, }; + use std::cell::RefCell; use smallvec::smallvec; const CALL: &::Call = @@ -598,18 +615,36 @@ mod tests { pub enum Origin for Runtime {} } + thread_local! { + static EXTRINSIC_BASE_WEIGHT: RefCell = RefCell::new(0); + } + + pub struct BlockWeights; + impl Get for BlockWeights { + fn get() -> frame_system::limits::BlockWeights { + frame_system::limits::BlockWeights::builder() + .base_block(0) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = EXTRINSIC_BASE_WEIGHT.with(|v| *v.borrow()).into(); + }) + .for_class(DispatchClass::non_mandatory(), |weights| { + weights.max_total = 1024.into(); + }) + .build_or_panic() + } + } + parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub static ExtrinsicBaseWeight: u64 = 0; pub static TransactionByteFee: u64 = 1; pub static WeightToFee: u64 = 1; } impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -621,13 +656,6 @@ mod tests { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; @@ -841,7 +869,7 @@ mod tests { // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 + (10000 - ::BlockWeights::get().max_block) as u64 ); }); } @@ -939,7 +967,7 @@ mod tests { partial_fee: 5 * 2 /* base * weight_fee */ + len as u64 /* len * 1 */ - + info.weight.min(MaximumBlockWeight::get()) as u64 * 2 * 3 / 2 /* weight */ + + info.weight.min(BlockWeights::get().max_block) as u64 * 2 * 3 / 2 /* weight */ }, ); diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index bbc38ddc8f8..3cf1272a19e 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -22,12 +22,12 @@ use super::*; use std::cell::RefCell; use frame_support::{ - assert_noop, assert_ok, impl_outer_origin, impl_outer_event, parameter_types, weights::Weight, + assert_noop, assert_ok, impl_outer_origin, impl_outer_event, parameter_types, traits::{Contains, OnInitialize} }; use sp_core::H256; use sp_runtime::{ - Perbill, ModuleId, + ModuleId, testing::Header, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, }; @@ -55,12 +55,14 @@ impl_outer_event! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -72,13 +74,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 5c1cbaf94cb..95973a8823f 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -30,7 +30,7 @@ use frame_support::{ storage, }; use sp_core::H256; -use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use crate as utility; // example module to test behaviors. @@ -93,12 +93,14 @@ impl_outer_dispatch! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = Weight::max_value(); - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::max_value()); } impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -110,13 +112,6 @@ impl frame_system::Config for Test { type Header = Header; type Event = TestEvent; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; @@ -350,6 +345,7 @@ fn batch_early_exit_works() { #[test] fn batch_weight_calculation_doesnt_overflow() { + use sp_runtime::Perbill; new_test_ext().execute_with(|| { let big_call = Call::System(SystemCall::fill_block(Perbill::from_percent(50))); assert_eq!(big_call.get_dispatch_info().weight, Weight::max_value() / 2); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 4dbe27649ce..a7a8147a062 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -391,11 +391,10 @@ mod tests { use super::*; use frame_support::{ - assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, + assert_ok, assert_noop, impl_outer_origin, parameter_types, }; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup, Identity, BadOrigin}, }; @@ -409,12 +408,14 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } impl frame_system::Config for Test { type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -426,13 +427,6 @@ mod tests { type Header = Header; type Event = (); type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = pallet_balances::AccountData; diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index b4a69a491d5..da20f196b45 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -42,9 +42,11 @@ use sp_runtime::{ }, traits::{ BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, - GetNodeBlockType, GetRuntimeBlockType, NumberFor, Verify, IdentityLookup, + GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup, }, }; +#[cfg(feature = "std")] +use sp_runtime::traits::NumberFor; use sp_version::RuntimeVersion; pub use sp_core::hash::H256; #[cfg(any(feature = "std", test))] @@ -52,8 +54,9 @@ use sp_version::NativeVersion; use frame_support::{ impl_outer_origin, parameter_types, traits::KeyOwnerProofSystem, - weights::{RuntimeDbWeight, Weight}, + weights::RuntimeDbWeight, }; +use frame_system::limits::{BlockWeights, BlockLength}; use sp_inherents::{CheckInherentsResult, InherentData}; use cfg_if::cfg_if; @@ -427,17 +430,20 @@ impl From> for Event { parameter_types! { pub const BlockHashCount: BlockNumber = 2400; pub const MinimumPeriod: u64 = 5; - pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 100, write: 1000, }; - pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub RuntimeBlockLength: BlockLength = + BlockLength::max(4 * 1024 * 1024); + pub RuntimeBlockWeights: BlockWeights = + BlockWeights::with_sensible_defaults(4 * 1024 * 1024, Perbill::from_percent(75)); } impl frame_system::Config for Runtime { type BaseCallFilter = (); + type BlockWeights = RuntimeBlockWeights; + type BlockLength = RuntimeBlockLength; type Origin = Origin; type Call = Extrinsic; type Index = u64; @@ -449,13 +455,7 @@ impl frame_system::Config for Runtime { type Header = Header; type Event = Event; type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); - type MaximumExtrinsicWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type PalletInfo = (); type AccountData = (); -- GitLab From f9d938215fc2fa06114f02b587a9fae608822795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Tue, 8 Dec 2020 13:07:24 +0000 Subject: [PATCH 093/163] client: remove duplicate implementation of block_status (#7694) --- client/service/src/client/client.rs | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index f72fcb81076..84174738b56 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -1901,8 +1901,7 @@ impl BlockBackend for Client self.body(id) } - fn block(&self, id: &BlockId) -> sp_blockchain::Result>> - { + fn block(&self, id: &BlockId) -> sp_blockchain::Result>> { Ok(match (self.header(id)?, self.body(id)?, self.justification(id)?) { (Some(header), Some(extrinsics), justification) => Some(SignedBlock { block: Block::new(header, extrinsics), justification }), @@ -1911,26 +1910,7 @@ impl BlockBackend for Client } fn block_status(&self, id: &BlockId) -> sp_blockchain::Result { - // this can probably be implemented more efficiently - if let BlockId::Hash(ref h) = id { - if self.importing_block.read().as_ref().map_or(false, |importing| h == importing) { - return Ok(BlockStatus::Queued); - } - } - let hash_and_number = match id.clone() { - BlockId::Hash(hash) => self.backend.blockchain().number(hash)?.map(|n| (hash, n)), - BlockId::Number(n) => self.backend.blockchain().hash(n)?.map(|hash| (hash, n)), - }; - match hash_and_number { - Some((hash, number)) => { - if self.backend.have_state_at(&hash, number) { - Ok(BlockStatus::InChainWithState) - } else { - Ok(BlockStatus::InChainPruned) - } - } - None => Ok(BlockStatus::Unknown), - } + Client::block_status(self, id) } fn justification(&self, id: &BlockId) -> sp_blockchain::Result> { -- GitLab From 4c0779e751552419f0973ea14c455c8afce78def Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Tue, 8 Dec 2020 18:00:36 +0100 Subject: [PATCH 094/163] Pin md link checker's version (#7697) * CI: pin md link checker's version to the previous release * CI: add a whitelist for allowed GH actions pins * CI: try master tip [skip ci] * CI: return to a previous markdown-link-check dependency version [skip ci] * CI: substitute %20 for a literal space [skip ci] * CI: substitute %20 for a literal space --- .github/allowed-actions.js | 7 +++++++ .github/workflows/md-link-check.yml | 2 +- .github/workflows/mlc_config.json | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .github/allowed-actions.js diff --git a/.github/allowed-actions.js b/.github/allowed-actions.js new file mode 100644 index 00000000000..4a8af91328f --- /dev/null +++ b/.github/allowed-actions.js @@ -0,0 +1,7 @@ +// This is a whitelist of GitHub Actions that are approved for use in this project. +// If a new or existing workflow file is updated to use an action or action version +// not listed here, CI will fail. + +module.exports = [ + 'gaurav-nelson/github-action-markdown-link-check@e3c371c731b2f494f856dc5de7f61cea4d519907', // gaurav-nelson/github-action-markdown-link-check@v1.0.8 +] diff --git a/.github/workflows/md-link-check.yml b/.github/workflows/md-link-check.yml index 75948534b3c..e15a506c567 100644 --- a/.github/workflows/md-link-check.yml +++ b/.github/workflows/md-link-check.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: gaurav-nelson/github-action-markdown-link-check@v1 + - uses: gaurav-nelson/github-action-markdown-link-check@e3c371c731b2f494f856dc5de7f61cea4d519907 with: use-quiet-mode: 'yes' config-file: '.github/workflows/mlc_config.json' diff --git a/.github/workflows/mlc_config.json b/.github/workflows/mlc_config.json index f741e987b1b..ffd0a0319fe 100644 --- a/.github/workflows/mlc_config.json +++ b/.github/workflows/mlc_config.json @@ -3,5 +3,11 @@ { "pattern": "^https://crates.io" } + ], + "replacementPatterns": [ + { + "pattern": "%20", + "replacement": " " + } ] } -- GitLab From 609efdbd91073d7873f20048bf778f6ee9d802fe Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Tue, 8 Dec 2020 18:53:22 +0100 Subject: [PATCH 095/163] Remove waterfall CI trigger (#7519) * fix (CI): fix the triggered project name * fix (CI): debug run * fix (CI): debug run 2 * fix (CI): revert debug2 * Revert "fix (CI): debug run" This reverts commit 96866a953da797ef6e0689374eecc0d8cba4627d. * CI: remove the trigger --- .gitlab-ci.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 215157061bb..07b0dd319cf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,6 @@ stages: - check - test - build - - post-build-test - chaos-env - chaos - publish @@ -491,24 +490,6 @@ build-rust-doc: - echo "" > ./crate-docs/index.html - sccache -s -#### stage: post-build-test - -trigger-contracts-ci: - stage: post-build-test - needs: - - job: build-linux-substrate - artifacts: false - - job: test-linux-stable - artifacts: false - trigger: - project: parity/srml-contracts-waterfall - branch: master - strategy: depend - rules: - - if: $CI_PIPELINE_SOURCE == "web" - - if: $CI_PIPELINE_SOURCE == "schedule" - - if: $CI_COMMIT_REF_NAME == "master" - #### stage: chaos-env build-chaos-docker: -- GitLab From d877123b3050d8a50e83fc310d7091f45f23a748 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Tue, 8 Dec 2020 12:13:21 -0600 Subject: [PATCH 096/163] add an upgrade_keys method for pallet-session (#7688) * add an upgrade_keys method for pallet-session * test the upgrade_keys function --- frame/session/src/lib.rs | 49 ++++++++++++++++++++ frame/session/src/mock.rs | 25 ++++++++++ frame/session/src/tests.rs | 95 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 883a0cc5ab2..dd176219aa7 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -683,6 +683,55 @@ impl Module { Self::validators().iter().position(|i| i == c).map(Self::disable_index).ok_or(()) } + /// Upgrade the key type from some old type to a new type. Supports adding + /// and removing key types. + /// + /// This function should be used with extreme care and only during an + /// `on_runtime_upgrade` block. Misuse of this function can put your blockchain + /// into an unrecoverable state. + /// + /// Care should be taken that the raw versions of the + /// added keys are unique for every `ValidatorId, KeyTypeId` combination. + /// This is an invariant that the session module typically maintains internally. + /// + /// As the actual values of the keys are typically not known at runtime upgrade, + /// it's recommended to initialize the keys to a (unique) dummy value with the expectation + /// that all validators should invoke `set_keys` before those keys are actually + /// required. + pub fn upgrade_keys(upgrade: F) where + Old: OpaqueKeys + Member + Decode, + F: Fn(T::ValidatorId, Old) -> T::Keys, + { + let old_ids = Old::key_ids(); + let new_ids = T::Keys::key_ids(); + + // Translate NextKeys, and key ownership relations at the same time. + >::translate::(|val, old_keys| { + // Clear all key ownership relations. Typically the overlap should + // stay the same, but no guarantees by the upgrade function. + for i in old_ids.iter() { + Self::clear_key_owner(*i, old_keys.get_raw(*i)); + } + + let new_keys = upgrade(val.clone(), old_keys); + + // And now set the new ones. + for i in new_ids.iter() { + Self::put_key_owner(*i, new_keys.get_raw(*i), &val); + } + + Some(new_keys) + }); + + let _ = >::translate::, _>( + |k| { + k.map(|k| k.into_iter() + .map(|(val, old_keys)| (val.clone(), upgrade(val, old_keys))) + .collect::>()) + } + ); + } + /// Perform the set_key operation, checking for duplicates. Does not set `Changed`. /// /// This ensures that the reference counter in system is incremented appropriately and as such diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 0a7f89f5d57..fa71859feb4 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -40,6 +40,31 @@ impl From for MockSessionKeys { } } +pub const KEY_ID_A: KeyTypeId = KeyTypeId([4; 4]); +pub const KEY_ID_B: KeyTypeId = KeyTypeId([9; 4]); + +#[derive(Debug, Clone, codec::Encode, codec::Decode, PartialEq, Eq)] +pub struct PreUpgradeMockSessionKeys { + pub a: [u8; 32], + pub b: [u8; 64], +} + +impl OpaqueKeys for PreUpgradeMockSessionKeys { + type KeyTypeIdProviders = (); + + fn key_ids() -> &'static [KeyTypeId] { + &[KEY_ID_A, KEY_ID_B] + } + + fn get_raw(&self, i: KeyTypeId) -> &[u8] { + match i { + i if i == KEY_ID_A => &self.a[..], + i if i == KEY_ID_B => &self.b[..], + _ => &[], + } + } +} + impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 36857824de8..7a33aa5296b 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -25,6 +25,7 @@ use mock::{ SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Origin, System, Session, reset_before_session_end_called, before_session_end_called, new_test_ext, + PreUpgradeMockSessionKeys, }; fn initialize_block(block: u64) { @@ -308,3 +309,97 @@ fn return_true_if_more_than_third_is_disabled() { assert_eq!(Session::disable_index(3), true); }); } + +#[test] +fn upgrade_keys() { + use frame_support::storage; + use mock::Test; + use sp_core::crypto::key_types::DUMMY; + + // This test assumes certain mocks. + assert_eq!(mock::NEXT_VALIDATORS.with(|l| l.borrow().clone()), vec![1, 2, 3]); + assert_eq!(mock::VALIDATORS.with(|l| l.borrow().clone()), vec![1, 2, 3]); + + new_test_ext().execute_with(|| { + let pre_one = PreUpgradeMockSessionKeys { + a: [1u8; 32], + b: [1u8; 64], + }; + + let pre_two = PreUpgradeMockSessionKeys { + a: [2u8; 32], + b: [2u8; 64], + }; + + let pre_three = PreUpgradeMockSessionKeys { + a: [3u8; 32], + b: [3u8; 64], + }; + + let val_keys = vec![ + (1u64, pre_one), + (2u64, pre_two), + (3u64, pre_three), + ]; + + // Set `QueuedKeys`. + { + let storage_key = >::hashed_key(); + assert!(storage::unhashed::exists(&storage_key)); + storage::unhashed::put(&storage_key, &val_keys); + } + + // Set `NextKeys`. + { + for &(i, ref keys) in val_keys.iter() { + let storage_key = >::hashed_key_for(i); + assert!(storage::unhashed::exists(&storage_key)); + storage::unhashed::put(&storage_key, keys); + } + } + + // Set `KeyOwner`. + { + for &(i, ref keys) in val_keys.iter() { + // clear key owner for `UintAuthorityId` keys set in genesis. + let presumed = UintAuthorityId(i); + let raw_prev = presumed.as_ref(); + + assert_eq!(Session::key_owner(DUMMY, raw_prev), Some(i)); + Session::clear_key_owner(DUMMY, raw_prev); + + Session::put_key_owner(mock::KEY_ID_A, keys.get_raw(mock::KEY_ID_A), &i); + Session::put_key_owner(mock::KEY_ID_B, keys.get_raw(mock::KEY_ID_B), &i); + } + } + + // Do the upgrade and check sanity. + let mock_keys_for = |val| mock::MockSessionKeys { dummy: UintAuthorityId(val) }; + Session::upgrade_keys::( + |val, _old_keys| mock_keys_for(val), + ); + + // Check key ownership. + for (i, ref keys) in val_keys.iter() { + assert!(Session::key_owner(mock::KEY_ID_A, keys.get_raw(mock::KEY_ID_A)).is_none()); + assert!(Session::key_owner(mock::KEY_ID_B, keys.get_raw(mock::KEY_ID_B)).is_none()); + + let migrated_key = UintAuthorityId(*i); + assert_eq!(Session::key_owner(DUMMY, migrated_key.as_ref()), Some(*i)); + } + + // Check queued keys. + assert_eq!( + Session::queued_keys(), + vec![ + (1, mock_keys_for(1)), + (2, mock_keys_for(2)), + (3, mock_keys_for(3)), + ], + ); + + for i in 1u64..4 { + assert_eq!(>::get(&i), Some(mock_keys_for(i))); + } + }) +} -- GitLab From 469836fb550b48f09a42fe5498a2a5af3c8a5935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 9 Dec 2020 02:17:28 +0100 Subject: [PATCH 097/163] Allow capping the amount of work performed when deleting a child trie (#7671) * Allow Backend::for_keys_in_child_storage to be aborted by the closure * Ext::kill_child_storage now takes an upper limit for backend deletion * Add Storage::storage_kill_limited() runtime interface * review: Use a new version of kill_storage instead of a new interface * review: Simplify boolean expression Co-authored-by: cheme * review: Rename for_keys_in_child_storage Co-authored-by: cheme --- client/db/src/bench.rs | 4 +- client/db/src/lib.rs | 4 +- client/db/src/storage_cache.rs | 8 +- client/light/src/backend.rs | 4 +- frame/contracts/src/rent.rs | 2 + frame/contracts/src/storage.rs | 2 +- frame/support/src/storage/child.rs | 36 ++++++++- primitives/externalities/src/lib.rs | 12 ++- primitives/io/src/lib.rs | 30 ++++++- primitives/state-machine/src/backend.rs | 7 +- primitives/state-machine/src/basic.rs | 6 +- primitives/state-machine/src/ext.rs | 33 ++++++-- primitives/state-machine/src/lib.rs | 81 +++++++++++++++++++ .../state-machine/src/proving_backend.rs | 4 +- primitives/state-machine/src/read_only.rs | 3 +- primitives/state-machine/src/trie_backend.rs | 4 +- .../state-machine/src/trie_backend_essence.rs | 3 +- primitives/tasks/src/async_externalities.rs | 3 +- primitives/trie/src/lib.rs | 7 +- 19 files changed, 219 insertions(+), 34 deletions(-) diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index f3c8f1aff9e..5696922b4fb 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -350,13 +350,13 @@ impl StateBackend> for BenchmarkingState { } } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { if let Some(ref state) = *self.state.borrow() { - state.for_keys_in_child_storage(child_info, f) + state.apply_to_child_keys_while(child_info, f) } } diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 8254e652f68..e32e45a2f31 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -195,12 +195,12 @@ impl StateBackend> for RefTrackingState { self.state.for_key_values_with_prefix(prefix, f) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - self.state.for_keys_in_child_storage(child_info, f) + self.state.apply_to_child_keys_while(child_info, f) } fn for_child_keys_with_prefix( diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 0b4b6d4f88e..292d3c51626 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -584,12 +584,12 @@ impl>, B: BlockT> StateBackend> for Cachin self.state.exists_child_storage(child_info, key) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - self.state.for_keys_in_child_storage(child_info, f) + self.state.apply_to_child_keys_while(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { @@ -766,12 +766,12 @@ impl>, B: BlockT> StateBackend> for Syncin self.caching_state().exists_child_storage(child_info, key) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - self.caching_state().for_keys_in_child_storage(child_info, f) + self.caching_state().apply_to_child_keys_while(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { diff --git a/client/light/src/backend.rs b/client/light/src/backend.rs index be7953e528b..74e1d613bcf 100644 --- a/client/light/src/backend.rs +++ b/client/light/src/backend.rs @@ -441,14 +441,14 @@ impl StateBackend for GenesisOrUnavailableState } } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, action: A, ) { match *self { GenesisOrUnavailableState::Genesis(ref state) => - state.for_keys_in_child_storage(child_info, action), + state.apply_to_child_keys_while(child_info, action), GenesisOrUnavailableState::Unavailable => (), } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 6ee65a54bb5..8b6f81c916b 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -240,6 +240,7 @@ where >::remove(account); child::kill_storage( &alive_contract_info.child_trie_info(), + None, ); >::deposit_event(RawEvent::Evicted(account.clone(), false)); None @@ -263,6 +264,7 @@ where child::kill_storage( &alive_contract_info.child_trie_info(), + None, ); >::deposit_event(RawEvent::Evicted(account.clone(), true)); diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index c9eeba4633a..ba09adb285b 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -195,7 +195,7 @@ where /// This function doesn't affect the account. pub fn destroy_contract(address: &AccountIdOf, trie_id: &TrieId) { >::remove(address); - child::kill_storage(&crate::child_trie_info(&trie_id)); + child::kill_storage(&crate::child_trie_info(&trie_id), None); } /// This generator uses inner counter for account id and applies the hash over `AccountId + diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index 431b5e09303..d9861554472 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -25,6 +25,14 @@ use crate::sp_std::prelude::*; use codec::{Codec, Encode, Decode}; pub use sp_core::storage::{ChildInfo, ChildType}; +/// The outcome of calling [`kill_storage`]. +pub enum KillOutcome { + /// No key remains in the child trie. + AllRemoved, + /// At least one key still resides in the child trie due to the supplied limit. + SomeRemaining, +} + /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get( child_info: &ChildInfo, @@ -148,13 +156,37 @@ pub fn exists( } /// Remove all `storage_key` key/values +/// +/// Deletes all keys from the overlay and up to `limit` keys from the backend if +/// it is set to `Some`. No limit is applied when `limit` is set to `None`. +/// +/// The limit can be used to partially delete a child trie in case it is too large +/// to delete in one go (block). +/// +/// # Note +/// +/// Please note that keys that are residing in the overlay for that child trie when +/// issuing this call are all deleted without counting towards the `limit`. Only keys +/// written during the current block are part of the overlay. Deleting with a `limit` +/// mostly makes sense with an empty overlay for that child trie. +/// +/// Calling this function multiple times per block for the same `storage_key` does +/// not make much sense because it is not cumulative when called inside the same block. +/// Use this function to distribute the deletion of a single child trie across multiple +/// blocks. pub fn kill_storage( child_info: &ChildInfo, -) { - match child_info.child_type() { + limit: Option, +) -> KillOutcome { + let all_removed = match child_info.child_type() { ChildType::ParentKeyId => sp_io::default_child_storage::storage_kill( child_info.storage_key(), + limit ), + }; + match all_removed { + true => KillOutcome::AllRemoved, + false => KillOutcome::SomeRemaining, } } diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 388482964f1..6869969f4ba 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -137,7 +137,17 @@ pub trait Externalities: ExtensionStore { ) -> Option>; /// Clear an entire child storage. - fn kill_child_storage(&mut self, child_info: &ChildInfo); + /// + /// Deletes all keys from the overlay and up to `limit` keys from the backend. No + /// limit is applied if `limit` is `None`. Returns `true` if the child trie was + /// removed completely and `false` if there are remaining keys after the function + /// returns. + /// + /// # Note + /// + /// An implementation is free to delete more keys than the specified limit as long as + /// it is able to do that in constant time. + fn kill_child_storage(&mut self, child_info: &ChildInfo, limit: Option) -> bool; /// Clear storage entries which keys are start with the given prefix. fn clear_prefix(&mut self, prefix: &[u8]); diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index d812baefb57..b6ae64e5f89 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -279,7 +279,35 @@ pub trait DefaultChildStorage { storage_key: &[u8], ) { let child_info = ChildInfo::new_default(storage_key); - self.kill_child_storage(&child_info); + self.kill_child_storage(&child_info, None); + } + + /// Clear a child storage key. + /// + /// Deletes all keys from the overlay and up to `limit` keys from the backend if + /// it is set to `Some`. No limit is applied when `limit` is set to `None`. + /// + /// The limit can be used to partially delete a child trie in case it is too large + /// to delete in one go (block). + /// + /// It returns false iff some keys are remaining in + /// the child trie after the functions returns. + /// + /// # Note + /// + /// Please note that keys that are residing in the overlay for that child trie when + /// issuing this call are all deleted without counting towards the `limit`. Only keys + /// written during the current block are part of the overlay. Deleting with a `limit` + /// mostly makes sense with an empty overlay for that child trie. + /// + /// Calling this function multiple times per block for the same `storage_key` does + /// not make much sense because it is not cumulative when called inside the same block. + /// Use this function to distribute the deletion of a single child trie across multiple + /// blocks. + #[version(2)] + fn storage_kill(&mut self, storage_key: &[u8], limit: Option) -> bool { + let child_info = ChildInfo::new_default(storage_key); + self.kill_child_storage(&child_info, limit) } /// Check a child storage key. diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 360fe9a9856..02151c2480e 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -94,7 +94,8 @@ pub trait Backend: sp_std::fmt::Debug { ) -> Result, Self::Error>; /// Retrieve all entries keys of child storage and call `f` for each of those keys. - fn for_keys_in_child_storage( + /// Aborts as soon as `f` returns false. + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, @@ -263,12 +264,12 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { (*self).child_storage(child_info, key) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - (*self).for_keys_in_child_storage(child_info, f) + (*self).apply_to_child_keys_while(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result, Self::Error> { diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index 5e3c9bed64f..9de75785e45 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -210,8 +210,10 @@ impl Externalities for BasicExternalities { fn kill_child_storage( &mut self, child_info: &ChildInfo, - ) { + _limit: Option, + ) -> bool { self.inner.children_default.remove(child_info.storage_key()); + true } fn clear_prefix(&mut self, prefix: &[u8]) { @@ -407,7 +409,7 @@ mod tests { ext.clear_child_storage(child_info, b"dog"); assert_eq!(ext.child_storage(child_info, b"dog"), None); - ext.kill_child_storage(child_info); + ext.kill_child_storage(child_info, None); assert_eq!(ext.child_storage(child_info, b"doe"), None); } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 53aab42999d..3c4d88f3920 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -411,18 +411,41 @@ where fn kill_child_storage( &mut self, child_info: &ChildInfo, - ) { + limit: Option, + ) -> bool { trace!(target: "state", "{:04x}: KillChild({})", self.id, HexDisplay::from(&child_info.storage_key()), ); let _guard = guard(); - self.mark_dirty(); self.overlay.clear_child_storage(child_info); - self.backend.for_keys_in_child_storage(child_info, |key| { - self.overlay.set_child_storage(child_info, key.to_vec(), None); - }); + + if let Some(limit) = limit { + let mut num_deleted: u32 = 0; + let mut all_deleted = true; + self.backend.apply_to_child_keys_while(child_info, |key| { + if num_deleted == limit { + all_deleted = false; + return false; + } + if let Some(num) = num_deleted.checked_add(1) { + num_deleted = num; + } else { + all_deleted = false; + return false; + } + self.overlay.set_child_storage(child_info, key.to_vec(), None); + true + }); + all_deleted + } else { + self.backend.apply_to_child_keys_while(child_info, |key| { + self.overlay.set_child_storage(child_info, key.to_vec(), None); + true + }); + true + } } fn clear_prefix(&mut self, prefix: &[u8]) { diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index 28148b6411a..c83dce4bedf 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -1147,6 +1147,86 @@ mod tests { ); } + #[test] + fn limited_child_kill_works() { + let child_info = ChildInfo::new_default(b"sub1"); + let initial: HashMap<_, BTreeMap<_, _>> = map![ + Some(child_info.clone()) => map![ + b"a".to_vec() => b"0".to_vec(), + b"b".to_vec() => b"1".to_vec(), + b"c".to_vec() => b"2".to_vec(), + b"d".to_vec() => b"3".to_vec() + ], + ]; + let backend = InMemoryBackend::::from(initial); + + let mut overlay = OverlayedChanges::default(); + overlay.set_child_storage(&child_info, b"1".to_vec(), Some(b"1312".to_vec())); + overlay.set_child_storage(&child_info, b"2".to_vec(), Some(b"1312".to_vec())); + overlay.set_child_storage(&child_info, b"3".to_vec(), Some(b"1312".to_vec())); + overlay.set_child_storage(&child_info, b"4".to_vec(), Some(b"1312".to_vec())); + + { + let mut offchain_overlay = Default::default(); + let mut cache = StorageTransactionCache::default(); + let mut ext = Ext::new( + &mut overlay, + &mut offchain_overlay, + &mut cache, + &backend, + changes_trie::disabled_state::<_, u64>(), + None, + ); + assert_eq!(ext.kill_child_storage(&child_info, Some(2)), false); + } + + assert_eq!( + overlay.children() + .flat_map(|(iter, _child_info)| iter) + .map(|(k, v)| (k.clone(), v.value().clone())) + .collect::>(), + map![ + b"1".to_vec() => None.into(), + b"2".to_vec() => None.into(), + b"3".to_vec() => None.into(), + b"4".to_vec() => None.into(), + b"a".to_vec() => None.into(), + b"b".to_vec() => None.into(), + ], + ); + } + + #[test] + fn limited_child_kill_off_by_one_works() { + let child_info = ChildInfo::new_default(b"sub1"); + let initial: HashMap<_, BTreeMap<_, _>> = map![ + Some(child_info.clone()) => map![ + b"a".to_vec() => b"0".to_vec(), + b"b".to_vec() => b"1".to_vec(), + b"c".to_vec() => b"2".to_vec(), + b"d".to_vec() => b"3".to_vec() + ], + ]; + let backend = InMemoryBackend::::from(initial); + let mut overlay = OverlayedChanges::default(); + let mut offchain_overlay = Default::default(); + let mut cache = StorageTransactionCache::default(); + let mut ext = Ext::new( + &mut overlay, + &mut offchain_overlay, + &mut cache, + &backend, + changes_trie::disabled_state::<_, u64>(), + None, + ); + assert_eq!(ext.kill_child_storage(&child_info, Some(0)), false); + assert_eq!(ext.kill_child_storage(&child_info, Some(1)), false); + assert_eq!(ext.kill_child_storage(&child_info, Some(2)), false); + assert_eq!(ext.kill_child_storage(&child_info, Some(3)), false); + assert_eq!(ext.kill_child_storage(&child_info, Some(4)), true); + assert_eq!(ext.kill_child_storage(&child_info, Some(5)), true); + } + #[test] fn set_child_storage_works() { let child_info = ChildInfo::new_default(b"sub1"); @@ -1179,6 +1259,7 @@ mod tests { ); ext.kill_child_storage( child_info, + None, ); assert_eq!( ext.child_storage( diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 0888c561cae..63a027cfba0 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -204,12 +204,12 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.child_storage(child_info, key) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - self.0.for_keys_in_child_storage(child_info, f) + self.0.apply_to_child_keys_while(child_info, f) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { diff --git a/primitives/state-machine/src/read_only.rs b/primitives/state-machine/src/read_only.rs index 1b70958145c..2ab92f5fbb6 100644 --- a/primitives/state-machine/src/read_only.rs +++ b/primitives/state-machine/src/read_only.rs @@ -131,7 +131,8 @@ impl<'a, H: Hasher, B: 'a + Backend> Externalities for ReadOnlyExternalities< fn kill_child_storage( &mut self, _child_info: &ChildInfo, - ) { + _limit: Option, + ) -> bool { unimplemented!("kill_child_storage is not supported in ReadOnlyExternalities") } diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index 4eaa0870bae..ffae1a02c03 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -113,12 +113,12 @@ impl, H: Hasher> Backend for TrieBackend where self.essence.for_key_values_with_prefix(prefix, f) } - fn for_keys_in_child_storage( + fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, ) { - self.essence.for_keys_in_child_storage(child_info, f) + self.essence.apply_to_child_keys_while(child_info, f) } fn for_child_keys_with_prefix( diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 37bbbb7cf98..8485cb27e70 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -190,7 +190,8 @@ impl, H: Hasher> TrieBackendEssence where H::Out: } /// Retrieve all entries keys of child storage and call `f` for each of those keys. - pub fn for_keys_in_child_storage( + /// Aborts as soon as `f` returns false. + pub fn apply_to_child_keys_while bool>( &self, child_info: &ChildInfo, f: F, diff --git a/primitives/tasks/src/async_externalities.rs b/primitives/tasks/src/async_externalities.rs index 8994d069e4c..efb4c498f75 100644 --- a/primitives/tasks/src/async_externalities.rs +++ b/primitives/tasks/src/async_externalities.rs @@ -118,7 +118,8 @@ impl Externalities for AsyncExternalities { fn kill_child_storage( &mut self, _child_info: &ChildInfo, - ) { + _limit: Option, + ) -> bool { panic!("`kill_child_storage`: should not be used in async externalities!") } diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 73a4a8029b2..2687d8e4227 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -271,7 +271,8 @@ pub fn child_delta_trie_root( } /// Call `f` for all keys in a child trie. -pub fn for_keys_in_child_trie( +/// Aborts as soon as `f` returns false. +pub fn for_keys_in_child_trie bool, DB>( keyspace: &[u8], db: &DB, root_slice: &[u8], @@ -290,7 +291,9 @@ pub fn for_keys_in_child_trie( for x in iter { let (key, _) = x?; - f(&key); + if !f(&key) { + break; + } } Ok(()) -- GitLab From 4b8c862ae3b0d34ecdc351888469f81704df68e2 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 8 Dec 2020 20:00:52 -0800 Subject: [PATCH 098/163] benchmarks: Fix panic in case of a missing model (#7698) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Theißen --- frame/benchmarking/src/analysis.rs | 4 +++- frame/benchmarking/src/lib.rs | 2 +- utils/frame/benchmarking-cli/src/writer.rs | 25 ++++++++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/frame/benchmarking/src/analysis.rs b/frame/benchmarking/src/analysis.rs index dafb4a74b66..dafe42de92e 100644 --- a/frame/benchmarking/src/analysis.rs +++ b/frame/benchmarking/src/analysis.rs @@ -18,9 +18,11 @@ //! Tools for analyzing the benchmark results. use std::collections::BTreeMap; -use linregress::{FormulaRegressionBuilder, RegressionDataBuilder, RegressionModel}; +use linregress::{FormulaRegressionBuilder, RegressionDataBuilder}; use crate::BenchmarkResults; +pub use linregress::RegressionModel; + pub struct Analysis { pub base: u128, pub slopes: Vec, diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index fdfe857e4be..97b58ae19ec 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -26,7 +26,7 @@ mod analysis; pub use utils::*; #[cfg(feature = "std")] -pub use analysis::{Analysis, BenchmarkSelector}; +pub use analysis::{Analysis, BenchmarkSelector, RegressionModel}; #[doc(hidden)] pub use sp_io::storage::root as storage_root; pub use sp_runtime::traits::Zero; diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs index efa356a0fa0..fd72e003b41 100644 --- a/utils/frame/benchmarking-cli/src/writer.rs +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -24,7 +24,7 @@ use std::path::PathBuf; use serde::Serialize; use crate::BenchmarkCmd; -use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis}; +use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis, RegressionModel}; use sp_runtime::traits::Zero; const VERSION: &'static str = env!("CARGO_PKG_VERSION"); @@ -134,6 +134,17 @@ fn map_results(batches: &[BenchmarkBatch]) -> Result) -> impl Iterator + '_ { + let mut errors = model.as_ref().map(|m| m.se.regressor_values.iter()); + std::iter::from_fn(move || { + match &mut errors { + Some(model) => model.next().map(|val| *val as u128), + _ => Some(0), + } + }) +} + // Analyze and return the relevant results for a given benchmark. fn get_benchmark_data(batch: &BenchmarkBatch) -> BenchmarkData { // Analyze benchmarks to get the linear regression. @@ -149,40 +160,40 @@ fn get_benchmark_data(batch: &BenchmarkBatch) -> BenchmarkData { extrinsic_time.slopes.into_iter() .zip(extrinsic_time.names.iter()) - .zip(extrinsic_time.model.unwrap().se.regressor_values.iter()) + .zip(extract_errors(&extrinsic_time.model)) .for_each(|((slope, name), error)| { if !slope.is_zero() { if !used_components.contains(&name) { used_components.push(name); } used_extrinsic_time.push(ComponentSlope { name: name.clone(), slope: slope.saturating_mul(1000), - error: (*error as u128).saturating_mul(1000), + error: error.saturating_mul(1000), }); } }); reads.slopes.into_iter() .zip(reads.names.iter()) - .zip(reads.model.unwrap().se.regressor_values.iter()) + .zip(extract_errors(&reads.model)) .for_each(|((slope, name), error)| { if !slope.is_zero() { if !used_components.contains(&name) { used_components.push(name); } used_reads.push(ComponentSlope { name: name.clone(), slope, - error: *error as u128, + error, }); } }); writes.slopes.into_iter() .zip(writes.names.iter()) - .zip(writes.model.unwrap().se.regressor_values.iter()) + .zip(extract_errors(&writes.model)) .for_each(|((slope, name), error)| { if !slope.is_zero() { if !used_components.contains(&name) { used_components.push(name); } used_writes.push(ComponentSlope { name: name.clone(), slope, - error: *error as u128, + error, }); } }); -- GitLab From 9599f39a15007eba3bcc38d0eddb8af08de2b2b9 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 9 Dec 2020 10:52:56 +0100 Subject: [PATCH 099/163] Expand remote keystore interface to allow for hybrid mode (#7628) * update to latest master * updates on docs, license, meta * hide ssrs behind feature flag * implement remaining functions on the server * sign server line length fix * fix tests * fixup in-memory-keystore * adding failsafe * skipping ecdsa test for now * remote keystore param * remote sign urls made available * integrating keystore remotes features * don't forget the dependency * remove old cruft * reset local keystore * applying suggestions * Switch to single remote, minor grumbles * minor grumbles, docs --- Cargo.lock | 3 ++ bin/node-template/node/Cargo.toml | 1 + bin/node-template/node/src/service.rs | 23 ++++++++- client/cli/src/commands/insert.rs | 2 +- client/cli/src/config.rs | 8 +-- client/cli/src/params/keystore_params.rs | 9 +++- client/service/src/builder.rs | 50 ++++++++++++++----- client/service/src/config.rs | 2 + client/service/test/src/lib.rs | 1 + primitives/application-crypto/test/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- primitives/core/src/crypto.rs | 3 ++ primitives/keystore/Cargo.toml | 11 +++- primitives/keystore/src/vrf.rs | 3 ++ utils/browser/src/lib.rs | 1 + 15 files changed, 99 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53c42e08774..e277d1d24a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3967,6 +3967,7 @@ dependencies = [ "sc-consensus-aura", "sc-executor", "sc-finality-grandpa", + "sc-keystore", "sc-rpc", "sc-rpc-api", "sc-service", @@ -7484,6 +7485,7 @@ dependencies = [ "merlin", "rand 0.7.3", "rand_core 0.5.1", + "serde", "sha2 0.8.2", "subtle 2.3.0", "zeroize", @@ -8276,6 +8278,7 @@ dependencies = [ "rand 0.7.3", "rand_chacha 0.2.2", "schnorrkel", + "serde", "sp-core", "sp-externalities", ] diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index d2b5a35b352..38cdaa1eea4 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -22,6 +22,7 @@ sc-cli = { version = "0.8.0", path = "../../../client/cli", features = ["wasmtim sp-core = { version = "2.0.0", path = "../../../primitives/core" } sc-executor = { version = "0.8.0", path = "../../../client/executor", features = ["wasmtime"] } sc-service = { version = "0.8.0", path = "../../../client/service", features = ["wasmtime"] } +sc-keystore = { version = "2.0.0", path = "../../../client/keystore" } sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } sc-transaction-pool = { version = "2.0.0", path = "../../../client/transaction-pool" } sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 1fa1a372a05..7e1939fb023 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -10,6 +10,7 @@ use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; use sc_finality_grandpa::SharedVoterState; +use sc_keystore::LocalKeystore; // Our native executor instance. native_executor_instance!( @@ -37,6 +38,10 @@ pub fn new_partial(config: &Configuration) -> Result ) >, ServiceError> { + if config.keystore_remote.is_some() { + return Err(ServiceError::Other( + format!("Remote Keystores are not supported."))) + } let inherent_data_providers = sp_inherents::InherentDataProviders::new(); let (client, backend, keystore_container, task_manager) = @@ -78,14 +83,30 @@ pub fn new_partial(config: &Configuration) -> Result Result, &'static str> { + // FIXME: here would the concrete keystore be built, + // must return a concrete type (NOT `LocalKeystore`) that + // implements `CryptoStore` and `SyncCryptoStore` + Err("Remote Keystore not supported.") +} + /// Builds a new service for a full client. pub fn new_full(mut config: Configuration) -> Result { let sc_service::PartialComponents { - client, backend, mut task_manager, import_queue, keystore_container, + client, backend, mut task_manager, import_queue, mut keystore_container, select_chain, transaction_pool, inherent_data_providers, other: (block_import, grandpa_link), } = new_partial(&config)?; + if let Some(url) = &config.keystore_remote { + match remote_keystore(url) { + Ok(k) => keystore_container.set_remote_keystore(k), + Err(e) => { + return Err(ServiceError::Other( + format!("Error hooking up remote keystore for {}: {}", url, e))) + } + }; + } config.network.notifications_protocols.push(sc_finality_grandpa::GRANDPA_PROTOCOL_NAME.into()); let (network, network_status_sinks, system_rpc_tx, network_starter) = diff --git a/client/cli/src/commands/insert.rs b/client/cli/src/commands/insert.rs index fc307e45e7c..8b7fe98fc0b 100644 --- a/client/cli/src/commands/insert.rs +++ b/client/cli/src/commands/insert.rs @@ -65,7 +65,7 @@ impl InsertCmd { .ok_or_else(|| Error::MissingBasePath)?; let (keystore, public) = match self.keystore_params.keystore_config(base_path)? { - KeystoreConfig::Path { path, password } => { + (_, KeystoreConfig::Path { path, password }) => { let public = with_crypto_scheme!( self.crypto_scheme.scheme, to_vec(&suri, password.clone()) diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index e4411e49408..bf6b444c4d7 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -188,10 +188,10 @@ pub trait CliConfiguration: Sized { /// /// Bu default this is retrieved from `KeystoreParams` if it is available. Otherwise it uses /// `KeystoreConfig::InMemory`. - fn keystore_config(&self, base_path: &PathBuf) -> Result { + fn keystore_config(&self, base_path: &PathBuf) -> Result<(Option, KeystoreConfig)> { self.keystore_params() .map(|x| x.keystore_config(base_path)) - .unwrap_or(Ok(KeystoreConfig::InMemory)) + .unwrap_or_else(|| Ok((None, KeystoreConfig::InMemory))) } /// Get the database cache size. @@ -471,6 +471,7 @@ pub trait CliConfiguration: Sized { let role = self.role(is_dev)?; let max_runtime_instances = self.max_runtime_instances()?.unwrap_or(8); let is_validator = role.is_network_authority(); + let (keystore_remote, keystore) = self.keystore_config(&config_dir)?; let unsafe_pruning = self .import_params() @@ -491,7 +492,8 @@ pub trait CliConfiguration: Sized { node_key, DCV::p2p_listen_port(), )?, - keystore: self.keystore_config(&config_dir)?, + keystore_remote, + keystore, database: self.database_config(&config_dir, database_cache_size, database)?, state_cache_size: self.state_cache_size()?, state_cache_child_ratio: self.state_cache_child_ratio()?, diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs index 2ecd21cb3dd..f03fafeb965 100644 --- a/client/cli/src/params/keystore_params.rs +++ b/client/cli/src/params/keystore_params.rs @@ -30,6 +30,9 @@ const DEFAULT_KEYSTORE_CONFIG_PATH: &'static str = "keystore"; /// Parameters of the keystore #[derive(Debug, StructOpt)] pub struct KeystoreParams { + /// Specify custom URIs to connect to for keystore-services + #[structopt(long = "keystore-uri")] + pub keystore_uri: Option, /// Specify custom keystore path. #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] pub keystore_path: Option, @@ -67,7 +70,9 @@ pub fn secret_string_from_str(s: &str) -> std::result::Result Result { + /// returns a vector of remote-urls and the local Keystore configuration + pub fn keystore_config(&self, base_path: &PathBuf) -> Result<(Option, KeystoreConfig)> { + let password = if self.password_interactive { #[cfg(not(target_os = "unknown"))] { @@ -89,7 +94,7 @@ impl KeystoreParams { .clone() .unwrap_or_else(|| base_path.join(DEFAULT_KEYSTORE_CONFIG_PATH)); - Ok(KeystoreConfig::Path { path, password }) + Ok((self.keystore_uri.clone(), KeystoreConfig::Path { path, password })) } /// helper method to fetch password from `KeyParams` or read from stdin diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 52c1121d504..5e511d3d7c7 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -59,7 +59,7 @@ use sp_core::traits::{ CodeExecutor, SpawnNamed, }; -use sp_keystore::{CryptoStore, SyncCryptoStorePtr}; +use sp_keystore::{CryptoStore, SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::BuildStorage; use sc_client_api::{ BlockBackend, BlockchainEvents, @@ -205,12 +205,25 @@ pub type TLightClientWithBackend = Client< TRtApi, >; -enum KeystoreContainerInner { - Local(Arc) +trait AsCryptoStoreRef { + fn keystore_ref(&self) -> Arc; + fn sync_keystore_ref(&self) -> Arc; +} + +impl AsCryptoStoreRef for Arc where T: CryptoStore + SyncCryptoStore + 'static { + fn keystore_ref(&self) -> Arc { + self.clone() + } + fn sync_keystore_ref(&self) -> Arc { + self.clone() + } } /// Construct and hold different layers of Keystore wrappers -pub struct KeystoreContainer(KeystoreContainerInner); +pub struct KeystoreContainer { + remote: Option>, + local: Arc, +} impl KeystoreContainer { /// Construct KeystoreContainer @@ -223,20 +236,35 @@ impl KeystoreContainer { KeystoreConfig::InMemory => LocalKeystore::in_memory(), }); - Ok(Self(KeystoreContainerInner::Local(keystore))) + Ok(Self{remote: Default::default(), local: keystore}) + } + + /// Set the remote keystore. + /// Should be called right away at startup and not at runtime: + /// even though this overrides any previously set remote store, it + /// does not reset any references previously handed out - they will + /// stick araound. + pub fn set_remote_keystore(&mut self, remote: Arc) + where T: CryptoStore + SyncCryptoStore + 'static + { + self.remote = Some(Box::new(remote)) } /// Returns an adapter to the asynchronous keystore that implements `CryptoStore` pub fn keystore(&self) -> Arc { - match self.0 { - KeystoreContainerInner::Local(ref keystore) => keystore.clone(), + if let Some(c) = self.remote.as_ref() { + c.keystore_ref() + } else { + self.local.clone() } } /// Returns the synchrnous keystore wrapper pub fn sync_keystore(&self) -> SyncCryptoStorePtr { - match self.0 { - KeystoreContainerInner::Local(ref keystore) => keystore.clone() as SyncCryptoStorePtr, + if let Some(c) = self.remote.as_ref() { + c.sync_keystore_ref() + } else { + self.local.clone() as SyncCryptoStorePtr } } @@ -249,9 +277,7 @@ impl KeystoreContainer { /// Using the [`LocalKeystore`] will result in loosing the ability to use any other keystore implementation, like /// a remote keystore for example. Only use this if you a certain that you require it! pub fn local_keystore(&self) -> Option> { - match self.0 { - KeystoreContainerInner::Local(ref keystore) => Some(keystore.clone()), - } + Some(self.local.clone()) } } diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 20a4995bbc7..e360e610d49 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -50,6 +50,8 @@ pub struct Configuration { pub network: NetworkConfiguration, /// Configuration for the keystore. pub keystore: KeystoreConfig, + /// Remote URI to connect to for async keystore support + pub keystore_remote: Option, /// Configuration for the database. pub database: DatabaseConfig, /// Size of internal state cache in Bytes diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index cfcf7e9ab38..1f200b4cbee 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -239,6 +239,7 @@ fn node_config for KeyTypeId { @@ -1058,10 +1059,12 @@ impl<'a> TryFrom<&'a str> for KeyTypeId { /// An identifier for a specific cryptographic algorithm used by a key pair #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct CryptoTypeId(pub [u8; 4]); /// A type alias of CryptoTypeId & a public key #[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct CryptoTypePublicPair(pub CryptoTypeId, pub Vec); #[cfg(feature = "std")] diff --git a/primitives/keystore/Cargo.toml b/primitives/keystore/Cargo.toml index d53d1ebd533..deffc2ccf9d 100644 --- a/primitives/keystore/Cargo.toml +++ b/primitives/keystore/Cargo.toml @@ -20,10 +20,19 @@ futures = { version = "0.3.1" } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false } merlin = { version = "2.0", default-features = false } parking_lot = { version = "0.10.0", default-features = false } - +serde = { version = "1.0", optional = true} sp-core = { version = "2.0.0", path = "../core" } sp-externalities = { version = "0.8.0", path = "../externalities", default-features = false } [dev-dependencies] rand = "0.7.2" rand_chacha = "0.2.2" + + +[features] +default = ["std"] +std = [ + "serde", + "schnorrkel/std", + "schnorrkel/serde", +] diff --git a/primitives/keystore/src/vrf.rs b/primitives/keystore/src/vrf.rs index 750ca0eac6b..9c1ac92738d 100644 --- a/primitives/keystore/src/vrf.rs +++ b/primitives/keystore/src/vrf.rs @@ -20,9 +20,11 @@ use codec::Encode; use merlin::Transcript; use schnorrkel::vrf::{VRFOutput, VRFProof}; + /// An enum whose variants represent possible /// accepted values to construct the VRF transcript #[derive(Clone, Encode)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub enum VRFTranscriptValue { /// Value is an array of bytes Bytes(Vec), @@ -38,6 +40,7 @@ pub struct VRFTranscriptData { pub items: Vec<(&'static str, VRFTranscriptValue)>, } /// VRF signature data +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct VRFSignature { /// The VRFOutput serialized pub output: VRFOutput, diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index bffd9fbedb2..071ed332fcd 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -75,6 +75,7 @@ where DatabaseConfig::Custom(sp_database::as_database(db)) }, + keystore_remote: Default::default(), keystore: KeystoreConfig::InMemory, default_heap_pages: Default::default(), dev_key_seed: Default::default(), -- GitLab From be8fd0588013a3b8eab5d5c761fe1c55bdd60dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Wed, 9 Dec 2020 11:04:57 +0000 Subject: [PATCH 100/163] fork-tree: expose silent failures of is_descendent_of (#7695) * fork-tree: expose silent failures of is_descendent_of * fork-tree: use mem::take instead of mem::swap --- utils/fork-tree/src/lib.rs | 49 ++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index f266b642230..d2a0a4f3dd6 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -144,7 +144,7 @@ impl ForkTree where for child in root_children { if is_first && (child.number == *number && child.hash == *hash || - child.number < *number && is_descendent_of(&child.hash, hash).unwrap_or(false)) + child.number < *number && is_descendent_of(&child.hash, hash)?) { root.children.push(child); // assuming that the tree is well formed only one child should pass this requirement @@ -415,15 +415,15 @@ impl ForkTree where // another fork not part of the tree). make sure to only keep roots that // are part of the finalized branch let mut changed = false; - self.roots.retain(|root| { - let retain = root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false); + let roots = std::mem::take(&mut self.roots); - if !retain { + for root in roots { + if root.number > number && is_descendent_of(hash, &root.hash)? { + self.roots.push(root); + } else { changed = true; } - - retain - }); + } self.best_finalized_number = Some(number); @@ -467,16 +467,19 @@ impl ForkTree where let (is_finalized, is_descendant, is_ancestor) = { let root = &self.roots[idx]; let is_finalized = root.hash == *hash; - let is_descendant = !is_finalized - && root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false); - let is_ancestor = !is_finalized && !is_descendant - && root.number < number && is_descendent_of(&root.hash, hash).unwrap_or(false); + let is_descendant = + !is_finalized && root.number > number && is_descendent_of(hash, &root.hash)?; + let is_ancestor = !is_finalized + && !is_descendant && root.number < number + && is_descendent_of(&root.hash, hash)?; (is_finalized, is_descendant, is_ancestor) }; // if we have met finalized root - open it and return if is_finalized { - return Ok(FinalizationResult::Changed(Some(self.finalize_root_at(idx)))); + return Ok(FinalizationResult::Changed(Some( + self.finalize_root_at(idx), + ))); } // if node is descendant of finalized block - just leave it as is @@ -610,18 +613,19 @@ impl ForkTree where // descendent (in this case the node wasn't finalized earlier presumably // because the predicate didn't pass). let mut changed = false; - self.roots.retain(|root| { - let retain = - root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false) || - root.number == number && root.hash == *hash || - is_descendent_of(&root.hash, hash).unwrap_or(false); + let roots = std::mem::take(&mut self.roots); + + for root in roots { + let retain = root.number > number && is_descendent_of(hash, &root.hash)? + || root.number == number && root.hash == *hash + || is_descendent_of(&root.hash, hash)?; - if !retain { + if retain { + self.roots.push(root); + } else { changed = true; } - - retain - }); + } self.best_finalized_number = Some(number); @@ -903,8 +907,7 @@ impl Iterator for RemovedIterator { // child nodes are stored ordered by max branch height (decreasing), // we want to keep this ordering while iterating but since we're // using a stack for iterator state we need to reverse it. - let mut children = Vec::new(); - std::mem::swap(&mut children, &mut node.children); + let children = std::mem::take(&mut node.children); self.stack.extend(children.into_iter().rev()); (node.hash, node.number, node.data) -- GitLab From 661bbc9a73107d144aaea80e4ed0e4b54a5b2a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 9 Dec 2020 16:35:13 +0100 Subject: [PATCH 101/163] Merkle Mountain Range pallet (#7312) * Add MMR pallet. * WiP * Working on testing. * WiP - test * Tests passing. * Add proof generation. * Generate and verify proofs. * Allow verification of older proofs. * Move stuff to a module. * Split MMR stuff to it's own module. * Add docs. * Make parent hash optional. * LeafData failed approach. * Finally implement Compact stuff. * Compact encoding WiP * Implement remaining pieces. * Fix tests * Add docs to compact. * Implement for tuples. * Fix documentation. * Fix warnings and address review suggestion. * Update frame/merkle-mountain-range/src/primitives.rs Co-authored-by: cheme * Address review grumbles. * Removing missing crate. * Fix test. * Add some docs and test. * Add multiple instances. * Cargo.toml sync. * Fix no_std compilation. * More no_std stuff. * Rename MMR struct. * Addressing other grumbles. * Fix test. * Remove format for no_std compat. * Add test for MMR pallet. * Fix std feature. * Update versions. * Add to node/runtime. * Add hook to insert digest. * Make primitives public. * Update lib.rs tech spec/typos etc * Use WeightInfo and benchmarks. * Fix test. * Fix benchmarks. * Trait -> Config. * Fix typo. * Fix tests. Co-authored-by: cheme Co-authored-by: Addie Wagenknecht --- Cargo.lock | 47 +- Cargo.toml | 64 +-- bin/node/runtime/Cargo.toml | 3 + bin/node/runtime/src/lib.rs | 11 + client/executor/src/integration_tests/mod.rs | 4 +- frame/merkle-mountain-range/Cargo.toml | 44 ++ .../merkle-mountain-range/src/benchmarking.rs | 56 +++ .../src/default_weights.rs | 42 ++ frame/merkle-mountain-range/src/lib.rs | 231 ++++++++++ frame/merkle-mountain-range/src/mmr/mmr.rs | 186 ++++++++ frame/merkle-mountain-range/src/mmr/mod.rs | 45 ++ .../merkle-mountain-range/src/mmr/storage.rs | 112 +++++ frame/merkle-mountain-range/src/mmr/utils.rs | 131 ++++++ frame/merkle-mountain-range/src/mock.rs | 105 +++++ frame/merkle-mountain-range/src/primitives.rs | 415 ++++++++++++++++++ frame/merkle-mountain-range/src/tests.rs | 275 ++++++++++++ primitives/core/src/offchain/testing.rs | 15 +- primitives/runtime/src/offchain/storage.rs | 5 +- .../runtime/src/offchain/storage_lock.rs | 10 +- 19 files changed, 1751 insertions(+), 50 deletions(-) create mode 100644 frame/merkle-mountain-range/Cargo.toml create mode 100644 frame/merkle-mountain-range/src/benchmarking.rs create mode 100644 frame/merkle-mountain-range/src/default_weights.rs create mode 100644 frame/merkle-mountain-range/src/lib.rs create mode 100644 frame/merkle-mountain-range/src/mmr/mmr.rs create mode 100644 frame/merkle-mountain-range/src/mmr/mod.rs create mode 100644 frame/merkle-mountain-range/src/mmr/storage.rs create mode 100644 frame/merkle-mountain-range/src/mmr/utils.rs create mode 100644 frame/merkle-mountain-range/src/mock.rs create mode 100644 frame/merkle-mountain-range/src/primitives.rs create mode 100644 frame/merkle-mountain-range/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index e277d1d24a8..6a92f8e35f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,7 +419,7 @@ dependencies = [ "cfg-if 0.1.10", "clang-sys", "clap", - "env_logger", + "env_logger 0.7.1", "lazy_static", "lazycell", "log", @@ -716,6 +716,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e486fe53bb9f2ca0f58cb60e8679a5354fd6687a839942ef0a75967250289ca6" +dependencies = [ + "cfg-if 0.1.10", +] + [[package]] name = "clang-sys" version = "0.29.3" @@ -1328,6 +1337,19 @@ dependencies = [ "syn", ] +[[package]] +name = "env_logger" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -1450,7 +1472,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fdbe0d94371f9ce939b555dd342d0686cc4c0cadbcd4b61d70af5ff97eb4126" dependencies = [ - "env_logger", + "env_logger 0.7.1", "log", ] @@ -3911,6 +3933,7 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", + "pallet-mmr", "pallet-multisig", "pallet-offences", "pallet-offences-benchmarking", @@ -4651,6 +4674,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-mmr" +version = "2.0.0" +dependencies = [ + "ckb-merkle-mountain-range", + "env_logger 0.5.13", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-multisig" version = "2.0.0" @@ -5754,7 +5795,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger", + "env_logger 0.7.1", "log", "rand 0.7.3", "rand_core 0.5.1", diff --git a/Cargo.toml b/Cargo.toml index 6a007a209f1..206673c0ef2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,19 @@ [workspace] members = [ "bin/node-template/node", - "bin/node-template/runtime", "bin/node-template/pallets/template", + "bin/node-template/runtime", "bin/node/bench", "bin/node/browser-testing", "bin/node/cli", "bin/node/executor", "bin/node/primitives", - "bin/node/rpc-client", "bin/node/rpc", + "bin/node/rpc-client", "bin/node/runtime", "bin/node/testing", - "bin/utils/subkey", "bin/utils/chain-spec-builder", + "bin/utils/subkey", "client/api", "client/authority-discovery", "client/basic-authorship", @@ -26,42 +26,41 @@ members = [ "client/consensus/babe", "client/consensus/babe/rpc", "client/consensus/common", + "client/consensus/epochs", "client/consensus/manual-seal", "client/consensus/pow", - "client/consensus/uncles", "client/consensus/slots", - "client/consensus/epochs", + "client/consensus/uncles", "client/db", "client/executor", "client/executor/common", + "client/executor/runtime-test", "client/executor/wasmi", "client/executor/wasmtime", - "client/executor/runtime-test", "client/finality-grandpa", "client/informant", - "client/light", - "client/tracing", "client/keystore", + "client/light", "client/network", - "client/network/test", "client/network-gossip", + "client/network/test", "client/offchain", "client/peerset", "client/proposer-metrics", - "client/rpc-servers", "client/rpc", "client/rpc-api", + "client/rpc-servers", "client/service", "client/service/test", "client/state-db", "client/sync-state-rpc", "client/telemetry", + "client/tracing", "client/transaction-pool", "client/transaction-pool/graph", - "utils/prometheus", "frame/assets", - "frame/aura", "frame/atomic-swap", + "frame/aura", "frame/authority-discovery", "frame/authorship", "frame/babe", @@ -72,7 +71,6 @@ members = [ "frame/contracts/rpc", "frame/contracts/rpc/runtime-api", "frame/democracy", - "frame/elections-phragmen", "frame/elections", "frame/example", "frame/example-offchain-worker", @@ -83,6 +81,7 @@ members = [ "frame/im-online", "frame/indices", "frame/membership", + "frame/merkle-mountain-range", "frame/metadata", "frame/multisig", "frame/nicks", @@ -97,8 +96,8 @@ members = [ "frame/session/benchmarking", "frame/society", "frame/staking", - "frame/staking/reward-curve", "frame/staking/fuzzer", + "frame/staking/reward-curve", "frame/sudo", "frame/support", "frame/support/procedural", @@ -116,59 +115,59 @@ members = [ "frame/utility", "frame/vesting", "primitives/allocator", + "primitives/api", + "primitives/api/proc-macro", + "primitives/api/test", "primitives/application-crypto", "primitives/application-crypto/test", + "primitives/arithmetic", + "primitives/arithmetic/fuzzer", "primitives/authority-discovery", "primitives/authorship", "primitives/block-builder", "primitives/blockchain", + "primitives/chain-spec", "primitives/consensus/aura", "primitives/consensus/babe", "primitives/consensus/common", "primitives/consensus/pow", "primitives/consensus/vrf", "primitives/core", - "primitives/chain-spec", "primitives/database", "primitives/debug-derive", - "primitives/storage", "primitives/externalities", "primitives/finality-grandpa", "primitives/inherents", + "primitives/io", "primitives/keyring", "primitives/keystore", - "primitives/offchain", - "primitives/panic-handler", "primitives/npos-elections", - "primitives/npos-elections/fuzzer", "primitives/npos-elections/compact", + "primitives/npos-elections/fuzzer", + "primitives/offchain", + "primitives/panic-handler", "primitives/rpc", + "primitives/runtime", "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", + "primitives/runtime-interface/test", "primitives/runtime-interface/test-wasm", "primitives/runtime-interface/test-wasm-deprecated", - "primitives/runtime-interface/test", + "primitives/sandbox", "primitives/serializer", "primitives/session", - "primitives/api", - "primitives/api/proc-macro", - "primitives/api/test", - "primitives/arithmetic", - "primitives/arithmetic/fuzzer", - "primitives/io", - "primitives/runtime", - "primitives/sandbox", "primitives/staking", - "primitives/std", - "primitives/version", "primitives/state-machine", + "primitives/std", + "primitives/storage", "primitives/tasks", - "primitives/timestamp", "primitives/test-primitives", - "primitives/transaction-pool", + "primitives/timestamp", "primitives/tracing", + "primitives/transaction-pool", "primitives/trie", "primitives/utils", + "primitives/version", "primitives/wasm-interface", "test-utils/client", "test-utils/derive", @@ -183,6 +182,7 @@ members = [ "utils/frame/frame-utilities-cli", "utils/frame/rpc/support", "utils/frame/rpc/system", + "utils/prometheus", "utils/wasm-builder", ] diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 7d4cf5588e3..ad0f6b35a25 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -59,6 +59,7 @@ pallet-im-online = { version = "2.0.0", default-features = false, path = "../../ pallet-indices = { version = "2.0.0", default-features = false, path = "../../../frame/indices" } pallet-identity = { version = "2.0.0", default-features = false, path = "../../../frame/identity" } pallet-membership = { version = "2.0.0", default-features = false, path = "../../../frame/membership" } +pallet-mmr = { version = "2.0.0", default-features = false, path = "../../../frame/merkle-mountain-range" } pallet-multisig = { version = "2.0.0", default-features = false, path = "../../../frame/multisig" } pallet-offences = { version = "2.0.0", default-features = false, path = "../../../frame/offences" } pallet-offences-benchmarking = { version = "2.0.0", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } @@ -110,6 +111,7 @@ std = [ "pallet-indices/std", "sp-inherents/std", "pallet-membership/std", + "pallet-mmr/std", "pallet-multisig/std", "pallet-identity/std", "pallet-scheduler/std", @@ -160,6 +162,7 @@ runtime-benchmarks = [ "pallet-identity/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-indices/runtime-benchmarks", + "pallet-mmr/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ea9921beeef..2962ef10661 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -915,6 +915,15 @@ impl pallet_vesting::Config for Runtime { type WeightInfo = pallet_vesting::weights::SubstrateWeight; } +impl pallet_mmr::Config for Runtime { + const INDEXING_PREFIX: &'static [u8] = b"mmr"; + type Hashing = ::Hashing; + type Hash = ::Hash; + type LeafData = frame_system::Module; + type OnNewRoot = (); + type WeightInfo = (); +} + parameter_types! { pub const AssetDepositBase: Balance = 100 * DOLLARS; pub const AssetDepositPerZombie: Balance = 1 * DOLLARS; @@ -969,6 +978,7 @@ construct_runtime!( Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, Assets: pallet_assets::{Module, Call, Storage, Event}, + Mmr: pallet_mmr::{Module, Storage}, } ); @@ -1246,6 +1256,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_identity, Identity); add_benchmark!(params, batches, pallet_im_online, ImOnline); add_benchmark!(params, batches, pallet_indices, Indices); + add_benchmark!(params, batches, pallet_mmr, Mmr); add_benchmark!(params, batches, pallet_multisig, Multisig); add_benchmark!(params, batches, pallet_offences, OffencesBench::); add_benchmark!(params, batches, pallet_proxy, Proxy); diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index d41784f5aa0..0a00375145f 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -475,8 +475,6 @@ fn offchain_index(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn offchain_local_storage_should_work(wasm_method: WasmExecutionMethod) { - use sp_core::offchain::OffchainStorage; - let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); ext.register_extension(OffchainExt::new(offchain)); @@ -489,7 +487,7 @@ fn offchain_local_storage_should_work(wasm_method: WasmExecutionMethod) { ).unwrap(), true.encode(), ); - assert_eq!(state.read().persistent_storage.get(b"", b"test"), Some(vec![])); + assert_eq!(state.read().persistent_storage.get(b"test"), Some(vec![])); } #[test_case(WasmExecutionMethod::Interpreted)] diff --git a/frame/merkle-mountain-range/Cargo.toml b/frame/merkle-mountain-range/Cargo.toml new file mode 100644 index 00000000000..b46f42cacf6 --- /dev/null +++ b/frame/merkle-mountain-range/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "pallet-mmr" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME Merkle Mountain Range pallet." + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +mmr-lib = { package = "ckb-merkle-mountain-range", default-features = false, version = "0.3.1" } +serde = { version = "1.0.101", optional = true } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } + +[dev-dependencies] +env_logger = "0.5" +hex-literal = "0.3" + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "mmr-lib/std", + "serde", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", +] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/merkle-mountain-range/src/benchmarking.rs b/frame/merkle-mountain-range/src/benchmarking.rs new file mode 100644 index 00000000000..af634e18821 --- /dev/null +++ b/frame/merkle-mountain-range/src/benchmarking.rs @@ -0,0 +1,56 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Benchmarks for the MMR pallet. + +#![cfg_attr(not(feature = "std"), no_std)] + +use crate::*; +use frame_support::traits::OnInitialize; +use frame_benchmarking::benchmarks; +use sp_std::prelude::*; + +benchmarks! { + _ { } + + on_initialize { + let x in 1 .. 1_000; + + let leaves = x as u64; + }: { + for b in 0..leaves { + Module::::on_initialize((b as u32).into()); + } + } verify { + assert_eq!(crate::NumberOfLeaves::::get(), leaves); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::*; + use crate::tests::new_test_ext; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_on_initialize::()); + }) + } +} diff --git a/frame/merkle-mountain-range/src/default_weights.rs b/frame/merkle-mountain-range/src/default_weights.rs new file mode 100644 index 00000000000..0b31698545a --- /dev/null +++ b/frame/merkle-mountain-range/src/default_weights.rs @@ -0,0 +1,42 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Default weights for the MMR Pallet +//! This file was not auto-generated. + +use frame_support::weights::{ + Weight, constants::{WEIGHT_PER_NANOS, RocksDbWeight as DbWeight}, +}; + +impl crate::WeightInfo for () { + fn on_initialize(peaks: u64) -> Weight { + // Reading the parent hash. + let leaf_weight = DbWeight::get().reads(1); + // Blake2 hash cost. + let hash_weight = 2 * WEIGHT_PER_NANOS; + // No-op hook. + let hook_weight = 0; + + leaf_weight + .saturating_add(hash_weight) + .saturating_add(hook_weight) + .saturating_add(DbWeight::get().reads_writes( + 2 + peaks, + 2 + peaks, + )) + } +} diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs new file mode 100644 index 00000000000..afa6c9083c1 --- /dev/null +++ b/frame/merkle-mountain-range/src/lib.rs @@ -0,0 +1,231 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! # Merkle Mountain Range +//! +//! ## Overview +//! +//! Details on Merkle Mountain Ranges (MMRs) can be found here: +//! https://github.com/mimblewimble/grin/blob/master/doc/mmr.md +//! +//! The MMR pallet constructs a MMR from leaf data obtained on every block from +//! `LeafDataProvider`. MMR nodes are stored both in: +//! - on-chain storage - hashes only; not full leaf content) +//! - off-chain storage - via Indexing API we push full leaf content (and all internal nodes as +//! well) to the Off-chain DB, so that the data is available for Off-chain workers. +//! Hashing used for MMR is configurable independently from the rest of the runtime (i.e. not using +//! `frame_system::Hashing`) so something compatible with external chains can be used (like +//! Keccak256 for Ethereum compatibility). +//! +//! Depending on the usage context (off-chain vs on-chain) the pallet is able to: +//! - verify MMR leaf proofs (on-chain) +//! - generate leaf proofs (off-chain) +//! +//! See [primitives::Compact] documentation for how you can optimize proof size for leafs that are +//! composed from multiple elements. +//! +//! ## What for? +//! +//! Primary use case for this pallet is to generate MMR root hashes, that can latter on be used by +//! BEEFY protocol (see https://github.com/paritytech/grandpa-bridge-gadget). +//! MMR root hashes along with BEEFY will make it possible to build Super Light Clients (SLC) of +//! Substrate-based chains. The SLC will be able to follow finality and can be shown proofs of more +//! details that happened on the source chain. +//! In that case the chain which contains the pallet generates the Root Hashes and Proofs, which +//! are then presented to another chain acting as a light client which can verify them. +//! +//! Secondary use case is to archive historical data, but still be able to retrieve them on-demand +//! if needed. For instance if parent block hashes are stored in the MMR it's possible at any point +//! in time to provide a MMR proof about some past block hash, while this data can be safely pruned +//! from on-chain storage. +//! +//! NOTE This pallet is experimental and not proven to work in production. +//! +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::Encode; +use frame_support::{ + decl_module, decl_storage, + weights::Weight, +}; +use sp_runtime::traits; + +mod default_weights; +mod mmr; +#[cfg(any(feature = "runtime-benchmarks", test))] +mod benchmarking; +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +pub mod primitives; + +pub trait WeightInfo { + fn on_initialize(peaks: u64) -> Weight; +} + +/// This pallet's configuration trait +pub trait Config: frame_system::Config { + /// Prefix for elements stored in the Off-chain DB via Indexing API. + /// + /// Each node of the MMR is inserted both on-chain and off-chain via Indexing API. + /// The former does not store full leaf content, just it's compact version (hash), + /// and some of the inner mmr nodes might be pruned from on-chain storage. + /// The later will contain all the entries in their full form. + /// + /// Each node is stored in the Off-chain DB under key derived from the [INDEXING_PREFIX] and + /// it's in-tree index (MMR position). + const INDEXING_PREFIX: &'static [u8]; + + /// A hasher type for MMR. + /// + /// To construct trie nodes that result in merging (bagging) two peaks, depending on the node + /// kind we take either: + /// - The node (hash) itself if it's an inner node. + /// - The hash of SCALE-encoding of the leaf data if it's a leaf node. + /// + /// Then we create a tuple of these two hashes, SCALE-encode it (concatenate) and + /// hash, to obtain a new MMR inner node - the new peak. + type Hashing: traits::Hash>::Hash>; + + /// The hashing output type. + /// + /// This type is actually going to be stored in the MMR. + /// Required to be provided again, to satisfy trait bounds for storage items. + type Hash: traits::Member + traits::MaybeSerializeDeserialize + sp_std::fmt::Debug + + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + codec::Codec + + codec::EncodeLike; + + /// Data stored in the leaf nodes. + /// + /// The [LeafData](primitives::LeafDataProvider) is responsible for returning the entire leaf + /// data that will be inserted to the MMR. + /// [LeafDataProvider](primitives::LeafDataProvider)s can be composed into tuples to put + /// multiple elements into the tree. In such a case it might be worth using [primitives::Compact] + /// to make MMR proof for one element of the tuple leaner. + type LeafData: primitives::LeafDataProvider; + + /// A hook to act on the new MMR root. + /// + /// For some applications it might be beneficial to make the MMR root available externally + /// apart from having it in the storage. For instance you might output it in the header digest + /// (see [frame_system::Module::deposit_log]) to make it available for Light Clients. + /// Hook complexity should be `O(1)`. + type OnNewRoot: primitives::OnNewRoot<>::Hash>; + + /// Weights for this pallet. + type WeightInfo: WeightInfo; +} + +decl_storage! { + trait Store for Module, I: Instance = DefaultInstance> as MerkleMountainRange { + /// Latest MMR Root hash. + pub RootHash get(fn mmr_root_hash): >::Hash; + + /// Current size of the MMR (number of leaves). + pub NumberOfLeaves get(fn mmr_leaves): u64; + + /// Hashes of the nodes in the MMR. + /// + /// Note this collection only contains MMR peaks, the inner nodes (and leaves) + /// are pruned and only stored in the Offchain DB. + pub Nodes get(fn mmr_peak): map hasher(identity) u64 => Option<>::Hash>; + } +} + +decl_module! { + /// A public part of the pallet. + pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { + fn on_initialize(n: T::BlockNumber) -> Weight { + use primitives::LeafDataProvider; + let leaves = Self::mmr_leaves(); + let peaks_before = mmr::utils::NodesUtils::new(leaves).number_of_peaks(); + let data = T::LeafData::leaf_data(); + // append new leaf to MMR + let mut mmr: ModuleMmr = mmr::Mmr::new(leaves); + mmr.push(data).expect("MMR push never fails."); + + // update the size + let (leaves, root) = mmr.finalize().expect("MMR finalize never fails."); + >::on_new_root(&root); + + ::put(leaves); + >::put(root); + + let peaks_after = mmr::utils::NodesUtils::new(leaves).number_of_peaks(); + T::WeightInfo::on_initialize(peaks_before.max(peaks_after)) + } + } +} + +/// A MMR specific to the pallet. +type ModuleMmr = mmr::Mmr>; + +/// Leaf data. +type LeafOf = <>::LeafData as primitives::LeafDataProvider>::LeafData; + +/// Hashing used for the pallet. +pub(crate) type HashingOf = >::Hashing; + +impl, I: Instance> Module { + fn offchain_key(pos: u64) -> sp_std::prelude::Vec { + (T::INDEXING_PREFIX, pos).encode() + } + + /// Generate a MMR proof for the given `leaf_index`. + /// + /// Note this method can only be used from an off-chain context + /// (Offchain Worker or Runtime API call), since it requires + /// all the leaves to be present. + /// It may return an error or panic if used incorrectly. + pub fn generate_proof(leaf_index: u64) -> Result< + (LeafOf, primitives::Proof<>::Hash>), + mmr::Error, + > { + let mmr: ModuleMmr = mmr::Mmr::new(Self::mmr_leaves()); + mmr.generate_proof(leaf_index) + } + + /// Verify MMR proof for given `leaf`. + /// + /// This method is safe to use within the runtime code. + /// It will return `Ok(())` if the proof is valid + /// and an `Err(..)` if MMR is inconsistent (some leaves are missing) + /// or the proof is invalid. + pub fn verify_leaf( + leaf: LeafOf, + proof: primitives::Proof<>::Hash>, + ) -> Result<(), mmr::Error> { + if proof.leaf_count > Self::mmr_leaves() + || proof.leaf_count == 0 + || proof.items.len() as u32 > mmr::utils::NodesUtils::new(proof.leaf_count).depth() + { + return Err(mmr::Error::Verify.log_debug( + "The proof has incorrect number of leaves or proof items." + )); + } + + let mmr: ModuleMmr = mmr::Mmr::new(proof.leaf_count); + let is_valid = mmr.verify_leaf_proof(leaf, proof)?; + if is_valid { + Ok(()) + } else { + Err(mmr::Error::Verify.log_debug("The proof is incorrect.")) + } + } +} diff --git a/frame/merkle-mountain-range/src/mmr/mmr.rs b/frame/merkle-mountain-range/src/mmr/mmr.rs new file mode 100644 index 00000000000..ee27163ae43 --- /dev/null +++ b/frame/merkle-mountain-range/src/mmr/mmr.rs @@ -0,0 +1,186 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::{ + Config, HashingOf, Instance, + mmr::{ + Node, NodeOf, Hasher, + storage::{Storage, OffchainStorage, RuntimeStorage}, + utils::NodesUtils, + }, + primitives, +}; +use frame_support::{debug, RuntimeDebug}; +use sp_std::fmt; +#[cfg(not(feature = "std"))] +use sp_std::{vec, prelude::Vec}; + +/// A wrapper around a MMR library to expose limited functionality. +/// +/// Available functions depend on the storage kind ([Runtime](crate::mmr::storage::RuntimeStorage) +/// vs [Off-chain](crate::mmr::storage::OffchainStorage)). +pub struct Mmr where + T: Config, + I: Instance, + L: primitives::FullLeaf, + Storage: mmr_lib::MMRStore>, +{ + mmr: mmr_lib::MMR< + NodeOf, + Hasher, L>, + Storage + >, + leaves: u64, +} + +impl Mmr where + T: Config, + I: Instance, + L: primitives::FullLeaf, + Storage: mmr_lib::MMRStore>, +{ + /// Create a pointer to an existing MMR with given number of leaves. + pub fn new(leaves: u64) -> Self { + let size = NodesUtils::new(leaves).size(); + Self { + mmr: mmr_lib::MMR::new(size, Default::default()), + leaves, + } + } + + /// Verify proof of a single leaf. + pub fn verify_leaf_proof( + &self, + leaf: L, + proof: primitives::Proof<>::Hash>, + ) -> Result { + let p = mmr_lib::MerkleProof::< + NodeOf, + Hasher, L>, + >::new( + self.mmr.mmr_size(), + proof.items.into_iter().map(Node::Hash).collect(), + ); + let position = mmr_lib::leaf_index_to_pos(proof.leaf_index); + let root = self.mmr.get_root().map_err(|e| Error::GetRoot.log_error(e))?; + p.verify( + root, + vec![(position, Node::Data(leaf))], + ).map_err(|e| Error::Verify.log_debug(e)) + } + + /// Return the internal size of the MMR (number of nodes). + #[cfg(test)] + pub fn size(&self) -> u64 { + self.mmr.mmr_size() + } +} + +/// Runtime specific MMR functions. +impl Mmr where + T: Config, + I: Instance, + L: primitives::FullLeaf, +{ + + /// Push another item to the MMR. + /// + /// Returns element position (index) in the MMR. + pub fn push(&mut self, leaf: L) -> Option { + let position = self.mmr.push(Node::Data(leaf)) + .map_err(|e| Error::Push.log_error(e)) + .ok()?; + + self.leaves += 1; + + Some(position) + } + + /// Commit the changes to underlying storage, return current number of leaves and + /// calculate the new MMR's root hash. + pub fn finalize(self) -> Result<(u64, >::Hash), Error> { + let root = self.mmr.get_root().map_err(|e| Error::GetRoot.log_error(e))?; + self.mmr.commit().map_err(|e| Error::Commit.log_error(e))?; + Ok((self.leaves, root.hash())) + } +} + +/// Off-chain specific MMR functions. +impl Mmr where + T: Config, + I: Instance, + L: primitives::FullLeaf, +{ + /// Generate a proof for given leaf index. + /// + /// Proof generation requires all the nodes (or their hashes) to be available in the storage. + /// (i.e. you can't run the function in the pruned storage). + pub fn generate_proof(&self, leaf_index: u64) -> Result< + (L, primitives::Proof<>::Hash>), + Error + > { + let position = mmr_lib::leaf_index_to_pos(leaf_index); + let store = >::default(); + let leaf = match mmr_lib::MMRStore::get_elem(&store, position) { + Ok(Some(Node::Data(leaf))) => leaf, + e => return Err(Error::LeafNotFound.log_debug(e)), + }; + let leaf_count = self.leaves; + self.mmr.gen_proof(vec![position]) + .map_err(|e| Error::GenerateProof.log_error(e)) + .map(|p| primitives::Proof { + leaf_index, + leaf_count, + items: p.proof_items().iter().map(|x| x.hash()).collect(), + }) + .map(|p| (leaf, p)) + } +} + +/// Merkle Mountain Range operation error. +#[derive(RuntimeDebug)] +#[cfg_attr(test, derive(PartialEq, Eq))] +pub enum Error { + /// Error while pushing new node. + Push, + /// Error getting the new root. + GetRoot, + /// Error commiting changes. + Commit, + /// Error during proof generation. + GenerateProof, + /// Proof verification error. + Verify, + /// Leaf not found in the storage. + LeafNotFound, +} + +impl Error { + /// Consume given error `e` with `self` and generate a native log entry with error details. + pub(crate) fn log_error(self, e: impl fmt::Debug) -> Self { + debug::native::error!("[{:?}] MMR error: {:?}", self, e); + self + } + + /// Consume given error `e` with `self` and generate a native log entry with error details. + pub(crate) fn log_debug(self, e: impl fmt::Debug) -> Self { + debug::native::debug!("[{:?}] MMR error: {:?}", self, e); + self + } + +} + diff --git a/frame/merkle-mountain-range/src/mmr/mod.rs b/frame/merkle-mountain-range/src/mmr/mod.rs new file mode 100644 index 00000000000..7fd8f5ae1bf --- /dev/null +++ b/frame/merkle-mountain-range/src/mmr/mod.rs @@ -0,0 +1,45 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +pub mod storage; +pub mod utils; +mod mmr; + +use crate::primitives::FullLeaf; +use sp_runtime::traits; + +pub use self::mmr::{Mmr, Error}; + +/// Node type for runtime `T`. +pub type NodeOf = Node<>::Hashing, L>; + +/// A node stored in the MMR. +pub type Node = crate::primitives::DataOrHash; + +/// Default Merging & Hashing behavior for MMR. +pub struct Hasher(sp_std::marker::PhantomData<(H, L)>); + +impl mmr_lib::Merge for Hasher { + type Item = Node; + + fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item { + let mut concat = left.hash().as_ref().to_vec(); + concat.extend_from_slice(right.hash().as_ref()); + + Node::Hash(::hash(&concat)) + } +} diff --git a/frame/merkle-mountain-range/src/mmr/storage.rs b/frame/merkle-mountain-range/src/mmr/storage.rs new file mode 100644 index 00000000000..a1aa57087a2 --- /dev/null +++ b/frame/merkle-mountain-range/src/mmr/storage.rs @@ -0,0 +1,112 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A MMR storage implementations. + +use codec::Encode; +use crate::mmr::{NodeOf, Node}; +use crate::{NumberOfLeaves, Nodes, Module, Config, Instance, primitives}; +use frame_support::{StorageMap, StorageValue}; +#[cfg(not(feature = "std"))] +use sp_std::prelude::Vec; + +/// A marker type for runtime-specific storage implementation. +/// +/// Allows appending new items to the MMR and proof verification. +/// MMR nodes are appended to two different storages: +/// 1. We add nodes (leaves) hashes to the on-chain storge (see [crate::Nodes]). +/// 2. We add full leaves (and all inner nodes as well) into the `IndexingAPI` during block +/// processing, so the values end up in the Offchain DB if indexing is enabled. +pub struct RuntimeStorage; + +/// A marker type for offchain-specific storage implementation. +/// +/// Allows proof generation and verification, but does not support appending new items. +/// MMR nodes are assumed to be stored in the Off-Chain DB. Note this storage type +/// DOES NOT support adding new items to the MMR. +pub struct OffchainStorage; + +/// A storage layer for MMR. +/// +/// There are two different implementations depending on the use case. +/// See docs for [RuntimeStorage] and [OffchainStorage]. +pub struct Storage( + sp_std::marker::PhantomData<(StorageType, T, I, L)> +); + +impl Default for Storage { + fn default() -> Self { + Self(Default::default()) + } +} + +impl mmr_lib::MMRStore> for Storage where + T: Config, + I: Instance, + L: primitives::FullLeaf, +{ + fn get_elem(&self, pos: u64) -> mmr_lib::Result>> { + let key = Module::::offchain_key(pos); + // Retrieve the element from Off-chain DB. + Ok( + sp_io::offchain ::local_storage_get(sp_core::offchain::StorageKind::PERSISTENT, &key) + .and_then(|v| codec::Decode::decode(&mut &*v).ok()) + ) + } + + fn append(&mut self, _: u64, _: Vec>) -> mmr_lib::Result<()> { + panic!("MMR must not be altered in the off-chain context.") + } +} + +impl mmr_lib::MMRStore> for Storage where + T: Config, + I: Instance, + L: primitives::FullLeaf, +{ + fn get_elem(&self, pos: u64) -> mmr_lib::Result>> { + Ok(>::get(pos) + .map(Node::Hash) + ) + } + + fn append(&mut self, pos: u64, elems: Vec>) -> mmr_lib::Result<()> { + let mut leaves = crate::NumberOfLeaves::::get(); + let mut size = crate::mmr::utils::NodesUtils::new(leaves).size(); + if pos != size { + return Err(mmr_lib::Error::InconsistentStore); + } + + for elem in elems { + // on-chain we only store the hash (even if it's a leaf) + >::insert(size, elem.hash()); + // Indexing API is used to store the full leaf content. + elem.using_encoded(|elem| { + sp_io::offchain_index::set(&Module::::offchain_key(size), elem) + }); + size += 1; + + if let Node::Data(..) = elem { + leaves += 1; + } + } + + NumberOfLeaves::::put(leaves); + + Ok(()) + } +} diff --git a/frame/merkle-mountain-range/src/mmr/utils.rs b/frame/merkle-mountain-range/src/mmr/utils.rs new file mode 100644 index 00000000000..7a55605a64c --- /dev/null +++ b/frame/merkle-mountain-range/src/mmr/utils.rs @@ -0,0 +1,131 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Merkle Mountain Range utilities. + +/// MMR nodes & size -related utilities. +pub struct NodesUtils { + no_of_leaves: u64, +} + +impl NodesUtils { + /// Create new instance of MMR nodes utilities for given number of leaves. + pub fn new(no_of_leaves: u64) -> Self { + Self { no_of_leaves } + } + + /// Calculate number of peaks in the MMR. + pub fn number_of_peaks(&self) -> u64 { + self.number_of_leaves().count_ones() as u64 + } + + /// Return the number of leaves in the MMR. + pub fn number_of_leaves(&self) -> u64 { + self.no_of_leaves + } + + /// Calculate the total size of MMR (number of nodes). + pub fn size(&self) -> u64 { + 2 * self.no_of_leaves - self.number_of_peaks() + } + + /// Calculate maximal depth of the MMR. + pub fn depth(&self) -> u32 { + if self.no_of_leaves == 0 { + return 0 + } + + 64 - self.no_of_leaves + .next_power_of_two() + .leading_zeros() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_calculate_number_of_leaves_correctly() { + assert_eq!( + vec![0, 1, 2, 3, 4, 9, 15, 21] + .into_iter() + .map(|n| NodesUtils::new(n).depth()) + .collect::>(), + vec![0, 1, 2, 3, 3, 5, 5, 6] + ); + } + + #[test] + fn should_calculate_depth_correclty() { + assert_eq!( + vec![0, 1, 2, 3, 4, 9, 15, 21] + .into_iter() + .map(|n| NodesUtils::new(n).number_of_leaves()) + .collect::>(), + vec![0, 1, 2, 3, 4, 9, 15, 21] + ); + } + + #[test] + fn should_calculate_number_of_peaks_correctly() { + assert_eq!( + vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21] + .into_iter() + .map(|n| NodesUtils::new(n).number_of_peaks()) + .collect::>(), + vec![0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 3] + ); + } + + #[test] + fn should_calculate_the_size_correctly() { + let _ = env_logger::try_init(); + + let leaves = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21]; + let sizes = vec![0, 1, 3, 4, 7, 8, 10, 11, 15, 16, 18, 19, 22, 23, 25, 26, 39]; + assert_eq!( + leaves + .clone() + .into_iter() + .map(|n| NodesUtils::new(n).size()) + .collect::>(), + sizes.clone() + ); + + // size cross-check + let mut actual_sizes = vec![]; + for s in &leaves[1..] { + crate::tests::new_test_ext().execute_with(|| { + let mut mmr = crate::mmr::Mmr::< + crate::mmr::storage::RuntimeStorage, + crate::mock::Test, + crate::DefaultInstance, + _, + >::new(0); + for i in 0..*s { + mmr.push(i); + } + actual_sizes.push(mmr.size()); + }) + } + assert_eq!( + sizes[1..], + actual_sizes[..], + ); + } +} diff --git a/frame/merkle-mountain-range/src/mock.rs b/frame/merkle-mountain-range/src/mock.rs new file mode 100644 index 00000000000..c311d53446b --- /dev/null +++ b/frame/merkle-mountain-range/src/mock.rs @@ -0,0 +1,105 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::*; +use crate::primitives::{LeafDataProvider, Compact}; + +use codec::{Encode, Decode}; +use frame_support::{ + impl_outer_origin, parameter_types, +}; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{ + BlakeTwo256, Keccak256, IdentityLookup, + }, +}; +use sp_std::cell::RefCell; +use sp_std::prelude::*; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; +} +impl frame_system::Config for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Call = (); + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = sp_core::sr25519::Public; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +impl Config for Test { + const INDEXING_PREFIX: &'static [u8] = b"mmr-"; + + type Hashing = Keccak256; + type Hash = H256; + type LeafData = Compact, LeafData)>; + type OnNewRoot = (); + type WeightInfo = (); +} + +#[derive(Encode, Decode, Clone, Default, Eq, PartialEq, Debug)] +pub struct LeafData { + pub a: u64, + pub b: Vec, +} + +impl LeafData { + pub fn new(a: u64) -> Self { + Self { + a, + b: Default::default(), + } + } +} + +thread_local! { + pub static LEAF_DATA: RefCell = RefCell::new(Default::default()); +} + +impl LeafDataProvider for LeafData { + type LeafData = Self; + + fn leaf_data() -> Self::LeafData { + LEAF_DATA.with(|r| r.borrow().clone()) + } +} + +pub(crate) type MMR = Module; diff --git a/frame/merkle-mountain-range/src/primitives.rs b/frame/merkle-mountain-range/src/primitives.rs new file mode 100644 index 00000000000..cab4b6a0dc8 --- /dev/null +++ b/frame/merkle-mountain-range/src/primitives.rs @@ -0,0 +1,415 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Merkle Mountain Range primitive types. + +use frame_support::RuntimeDebug; +use sp_runtime::traits; +use sp_std::fmt; +#[cfg(not(feature = "std"))] +use sp_std::prelude::Vec; + +/// A provider of the MMR's leaf data. +pub trait LeafDataProvider { + /// A type that should end up in the leaf of MMR. + type LeafData: FullLeaf; + + /// The method to return leaf data that should be placed + /// in the leaf node appended MMR at this block. + /// + /// This is being called by the `on_initialize` method of + /// this pallet at the very beginning of each block. + fn leaf_data() -> Self::LeafData; +} + +impl LeafDataProvider for () { + type LeafData = (); + + fn leaf_data() -> Self::LeafData { + () + } +} + +/// The most common use case for MMRs is to store historical block hashes, +/// so that any point in time in the future we can receive a proof about some past +/// blocks without using excessive on-chain storage. +/// Hence we implement the [LeafDataProvider] for [frame_system::Module], since the +/// current block hash is not available (since the block is not finished yet), +/// we use the `parent_hash` here. +impl LeafDataProvider for frame_system::Module { + type LeafData = ::Hash; + + fn leaf_data() -> Self::LeafData { + Self::parent_hash() + } +} + +/// New MMR root notification hook. +pub trait OnNewRoot { + /// Function called by the pallet in case new MMR root has been computed. + fn on_new_root(root: &Hash); +} + +/// No-op implementation of [OnNewRoot]. +impl OnNewRoot for () { + fn on_new_root(_root: &Hash) {} +} + +/// A full leaf content stored in the offchain-db. +pub trait FullLeaf: Clone + PartialEq + fmt::Debug + codec::Decode { + /// Encode the leaf either in it's full or compact form. + /// + /// NOTE the encoding returned here MUST be `Decode`able into `FullLeaf`. + fn using_encoded R>(&self, f: F, compact: bool) -> R; +} + +impl FullLeaf for T { + fn using_encoded R>(&self, f: F, _compact: bool) -> R { + codec::Encode::using_encoded(self, f) + } +} + +/// An element representing either full data or it's hash. +/// +/// See [Compact] to see how it may be used in practice to reduce the size +/// of proofs in case multiple [LeafDataProvider]s are composed together. +/// This is also used internally by the MMR to differentiate leaf nodes (data) +/// and inner nodes (hashes). +/// +/// [DataOrHash::hash] method calculates the hash of this element in it's compact form, +/// so should be used instead of hashing the encoded form (which will always be non-compact). +#[derive(RuntimeDebug, Clone, PartialEq)] +pub enum DataOrHash { + /// Arbitrary data in it's full form. + Data(L), + /// A hash of some data. + Hash(H::Output), +} + +impl From for DataOrHash { + fn from(l: L) -> Self { + Self::Data(l) + } +} + +mod encoding { + use super::*; + + /// A helper type to implement [codec::Codec] for [DataOrHash]. + #[derive(codec::Encode, codec::Decode)] + enum Either { + Left(A), + Right(B), + } + + impl codec::Encode for DataOrHash { + fn encode_to(&self, dest: &mut T) { + match self { + Self::Data(l) => l.using_encoded( + |data| Either::<&[u8], &H::Output>::Left(data).encode_to(dest), false + ), + Self::Hash(h) => Either::<&[u8], &H::Output>::Right(h).encode_to(dest), + } + } + } + + impl codec::Decode for DataOrHash { + fn decode(value: &mut I) -> Result { + let decoded: Either, H::Output> = Either::decode(value)?; + Ok(match decoded { + Either::Left(l) => DataOrHash::Data(L::decode(&mut &*l)?), + Either::Right(r) => DataOrHash::Hash(r), + }) + } + } +} + +impl DataOrHash { + /// Retrieve a hash of this item. + /// + /// Depending on the node type it's going to either be a contained value for [DataOrHash::Hash] + /// node, or a hash of SCALE-encoded [DataOrHash::Data] data. + pub fn hash(&self) -> H::Output { + match *self { + Self::Data(ref leaf) => leaf.using_encoded(::hash, true), + Self::Hash(ref hash) => hash.clone(), + } + } +} + +/// A composition of multiple leaf elements with compact form representation. +/// +/// When composing together multiple [LeafDataProvider]s you will end up with +/// a tuple of `LeafData` that each element provides. +/// +/// However this will cause the leaves to have significant size, while for some +/// use cases it will be enough to prove only one element of the tuple. +/// That's the rationale for [Compact] struct. We wrap each element of the tuple +/// into [DataOrHash] and each tuple element is hashed first before constructing +/// the final hash of the entire tuple. This allows you to replace tuple elements +/// you don't care about with their hashes. +#[derive(RuntimeDebug, Clone, PartialEq)] +pub struct Compact { + pub tuple: T, + _hash: sp_std::marker::PhantomData, +} + +impl sp_std::ops::Deref for Compact { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.tuple + } +} + +impl Compact { + pub fn new(tuple: T) -> Self { + Self { tuple, _hash: Default::default() } + } +} + +impl codec::Decode for Compact { + fn decode(value: &mut I) -> Result { + T::decode(value).map(Compact::new) + } +} + +macro_rules! impl_leaf_data_for_tuple { + ( $( $name:ident : $id:tt ),+ ) => { + /// [FullLeaf] implementation for `Compact, ...)>` + impl FullLeaf for Compact, )+ )> where + H: traits::Hash, + $( $name: FullLeaf ),+ + { + fn using_encoded R>(&self, f: F, compact: bool) -> R { + if compact { + codec::Encode::using_encoded(&( + $( DataOrHash::::Hash(self.tuple.$id.hash()), )+ + ), f) + } else { + codec::Encode::using_encoded(&self.tuple, f) + } + } + } + + /// [LeafDataProvider] implementation for `Compact, ...)>` + /// + /// This provides a compact-form encoding for tuples wrapped in [Compact]. + impl LeafDataProvider for Compact where + H: traits::Hash, + $( $name: LeafDataProvider ),+ + { + type LeafData = Compact< + H, + ( $( DataOrHash, )+ ), + >; + + fn leaf_data() -> Self::LeafData { + let tuple = ( + $( DataOrHash::Data($name::leaf_data()), )+ + ); + Compact::new(tuple) + } + } + + /// [LeafDataProvider] implementation for `(Tuple, ...)` + /// + /// This provides regular (non-compactable) composition of [LeafDataProvider]s. + impl<$( $name ),+> LeafDataProvider for ( $( $name, )+ ) where + ( $( $name::LeafData, )+ ): FullLeaf, + $( $name: LeafDataProvider ),+ + { + type LeafData = ( $( $name::LeafData, )+ ); + + fn leaf_data() -> Self::LeafData { + ( + $( $name::leaf_data(), )+ + ) + } + } + } +} + +/// Test functions implementation for `Compact, ...)>` +#[cfg(test)] +impl Compact, DataOrHash)> where + H: traits::Hash, + A: FullLeaf, + B: FullLeaf, +{ + /// Retrieve a hash of this item in it's compact form. + pub fn hash(&self) -> H::Output { + self.using_encoded(::hash, true) + } +} + +impl_leaf_data_for_tuple!(A:0); +impl_leaf_data_for_tuple!(A:0, B:1); +impl_leaf_data_for_tuple!(A:0, B:1, C:2); +impl_leaf_data_for_tuple!(A:0, B:1, C:2, D:3); +impl_leaf_data_for_tuple!(A:0, B:1, C:2, D:3, E:4); + +/// A MMR proof data for one of the leaves. +#[derive(codec::Encode, codec::Decode, RuntimeDebug, Clone, PartialEq, Eq)] +pub struct Proof { + /// The index of the leaf the proof is for. + pub leaf_index: u64, + /// Number of leaves in MMR, when the proof was generated. + pub leaf_count: u64, + /// Proof elements (hashes of siblings of inner nodes on the path to the leaf). + pub items: Vec, +} + + +#[cfg(test)] +mod tests { + use super::*; + + use codec::Decode; + use crate::tests::hex; + use sp_runtime::traits::Keccak256; + + type Test = DataOrHash; + type TestCompact = Compact; + type TestProof = Proof<::Output>; + + #[test] + fn should_encode_decode_proof() { + // given + let proof: TestProof = Proof { + leaf_index: 5, + leaf_count: 10, + items: vec![ + hex("c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd"), + hex("d3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd"), + hex("e3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd"), + ], + }; + + // when + let encoded = codec::Encode::encode(&proof); + let decoded = TestProof::decode(&mut &*encoded); + + // then + assert_eq!(decoded, Ok(proof)); + } + + #[test] + fn should_encode_decode_correctly_if_no_compact() { + // given + let cases = vec![ + Test::Data("Hello World!".into()), + Test::Hash(hex("c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd")), + Test::Data("".into()), + Test::Data("3e48d6bcd417fb22e044747242451e2c0f3e602d1bcad2767c34808621956417".into()), + ]; + + // when + let encoded = cases + .iter() + .map(codec::Encode::encode) + .collect::>(); + + let decoded = encoded + .iter() + .map(|x| Test::decode(&mut &**x)) + .collect::>(); + + // then + assert_eq!(decoded, cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::>()); + // check encoding correctness + assert_eq!(&encoded[0], &hex_literal::hex!("00343048656c6c6f20576f726c6421")); + assert_eq!( + encoded[1].as_slice(), + hex_literal::hex!( + "01c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd" + ).as_ref() + ); + } + + #[test] + fn should_return_the_hash_correctly() { + // given + let a = Test::Data("Hello World!".into()); + let b = Test::Hash(hex("c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd")); + + // when + let a = a.hash(); + let b = b.hash(); + + // then + assert_eq!(a, hex("a9c321be8c24ba4dc2bd73f5300bde67dc57228ab8b68b607bb4c39c5374fac9")); + assert_eq!(b, hex("c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd")); + } + + #[test] + fn compact_should_work() { + // given + let a = Test::Data("Hello World!".into()); + let b = Test::Data("".into()); + + // when + let c: TestCompact = Compact::new((a.clone(), b.clone())); + let d: TestCompact = Compact::new(( + Test::Hash(a.hash()), + Test::Hash(b.hash()), + )); + + // then + assert_eq!(c.hash(), d.hash()); + } + + #[test] + fn compact_should_encode_decode_correctly() { + // given + let a = Test::Data("Hello World!".into()); + let b = Test::Data("".into()); + + let c: TestCompact = Compact::new((a.clone(), b.clone())); + let d: TestCompact = Compact::new(( + Test::Hash(a.hash()), + Test::Hash(b.hash()), + )); + let cases = vec![c, d.clone()]; + + // when + let encoded_compact = cases + .iter() + .map(|c| c.using_encoded(|x| x.to_vec(), true)) + .collect::>(); + + let encoded = cases + .iter() + .map(|c| c.using_encoded(|x| x.to_vec(), false)) + .collect::>(); + + let decoded_compact = encoded_compact + .iter() + .map(|x| TestCompact::decode(&mut &**x)) + .collect::>(); + + let decoded = encoded + .iter() + .map(|x| TestCompact::decode(&mut &**x)) + .collect::>(); + + // then + assert_eq!(decoded, cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::>()); + + assert_eq!(decoded_compact, vec![Ok(d.clone()), Ok(d.clone())]); + } +} diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs new file mode 100644 index 00000000000..059ff6612f1 --- /dev/null +++ b/frame/merkle-mountain-range/src/tests.rs @@ -0,0 +1,275 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::*; +use crate::mock::*; +use crate::primitives::{Proof, Compact}; + +use frame_support::traits::OnInitialize; +use sp_core::{ + H256, + offchain::{ + testing::TestOffchainExt, + OffchainExt, + }, +}; + +pub(crate) fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default().build_storage::().unwrap().into() +} + +fn register_offchain_ext(ext: &mut sp_io::TestExternalities) { + let (offchain, _offchain_state) = TestOffchainExt::with_offchain_db(ext.offchain_db()); + ext.register_extension(OffchainExt::new(offchain)); +} + +fn new_block() -> u64 { + let number = frame_system::Module::::block_number() + 1; + let hash = H256::repeat_byte(number as u8); + LEAF_DATA.with(|r| r.borrow_mut().a = number); + + frame_system::Module::::initialize( + &number, + &hash, + &Default::default(), + &Default::default(), + frame_system::InitKind::Full, + ); + MMR::on_initialize(number) +} + +pub(crate) fn hex(s: &str) -> H256 { + s.parse().unwrap() +} + +fn decode_node(v: Vec) -> mmr::Node< + ::Hashing, + (H256, LeafData), +> { + use crate::primitives::DataOrHash; + type A = DataOrHash::<::Hashing, H256>; + type B = DataOrHash::<::Hashing, LeafData>; + type Node = mmr::Node<::Hashing, (A, B)>; + let tuple: Node = codec::Decode::decode(&mut &v[..]).unwrap(); + + match tuple { + mmr::Node::Data((DataOrHash::Data(a), DataOrHash::Data(b))) => mmr::Node::Data((a, b)), + mmr::Node::Hash(hash) => mmr::Node::Hash(hash), + _ => unreachable!(), + } +} + +fn init_chain(blocks: usize) { + // given + for _ in 0..blocks { + new_block(); + } +} + +#[test] +fn should_start_empty() { + let _ = env_logger::try_init(); + new_test_ext().execute_with(|| { + // given + assert_eq!( + crate::RootHash::::get(), + "0000000000000000000000000000000000000000000000000000000000000000".parse().unwrap() + ); + assert_eq!(crate::NumberOfLeaves::::get(), 0); + assert_eq!(crate::Nodes::::get(0), None); + + // when + let weight = new_block(); + + // then + assert_eq!(crate::NumberOfLeaves::::get(), 1); + assert_eq!(crate::Nodes::::get(0), + Some(hex("da5e6d0616e05c6a6348605a37ca33493fc1a15ad1e6a405ee05c17843fdafed"))); + assert_eq!( + crate::RootHash::::get(), + hex("da5e6d0616e05c6a6348605a37ca33493fc1a15ad1e6a405ee05c17843fdafed") + ); + assert!(weight != 0); + }); +} + +#[test] +fn should_append_to_mmr_when_on_initialize_is_called() { + let _ = env_logger::try_init(); + let mut ext = new_test_ext(); + ext.execute_with(|| { + // when + new_block(); + new_block(); + + // then + assert_eq!(crate::NumberOfLeaves::::get(), 2); + assert_eq!(crate::Nodes::::get(0), + Some(hex("da5e6d0616e05c6a6348605a37ca33493fc1a15ad1e6a405ee05c17843fdafed"))); + assert_eq!(crate::Nodes::::get(1), + Some(hex("ff5d891b28463a3440e1b650984685efdf260e482cb3807d53c49090841e755f"))); + assert_eq!(crate::Nodes::::get(2), + Some(hex("bc54778fab79f586f007bd408dca2c4aa07959b27d1f2c8f4f2549d1fcfac8f8"))); + assert_eq!(crate::Nodes::::get(3), None); + assert_eq!( + crate::RootHash::::get(), + hex("bc54778fab79f586f007bd408dca2c4aa07959b27d1f2c8f4f2549d1fcfac8f8") + ); + }); + + // make sure the leaves end up in the offchain DB + ext.persist_offchain_overlay(); + let offchain_db = ext.offchain_db(); + assert_eq!(offchain_db.get(&MMR::offchain_key(0)).map(decode_node), Some(mmr::Node::Data(( + H256::repeat_byte(1), + LeafData::new(1), + )))); + assert_eq!(offchain_db.get(&MMR::offchain_key(1)).map(decode_node), Some(mmr::Node::Data(( + H256::repeat_byte(2), + LeafData::new(2), + )))); + assert_eq!(offchain_db.get(&MMR::offchain_key(2)).map(decode_node), Some(mmr::Node::Hash( + hex("bc54778fab79f586f007bd408dca2c4aa07959b27d1f2c8f4f2549d1fcfac8f8") + ))); + assert_eq!(offchain_db.get(&MMR::offchain_key(3)), None); +} + +#[test] +fn should_construct_larger_mmr_correctly() { + let _ = env_logger::try_init(); + new_test_ext().execute_with(|| { + // when + init_chain(7); + + // then + assert_eq!(crate::NumberOfLeaves::::get(), 7); + assert_eq!(crate::Nodes::::get(0), + Some(hex("da5e6d0616e05c6a6348605a37ca33493fc1a15ad1e6a405ee05c17843fdafed"))); + assert_eq!(crate::Nodes::::get(10), + Some(hex("af3327deed0515c8d1902c9b5cd375942d42f388f3bfe3d1cd6e1b86f9cc456c"))); + assert_eq!( + crate::RootHash::::get(), + hex("fc4f9042bd2f73feb26f3fc42db834c5f1943fa20070ddf106c486a478a0d561") + ); + }); +} + +#[test] +fn should_generate_proofs_correctly() { + let _ = env_logger::try_init(); + let mut ext = new_test_ext(); + // given + ext.execute_with(|| init_chain(7)); + ext.persist_offchain_overlay(); + + // Try to generate proofs now. This requires the offchain extensions to be present + // to retrieve full leaf data. + register_offchain_ext(&mut ext); + ext.execute_with(|| { + // when generate proofs for all leaves + let proofs = (0_u64..crate::NumberOfLeaves::::get()) + .into_iter() + .map(|leaf_index| crate::Module::::generate_proof(leaf_index).unwrap()) + .collect::>(); + + // then + assert_eq!(proofs[0], (Compact::new(( + H256::repeat_byte(1).into(), + LeafData::new(1).into(), + )), Proof { + leaf_index: 0, + leaf_count: 7, + items: vec![ + hex("ff5d891b28463a3440e1b650984685efdf260e482cb3807d53c49090841e755f"), + hex("00b0046bd2d63fcb760cf50a262448bb2bbf9a264b0b0950d8744044edf00dc3"), + hex("16de0900b57bf359a0733674ebfbba0f494e95a8391b4bfeae850019399f3ec0"), + ], + })); + assert_eq!(proofs[4], (Compact::new(( + H256::repeat_byte(5).into(), + LeafData::new(5).into(), + )), Proof { + leaf_index: 4, + leaf_count: 7, + items: vec![ + hex("e53ee36ba6c068b1a6cfef7862fed5005df55615e1c9fa6eeefe08329ac4b94b"), + hex("c09d4a008a0f1ef37860bef33ec3088ccd94268c0bfba7ff1b3c2a1075b0eb92"), + hex("af3327deed0515c8d1902c9b5cd375942d42f388f3bfe3d1cd6e1b86f9cc456c"), + ], + })); + assert_eq!(proofs[6], (Compact::new(( + H256::repeat_byte(7).into(), + LeafData::new(7).into(), + )), Proof { + leaf_index: 6, + leaf_count: 7, + items: vec![ + hex("e53ee36ba6c068b1a6cfef7862fed5005df55615e1c9fa6eeefe08329ac4b94b"), + hex("dad09f50b41822fc5ecadc25b08c3a61531d4d60e962a5aa0b6998fad5c37c5e"), + ], + })); + }); +} + +#[test] +fn should_verify() { + let _ = env_logger::try_init(); + + // Start off with chain initialisation and storing indexing data off-chain + // (MMR Leafs) + let mut ext = new_test_ext(); + ext.execute_with(|| init_chain(7)); + ext.persist_offchain_overlay(); + + // Try to generate proof now. This requires the offchain extensions to be present + // to retrieve full leaf data. + register_offchain_ext(&mut ext); + let (leaf, proof5) = ext.execute_with(|| { + // when + crate::Module::::generate_proof(5).unwrap() + }); + + // Now to verify the proof, we really shouldn't require offchain storage or extension. + // Hence we initialize the storage once again, using different externalities and then + // verify. + let mut ext2 = new_test_ext(); + ext2.execute_with(|| { + init_chain(7); + // then + assert_eq!(crate::Module::::verify_leaf(leaf, proof5), Ok(())); + }); +} + +#[test] +fn should_verify_on_the_next_block_since_there_is_no_pruning_yet() { + let _ = env_logger::try_init(); + let mut ext = new_test_ext(); + // given + ext.execute_with(|| init_chain(7)); + + ext.persist_offchain_overlay(); + register_offchain_ext(&mut ext); + + ext.execute_with(|| { + // when + let (leaf, proof5) = crate::Module::::generate_proof(5).unwrap(); + new_block(); + + // then + assert_eq!(crate::Module::::verify_leaf(leaf, proof5), Ok(())); + }); +} diff --git a/primitives/core/src/offchain/testing.rs b/primitives/core/src/offchain/testing.rs index 3fe34cc0cfa..5256f417711 100644 --- a/primitives/core/src/offchain/testing.rs +++ b/primitives/core/src/offchain/testing.rs @@ -70,6 +70,8 @@ pub struct TestPersistentOffchainDB { } impl TestPersistentOffchainDB { + const PREFIX: &'static [u8] = b""; + /// Create a new and empty offchain storage db for persistent items pub fn new() -> Self { Self { @@ -82,11 +84,16 @@ impl TestPersistentOffchainDB { let mut me = self.persistent.write(); for ((_prefix, key), value_operation) in changes.drain() { match value_operation { - OffchainOverlayedChange::SetValue(val) => me.set(b"", key.as_slice(), val.as_slice()), - OffchainOverlayedChange::Remove => me.remove(b"", key.as_slice()), + OffchainOverlayedChange::SetValue(val) => me.set(Self::PREFIX, key.as_slice(), val.as_slice()), + OffchainOverlayedChange::Remove => me.remove(Self::PREFIX, key.as_slice()), } } } + + /// Retrieve a key from the test backend. + pub fn get(&self, key: &[u8]) -> Option> { + OffchainStorage::get(self, Self::PREFIX, key) + } } impl OffchainStorage for TestPersistentOffchainDB { @@ -266,8 +273,8 @@ impl offchain::Externalities for TestOffchainExt { fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { let state = self.0.read(); match kind { - StorageKind::LOCAL => state.local_storage.get(b"", key), - StorageKind::PERSISTENT => state.persistent_storage.get(b"", key), + StorageKind::LOCAL => state.local_storage.get(TestPersistentOffchainDB::PREFIX, key), + StorageKind::PERSISTENT => state.persistent_storage.get(key), } } diff --git a/primitives/runtime/src/offchain/storage.rs b/primitives/runtime/src/offchain/storage.rs index 2f62d400c0b..e39514686e1 100644 --- a/primitives/runtime/src/offchain/storage.rs +++ b/primitives/runtime/src/offchain/storage.rs @@ -105,7 +105,6 @@ mod tests { use sp_io::TestExternalities; use sp_core::offchain::{ OffchainExt, - OffchainStorage, testing, }; @@ -125,7 +124,7 @@ mod tests { assert_eq!(val.get::(), Some(Some(15_u32))); assert_eq!(val.get::>(), Some(None)); assert_eq!( - state.read().persistent_storage.get(b"", b"testval"), + state.read().persistent_storage.get(b"testval"), Some(vec![15_u8, 0, 0, 0]) ); }) @@ -148,7 +147,7 @@ mod tests { assert_eq!(result, Ok(Ok(16_u32))); assert_eq!(val.get::(), Some(Some(16_u32))); assert_eq!( - state.read().persistent_storage.get(b"", b"testval"), + state.read().persistent_storage.get(b"testval"), Some(vec![16_u8, 0, 0, 0]) ); diff --git a/primitives/runtime/src/offchain/storage_lock.rs b/primitives/runtime/src/offchain/storage_lock.rs index 451753931ec..0d9cf835c15 100644 --- a/primitives/runtime/src/offchain/storage_lock.rs +++ b/primitives/runtime/src/offchain/storage_lock.rs @@ -452,7 +452,7 @@ pub trait BlockNumberProvider { #[cfg(test)] mod tests { use super::*; - use sp_core::offchain::{testing, OffchainExt, OffchainStorage}; + use sp_core::offchain::{testing, OffchainExt}; use sp_io::TestExternalities; const VAL_1: u32 = 0u32; @@ -485,7 +485,7 @@ mod tests { } }); // lock must have been cleared at this point - assert_eq!(state.read().persistent_storage.get(b"", b"lock_1"), None); + assert_eq!(state.read().persistent_storage.get(b"lock_1"), None); } #[test] @@ -508,7 +508,7 @@ mod tests { guard.forget(); }); // lock must have been cleared at this point - let opt = state.read().persistent_storage.get(b"", b"lock_2"); + let opt = state.read().persistent_storage.get(b"lock_2"); assert!(opt.is_some()); } @@ -540,7 +540,7 @@ mod tests { }); // lock must have been cleared at this point - let opt = state.read().persistent_storage.get(b"", b"lock_3"); + let opt = state.read().persistent_storage.get(b"lock_3"); assert!(opt.is_some()); } @@ -587,7 +587,7 @@ mod tests { }); // lock must have been cleared at this point - let opt = state.read().persistent_storage.get(b"", b"lock_4"); + let opt = state.read().persistent_storage.get(b"lock_4"); assert_eq!(opt.unwrap(), vec![132_u8, 3u8, 0, 0, 0, 0, 0, 0]); // 132 + 256 * 3 = 900 } } -- GitLab From 9d843c3e1b05c0ddfa2469277f5b522f7d57f612 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 9 Dec 2020 21:09:38 +0100 Subject: [PATCH 102/163] frame/staking/README: Fix broken link (#7703) --- frame/staking/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/staking/README.md b/frame/staking/README.md index 1f1ba3dffa8..a379d0a7ad5 100644 --- a/frame/staking/README.md +++ b/frame/staking/README.md @@ -176,7 +176,7 @@ Validators and nominators are rewarded at the end of each era. The total reward calculated using the era duration and the staking rate (the total amount of tokens staked by nominators and validators, divided by the total token supply). It aims to incentivize toward a defined staking rate. The full specification can be found -[here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model). +[here](https://research.web3.foundation/en/latest/polkadot/economics/1-token-economics.html#inflation-model). Total reward is split among validators and their nominators depending on the number of points they received during the era. Points are added to a validator using -- GitLab From 6b600cdeb4043e512bc5f342eb02a5a17d26797a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 9 Dec 2020 22:58:22 +0100 Subject: [PATCH 103/163] *: Update to libp2p v0.32.0 (#7696) * *: Update to libp2p v0.32.0 * Cargo.lock: Update async-tls to 0.10.2 * client/network/request_response: Adjust to new request response events * client/network/request_response.rs: Clean up silently failing responses * client/network/discovery: Lazily instantiate mdns * client/network/discovery: Exclude MdnsWrapper for target_os unknown * client/network/discovery: Fix indentation * client/network/request-response: Use LruCache to track pending resp time * client/network/request_responses: Fix early connection closed error * client/network/request-response: Replace debug_assert with debug * client/network/request-response: Fix typo * client/network/request-response: Don't emit event on send_response fail * client/network/request-response: Revert waker.wake_by_ref() * client/network/request-resp: Make duration in InboundRequest optional * client/network/req-resp: Don't emit two events for busy builder When a response builder is busy incoming requests are dropped. Previously this was reported both via a `ResponseFailure::Busy` and a `ReponseFailure::Network(InboundFailure::Omisssion)` event. With this commit the former is removed, leaving only the latter in place. --- Cargo.lock | 93 ++++++++----- bin/node/browser-testing/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 6 +- client/network/src/behaviour.rs | 4 +- client/network/src/discovery.rs | 56 ++++++-- client/network/src/request_responses.rs | 171 +++++++++++++++--------- client/network/src/service.rs | 10 +- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- 14 files changed, 225 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a92f8e35f0..ccecc302c2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "async-io" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a0b2bb8ae20fede194e779150fe283f65a4a08461b496de546ec366b174ad9" +checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" dependencies = [ "concurrent-queue", "fastrand", @@ -306,15 +306,15 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-tls" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85a97c4a0ecce878efd3f945f119c78a646d8975340bca0398f9bb05c30cc52" +checksum = "dd0d8b6fc362bebff7502479fb5e9aed00c8cc3abc5af755536e73a128f0cb88" dependencies = [ "futures-core", "futures-io", - "rustls", + "rustls 0.19.0", "webpki", - "webpki-roots 0.20.0", + "webpki-roots", ] [[package]] @@ -2364,7 +2364,7 @@ dependencies = [ "futures-util", "hyper 0.13.9", "log", - "rustls", + "rustls 0.18.1", "rustls-native-certs", "tokio 0.2.23", "tokio-rustls", @@ -2414,6 +2414,22 @@ dependencies = [ "libc", ] +[[package]] +name = "if-watch" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d7c5e361e6b05c882b4847dd98992534cebc6fcde7f4bc98225bcf10fd6d0d" +dependencies = [ + "async-io", + "futures 0.3.8", + "futures-lite", + "if-addrs", + "ipnet", + "libc", + "log", + "winapi 0.3.9", +] + [[package]] name = "impl-codec" version = "0.4.2" @@ -2780,9 +2796,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" [[package]] name = "libloading" @@ -2802,9 +2818,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.31.2" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "724846a3194368fefcac7ebdab12e01b8ac382e3efe399ddbd28851ab34f396f" +checksum = "fac71e0cd4ba56b06464c3669bdfe893dd6c14f05f7ed1ba0965b1bc5933ee71" dependencies = [ "atomic", "bytes 0.5.6", @@ -2993,24 +3009,23 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4458ec36b5ab2662fb4d5c8bb9b6e1591da0ab6efe8881c7a7670ef033bc8937" +checksum = "7b934ee03a361f317df7d75defa4177b285534c58f49d5e6e240278e13ef3f65" dependencies = [ - "async-std", + "async-io", "data-encoding", "dns-parser", - "either", "futures 0.3.8", + "if-watch", "lazy_static", "libp2p-core", "libp2p-swarm", "log", - "net2", "rand 0.7.3", "smallvec 1.5.0", + "socket2", "void", - "wasm-timer", ] [[package]] @@ -3101,9 +3116,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e952dcc9d2d7e7e45ae8bfcff255723091bd43e3e9a7741a0af8a17fe55b3ed" +checksum = "bd96c3580fe59a9379ac7906c2f61c7f5ad3b7515362af0e72153a7cc9a45550" dependencies = [ "async-trait", "bytes 0.5.6", @@ -3179,9 +3194,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5736e2fccdcea6e728bbaf903bddc113be223313ce2c756ad9fe43b5a2b0f06" +checksum = "046031ad8ade16f2f0547350e4b2cea36c78cb10426e9c0d9eab35fa9943b969" dependencies = [ "async-tls", "either", @@ -3189,12 +3204,12 @@ dependencies = [ "libp2p-core", "log", "quicksink", - "rustls", + "rustls 0.19.0", "rw-stream-sink", "soketto", "url 2.2.0", "webpki", - "webpki-roots 0.21.0", + "webpki-roots", ] [[package]] @@ -6258,6 +6273,19 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b" +dependencies = [ + "base64 0.13.0", + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "rustls-native-certs" version = "0.4.0" @@ -6265,7 +6293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "629d439a7672da82dd955498445e496ee2096fe2117b9f796558a43fdb9e59b8" dependencies = [ "openssl-probe", - "rustls", + "rustls 0.18.1", "schannel", "security-framework", ] @@ -7892,11 +7920,11 @@ dependencies = [ [[package]] name = "socket2" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d" +checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "redox_syscall", "winapi 0.3.9", @@ -9399,7 +9427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a" dependencies = [ "futures-core", - "rustls", + "rustls 0.18.1", "tokio 0.2.23", "webpki", ] @@ -10255,15 +10283,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "webpki-roots" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.21.0" diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index f1cad30aede..53f83b8fcaa 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.31.1", default-features = false } +libp2p = { version = "0.32.0", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 4cd2dae1388..90f8f229b4d 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -23,7 +23,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.31.2", default-features = false, features = ["kad"] } +libp2p = { version = "0.32.0", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index f323f1940b1..ece015cc4bc 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -19,7 +19,7 @@ regex = "1.4.2" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.31.2" +libp2p = "0.32.0" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index bbbb83f2061..b1ae4aa31c9 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.31.2", default-features = false } +libp2p = { version = "0.32.0", default-features = false } log = "0.4.8" lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 0b8d3da928f..6c40b08ed84 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -64,13 +64,13 @@ wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.31.2" +version = "0.32.0" default-features = false -features = ["identify", "kad", "mdns-async-std", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] +features = ["identify", "kad", "mdns", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.31.2", default-features = false } +libp2p = { version = "0.32.0", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index b2914a5e0a7..8b9e321ca59 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -88,7 +88,7 @@ pub enum BehaviourOut { protocol: Cow<'static, str>, /// If `Ok`, contains the time elapsed between when we received the request and when we /// sent back the response. If `Err`, the error that happened. - result: Result, + result: Result, ResponseFailure>, }, /// A request initiated using [`Behaviour::send_request`] has succeeded or failed. @@ -417,7 +417,7 @@ impl NetworkBehaviourEventProcess { diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index e65d557a7bd..b2517efb660 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -59,8 +59,6 @@ use libp2p::kad::handler::KademliaHandlerProto; use libp2p::kad::QueryId; use libp2p::kad::record::{self, store::{MemoryStore, RecordStore}}; #[cfg(not(target_os = "unknown"))] -use libp2p::swarm::toggle::Toggle; -#[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn}; @@ -206,15 +204,9 @@ impl DiscoveryConfig { discovery_only_if_under_num, #[cfg(not(target_os = "unknown"))] mdns: if enable_mdns { - match Mdns::new() { - Ok(mdns) => Some(mdns).into(), - Err(err) => { - warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err); - None.into() - } - } + MdnsWrapper::Instantiating(Mdns::new().boxed()) } else { - None.into() + MdnsWrapper::Disabled }, allow_non_globals_in_dht, known_external_addresses: LruHashSet::new( @@ -234,7 +226,7 @@ pub struct DiscoveryBehaviour { kademlias: HashMap>, /// Discovers nodes on the local network. #[cfg(not(target_os = "unknown"))] - mdns: Toggle, + mdns: MdnsWrapper, /// Stream that fires when we need to perform the next random Kademlia query. next_kad_random_query: Delay, /// After `next_kad_random_query` triggers, the next one triggers after this duration. @@ -785,6 +777,48 @@ fn protocol_name_from_protocol_id(id: &ProtocolId) -> Vec { v } +/// [`Mdns::new`] returns a future. Instead of forcing [`DiscoveryConfig::finish`] and all its +/// callers to be async, lazily instantiate [`Mdns`]. +#[cfg(not(target_os = "unknown"))] +enum MdnsWrapper { + Instantiating(futures::future::BoxFuture<'static, std::io::Result>), + Ready(Mdns), + Disabled, +} + +#[cfg(not(target_os = "unknown"))] +impl MdnsWrapper { + fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { + match self { + MdnsWrapper::Instantiating(_) => Vec::new(), + MdnsWrapper::Ready(mdns) => mdns.addresses_of_peer(peer_id), + MdnsWrapper::Disabled => Vec::new(), + } + } + + fn poll( + &mut self, + cx: &mut Context<'_>, + params: &mut impl PollParameters, + ) -> Poll> { + loop { + match self { + MdnsWrapper::Instantiating(fut) => { + *self = match futures::ready!(fut.as_mut().poll(cx)) { + Ok(mdns) => MdnsWrapper::Ready(mdns), + Err(err) => { + warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err); + MdnsWrapper::Disabled + }, + } + } + MdnsWrapper::Ready(mdns) => return mdns.poll(cx, params), + MdnsWrapper::Disabled => return Poll::Pending, + } + } + } +} + #[cfg(test)] mod tests { use crate::config::ProtocolId; diff --git a/client/network/src/request_responses.rs b/client/network/src/request_responses.rs index 69a2ffda1c8..a410ae0dff5 100644 --- a/client/network/src/request_responses.rs +++ b/client/network/src/request_responses.rs @@ -48,9 +48,10 @@ use libp2p::{ PollParameters, ProtocolsHandler, }, }; +use lru::LruCache; use std::{ borrow::Cow, collections::{hash_map::Entry, HashMap}, convert::TryFrom as _, io, iter, - pin::Pin, task::{Context, Poll}, time::Duration, + pin::Pin, task::{Context, Poll}, time::{Duration, Instant}, }; pub use libp2p::request_response::{InboundFailure, OutboundFailure, RequestId}; @@ -128,7 +129,10 @@ pub enum Event { protocol: Cow<'static, str>, /// If `Ok`, contains the time elapsed between when we received the request and when we /// sent back the response. If `Err`, the error that happened. - result: Result, + /// + /// Note: Given that response time is tracked on a best-effort basis only, `Ok(time)` can be + /// `None`. + result: Result, ResponseFailure>, }, /// A request initiated using [`RequestResponsesBehaviour::send_request`] has succeeded or @@ -154,21 +158,19 @@ pub struct RequestResponsesBehaviour { /// Whenever an incoming request arrives, a `Future` is added to this list and will yield the /// response to send back to the remote. pending_responses: stream::FuturesUnordered< - Pin + Send>> + Pin> + Send>> >, + + /// Whenever an incoming request arrives, the arrival [`Instant`] is recorded here. + pending_responses_arrival_time: LruCache, } /// Generated by the response builder and waiting to be processed. -enum RequestProcessingOutcome { - Response { - protocol: Cow<'static, str>, - inner_channel: ResponseChannel, ()>>, - response: Vec, - }, - Busy { - peer: PeerId, - protocol: Cow<'static, str>, - }, +struct RequestProcessingOutcome { + request_id: RequestId, + protocol: Cow<'static, str>, + inner_channel: ResponseChannel, ()>>, + response: Vec, } impl RequestResponsesBehaviour { @@ -201,7 +203,8 @@ impl RequestResponsesBehaviour { Ok(Self { protocols, - pending_responses: stream::FuturesUnordered::new(), + pending_responses: Default::default(), + pending_responses_arrival_time: LruCache::new(1_000), }) } @@ -347,22 +350,31 @@ impl NetworkBehaviour for RequestResponsesBehaviour { > { 'poll_all: loop { // Poll to see if any response is ready to be sent back. - while let Poll::Ready(Some(result)) = self.pending_responses.poll_next_unpin(cx) { - match result { - RequestProcessingOutcome::Response { - protocol, inner_channel, response - } => { - if let Some((protocol, _)) = self.protocols.get_mut(&*protocol) { - protocol.send_response(inner_channel, Ok(response)); - } - } - RequestProcessingOutcome::Busy { peer, protocol } => { - let out = Event::InboundRequest { - peer, - protocol, - result: Err(ResponseFailure::Busy), - }; - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(out)); + while let Poll::Ready(Some(outcome)) = self.pending_responses.poll_next_unpin(cx) { + let RequestProcessingOutcome { + request_id, + protocol: protocol_name, + inner_channel, + response + } = match outcome { + Some(outcome) => outcome, + // The response builder was too busy and thus the request was dropped. This is + // later on reported as a `InboundFailure::Omission`. + None => continue, + }; + + if let Some((protocol, _)) = self.protocols.get_mut(&*protocol_name) { + if let Err(_) = protocol.send_response(inner_channel, Ok(response)) { + // Note: In case this happened due to a timeout, the corresponding + // `RequestResponse` behaviour will emit an `InboundFailure::Timeout` event. + self.pending_responses_arrival_time.pop(&request_id); + log::debug!( + target: "sub-libp2p", + "Failed to send response for {:?} on protocol {:?} due to a \ + timeout or due to the connection to the peer being closed. \ + Dropping response", + request_id, protocol_name, + ); } } } @@ -409,15 +421,21 @@ impl NetworkBehaviour for RequestResponsesBehaviour { // Received a request from a remote. RequestResponseEvent::Message { peer, - message: RequestResponseMessage::Request { request, channel, .. }, + message: RequestResponseMessage::Request { request_id, request, channel, .. }, } => { + self.pending_responses_arrival_time.put( + request_id.clone(), + Instant::now(), + ); + let (tx, rx) = oneshot::channel(); // Submit the request to the "response builder" passed by the user at // initialization. if let Some(resp_builder) = resp_builder { - // If the response builder is too busy, silently drop `tx`. - // This will be reported as a `Busy` error. + // If the response builder is too busy, silently drop `tx`. This + // will be reported by the corresponding `RequestResponse` through + // an `InboundFailure::Omission` event. let _ = resp_builder.try_send(IncomingRequest { peer: peer.clone(), payload: request, @@ -428,13 +446,14 @@ impl NetworkBehaviour for RequestResponsesBehaviour { let protocol = protocol.clone(); self.pending_responses.push(Box::pin(async move { // The `tx` created above can be dropped if we are not capable of - // processing this request, which is reflected as a "Busy" error. + // processing this request, which is reflected as a + // `InboundFailure::Omission` event. if let Ok(response) = rx.await { - RequestProcessingOutcome::Response { - protocol, inner_channel: channel, response - } + Some(RequestProcessingOutcome { + request_id, protocol, inner_channel: channel, response + }) } else { - RequestProcessingOutcome::Busy { peer, protocol } + None } })); @@ -445,11 +464,10 @@ impl NetworkBehaviour for RequestResponsesBehaviour { // Received a response from a remote to one of our requests. RequestResponseEvent::Message { - message: - RequestResponseMessage::Response { - request_id, - response, - }, + message: RequestResponseMessage::Response { + request_id, + response, + }, .. } => { let out = Event::RequestFinished { @@ -472,8 +490,10 @@ impl NetworkBehaviour for RequestResponsesBehaviour { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(out)); } - // Remote has tried to send a request but failed. - RequestResponseEvent::InboundFailure { peer, error, .. } => { + // An inbound request failed, either while reading the request or due to failing + // to send a response. + RequestResponseEvent::InboundFailure { request_id, peer, error, .. } => { + self.pending_responses_arrival_time.pop(&request_id); let out = Event::InboundRequest { peer, protocol: protocol.clone(), @@ -481,6 +501,24 @@ impl NetworkBehaviour for RequestResponsesBehaviour { }; return Poll::Ready(NetworkBehaviourAction::GenerateEvent(out)); } + RequestResponseEvent::ResponseSent { request_id, peer } => { + let arrival_time = self.pending_responses_arrival_time.pop(&request_id) + .map(|t| t.elapsed()); + if arrival_time.is_none() { + log::debug!( + "Expected to find arrival time for sent response. Is the LRU \ + cache size set too small?", + ); + } + + let out = Event::InboundRequest { + peer, + protocol: protocol.clone(), + result: Ok(arrival_time), + }; + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(out)); + + } }; } } @@ -520,8 +558,6 @@ pub enum RequestFailure { /// Error when processing a request sent by a remote. #[derive(Debug, derive_more::Display, derive_more::Error)] pub enum ResponseFailure { - /// Internal response builder is too busy to process this request. - Busy, /// Problem on the network. #[display(fmt = "Problem on the network")] Network(#[error(ignore)] InboundFailure), @@ -655,7 +691,10 @@ impl RequestResponseCodec for GenericCodec { #[cfg(test)] mod tests { - use futures::{channel::mpsc, prelude::*}; + use futures::channel::mpsc; + use futures::executor::LocalPool; + use futures::prelude::*; + use futures::task::Spawn; use libp2p::identity::Keypair; use libp2p::Multiaddr; use libp2p::core::upgrade; @@ -666,7 +705,8 @@ mod tests { #[test] fn basic_request_response_works() { - let protocol_name = "/test/req-rep/1"; + let protocol_name = "/test/req-resp/1"; + let mut pool = LocalPool::new(); // Build swarms whose behaviour is `RequestResponsesBehaviour`. let mut swarms = (0..2) @@ -694,12 +734,12 @@ mod tests { inbound_queue: Some(tx), })).unwrap(); - async_std::task::spawn(async move { + pool.spawner().spawn_obj(async move { while let Some(rq) = rx.next().await { assert_eq!(rq.payload, b"this is a request"); let _ = rq.pending_response.send(b"this is a response".to_vec()); } - }); + }.boxed().into()).unwrap(); b }; @@ -719,26 +759,24 @@ mod tests { Swarm::dial_addr(&mut swarms[0].0, dial_addr).unwrap(); } - // Running `swarm[0]` in the background until a `InboundRequest` event happens, - // which is a hint about the test having ended. - async_std::task::spawn({ + // Running `swarm[0]` in the background. + pool.spawner().spawn_obj({ let (mut swarm, _) = swarms.remove(0); async move { loop { match swarm.next_event().await { SwarmEvent::Behaviour(super::Event::InboundRequest { result, .. }) => { - assert!(result.is_ok()); - break + result.unwrap(); }, _ => {} } } - } - }); + }.boxed().into() + }).unwrap(); // Remove and run the remaining swarm. let (mut swarm, _) = swarms.remove(0); - async_std::task::block_on(async move { + pool.run_until(async move { let mut sent_request_id = None; loop { @@ -769,7 +807,8 @@ mod tests { #[test] fn max_response_size_exceeded() { - let protocol_name = "/test/req-rep/1"; + let protocol_name = "/test/req-resp/1"; + let mut pool = LocalPool::new(); // Build swarms whose behaviour is `RequestResponsesBehaviour`. let mut swarms = (0..2) @@ -797,12 +836,12 @@ mod tests { inbound_queue: Some(tx), })).unwrap(); - async_std::task::spawn(async move { + pool.spawner().spawn_obj(async move { while let Some(rq) = rx.next().await { assert_eq!(rq.payload, b"this is a request"); let _ = rq.pending_response.send(b"this response exceeds the limit".to_vec()); } - }); + }.boxed().into()).unwrap(); b }; @@ -824,7 +863,7 @@ mod tests { // Running `swarm[0]` in the background until a `InboundRequest` event happens, // which is a hint about the test having ended. - async_std::task::spawn({ + pool.spawner().spawn_obj({ let (mut swarm, _) = swarms.remove(0); async move { loop { @@ -836,12 +875,12 @@ mod tests { _ => {} } } - } - }); + }.boxed().into() + }).unwrap(); // Remove and run the remaining swarm. let (mut swarm, _) = swarms.remove(0); - async_std::task::block_on(async move { + pool.run_until(async move { let mut sent_request_id = None; loop { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index c59aeb41229..3a368088e53 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1373,19 +1373,21 @@ impl Future for NetworkWorker { Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::InboundRequest { protocol, result, .. })) => { if let Some(metrics) = this.metrics.as_ref() { match result { - Ok(serve_time) => { + Ok(Some(serve_time)) => { metrics.requests_in_success_total .with_label_values(&[&protocol]) .observe(serve_time.as_secs_f64()); } + // Response time tracking is happening on a best-effort basis. Ignore + // the event in case response time could not be provided. + Ok(None) => {}, Err(err) => { let reason = match err { - ResponseFailure::Busy => "busy", ResponseFailure::Network(InboundFailure::Timeout) => "timeout", ResponseFailure::Network(InboundFailure::UnsupportedProtocols) => "unsupported", - ResponseFailure::Network(InboundFailure::ConnectionClosed) => - "connection-closed", + ResponseFailure::Network(InboundFailure::ResponseOmission) => + "busy-omitted", }; metrics.requests_in_failure_total diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 9640ca9ae8c..fea6ead4f70 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.31.2", default-features = false } +libp2p = { version = "0.32.0", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index d3f782bb945..1b74a8099b6 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.31.2", default-features = false } +libp2p = { version = "0.32.0", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 58f2a066293..aa585fb8f4d 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.5" -libp2p = { version = "0.31.2", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.32.0", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 375e976ce5b..cf9804f86f2 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.31.2", default-features = false } +libp2p = { version = "0.32.0", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } -- GitLab From 12823277857d73e8b9e520930783996c227099a6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 10 Dec 2020 10:22:40 +0100 Subject: [PATCH 104/163] *: Update to libp2p v0.32.2 (#7708) Version v0.32.2 pins async-tls to the semver compliant v0.11.0 instead of the yanked async-tls v0.10.2. --- Cargo.lock | 12 ++++++------ bin/node/browser-testing/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 4 ++-- client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccecc302c2e..1555957f80e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -306,9 +306,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-tls" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0d8b6fc362bebff7502479fb5e9aed00c8cc3abc5af755536e73a128f0cb88" +checksum = "2f23d769dbf1838d5df5156e7b1ad404f4c463d1ac2c6aeb6cd943630f8a8400" dependencies = [ "futures-core", "futures-io", @@ -2818,9 +2818,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.32.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac71e0cd4ba56b06464c3669bdfe893dd6c14f05f7ed1ba0965b1bc5933ee71" +checksum = "022cdac4ab124be12de581e591796d4dfb7d1f1eef94669d2c1eaa0e98dd2f0e" dependencies = [ "atomic", "bytes 0.5.6", @@ -3194,9 +3194,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046031ad8ade16f2f0547350e4b2cea36c78cb10426e9c0d9eab35fa9943b969" +checksum = "522a877ce42ededf1f5dd011dbc40ea116f1776818f09dacb3d7a206f3ad6305" dependencies = [ "async-tls", "either", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index 53f83b8fcaa..f60dc55b6f7 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 90f8f229b4d..8878becd7e0 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -23,7 +23,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.32.0", default-features = false, features = ["kad"] } +libp2p = { version = "0.32.2", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index ece015cc4bc..02d14d0d194 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -19,7 +19,7 @@ regex = "1.4.2" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.32.0" +libp2p = "0.32.2" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index b1ae4aa31c9..5b82bd679c0 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } log = "0.4.8" lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 6c40b08ed84..1ad54366ce4 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -64,13 +64,13 @@ wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.32.0" +version = "0.32.2" default-features = false features = ["identify", "kad", "mdns", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index fea6ead4f70..880e2c1f04e 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 1b74a8099b6..41e2033bccf 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index aa585fb8f4d..98ed6388661 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.5" -libp2p = { version = "0.32.0", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.32.2", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index cf9804f86f2..dc1550ed295 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.32.0", default-features = false } +libp2p = { version = "0.32.2", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } -- GitLab From b1ef77071f9b085777b4cef08a2348b762131003 Mon Sep 17 00:00:00 2001 From: Albrecht <14820950+weichweich@users.noreply.github.com> Date: Thu, 10 Dec 2020 14:23:47 +0100 Subject: [PATCH 105/163] kilt&polimec ss58 prefix (#7547) * kilt ss58 address * polimec ss58 prefix --- primitives/core/src/crypto.rs | 4 ++++ ss58-registry.json | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 6a07e3ce402..f2101a67124 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -506,6 +506,10 @@ ss58_address_format!( (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") NodleAccount => (37, "nodle", "Nodle Chain mainnet, standard account (*25519).") + KiltAccount => + (38, "kilt", "KILT Chain mainnet, standard account (*25519).") + PolimecAccount => + (41, "poli", "Polimec Chain mainnet, standard account (*25519).") SubstrateAccount => (42, "substrate", "Any Substrate network, standard account (*25519).") Reserved43 => diff --git a/ss58-registry.json b/ss58-registry.json index 8c7110060ba..5c90856505a 100644 --- a/ss58-registry.json +++ b/ss58-registry.json @@ -298,6 +298,15 @@ "standardAccount": "*25519", "website": "https://nodle.io/" }, + { + "prefix": 38, + "network": "kilt", + "displayName": "KILT Chain", + "symbols": ["KILT"], + "decimals": [18], + "standardAccount": "*25519", + "website": "https://kilt.io/" + }, { "prefix": 39, "network": "mathchain", @@ -316,6 +325,15 @@ "standardAccount": "*25519", "website": "https://mathwallet.org" }, + { + "prefix": 41, + "network": "poli", + "displayName": "Polimec Chain", + "symbols": null, + "decimals": null, + "standardAccount": "*25519", + "website": "https://polimec.io/" + }, { "prefix": 42, "network": "substrate", -- GitLab From 2a7a985d34fea5db68f12e9c1fbde8142de27cdc Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 10 Dec 2020 14:38:56 +0100 Subject: [PATCH 106/163] Fix docs (#7710) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix docs * Update frame/merkle-mountain-range/src/lib.rs Co-authored-by: Alexander Theißen Co-authored-by: Alexander Theißen --- bin/node/browser-testing/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 2 +- client/authority-discovery/src/service.rs | 8 ++++---- client/authority-discovery/src/worker.rs | 6 +++--- client/basic-authorship/src/basic_authorship.rs | 2 +- client/basic-authorship/src/lib.rs | 2 +- client/cli/src/commands/run_cmd.rs | 7 ++++--- client/cli/src/commands/utils.rs | 2 +- client/cli/src/config.rs | 2 +- client/finality-grandpa/src/lib.rs | 2 +- client/network/src/gossip.rs | 2 +- client/service/src/client/mod.rs | 11 ++++++----- client/telemetry/src/async_record.rs | 2 +- frame/contracts/src/schedule.rs | 2 +- frame/example/src/lib.rs | 6 +++--- frame/merkle-mountain-range/src/lib.rs | 6 +++--- frame/proxy/src/lib.rs | 2 +- frame/session/src/historical/onchain.rs | 2 +- frame/staking/src/lib.rs | 4 ++-- frame/staking/src/slashing.rs | 2 +- frame/support/src/traits.rs | 2 +- frame/transaction-payment/src/lib.rs | 2 +- frame/treasury/src/lib.rs | 8 ++++---- primitives/npos-elections/compact/src/lib.rs | 4 ++-- primitives/npos-elections/src/balancing.rs | 2 +- primitives/npos-elections/src/lib.rs | 8 ++++---- primitives/npos-elections/src/phragmen.rs | 3 +-- primitives/npos-elections/src/reduce.rs | 2 +- test-utils/runtime/src/lib.rs | 2 +- utils/prometheus/src/lib.rs | 2 +- 30 files changed, 55 insertions(+), 54 deletions(-) diff --git a/bin/node/browser-testing/src/lib.rs b/bin/node/browser-testing/src/lib.rs index 777e5ea9f13..f4dc0908567 100644 --- a/bin/node/browser-testing/src/lib.rs +++ b/bin/node/browser-testing/src/lib.rs @@ -26,7 +26,7 @@ //! ``` //! For debug infomation, such as the informant, run without the `--headless` //! flag and open a browser to the url that `wasm-pack test` outputs. -//! For more infomation see https://rustwasm.github.io/docs/wasm-pack/. +//! For more infomation see . use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; use wasm_bindgen_futures::JsFuture; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2962ef10661..fb8f720898b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! The Substrate runtime. This can be compiled with ``#[no_std]`, ready for Wasm. +//! The Substrate runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. diff --git a/client/authority-discovery/src/service.rs b/client/authority-discovery/src/service.rs index 7eabeb3daf5..d23d2f3a480 100644 --- a/client/authority-discovery/src/service.rs +++ b/client/authority-discovery/src/service.rs @@ -22,14 +22,14 @@ use futures::SinkExt; use sc_network::{Multiaddr, PeerId}; use sp_authority_discovery::AuthorityId; -/// Service to interact with the [`Worker`]. +/// Service to interact with the [`crate::Worker`]. #[derive(Clone)] pub struct Service { to_worker: mpsc::Sender, } -/// A [`Service`] allows to interact with a [`Worker`], e.g. by querying the -/// [`Worker`]'s local address cache for a given [`AuthorityId`]. +/// A [`Service`] allows to interact with a [`crate::Worker`], e.g. by querying the +/// [`crate::Worker`]'s local address cache for a given [`AuthorityId`]. impl Service { pub(crate) fn new(to_worker: mpsc::Sender) -> Self { Self { @@ -44,7 +44,7 @@ impl Service { /// [`crate::Worker`] failed. /// /// Note: [`Multiaddr`]s returned always include a [`PeerId`] via a - /// [`libp2p::core::multiaddr:Protocol::P2p`] component. Equality of + /// [`libp2p::core::multiaddr::Protocol::P2p`] component. Equality of /// [`PeerId`]s across [`Multiaddr`]s returned by a single call is not /// enforced today, given that there are still authorities out there /// publishing the addresses of their sentry nodes on the DHT. In the future diff --git a/client/authority-discovery/src/worker.rs b/client/authority-discovery/src/worker.rs index 45b55f76673..d886f24542d 100644 --- a/client/authority-discovery/src/worker.rs +++ b/client/authority-discovery/src/worker.rs @@ -100,7 +100,7 @@ pub enum Role { /// /// 5. Allow querying of the collected addresses via the [`crate::Service`]. pub struct Worker { - /// Channel receiver for messages send by a [`Service`]. + /// Channel receiver for messages send by a [`crate::Service`]. from_service: Fuse>, client: Arc, @@ -615,8 +615,8 @@ where } /// NetworkProvider provides [`Worker`] with all necessary hooks into the -/// underlying Substrate networking. Using this trait abstraction instead of [`NetworkService`] -/// directly is necessary to unit test [`Worker`]. +/// underlying Substrate networking. Using this trait abstraction instead of +/// [`sc_network::NetworkService`] directly is necessary to unit test [`Worker`]. #[async_trait] pub trait NetworkProvider: NetworkStateInfo { /// Modify a peerset priority group. diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 8c022ef3a97..065acbde2cc 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -44,7 +44,7 @@ use sc_proposer_metrics::MetricsLink as PrometheusMetrics; /// Default maximum block size in bytes used by [`Proposer`]. /// -/// Can be overwritten by [`ProposerFactory::set_maxium_block_size`]. +/// Can be overwritten by [`ProposerFactory::set_maximum_block_size`]. /// /// Be aware that there is also an upper packet size on what the networking code /// will accept. If the block doesn't fit in such a package, it can not be diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 9b0c4915082..2cb66d4ccc4 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -71,4 +71,4 @@ mod basic_authorship; -pub use crate::basic_authorship::{ProposerFactory, Proposer}; +pub use crate::basic_authorship::{ProposerFactory, Proposer, DEFAULT_MAX_BLOCK_SIZE}; diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs index 019b760e5b4..48bad16afb6 100644 --- a/client/cli/src/commands/run_cmd.rs +++ b/client/cli/src/commands/run_cmd.rs @@ -75,7 +75,8 @@ pub struct RunCmd { /// Listen to all RPC interfaces. /// /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC proxy - /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. + /// server to filter out dangerous methods. More details: + /// . /// Use `--unsafe-rpc-external` to suppress the warning if you understand the risks. #[structopt(long = "rpc-external")] pub rpc_external: bool, @@ -105,7 +106,7 @@ pub struct RunCmd { /// Listen to all Websocket interfaces. /// /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use an RPC proxy - /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. + /// server to filter out dangerous methods. More details: . /// Use `--unsafe-ws-external` to suppress the warning if you understand the risks. #[structopt(long = "ws-external")] pub ws_external: bool, @@ -142,7 +143,7 @@ pub struct RunCmd { /// /// A comma-separated list of origins (protocol://domain or special `null` /// value). Value of `all` will disable origin validation. Default is to - /// allow localhost and https://polkadot.js.org origins. When running in + /// allow localhost and origins. When running in /// --dev mode the default is to allow all origins. #[structopt(long = "rpc-cors", value_name = "ORIGINS", parse(try_from_str = parse_cors))] pub rpc_cors: Option, diff --git a/client/cli/src/commands/utils.rs b/client/cli/src/commands/utils.rs index 6e48d04e132..25c7294fd1e 100644 --- a/client/cli/src/commands/utils.rs +++ b/client/cli/src/commands/utils.rs @@ -57,7 +57,7 @@ pub fn read_uri(uri: Option<&String>) -> error::Result { /// 2. Try to construct the `Pair` while using `uri` as input for [`sp_core::Pair::from_string_with_seed`]. /// /// 3. Try to construct the `Pair::Public` while using `uri` as input for -/// [`sp_core::Pair::Public::from_string_with_version`]. +/// [`sp_core::crypto::Ss58Codec::from_string_with_version`]. pub fn print_from_uri( uri: &str, password: Option, diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index bf6b444c4d7..4e1ad19fc46 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -47,7 +47,7 @@ const RECOMMENDED_OPEN_FILE_DESCRIPTOR_LIMIT: u64 = 10_000; /// Default configuration values used by Substrate /// -/// These values will be used by [`CliConfiguritation`] to set +/// These values will be used by [`CliConfiguration`] to set /// default values for e.g. the listen port or the RPC port. pub trait DefaultConfigurationValues { /// The port Substrate should listen on for p2p connections. diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index ced101b8c85..0757a484afb 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -329,7 +329,7 @@ impl BlockStatus for Arc where /// A trait that includes all the client functionalities grandpa requires. /// Ideally this would be a trait alias, we're not there yet. -/// tracking issue https://github.com/rust-lang/rust/issues/41517 +/// tracking issue pub trait ClientForGrandpa: LockImportRun + Finalizer + AuxStore + HeaderMetadata + HeaderBackend diff --git a/client/network/src/gossip.rs b/client/network/src/gossip.rs index ac3f92e9d37..8a46d0701e9 100644 --- a/client/network/src/gossip.rs +++ b/client/network/src/gossip.rs @@ -41,7 +41,7 @@ //! In normal situations, messages sent through a [`QueuedSender`] will arrive in the same //! order as they have been sent. //! It is possible, in the situation of disconnects and reconnects, that messages arrive in a -//! different order. See also https://github.com/paritytech/substrate/issues/6756. +//! different order. See also . //! However, if multiple instances of [`QueuedSender`] exist for the same peer and protocol, or //! if some other code uses the [`NetworkService`] to send notifications to this combination or //! peer and protocol, then the notifications will be interleaved in an unpredictable way. diff --git a/client/service/src/client/mod.rs b/client/service/src/client/mod.rs index b3aa2fa076a..e4d1dc8bd85 100644 --- a/client/service/src/client/mod.rs +++ b/client/service/src/client/mod.rs @@ -23,22 +23,23 @@ //! //! - A database containing the blocks and chain state, generally referred to as //! the [`Backend`](sc_client_api::backend::Backend). -//! - A runtime environment, generally referred to as the [`Executor`](CallExecutor). +//! - A runtime environment, generally referred to as the +//! [`Executor`](sc_client_api::call_executor::CallExecutor). //! //! # Initialization //! //! Creating a [`Client`] is done by calling the `new` method and passing to it a -//! [`Backend`](sc_client_api::backend::Backend) and an [`Executor`](CallExecutor). +//! [`Backend`](sc_client_api::backend::Backend) and an +//! [`Executor`](sc_client_api::call_executor::CallExecutor). //! //! The former is typically provided by the `sc-client-db` crate. //! //! The latter typically requires passing one of: //! //! - A [`LocalCallExecutor`] running the runtime locally. -//! - A [`RemoteCallExecutor`](light::call_executor::RemoteCallRequest) that will ask a +//! - A [`RemoteCallExecutor`](sc_client_api::light::RemoteCallRequest) that will ask a //! third-party to perform the executions. -//! - A [`RemoteOrLocalCallExecutor`](light::call_executor::RemoteOrLocalCallExecutor), combination -//! of the two. +//! - A [`RemoteOrLocalCallExecutor`](sc_client_api::light::LocalOrRemote), combination of the two. //! //! Additionally, the fourth generic parameter of the `Client` is a marker type representing //! the ways in which the runtime can interface with the outside. Any code that builds a `Client` diff --git a/client/telemetry/src/async_record.rs b/client/telemetry/src/async_record.rs index 34b7c1435af..06650a54def 100644 --- a/client/telemetry/src/async_record.rs +++ b/client/telemetry/src/async_record.rs @@ -1,6 +1,6 @@ //! # Internal types to ssync drain slog //! FIXME: REMOVE THIS ONCE THE PR WAS MERGE -//! https://github.com/slog-rs/async/pull/14 +//! use slog::{Record, RecordStatic, Level, SingleKV, KV, BorrowedKV}; use slog::{Serializer, OwnedKVList, Key}; diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index b80aceb361f..df1ea240630 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -69,7 +69,7 @@ pub struct Limits { /// Maximum allowed stack height in number of elements. /// - /// See https://wiki.parity.io/WebAssembly-StackHeight to find out + /// See to find out /// how the stack frame cost is calculated. Each element can be of one of the /// wasm value types. This means the maximum size per element is 64bit. pub stack_height: u32, diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index b3e883781f5..3ddb2fd4c1d 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -131,7 +131,7 @@ //! //! //! // Reference documentation of aspects such as `storageItems` and `dispatchable` functions should only be -//! // included in the https://docs.rs Rustdocs for Substrate and not repeated in the README file. +//! // included in the Rustdocs for Substrate and not repeated in the README file. //! //! \### Dispatchable Functions //! @@ -224,8 +224,8 @@ //! // Show a usage example in an actual runtime //! //! // See: -//! // - Substrate TCR https://github.com/parity-samples/substrate-tcr -//! // - Substrate Kitties https://shawntabrizi.github.io/substrate-collectables-workshop/#/ +//! // - Substrate TCR +//! // - Substrate Kitties //! //! \## Genesis Config //! diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index afa6c9083c1..81833a20538 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -20,7 +20,7 @@ //! ## Overview //! //! Details on Merkle Mountain Ranges (MMRs) can be found here: -//! https://github.com/mimblewimble/grin/blob/master/doc/mmr.md +//! //! //! The MMR pallet constructs a MMR from leaf data obtained on every block from //! `LeafDataProvider`. MMR nodes are stored both in: @@ -41,7 +41,7 @@ //! ## What for? //! //! Primary use case for this pallet is to generate MMR root hashes, that can latter on be used by -//! BEEFY protocol (see https://github.com/paritytech/grandpa-bridge-gadget). +//! BEEFY protocol (see ). //! MMR root hashes along with BEEFY will make it possible to build Super Light Clients (SLC) of //! Substrate-based chains. The SLC will be able to follow finality and can be shown proofs of more //! details that happened on the source chain. @@ -88,7 +88,7 @@ pub trait Config: frame_system::Config { /// and some of the inner mmr nodes might be pruned from on-chain storage. /// The later will contain all the entries in their full form. /// - /// Each node is stored in the Off-chain DB under key derived from the [INDEXING_PREFIX] and + /// Each node is stored in the Off-chain DB under key derived from the [`Self::INDEXING_PREFIX`] and /// it's in-tree index (MMR position). const INDEXING_PREFIX: &'static [u8]; diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 7a59cdc648a..6342f0c052b 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -706,7 +706,7 @@ impl Module { pub mod migration { use super::*; - /// Migration code for https://github.com/paritytech/substrate/pull/6770 + /// Migration code for /// /// Details: This migration was introduced between Substrate 2.0-RC6 and Substrate 2.0 releases. /// Before this migration, the `Proxies` storage item used a tuple of `AccountId` and diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs index f4576675c11..1ee7ce4419d 100644 --- a/frame/session/src/historical/onchain.rs +++ b/frame/session/src/historical/onchain.rs @@ -55,7 +55,7 @@ pub fn store_session_validator_set_to_offchain() { store_session_validator_set_to_offchain::(>::current_index()); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 5f5f5ff2bb6..3fda8306503 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -2166,7 +2166,7 @@ impl Module { Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } - /// Internal impl of [`slashable_balance_of`] that returns [`VoteWeight`]. + /// Internal impl of [`Self::slashable_balance_of`] that returns [`VoteWeight`]. pub fn slashable_balance_of_vote_weight(stash: &T::AccountId, issuance: BalanceOf) -> VoteWeight { T::CurrencyToVote::to_vote(Self::slashable_balance_of(stash), issuance) } @@ -2833,7 +2833,7 @@ impl Module { /// Execute election and return the new results. The edge weights are processed into support /// values. /// - /// This is basically a wrapper around [`do_phragmen`] which translates + /// This is basically a wrapper around [`Self::do_phragmen`] which translates /// `PrimitiveElectionResult` into `ElectionResult`. /// /// No storage item is updated. diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index b1f0c9d9a44..e59f2e84e43 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -47,7 +47,7 @@ //! has multiple misbehaviors. However, accounting for such cases is necessary //! to deter a class of "rage-quit" attacks. //! -//! Based on research at https://research.web3.foundation/en/latest/polkadot/slashing/npos/ +//! Based on research at use super::{ EraIndex, Config, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 1bbcd87cc2e..718f1d6354a 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1901,7 +1901,7 @@ impl PalletVersion { /// Returns the storage key for a pallet version. /// - /// See [`PALLET_VERSION_STORAGE_KEY_POSTIFX`] on how this key is built. + /// See [`PALLET_VERSION_STORAGE_KEY_POSTFIX`] on how this key is built. /// /// Returns `None` if the given `PI` returned a `None` as name for the given /// `Pallet`. diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 247755aa07c..e530380dfbb 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -109,7 +109,7 @@ type BalanceOf = /// Meaning that fees can change by around ~23% per day, given extreme congestion. /// /// More info can be found at: -/// https://w3f-research.readthedocs.io/en/latest/polkadot/Token%20Economics.html +/// pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData<(T, S, V, M)>); /// Something that can convert the current multiplier to the next one. diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index e180f64d1cb..6ccd8f03a15 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -414,19 +414,19 @@ decl_event!( TipClosed(Hash, AccountId, Balance), /// A tip suggestion has been retracted. \[tip_hash\] TipRetracted(Hash), - /// New bounty proposal. [index] + /// New bounty proposal. \[index\] BountyProposed(BountyIndex), /// A bounty proposal was rejected; funds were slashed. [index, bond] BountyRejected(BountyIndex, Balance), - /// A bounty proposal is funded and became active. [index] + /// A bounty proposal is funded and became active. \[index\] BountyBecameActive(BountyIndex), /// A bounty is awarded to a beneficiary. [index, beneficiary] BountyAwarded(BountyIndex, AccountId), /// A bounty is claimed by beneficiary. [index, payout, beneficiary] BountyClaimed(BountyIndex, Balance, AccountId), - /// A bounty is cancelled. [index] + /// A bounty is cancelled. \[index\] BountyCanceled(BountyIndex), - /// A bounty expiry is extended. [index] + /// A bounty expiry is extended. \[index\] BountyExtended(BountyIndex), } ); diff --git a/primitives/npos-elections/compact/src/lib.rs b/primitives/npos-elections/compact/src/lib.rs index b35c407c40c..22997e4f616 100644 --- a/primitives/npos-elections/compact/src/lib.rs +++ b/primitives/npos-elections/compact/src/lib.rs @@ -58,8 +58,8 @@ pub(crate) fn syn_err(message: &'static str) -> syn::Error { /// /// The given struct provides function to convert from/to Assignment: /// -/// - [`from_assignment()`]. -/// - [`fn into_assignment()`]. +/// - `fn from_assignment<..>(..)` +/// - `fn into_assignment<..>(..)` /// /// The generated struct is by default deriving both `Encode` and `Decode`. This is okay but could /// lead to many 0s in the solution. If prefixed with `#[compact]`, then a custom compact encoding diff --git a/primitives/npos-elections/src/balancing.rs b/primitives/npos-elections/src/balancing.rs index 04083cc9b0d..517ac5c03f1 100644 --- a/primitives/npos-elections/src/balancing.rs +++ b/primitives/npos-elections/src/balancing.rs @@ -36,7 +36,7 @@ use sp_std::prelude::*; /// change has been made (`difference = 0`). /// /// In almost all cases, a balanced solution will have a better score than an unbalanced solution, -/// yet this is not 100% guaranteed because the first element of a [`ElectionScore`] does not +/// yet this is not 100% guaranteed because the first element of a [`crate::ElectionScore`] does not /// directly related to balancing. /// /// Note that some reference implementation adopt an approach in which voters are balanced randomly diff --git a/primitives/npos-elections/src/lib.rs b/primitives/npos-elections/src/lib.rs index d82839f0208..2c7d133529c 100644 --- a/primitives/npos-elections/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -18,10 +18,10 @@ //! - [`seq_phragmen`]: Implements the Phragmén Sequential Method. An un-ranked, relatively fast //! election method that ensures PJR, but does not provide a constant factor approximation of the //! maximin problem. -//! - [`phragmms`]: Implements a hybrid approach inspired by Phragmén which is executed faster but +//! - [`phragmms()`]: Implements a hybrid approach inspired by Phragmén which is executed faster but //! it can achieve a constant factor approximation of the maximin problem, similar to that of the //! MMS algorithm. -//! - [`balance_solution`]: Implements the star balancing algorithm. This iterative process can push +//! - [`balance`]: Implements the star balancing algorithm. This iterative process can push //! a solution toward being more `balances`, which in turn can increase its score. //! //! ### Terminology @@ -70,7 +70,7 @@ //! `StakedAssignment`. //! //! -//! More information can be found at: https://arxiv.org/abs/2004.12990 +//! More information can be found at: #![cfg_attr(not(feature = "std"), no_std)] @@ -283,7 +283,7 @@ impl Voter { }) } - /// Same as [`try_normalize`] but the normalization is only limited between elected edges. + /// Same as [`Self::try_normalize`] but the normalization is only limited between elected edges. pub fn try_normalize_elected(&mut self) -> Result<(), &'static str> { let elected_edge_weights = self .edges diff --git a/primitives/npos-elections/src/phragmen.rs b/primitives/npos-elections/src/phragmen.rs index cfbeed1cdd3..135f992aba7 100644 --- a/primitives/npos-elections/src/phragmen.rs +++ b/primitives/npos-elections/src/phragmen.rs @@ -108,9 +108,8 @@ pub fn seq_phragmen( /// `seq_phragmen` for more information. This function is left public in case a crate needs to use /// the implementation in a custom way. /// -/// To create th inputs needed for this function, see [`crate::setup_inputs`]. -/// /// This can only fail if the normalization fails. +// To create the inputs needed for this function, see [`crate::setup_inputs`]. pub fn seq_phragmen_core( rounds: usize, candidates: Vec>, diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index 17d7dd1290f..a96a2ed8457 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -45,7 +45,7 @@ //! //! ### Resources: //! -//! 1. https://hackmd.io/JOn9x98iS0e0DPWQ87zGWg?view +//! 1. use crate::node::{Node, NodeId, NodeRef, NodeRole}; use crate::{ExtendedBalance, IdentifierT, StakedAssignment}; diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index da20f196b45..ea29215a4f7 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! The Substrate runtime. This can be compiled with #[no_std], ready for Wasm. +//! The Substrate runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index be7050a8a07..097073239c4 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -33,7 +33,7 @@ use std::net::SocketAddr; mod networking; mod sourced; -pub use sourced::{SourcedCounter, SourcedGauge, MetricSource}; +pub use sourced::{SourcedCounter, SourcedGauge, MetricSource, SourcedMetric}; #[cfg(target_os = "unknown")] pub use unknown_os::init_prometheus; -- GitLab From d663ca53fdb0d5228747a04f95a9bab31fe87ad0 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Fri, 11 Dec 2020 10:02:59 +0100 Subject: [PATCH 107/163] Update md link checker (#7709) * CI: ignore %20 for md link checker * CI: update to a new action release that fixes %20 issue --- .github/allowed-actions.js | 2 +- .github/workflows/md-link-check.yml | 2 +- .github/workflows/mlc_config.json | 8 +------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/allowed-actions.js b/.github/allowed-actions.js index 4a8af91328f..4fb89475806 100644 --- a/.github/allowed-actions.js +++ b/.github/allowed-actions.js @@ -3,5 +3,5 @@ // not listed here, CI will fail. module.exports = [ - 'gaurav-nelson/github-action-markdown-link-check@e3c371c731b2f494f856dc5de7f61cea4d519907', // gaurav-nelson/github-action-markdown-link-check@v1.0.8 + 'gaurav-nelson/github-action-markdown-link-check@7481451f70251762f149d69596e3e276ebf2b236', // gaurav-nelson/github-action-markdown-link-check@v1.0.8 ] diff --git a/.github/workflows/md-link-check.yml b/.github/workflows/md-link-check.yml index e15a506c567..868569911d4 100644 --- a/.github/workflows/md-link-check.yml +++ b/.github/workflows/md-link-check.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: gaurav-nelson/github-action-markdown-link-check@e3c371c731b2f494f856dc5de7f61cea4d519907 + - uses: gaurav-nelson/github-action-markdown-link-check@7481451f70251762f149d69596e3e276ebf2b236 with: use-quiet-mode: 'yes' config-file: '.github/workflows/mlc_config.json' diff --git a/.github/workflows/mlc_config.json b/.github/workflows/mlc_config.json index ffd0a0319fe..e7e620b39e0 100644 --- a/.github/workflows/mlc_config.json +++ b/.github/workflows/mlc_config.json @@ -1,13 +1,7 @@ { "ignorePatterns": [ { - "pattern": "^https://crates.io" - } - ], - "replacementPatterns": [ - { - "pattern": "%20", - "replacement": " " + "pattern": "^https://crates.io", } ] } -- GitLab From 8bf9557247606ddbf22363a03fe4b628a4fba9e3 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 11 Dec 2020 09:14:28 +0000 Subject: [PATCH 108/163] Fix PerThing::from_percent. (#7701) * Fix overflow in per_things::from_percent. * Fix test * Fix the whole thing.. :| --- primitives/arithmetic/src/per_things.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 035a704ba30..59d98eea2b7 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -61,13 +61,11 @@ pub trait PerThing: fn is_one(&self) -> bool { self.deconstruct() == Self::ACCURACY } /// Build this type from a percent. Equivalent to `Self::from_parts(x * Self::ACCURACY / 100)` - /// but more accurate. + /// but more accurate and can cope with potential type overflows. fn from_percent(x: Self::Inner) -> Self { - let a = x.min(100.into()); - let b = Self::ACCURACY; - // if Self::ACCURACY % 100 > 0 then we need the correction for accuracy - let c = rational_mul_correction::(b, a, 100.into(), Rounding::Nearest); - Self::from_parts(a / 100.into() * b + c) + let a: Self::Inner = x.min(100.into()); + let b: Self::Inner = 100.into(); + Self::from_rational_approximation(a, b) } /// Return the product of multiplication of this value by itself. @@ -334,7 +332,7 @@ macro_rules! implement_per_thing { &self.0 } fn decode_from(x: Self::As) -> Self { - // Saturates if `x` is more than `$max` internally. + // Saturates if `x` is more than `$max` internally. Self::from_parts(x) } } @@ -707,6 +705,7 @@ macro_rules! implement_per_thing { assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); + assert_eq!($name::from_percent(50), $name::from_parts($max / 2)); assert_eq!($name::from_percent(100), $name::from_parts($max)); assert_eq!($name::from_percent(200), $name::from_parts($max)); @@ -717,6 +716,15 @@ macro_rules! implement_per_thing { assert_eq!($name::from_fraction(-1.0), $name::from_parts(Zero::zero())); } + #[test] + fn percent_trait_impl_works() { + assert_eq!(<$name as PerThing>::from_percent(0), $name::from_parts(Zero::zero())); + assert_eq!(<$name as PerThing>::from_percent(10), $name::from_parts($max / 10)); + assert_eq!(<$name as PerThing>::from_percent(50), $name::from_parts($max / 2)); + assert_eq!(<$name as PerThing>::from_percent(100), $name::from_parts($max)); + assert_eq!(<$name as PerThing>::from_percent(200), $name::from_parts($max)); + } + macro_rules! u256ify { ($val:expr) => { Into::::into($val) -- GitLab From ea48d6b3e7accc8d1cf8733b1e2ee38a22d7a441 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 11 Dec 2020 01:20:10 -0800 Subject: [PATCH 109/163] Support Multiple Instances with Benchmarks (#7669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Support multiple instances with benchmarks * fix tests * Apply suggestions from code review Co-authored-by: Bastian Köcher * docs * fix output * Update lib.rs Co-authored-by: Bastian Köcher --- Cargo.lock | 1 + frame/benchmarking/src/lib.rs | 29 ++++++++++++--- frame/benchmarking/src/utils.rs | 2 ++ utils/frame/benchmarking-cli/Cargo.toml | 3 +- utils/frame/benchmarking-cli/src/writer.rs | 42 +++++++++++++++------- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1555957f80e..dbb640806c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1568,6 +1568,7 @@ dependencies = [ name = "frame-benchmarking-cli" version = "2.0.0" dependencies = [ + "Inflector", "chrono", "frame-benchmarking", "handlebars", diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 97b58ae19ec..6296c000e28 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -1052,10 +1052,29 @@ macro_rules! impl_benchmark_test { /// ``` /// /// At the end of `dispatch_benchmark`, you should return this batches object. +/// +/// In the case where you have multiple instances of a pallet that you need to separately benchmark, +/// the name of your module struct will be used as a suffix to your outputted weight file. For +/// example: +/// +/// ```ignore +/// add_benchmark!(params, batches, pallet_balances, Balances); // pallet_balances.rs +/// add_benchmark!(params, batches, pallet_collective, Council); // pallet_collective_council.rs +/// add_benchmark!(params, batches, pallet_collective, TechnicalCommittee); // pallet_collective_technical_committee.rs +/// ``` +/// +/// You can manipulate this suffixed string by using a type alias if needed. For example: +/// +/// ```ignore +/// type Council2 = TechnicalCommittee; +/// add_benchmark!(params, batches, pallet_collective, Council2); // pallet_collective_council_2.rs +/// ``` + #[macro_export] macro_rules! add_benchmark { ( $params:ident, $batches:ident, $name:ident, $( $location:tt )* ) => ( let name_string = stringify!($name).as_bytes(); + let instance_string = stringify!( $( $location )* ).as_bytes(); let (config, whitelist) = $params; let $crate::BenchmarkConfig { pallet, @@ -1071,6 +1090,9 @@ macro_rules! add_benchmark { if &pallet[..] == &b"*"[..] || &benchmark[..] == &b"*"[..] { for benchmark in $( $location )*::benchmarks(*extra).into_iter() { $batches.push($crate::BenchmarkBatch { + pallet: name_string.to_vec(), + instance: instance_string.to_vec(), + benchmark: benchmark.to_vec(), results: $( $location )*::run_benchmark( benchmark, &lowest_range_values[..], @@ -1080,12 +1102,13 @@ macro_rules! add_benchmark { whitelist, *verify, )?, - pallet: name_string.to_vec(), - benchmark: benchmark.to_vec(), }); } } else { $batches.push($crate::BenchmarkBatch { + pallet: name_string.to_vec(), + instance: instance_string.to_vec(), + benchmark: benchmark.clone(), results: $( $location )*::run_benchmark( &benchmark[..], &lowest_range_values[..], @@ -1095,8 +1118,6 @@ macro_rules! add_benchmark { whitelist, *verify, )?, - pallet: name_string.to_vec(), - benchmark: benchmark.clone(), }); } } diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index 042f4b707ae..2c2aee910e3 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -43,6 +43,8 @@ impl std::fmt::Display for BenchmarkParameter { pub struct BenchmarkBatch { /// The pallet containing this benchmark. pub pallet: Vec, + /// The instance of this pallet being benchmarked. + pub instance: Vec, /// The extrinsic (or benchmark name) of this benchmark. pub benchmark: Vec, /// The results from this benchmark. diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 4ee2454e708..83f93799691 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -23,11 +23,12 @@ sp-externalities = { version = "0.8.0", path = "../../../primitives/externalitie sp-keystore = { version = "0.8.0", path = "../../../primitives/keystore" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } -structopt = "0.3.8" codec = { version = "1.3.1", package = "parity-scale-codec" } +structopt = "0.3.8" chrono = "0.4" serde = "1.0.116" handlebars = "3.5.0" +Inflector = "0.11.4" [features] default = ["db"] diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs index fd72e003b41..4afc8107306 100644 --- a/utils/frame/benchmarking-cli/src/writer.rs +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -22,6 +22,7 @@ use std::fs; use std::path::PathBuf; use serde::Serialize; +use inflector::Inflector; use crate::BenchmarkCmd; use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis, RegressionModel}; @@ -37,6 +38,7 @@ struct TemplateData { date: String, version: String, pallet: String, + instance: String, header: String, cmd: CmdData, benchmarks: Vec, @@ -102,7 +104,7 @@ fn io_error(s: &str) -> std::io::Error { // p1 -> [b1, b2, b3] // p2 -> [b1, b2] // ``` -fn map_results(batches: &[BenchmarkBatch]) -> Result>, std::io::Error> { +fn map_results(batches: &[BenchmarkBatch]) -> Result>, std::io::Error> { // Skip if batches is empty. if batches.is_empty() { return Err(io_error("empty batches")) } @@ -115,6 +117,7 @@ fn map_results(batches: &[BenchmarkBatch]) -> Result Result Date: Fri, 11 Dec 2020 16:41:18 +0100 Subject: [PATCH 110/163] Add keccak-512 to host functions. (#7531) --- primitives/core/src/hashing.rs | 5 +++++ primitives/io/src/lib.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/primitives/core/src/hashing.rs b/primitives/core/src/hashing.rs index 98dc0c2efc5..6807da02feb 100644 --- a/primitives/core/src/hashing.rs +++ b/primitives/core/src/hashing.rs @@ -16,6 +16,11 @@ // limitations under the License. //! Hashing functions. +//! +//! This module is gated by `full-crypto` feature. If you intend to use any of the functions +//! defined here within your runtime, you should most likely rather use [sp_io::hashing] instead, +//! unless you know what you're doing. Using `sp_io` will be more performant, since instead of +//! computing the hash in WASM it delegates that computation to the host client. use blake2_rfc; use sha2::{Digest, Sha256}; diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index b6ae64e5f89..023bf7dcb30 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -735,6 +735,11 @@ pub trait Hashing { sp_core::hashing::keccak_256(data) } + /// Conduct a 512-bit Keccak hash. + fn keccak_512(data: &[u8]) -> [u8; 64] { + sp_core::hashing::keccak_512(data) + } + /// Conduct a 256-bit Sha2 hash. fn sha2_256(data: &[u8]) -> [u8; 32] { sp_core::hashing::sha2_256(data) -- GitLab From 445fa2d43b166c90c2d8e681fa4ac9db5191f457 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:08:44 +0000 Subject: [PATCH 111/163] Update debug.rs (#7721) --- frame/support/src/debug.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index 04f5c529f0a..54a1e9c3a03 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -134,7 +134,7 @@ macro_rules! runtime_print { use core::fmt::Write; let mut w = $crate::sp_std::Writer::default(); let _ = core::write!(&mut w, $($arg)+); - sp_io::misc::print_utf8(&w.inner()) + $crate::sp_io::misc::print_utf8(&w.inner()) } } } -- GitLab From 557a9b84e40b217a0295dc729674adcdfbd5c9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 14 Dec 2020 13:34:41 +0100 Subject: [PATCH 112/163] Avoid too high values. (#7716) --- frame/system/benchmarking/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index ae898a6ecaa..080b1cd80f2 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -28,6 +28,7 @@ use frame_benchmarking::{benchmarks, whitelisted_caller}; use frame_support::{ storage::{self, StorageMap}, traits::Get, + weights::DispatchClass, }; use frame_system::{Module as System, Call, RawOrigin, DigestItemOf, AccountInfo}; @@ -40,7 +41,7 @@ benchmarks! { _ { } remark { - let b in 0 .. T::BlockWeights::get().max_block as u32; + let b in 0 .. *T::BlockLength::get().max.get(DispatchClass::Normal) as u32; let remark_message = vec![1; b as usize]; let caller = whitelisted_caller(); }: _(RawOrigin::Signed(caller), remark_message) -- GitLab From 956ccbc472e27a3db9cbc5e6961ed2c84774abc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:22:49 +0100 Subject: [PATCH 113/163] Bump hyper from 0.12.35 to 0.13.9 (#7569) * Bump hyper from 0.12.35 to 0.13.9 Bumps [hyper](https://github.com/hyperium/hyper) from 0.12.35 to 0.13.9. - [Release notes](https://github.com/hyperium/hyper/releases) - [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper/compare/v0.12.35...v0.13.9) Signed-off-by: dependabot[bot] * Update bin/node/rpc-client/Cargo.toml * Update Cargo.lock Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pierre Krieger --- bin/node/rpc-client/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- utils/prometheus/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 26d9de133c6..e88a1803269 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -12,7 +12,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.1.29" -hyper = "0.12.35" +hyper = "~0.12.35" jsonrpc-core-client = { version = "15.1.0", default-features = false, features = ["http"] } log = "0.4.8" node-primitives = { version = "2.0.0", path = "../primitives" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 5686d33da9b..1a31d278eb5 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -33,7 +33,7 @@ sc-network = { version = "0.8.0", path = "../network" } sc-keystore = { version = "2.0.0", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -hyper = "0.13.2" +hyper = "0.13.9" hyper-rustls = "0.21.0" [dev-dependencies] diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index 9eed7a2fdcf..335f84bf0f2 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -20,5 +20,5 @@ derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] async-std = { version = "1.6.5", features = ["unstable"] } -hyper = { version = "0.13.1", default-features = false, features = ["stream"] } +hyper = { version = "0.13.9", default-features = false, features = ["stream"] } tokio = "0.2" -- GitLab From 1f49b2a65042ea990a78d05aa1988ba0299f58fe Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 14 Dec 2020 15:45:49 +0000 Subject: [PATCH 114/163] Prevent dust in staking by disallowing cheap bond_extra (#7718) * prevent bond_extra to cause staking actve lower than ed * prevent bond_extra to cause staking actve lower than ed * Check in post conditions. * check rebond as well. * also change withdraw_unbonded. * Fix build * change check format. * Apply suggestions from code review Co-authored-by: Shawn Tabrizi Co-authored-by: Shawn Tabrizi --- frame/staking/src/lib.rs | 9 ++++- frame/staking/src/mock.rs | 12 +++++- frame/staking/src/tests.rs | 82 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 3fda8306503..af326e27c62 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1474,11 +1474,13 @@ decl_module! { let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash_balance = T::Currency::free_balance(&stash); - if let Some(extra) = stash_balance.checked_sub(&ledger.total) { let extra = extra.min(max_additional); ledger.total += extra; ledger.active += extra; + // last check: the new active amount of ledger must be more than ED. + ensure!(ledger.active >= T::Currency::minimum_balance(), Error::::InsufficientValue); + Self::deposit_event(RawEvent::Bonded(stash, extra)); Self::update_ledger(&controller, &ledger); } @@ -1586,7 +1588,7 @@ decl_module! { ledger = ledger.consolidate_unlocked(current_era) } - let post_info_weight = if ledger.unlocking.is_empty() && ledger.active.is_zero() { + let post_info_weight = if ledger.unlocking.is_empty() && ledger.active <= T::Currency::minimum_balance() { // This account must have called `unbond()` with some value that caused the active // portion to fall below existential deposit + will have no more unlocking chunks // left. We can now safely remove all staking-related information. @@ -1973,6 +1975,9 @@ decl_module! { ensure!(!ledger.unlocking.is_empty(), Error::::NoUnlockChunk); let ledger = ledger.rebond(value); + // last check: the new active amount of ledger must be more than ED. + ensure!(ledger.active >= T::Currency::minimum_balance(), Error::::InsufficientValue); + Self::update_ledger(&controller, &ledger); Ok(Some( 35 * WEIGHT_PER_MICROS diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 5deae116e5c..76689503f65 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -579,8 +579,18 @@ fn assert_is_stash(acc: AccountId) { fn assert_ledger_consistent(ctrl: AccountId) { // ensures ledger.total == ledger.active + sum(ledger.unlocking). let ledger = Staking::ledger(ctrl).expect("Not a controller."); - let real_total: Balance = ledger.unlocking.iter().fold(ledger.active, |a, c| a + c.value); + let real_total: Balance = ledger + .unlocking + .iter() + .fold(ledger.active, |a, c| a + c.value); assert_eq!(real_total, ledger.total); + assert!( + ledger.active >= Balances::minimum_balance() || ledger.active == 0, + "{}: active ledger amount ({}) must be greater than ED {}", + ctrl, + ledger.active, + Balances::minimum_balance() + ); } pub(crate) fn bond_validator(stash: AccountId, ctrl: AccountId, val: Balance) { diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index c50964a33bb..79edc012cd3 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -4696,3 +4696,85 @@ fn payout_to_any_account_works() { assert!(Balances::free_balance(42) > 0); }) } + +#[test] +fn cannot_bond_extra_to_lower_than_ed() { + ExtBuilder::default() + .existential_deposit(10) + .build_and_execute(|| { + // stash must have more balance than bonded for this to work. + assert_eq!(Balances::free_balance(&21), 512_000); + + // initial stuff. + assert_eq!( + Staking::ledger(&20).unwrap(), + StakingLedger { + stash: 21, + total: 1000, + active: 1000, + unlocking: vec![], + claimed_rewards: vec![] + } + ); + + // unbond all of it. + assert_ok!(Staking::unbond(Origin::signed(20), 1000)); + assert_eq!( + Staking::ledger(&20).unwrap(), + StakingLedger { + stash: 21, + total: 1000, + active: 0, + unlocking: vec![UnlockChunk { value: 1000, era: 3 }], + claimed_rewards: vec![] + } + ); + + // now bond a wee bit more + assert_noop!( + Staking::bond_extra(Origin::signed(21), 5), + Error::::InsufficientValue, + ); + }) +} + +#[test] +fn cannot_rebond_to_lower_than_ed() { + ExtBuilder::default() + .existential_deposit(10) + .build_and_execute(|| { + // stash must have more balance than bonded for this to work. + assert_eq!(Balances::free_balance(&21), 512_000); + + // initial stuff. + assert_eq!( + Staking::ledger(&20).unwrap(), + StakingLedger { + stash: 21, + total: 1000, + active: 1000, + unlocking: vec![], + claimed_rewards: vec![] + } + ); + + // unbond all of it. + assert_ok!(Staking::unbond(Origin::signed(20), 1000)); + assert_eq!( + Staking::ledger(&20).unwrap(), + StakingLedger { + stash: 21, + total: 1000, + active: 0, + unlocking: vec![UnlockChunk { value: 1000, era: 3 }], + claimed_rewards: vec![] + } + ); + + // now bond a wee bit more + assert_noop!( + Staking::rebond(Origin::signed(20), 5), + Error::::InsufficientValue, + ); + }) +} -- GitLab From d4d6844271667b4c7538d87dec7a6603df93f1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 14 Dec 2020 18:47:08 +0100 Subject: [PATCH 115/163] Default block announce validation should reject additional data (#7726) If we are using the default block announce validator and receive additional data alongside the block announcement, we should disconnect this peer. --- client/network/src/protocol.rs | 6 ++++- client/network/src/protocol/sync.rs | 12 ++++++---- .../consensus/common/src/block_validation.rs | 23 ++++++++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 52fbacd1be0..41326b6d82a 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1148,7 +1148,11 @@ impl Protocol { self.update_peer_info(&who); (header, is_best, who) } - sync::PollBlockAnnounceValidation::Failure { who } => { + sync::PollBlockAnnounceValidation::Failure { who, disconnect } => { + if disconnect { + self.disconnect_peer(&who); + } + self.report_peer(who, rep::BAD_BLOCK_ANNOUNCEMENT); return CustomMessageOutcome::None } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 380cec244cc..b7ae6371d93 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -324,6 +324,8 @@ pub enum PollBlockAnnounceValidation { Failure { /// Who sent the processed block announcement? who: PeerId, + /// Should the peer be disconnected? + disconnect: bool, }, /// The announcement does not require further handling. Nothing { @@ -354,6 +356,8 @@ enum PreValidateBlockAnnounce { Failure { /// Who sent the processed block announcement? who: PeerId, + /// Should the peer be disconnected? + disconnect: bool, }, /// The announcement does not require further handling. Nothing { @@ -1215,14 +1219,14 @@ impl ChainSync { announce, who, }, - Ok(Validation::Failure) => { + Ok(Validation::Failure { disconnect }) => { debug!( target: "sync", "Block announcement validation of block {} from {} failed", hash, who, ); - PreValidateBlockAnnounce::Failure { who } + PreValidateBlockAnnounce::Failure { who, disconnect } } Err(e) => { error!(target: "sync", "💔 Block announcement validation errored: {}", e); @@ -1280,9 +1284,9 @@ impl ChainSync { self.peer_block_announce_validation_finished(&who); return PollBlockAnnounceValidation::Nothing { is_best, who, header: announce.header } }, - PreValidateBlockAnnounce::Failure { who } => { + PreValidateBlockAnnounce::Failure { who, disconnect } => { self.peer_block_announce_validation_finished(&who); - return PollBlockAnnounceValidation::Failure { who } + return PollBlockAnnounceValidation::Failure { who, disconnect } }, PreValidateBlockAnnounce::Process { announce, is_new_best, who } => { self.peer_block_announce_validation_finished(&who); diff --git a/primitives/consensus/common/src/block_validation.rs b/primitives/consensus/common/src/block_validation.rs index f8255130e64..b9261441595 100644 --- a/primitives/consensus/common/src/block_validation.rs +++ b/primitives/consensus/common/src/block_validation.rs @@ -42,7 +42,12 @@ pub enum Validation { is_new_best: bool, }, /// Invalid block announcement. - Failure, + Failure { + /// Should we disconnect from this peer? + /// + /// This should be used if the peer for example send junk to spam us. + disconnect: bool, + }, } /// Type which checks incoming block announcements. @@ -68,8 +73,20 @@ impl BlockAnnounceValidator for DefaultBlockAnnounceValidator { fn validate( &mut self, _: &B::Header, - _: &[u8], + data: &[u8], ) -> Pin>> + Send>> { - async { Ok(Validation::Success { is_new_best: false }) }.boxed() + let is_empty = data.is_empty(); + + async move { + if !is_empty { + log::debug!( + target: "sync", + "Received unknown data alongside the block announcement.", + ); + Ok(Validation::Failure { disconnect: true }) + } else { + Ok(Validation::Success { is_new_best: false }) + } + }.boxed() } } -- GitLab From c88b104028b4fdda35311adb12eabf7aa5aa4316 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 14 Dec 2020 19:37:19 +0100 Subject: [PATCH 116/163] Fix wrong order of values in log line (#7728) --- client/network/src/protocol/sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index b7ae6371d93..1ff8d37afec 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -1541,7 +1541,7 @@ fn peer_block_request( trace!( target: "sync", "Requesting pre-finalized chain from {:?}, common={}, finalized={}, peer best={}, our best={}", - id, finalized, peer.common_number, peer.best_number, best_num, + id, peer.common_number, finalized, peer.best_number, best_num, ); } if let Some(range) = blocks.needed_blocks( -- GitLab From dac7ff1544bc5a04ccc5572c48cd7ed2312a8f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 15 Dec 2020 10:28:40 +0100 Subject: [PATCH 117/163] Fix polkadot companion test (#7732) --- .maintain/gitlab/check_polkadot_companion_build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 16fb2d35672..4a7e9869abf 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -45,6 +45,7 @@ cargo install -f --version 0.2.0 diener # Merge master into our branch before building Polkadot to make sure we don't miss # any commits that are required by Polkadot. +git fetch --depth 20 origin git merge origin/master # Clone the current Polkadot master branch into ./polkadot. -- GitLab From 31499cd29ed30df932fb71b7459796f7160d0272 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 15 Dec 2020 10:30:44 +0000 Subject: [PATCH 118/163] remove duplicate accounts in chain-spec. (#7725) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove duplicate accounts in chain-spec. * Fix build * Enforce in balances modules. * Apply suggestions from code review * Update frame/balances/src/lib.rs Co-authored-by: Bastian Köcher Co-authored-by: Bastian Köcher --- bin/node/cli/src/chain_spec.rs | 15 ++++++++++----- frame/balances/src/lib.rs | 6 ++++++ frame/balances/src/tests.rs | 9 +++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 90824a5572f..83dc95e3b64 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -218,7 +218,7 @@ pub fn testnet_genesis( endowed_accounts: Option>, enable_println: bool, ) -> GenesisConfig { - let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { + let mut endowed_accounts: Vec = endowed_accounts.unwrap_or_else(|| { vec![ get_account_id_from_seed::("Alice"), get_account_id_from_seed::("Bob"), @@ -234,10 +234,16 @@ pub fn testnet_genesis( get_account_id_from_seed::("Ferdie//stash"), ] }); + initial_authorities.iter().for_each(|x| + if !endowed_accounts.contains(&x.0) { + endowed_accounts.push(x.0.clone()) + } + ); + let num_endowed_accounts = endowed_accounts.len(); const ENDOWMENT: Balance = 10_000_000 * DOLLARS; - const STASH: Balance = 100 * DOLLARS; + const STASH: Balance = ENDOWMENT / 1000; GenesisConfig { frame_system: Some(SystemConfig { @@ -246,9 +252,8 @@ pub fn testnet_genesis( }), pallet_balances: Some(BalancesConfig { balances: endowed_accounts.iter().cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect(), + .map(|x| (x, ENDOWMENT)) + .collect() }), pallet_indices: Some(IndicesConfig { indices: vec![], diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 2852fbb953f..b7d2488bfdd 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -412,6 +412,12 @@ decl_storage! { "the balance of any account should always be at least the existential deposit.", ) } + + // ensure no duplicates exist. + let endowed_accounts = config.balances.iter().map(|(x, _)| x).cloned().collect::>(); + + assert!(endowed_accounts.len() == config.balances.len(), "duplicate balances in genesis."); + for &(ref who, free) in config.balances.iter() { T::AccountStore::insert(who, AccountData { free, .. Default::default() }); } diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 9a7e7ccb268..f47776e0ee6 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -639,6 +639,15 @@ macro_rules! decl_tests { }.assimilate_storage(&mut t).unwrap(); } + #[test] + #[should_panic = "duplicate balances in genesis."] + fn cannot_set_genesis_value_twice() { + let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); + let _ = GenesisConfig::<$test> { + balances: vec![(1, 10), (2, 20), (1, 15)], + }.assimilate_storage(&mut t).unwrap(); + } + #[test] fn dust_moves_between_free_and_reserved() { <$ext_builder>::default() -- GitLab From ba2fc2be16301520c5db959e12395d5e1ab30548 Mon Sep 17 00:00:00 2001 From: RK Date: Tue, 15 Dec 2020 23:59:11 +0530 Subject: [PATCH 119/163] Participating in Council Governance is Free for First Time Voters and Successful Closing (#7661) * wk2049 | D5 | addition-motions first free vote for members | p1 * Update frame/collective/src/lib.rs Co-authored-by: Shawn Tabrizi * wk2049 | D6 | addition-motions first free vote for members | p2 * Update frame/collective/src/lib.rs Co-authored-by: Shawn Tabrizi * Update frame/collective/src/lib.rs Co-authored-by: Shawn Tabrizi * wk2049 | D7 | addition-motions first free vote for members | p3 * Update frame/collective/src/lib.rs Co-authored-by: Shawn Tabrizi * wk2049 | D7 | addition-motions first free vote for members | p4 * wk2049 | D7 | addition-motions first free vote for members | p6 * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/collective/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * wk2050 | D3 | addition-motions first free vote for members | p7 * wk2050 | D3 | addition-motions first free vote for members | p8 * update comment Co-authored-by: Shawn Tabrizi Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/collective/src/lib.rs | 141 ++++++++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 14 deletions(-) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index abaf579861e..efc8626d689 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -56,7 +56,7 @@ use frame_support::{ }, ensure, traits::{ChangeMembers, EnsureOrigin, Get, InitializeMembers}, - weights::{DispatchClass, GetDispatchInfo, Weight}, + weights::{DispatchClass, GetDispatchInfo, Weight, Pays}, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -488,6 +488,8 @@ decl_module! { /// /// Requires the sender to be a member. /// + /// Transaction fees will be waived if the member is voting on any particular proposal + /// for the first time and the call is successful. Subsequent vote changes will charge a fee. /// # /// ## Weight /// - `O(M)` where `M` is members-count (code- and governance-bounded) @@ -515,6 +517,9 @@ decl_module! { let position_yes = voting.ayes.iter().position(|a| a == &who); let position_no = voting.nays.iter().position(|a| a == &who); + // Detects first vote of the member in the motion + let is_account_voting_first_time = position_yes.is_none() && position_no.is_none(); + if approve { if position_yes.is_none() { voting.ayes.push(who.clone()); @@ -541,7 +546,17 @@ decl_module! { Voting::::insert(&proposal, voting); - Ok(Some(T::WeightInfo::vote(members.len() as u32)).into()) + if is_account_voting_first_time { + Ok(( + Some(T::WeightInfo::vote(members.len() as u32)), + Pays::No, + ).into()) + } else { + Ok(( + Some(T::WeightInfo::vote(members.len() as u32)), + Pays::Yes, + ).into()) + } } /// Close a vote that is either approved, disapproved or whose voting period has ended. @@ -554,6 +569,9 @@ decl_module! { /// If called after the end of the voting period abstentions are counted as rejections /// unless there is a prime member set and the prime member cast an approval. /// + /// If the close operation completes successfully with disapproval, the transaction fee will + /// be waived. Otherwise execution of the approved operation will be charged to the caller. + /// /// + `proposal_weight_bound`: The maximum amount of weight consumed by executing the closed proposal. /// + `length_bound`: The upper bound for the length of the proposal in storage. Checked via /// `storage::read` so it is `size_of::() == 4` larger than the pure length. @@ -606,20 +624,23 @@ decl_module! { let (proposal, len) = Self::validate_and_get_proposal( &proposal_hash, length_bound, - proposal_weight_bound + proposal_weight_bound, )?; Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); - return Ok(Some( - T::WeightInfo::close_early_approved(len as u32, seats, proposal_count) - .saturating_add(proposal_weight) + return Ok(( + Some(T::WeightInfo::close_early_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight)), + Pays::Yes, ).into()); + } else if disapproved { Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); let proposal_count = Self::do_disapprove_proposal(proposal_hash); - return Ok(Some( - T::WeightInfo::close_early_disapproved(seats, proposal_count) + return Ok(( + Some(T::WeightInfo::close_early_disapproved(seats, proposal_count)), + Pays::No, ).into()); } @@ -642,20 +663,22 @@ decl_module! { let (proposal, len) = Self::validate_and_get_proposal( &proposal_hash, length_bound, - proposal_weight_bound + proposal_weight_bound, )?; Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); - return Ok(Some( - T::WeightInfo::close_approved(len as u32, seats, proposal_count) - .saturating_add(proposal_weight) + return Ok(( + Some(T::WeightInfo::close_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight)), + Pays::Yes, ).into()); } else { Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); let proposal_count = Self::do_disapprove_proposal(proposal_hash); - return Ok(Some( - T::WeightInfo::close_disapproved(seats, proposal_count) + return Ok(( + Some(T::WeightInfo::close_disapproved(seats, proposal_count)), + Pays::No, ).into()); } } @@ -1436,6 +1459,96 @@ mod tests { }); } + #[test] + fn motions_all_first_vote_free_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash: H256 = proposal.blake2_256().into(); + let end = 4; + assert_ok!( + Collective::propose( + Origin::signed(1), + 2, + Box::new(proposal.clone()), + proposal_len, + ) + ); + assert_eq!( + Collective::voting(&hash), + Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![], end }) + ); + + // For the motion, acc 2's first vote, expecting Ok with Pays::No. + let vote_rval: DispatchResultWithPostInfo = Collective::vote( + Origin::signed(2), + hash.clone(), + 0, + true, + ); + assert_eq!(vote_rval.unwrap().pays_fee, Pays::No); + + // Duplicate vote, expecting error with Pays::Yes. + let vote_rval: DispatchResultWithPostInfo = Collective::vote( + Origin::signed(2), + hash.clone(), + 0, + true, + ); + assert_eq!(vote_rval.unwrap_err().post_info.pays_fee, Pays::Yes); + + // Modifying vote, expecting ok with Pays::Yes. + let vote_rval: DispatchResultWithPostInfo = Collective::vote( + Origin::signed(2), + hash.clone(), + 0, + false, + ); + assert_eq!(vote_rval.unwrap().pays_fee, Pays::Yes); + + // For the motion, acc 3's first vote, expecting Ok with Pays::No. + let vote_rval: DispatchResultWithPostInfo = Collective::vote( + Origin::signed(3), + hash.clone(), + 0, + true, + ); + assert_eq!(vote_rval.unwrap().pays_fee, Pays::No); + + // acc 3 modify the vote, expecting Ok with Pays::Yes. + let vote_rval: DispatchResultWithPostInfo = Collective::vote( + Origin::signed(3), + hash.clone(), + 0, + false, + ); + assert_eq!(vote_rval.unwrap().pays_fee, Pays::Yes); + + // Test close() Extrincis | Check DispatchResultWithPostInfo with Pay Info + + let proposal_weight = proposal.get_dispatch_info().weight; + let close_rval: DispatchResultWithPostInfo = Collective::close( + Origin::signed(2), + hash.clone(), + 0, + proposal_weight, + proposal_len, + ); + assert_eq!(close_rval.unwrap().pays_fee, Pays::No); + + // trying to close the proposal, which is already closed. + // Expecting error "ProposalMissing" with Pays::Yes + let close_rval: DispatchResultWithPostInfo = Collective::close( + Origin::signed(2), + hash.clone(), + 0, + proposal_weight, + proposal_len, + ); + assert_eq!(close_rval.unwrap_err().post_info.pays_fee, Pays::Yes); + }); + } + #[test] fn motions_reproposing_disapproved_works() { new_test_ext().execute_with(|| { -- GitLab From 6584375358d77ba950fe39847497ad64e3227fea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Dec 2020 20:01:05 +0100 Subject: [PATCH 120/163] Bump zeroize from 1.1.1 to 1.2.0 (#7731) Bumps [zeroize](https://github.com/iqlusioninc/crates) from 1.1.1 to 1.2.0. - [Release notes](https://github.com/iqlusioninc/crates/releases) - [Commits](https://github.com/iqlusioninc/crates/compare/zeroize/v1.1.1...zeroize/v1.2.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- client/network/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbb640806c6..57f6028f5fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10391,9 +10391,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" +checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36" dependencies = [ "zeroize_derive", ] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 1ad54366ce4..b7cb1512dd4 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -61,7 +61,7 @@ thiserror = "1" unsigned-varint = { version = "0.5.0", features = ["futures", "futures-codec"] } void = "1.0.2" wasm-timer = "0.2" -zeroize = "1.0.0" +zeroize = "1.2.0" [dependencies.libp2p] version = "0.32.2" diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index ca385df2365..1d0ff4f2082 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -29,7 +29,7 @@ substrate-bip39 = { version = "0.4.2", optional = true } tiny-bip39 = { version = "0.8", optional = true } regex = { version = "1.4.2", optional = true } num-traits = { version = "0.2.8", default-features = false } -zeroize = { version = "1.0.0", default-features = false } +zeroize = { version = "1.2.0", default-features = false } secrecy = { version = "0.7.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -- GitLab From 566ad03cf8c07c3c3ab226a724b2dcb4b6dbbc9b Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Tue, 15 Dec 2020 20:07:04 +0100 Subject: [PATCH 121/163] Leave some header related info for inspection (#7727) * Leave some system data for inspection There is not much benefit in being active when removing this data. It's actively harmful when one tries to read the block number in runtime APIs in the context of a block. * Update the expected root hash This is excepted since now we persist new members. * Revert extrinsics_root to `take` It's going away in one of the following PRs anyway * Update the state root once again * Update the comment on the storage items that are left in the storage Excluding ExtrinsicsRoot since it's going away --- frame/executive/src/lib.rs | 2 +- frame/system/src/lib.rs | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 572d58d86b4..59e9cae1983 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -753,7 +753,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("6a3ad91caba5b8ac15c325a36d7568adf6a7e49321865de7527b851d870343d4").into(), + state_root: hex!("ba1a82a264b8007e0c04c9ea35e541593daad08b6e2bf7c0a6780a67d1c55018").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 7273ca09aab..c5586f98566 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1013,15 +1013,27 @@ impl Module { } } - /// Remove temporary "environment" entries in storage. + /// Remove temporary "environment" entries in storage, compute the storage root and return the + /// resulting header for this block. pub fn finalize() -> T::Header { ExecutionPhase::kill(); ExtrinsicCount::kill(); AllExtrinsicsLen::kill(); - let number = >::take(); - let parent_hash = >::take(); - let mut digest = >::take(); + // The following fields + // + // - > + // - > + // - > + // - > + // - > + // - > + // + // stay to be inspected by the client and will be cleared by `Self::initialize`. + let number = >::get(); + let parent_hash = >::get(); + let mut digest = >::get(); + let extrinsics_root = >::take(); // move block hash pruning window by one block @@ -1049,14 +1061,6 @@ impl Module { digest.push(item); } - // The following fields - // - // - > - // - > - // - > - // - // stay to be inspected by the client and will be cleared by `Self::initialize`. - ::new(number, extrinsics_root, storage_root, parent_hash, digest) } -- GitLab From 987a9723920217917f2708388d150add5ef52ef7 Mon Sep 17 00:00:00 2001 From: RK Date: Wed, 16 Dec 2020 16:02:16 +0530 Subject: [PATCH 122/163] Issue 7143 | Refactor Treasury Pallet into Bounties, Tips, and Proposals (#7536) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wk2046 | D5 | treasury refactor to bounties and tips * wk2046 | D5 | treasury refactor to bounties and tips | p2 * fix test compilation, ignoring events * initialize treasury in genesis * wk2046 | D7 | treasury refactor | fix bounties test build issues * wk2047 | D1 | treasury refactor | tips pallet bringup * wk2047 | D2 | treasury refactor | bounties pallet | unit test bringup * wk2047 | D2 | treasury refactor | bounties pallet | unit test bringup | p2 * wk2047 | D2 | treasury refactor | pallet-tips| test_last_reward_migration | test failure - analysis * wk2047 | D3 | treasury refactor | pallet-tips| test_last_reward_migration | test failure - fix * wk2047 | D3 | treasury refactor | pallet-bounties | on_initialize() fix * wk2047 | D3 | treasury refactor | pallet-bounties | on_initialize() fix | p2 * wk2047 | D4 | treasury refactor | pallet-bounties + pallet-treasury | spend_fund runtime hooks * wk2047 | D4 | treasury refactor | pallet-bounties + pallet-treasury | spend_fund runtime hooks | p2 * wk2047 | D4 | treasury refactor | pallet-bounties + pallet-treasury | spend_fund runtime hooks | p3 * wk2047 | D5 | treasury refactor | pallet-bounties + pallet-treasury | spend_fund runtime hooks | p4 * wk2047 | D6 | treasury refactor | review comments fix * some fixes * fix bounties instantiable * remove instantiable from tips and bounties * fix compile for benchmarks * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_treasury --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/treasury/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Update lib.rs * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_tips --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/tips/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * add back `on_initialize_bounties` * patch up bounties benchmarks * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_bounties --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/bounties/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Remove development TODO from public doc comment (#7500) * refactor subtrait/elevated trait as not needed (#7497) * Fix comments of indices pallet events (#7511) Arguments for IndexAssigned and IndexFrozen were inverted in comments. * Skip slot lenience on first block in BABE (#7515) The genesis header doesn't have the BABE pre-digest and we insert `0` as slot number. The slot lenience calculation will return the maximum in this situation. Besides returning the maximum which is not bad at all, it also prints some a debug message that can be confusing in the first moment. To prevent printing this debug message, we now just return early when we see that the parent block is the genesis block. * slots: incrementally backoff claiming slots if finality lags behind (#7186) * babe: backoff authoring blocks when finality lags * babe: move backoff authoring params to default constructor * babe: deduplicate the test a bit * babe: set backoff constants in service * babe: use better names for backoff authoring block parameters * babe: remove last unwrap * babe: slight style tweak * babe: fix comment * slots: move backoff block authorship logic to SimpleSlotWorker * aura: append SlotInfo in on_slot * slots: use the correct types for parameters * slots: fix review comments * aura: add missing backoff authoring blocks parameters * slots: add comments for default values * slots: add additional checks in test * slots: update implementation for new master * slots: revert the change to SlotInfo * Fix review comments * slots: rework unit tests for backing off claiming slots * slots: add test for asymptotic behaviour for slot claims * slots: address review comments * slots: add test for max_interval * slots: add assertion for intervals between between claimed slots * slots: remove rustfmt directive * slots: another attempt at explaining authoring_rate * slots: up unfinalized_slack to 50 by default * slots: add tests for time to reach max_interval * slots: fix typo in comments * Apply suggestions from code review Co-authored-by: Bastian Köcher * slots: additional tweaks to comments and info calls * slots: rename to BackoffAuthoringOnFinalizedHeadLagging * slots: make the backing off strategy generic * Apply suggestions from code review Co-authored-by: Bastian Köcher * slots: implement backoff trait for () for simplicity * slots: move logging inside backing off function to make it more specific * aura: add missing function parameter Co-authored-by: Bastian Köcher * Export app-crypto specific keystore functions (#7489) * Export app-crypto specific keystore functions * Also add back the insert function * Switch KeystoreContainer to an enum * Only export the bare minimal for LocalKeystore and fix service compile * fix: should return Arc * Add docs stating that functions only available in local keystore * Remove insert and generate functions * fix: generate function should be available in test * Add keypair function to trait * Revert "Add keypair function to trait" This reverts commit ad921b09ca73d3c09298e3a51b562ef8e0067781. * Add note for local_keystore function in service * Update doc for the --chain flag (#7520) * contracts: Add missing instruction to the `Schedule` (#7527) * Don't log with colors when we are writing to a tty (#7525) * Don't log with colors when we are writing to a tty This fixes a regression that was introduced by the switch to tracing. Before we killed all colors before writing to a tty, this pr brings the behaviour back. * Remove accidentally added crate * Review feedback * More feedback * Update client/cli/src/logging.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/cli/src/logging.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * MemoryId -> u32 (#7534) * Enable local addresses in DHT when chain type == `Local` | `Development` (#7538) * Enable local addresses in DHT when chain type == `Local` | `Development` This pr changes when to add local addresses to DHT. Instead of only checking if `--discover-local` and `--dev` are present, we now also check if the chain type is `Local` or `Development`. * Update the docs! * Update tiny-bip39 to v0.8 (#7539) It would improve secret zeroization due to https://github.com/maciejhirsz/tiny-bip39/pull/22, and would also remove one of the points where we depend on `failure` crate, which is deprecated (see https://github.com/rust-lang-nursery/failure/pull/347) * make LocalCallExecutor public (#7528) * Fix some weirdness in `offchain_worker` (#7541) We call `offchain_worker` with the state of the imported block and pass the header of this block. However in the runtime we call all `offchain_worker` functions with the number of the parent block. Besides that we also pass all digests and not only the pre runtime digests. In the context where the offchain worker is executed we have all digests, so there is no real reason to only pass pre runtime digests. Another fix is that we also insert the hash of the current header into the block hash map. * Use inbound peerslot slots when a substream is received, rather than a connection (#7464) * Use inbound peerslot slots when a substream is received, rather than a connection * Refactor PeerState * Some bugfixes * Fix warnings so that CI runs, gmlrlblbl * Bugfixes * Update docs * Apply suggestions from code review Co-authored-by: Roman Borschel * Clean up Banned state * Refactor connections state * Fix possibility of Enabled with no Opening or Open connection * Line width * Add some debug_asserts! and fix TODO * Refactor legacy handler * Rewrite group.rs entirely [part 1] * Rewrite group.rs entirely [part 2] * Remove faulty assertion Because of the asynchronous nature of the behaviour <-> handler communications, it is possible to receive notifications while in the Closing state * Don't poll the legacy substream is not Open * Tolerate when not all substreams are accepted * Remove TODOs * Dummy commit to make CI log interesting things * Try race condition fix * Revert "Try race condition fix" This reverts commit 0675c659d06195c30f8c5bc13e2d88141d57a3ba. * Correctly rebuild pending_opening * Minor tweaks * Printlns for CI debugging * Revert "Printlns for CI debugging" This reverts commit e7852a231f4fc418898767aaa27c9a4358e12e8b. * Revert "Dummy commit to make CI log interesting things" This reverts commit 259ddd74088e53e7c6a9b0a62a8d1573a0063ce3. * mv group.rs ../handler.rs * Apply suggestions from code review Co-authored-by: Max Inden * Banned => Backoff * Mention the actual PeerStates * OpenDesired -> OpenDesiredByRemote * OpeningThenClosing * Add doc links to PeerState * Simplify increment logic * One more debug_assert * debug_assert! * OpenDesiredByRemote * Update client/network/src/protocol/generic_proto/behaviour.rs Co-authored-by: Max Inden Co-authored-by: Roman Borschel Co-authored-by: Max Inden * *: Update to libp2p v0.30.0 (#7508) * *: Update to libp2p v0.30.0 * Cargo.lock: Update * *: Update to libp2p v0.30.1 * make ClientConfig public (#7544) * sc-basic-authorship: remove useless dependencies (#7550) Signed-off-by: koushiro * Add slashing events to elections-phragmen. (#7543) * Add slashing events to elections-phragmen. * Fix build * Apply suggestions from code review * Update frame/elections-phragmen/src/lib.rs * Update frame/elections-phragmen/src/lib.rs Co-authored-by: Guillaume Thiolliere Co-authored-by: Guillaume Thiolliere * Remove necessity to pass ConsensusEngineId when registering notifications protocol (#7549) * Remove necessity to pass ConsensusEngineId when registering notifications protocol * Line width * Fix tests protocol name * Other renames * Doc update * Change issue in TODO * sc-cli: replace bip39 with tiny-bip39 (#7551) Signed-off-by: koushiro * Add extra docs to on_initialize (#7552) * Add some extra on_initialize docs. * Address review comments. * More Extensible Multiaddress Format (#7380) * More extensible multiaddress format * update name * Don't depend on indices to define multiaddress type * Use MultiAddress in Node Template too! * reduce traits, fix build * support multiple `StaticLookup` * bump tx version * feedback * Fix weight template to remove ugliness in rust doc (#7565) fixed weight template * Cargo.lock: Run cargo update (#7553) * Cargo.lock: Run cargo update * Cargo.lock: Downgrade cc to v1.0.62 * Cargo.lock: Revert wasm-* updates * .github: Add dependabot config and thus enable dependabot (#7509) * .github: Add dependabot config and thus enable dependabot * Update .github/dependabot.yml Co-authored-by: Pierre Krieger Co-authored-by: Pierre Krieger * Thread-local parameter_types for testing. (#7542) * Thread-local parameter_types for testing. * Better docs. * Some minors * Merge'em * Update frame/support/src/lib.rs Co-authored-by: Bastian Köcher * Align more to basti's trick * Update frame/support/src/lib.rs * Update frame/support/src/lib.rs Co-authored-by: Bastian Köcher Co-authored-by: Bastian Köcher * Bump wasm-bindgen-test from 0.3.12 to 0.3.17 (#7567) * Bump wasm-bindgen-test from 0.3.12 to 0.3.17 Bumps [wasm-bindgen-test](https://github.com/rustwasm/wasm-bindgen) from 0.3.12 to 0.3.17. - [Release notes](https://github.com/rustwasm/wasm-bindgen/releases) - [Changelog](https://github.com/rustwasm/wasm-bindgen/blob/master/CHANGELOG.md) - [Commits](https://github.com/rustwasm/wasm-bindgen/commits) Signed-off-by: dependabot[bot] * Update wasm-bindgen pin to 0.2.68 Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pierre Krieger * wk2047 | D6 | treasury refactor | review comments fix | p2 * wk2048 | D1 | treasury refactor | review comments fix | p3 * Update bin/node/runtime/src/lib.rs Co-authored-by: Shawn Tabrizi * Update bin/node/runtime/src/lib.rs Co-authored-by: Shawn Tabrizi * wk2048 | D3 | treasury refactor | review comments fix | p4 * wk2048 | D3 | treasury refactor | review comments fix | p5 * wk2048 | D4 | treasury refactor | review comments fix | removal of deadcode | p6 * remove broken link * wk2048 | D5 | treasury refactor | review comments fix | bountise doc string | p7 * wk2048 | D5 | treasury refactor | review comments fix | p8 * docs and formatting * Update frame/tips/src/benchmarking.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * formatting nits * Trait -> Config * trait -> config in benchmarks * clean up weight docs * Trait -> Config in Runtime * fix test build * try to fix polkadot build check * fix traits * Update lib.rs * Apply suggestions from code review Co-authored-by: Guillaume Thiolliere * Apply suggestions from code review Co-authored-by: Guillaume Thiolliere * fix trait location * nits * uncomment on_initialize for bounties benchmarks * update weights Co-authored-by: Shawn Tabrizi Co-authored-by: Parity Benchmarking Bot Co-authored-by: Caio Co-authored-by: Guillaume Thiolliere Co-authored-by: Antoine Le Calvez Co-authored-by: Bastian Köcher Co-authored-by: Jon Häggblad Co-authored-by: Wei Tang Co-authored-by: Sergei Shulepov Co-authored-by: Alexander Theißen Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: Pierre Krieger Co-authored-by: Kirill Pimenov Co-authored-by: Andrew Plaza Co-authored-by: Roman Borschel Co-authored-by: Max Inden Co-authored-by: Qinxuan Chen Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Tomasz Drwięga Co-authored-by: Bastian Köcher Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Addie Wagenknecht --- Cargo.lock | 39 + Cargo.toml | 2 + bin/node/runtime/Cargo.toml | 6 + bin/node/runtime/src/lib.rs | 31 +- frame/bounties/Cargo.toml | 47 ++ frame/bounties/README.md | 52 ++ frame/bounties/src/benchmarking.rs | 247 ++++++ frame/bounties/src/lib.rs | 757 +++++++++++++++++++ frame/bounties/src/tests.rs | 903 ++++++++++++++++++++++ frame/bounties/src/weights.rs | 189 +++++ frame/tips/Cargo.toml | 47 ++ frame/tips/README.md | 32 + frame/tips/src/benchmarking.rs | 193 +++++ frame/tips/src/lib.rs | 576 ++++++++++++++ frame/tips/src/tests.rs | 465 ++++++++++++ frame/tips/src/weights.rs | 131 ++++ frame/treasury/Cargo.toml | 1 + frame/treasury/README.md | 109 +-- frame/treasury/src/benchmarking.rs | 297 +------- frame/treasury/src/lib.rs | 1113 ++-------------------------- frame/treasury/src/tests.rs | 805 +------------------- frame/treasury/src/weights.rs | 262 +------ 22 files changed, 3795 insertions(+), 2509 deletions(-) create mode 100644 frame/bounties/Cargo.toml create mode 100644 frame/bounties/README.md create mode 100644 frame/bounties/src/benchmarking.rs create mode 100644 frame/bounties/src/lib.rs create mode 100644 frame/bounties/src/tests.rs create mode 100644 frame/bounties/src/weights.rs create mode 100644 frame/tips/Cargo.toml create mode 100644 frame/tips/README.md create mode 100644 frame/tips/src/benchmarking.rs create mode 100644 frame/tips/src/lib.rs create mode 100644 frame/tips/src/tests.rs create mode 100644 frame/tips/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 57f6028f5fc..c775fbb062e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3938,6 +3938,7 @@ dependencies = [ "pallet-authorship", "pallet-babe", "pallet-balances", + "pallet-bounties", "pallet-collective", "pallet-contracts", "pallet-contracts-primitives", @@ -3964,6 +3965,7 @@ dependencies = [ "pallet-staking-reward-curve", "pallet-sudo", "pallet-timestamp", + "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-treasury", @@ -4397,6 +4399,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-bounties" +version = "2.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-treasury", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", +] + [[package]] name = "pallet-collective" version = "2.0.0" @@ -5037,6 +5057,24 @@ dependencies = [ "sp-timestamp", ] +[[package]] +name = "pallet-tips" +version = "2.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-treasury", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", +] + [[package]] name = "pallet-transaction-payment" version = "2.0.0" @@ -5092,6 +5130,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "impl-trait-for-tuples", "pallet-balances", "parity-scale-codec", "serde", diff --git a/Cargo.toml b/Cargo.toml index 206673c0ef2..61282189da3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ members = [ "frame/babe", "frame/balances", "frame/benchmarking", + "frame/bounties", "frame/collective", "frame/contracts", "frame/contracts/rpc", @@ -112,6 +113,7 @@ members = [ "frame/transaction-payment/rpc", "frame/transaction-payment/rpc/runtime-api", "frame/treasury", + "frame/tips", "frame/utility", "frame/vesting", "primitives/allocator", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index ad0f6b35a25..4dabc5c0159 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -48,6 +48,7 @@ pallet-authority-discovery = { version = "2.0.0", default-features = false, path pallet-authorship = { version = "2.0.0", default-features = false, path = "../../../frame/authorship" } pallet-babe = { version = "2.0.0", default-features = false, path = "../../../frame/babe" } pallet-balances = { version = "2.0.0", default-features = false, path = "../../../frame/balances" } +pallet-bounties = { version = "2.0.0", default-features = false, path = "../../../frame/bounties" } pallet-collective = { version = "2.0.0", default-features = false, path = "../../../frame/collective" } pallet-contracts = { version = "2.0.0", default-features = false, path = "../../../frame/contracts" } pallet-contracts-primitives = { version = "2.0.0", default-features = false, path = "../../../frame/contracts/common/" } @@ -74,6 +75,7 @@ pallet-scheduler = { version = "2.0.0", default-features = false, path = "../../ pallet-society = { version = "2.0.0", default-features = false, path = "../../../frame/society" } pallet-sudo = { version = "2.0.0", default-features = false, path = "../../../frame/sudo" } pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../../frame/timestamp" } +pallet-tips = { version = "2.0.0", default-features = false, path = "../../../frame/tips" } pallet-treasury = { version = "2.0.0", default-features = false, path = "../../../frame/treasury" } pallet-utility = { version = "2.0.0", default-features = false, path = "../../../frame/utility" } pallet-transaction-payment = { version = "2.0.0", default-features = false, path = "../../../frame/transaction-payment" } @@ -97,6 +99,7 @@ std = [ "sp-consensus-babe/std", "pallet-babe/std", "pallet-balances/std", + "pallet-bounties/std", "sp-block-builder/std", "codec/std", "pallet-collective/std", @@ -136,6 +139,7 @@ std = [ "frame-system-rpc-runtime-api/std", "frame-system/std", "pallet-timestamp/std", + "pallet-tips/std", "pallet-transaction-payment-rpc-runtime-api/std", "pallet-transaction-payment/std", "pallet-treasury/std", @@ -154,6 +158,7 @@ runtime-benchmarks = [ "pallet-assets/runtime-benchmarks", "pallet-babe/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-bounties/runtime-benchmarks", "pallet-collective/runtime-benchmarks", "pallet-contracts/runtime-benchmarks", "pallet-democracy/runtime-benchmarks", @@ -169,6 +174,7 @@ runtime-benchmarks = [ "pallet-society/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-tips/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index fb8f720898b..fb77fd2ebd4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -671,25 +671,38 @@ impl pallet_treasury::Config for Runtime { EnsureRoot, pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective> >; - type Tippers = Elections; - type TipCountdown = TipCountdown; - type TipFindersFee = TipFindersFee; - type TipReportDepositBase = TipReportDepositBase; - type DataDepositPerByte = DataDepositPerByte; type Event = Event; type OnSlash = (); type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; + type BurnDestination = (); + type SpendFunds = Bounties; + type WeightInfo = pallet_treasury::weights::SubstrateWeight; +} + +impl pallet_bounties::Config for Runtime { + type Event = Event; type BountyDepositBase = BountyDepositBase; type BountyDepositPayoutDelay = BountyDepositPayoutDelay; type BountyUpdatePeriod = BountyUpdatePeriod; type BountyCuratorDeposit = BountyCuratorDeposit; type BountyValueMinimum = BountyValueMinimum; + type DataDepositPerByte = DataDepositPerByte; type MaximumReasonLength = MaximumReasonLength; - type BurnDestination = (); - type WeightInfo = pallet_treasury::weights::SubstrateWeight; + type WeightInfo = pallet_bounties::weights::SubstrateWeight; +} + +impl pallet_tips::Config for Runtime { + type Event = Event; + type DataDepositPerByte = DataDepositPerByte; + type MaximumReasonLength = MaximumReasonLength; + type Tippers = Elections; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type WeightInfo = pallet_tips::weights::SubstrateWeight; } parameter_types! { @@ -977,6 +990,8 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, + Bounties: pallet_bounties::{Module, Call, Storage, Event}, + Tips: pallet_tips::{Module, Call, Storage, Event}, Assets: pallet_assets::{Module, Call, Storage, Event}, Mmr: pallet_mmr::{Module, Storage}, } @@ -1248,6 +1263,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_assets, Assets); add_benchmark!(params, batches, pallet_babe, Babe); add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_bounties, Bounties); add_benchmark!(params, batches, pallet_collective, Council); add_benchmark!(params, batches, pallet_contracts, Contracts); add_benchmark!(params, batches, pallet_democracy, Democracy); @@ -1265,6 +1281,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_staking, Staking); add_benchmark!(params, batches, frame_system, SystemBench::); add_benchmark!(params, batches, pallet_timestamp, Timestamp); + add_benchmark!(params, batches, pallet_tips, Tips); add_benchmark!(params, batches, pallet_treasury, Treasury); add_benchmark!(params, batches, pallet_utility, Utility); add_benchmark!(params, batches, pallet_vesting, Vesting); diff --git a/frame/bounties/Cargo.toml b/frame/bounties/Cargo.toml new file mode 100644 index 00000000000..214637bb6c8 --- /dev/null +++ b/frame/bounties/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "pallet-bounties" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME pallet to manage bounties" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-treasury = { version = "2.0.0", default-features = false, path = "../treasury" } + +frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true } + +[dev-dependencies] +sp-io ={ version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-storage = { version = "2.0.0", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-treasury/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/bounties/README.md b/frame/bounties/README.md new file mode 100644 index 00000000000..bf63fca5f34 --- /dev/null +++ b/frame/bounties/README.md @@ -0,0 +1,52 @@ +# Bounties Module ( pallet-bounties ) + +## Bounty + +**Note :: This pallet is tightly coupled with pallet-treasury** + +A Bounty Spending is a reward for a specified body of work - or specified set of objectives - that +needs to be executed for a predefined Treasury amount to be paid out. A curator is assigned after +the bounty is approved and funded by Council, to be delegated with the responsibility of assigning a +payout address once the specified set of objectives is completed. + +After the Council has activated a bounty, it delegates the work that requires expertise to a curator +in exchange of a deposit. Once the curator accepts the bounty, they get to close the active bounty. +Closing the active bounty enacts a delayed payout to the payout address, the curator fee and the +return of the curator deposit. The delay allows for intervention through regular democracy. The +Council gets to unassign the curator, resulting in a new curator election. The Council also gets to +cancel the bounty if deemed necessary before assigning a curator or once the bounty is active or +payout is pending, resulting in the slash of the curator's deposit. + +### Terminology + +- **Bounty spending proposal:** A proposal to reward a predefined body of work upon completion by + the Treasury. +- **Proposer:** An account proposing a bounty spending. +- **Curator:** An account managing the bounty and assigning a payout address receiving the reward + for the completion of work. +- **Deposit:** The amount held on deposit for placing a bounty proposal plus the amount held on + deposit per byte within the bounty description. +- **Curator deposit:** The payment from a candidate willing to curate an approved bounty. The + deposit is returned when/if the bounty is completed. +- **Bounty value:** The total amount that should be paid to the Payout Address if the bounty is + rewarded. +- **Payout address:** The account to which the total or part of the bounty is assigned to. +- **Payout Delay:** The delay period for which a bounty beneficiary needs to wait before claiming. +- **Curator fee:** The reserved upfront payment for a curator for work related to the bounty. + +## Interface + +### Dispatchable Functions + +Bounty protocol: +- `propose_bounty` - Propose a specific treasury amount to be earmarked for a predefined set of + tasks and stake the required deposit. +- `approve_bounty` - Accept a specific treasury amount to be earmarked for a predefined body of + work. +- `propose_curator` - Assign an account to a bounty as candidate curator. +- `accept_curator` - Accept a bounty assignment from the Council, setting a curator deposit. +- `extend_bounty_expiry` - Extend the expiry block number of the bounty and stay active. +- `award_bounty` - Close and pay out the specified amount for the completed work. +- `claim_bounty` - Claim a specific bounty amount from the Payout Address. +- `unassign_curator` - Unassign an accepted curator from a specific earmark. +- `close_bounty` - Cancel the earmark for a specific treasury amount and close the bounty. diff --git a/frame/bounties/src/benchmarking.rs b/frame/bounties/src/benchmarking.rs new file mode 100644 index 00000000000..5a323ff0aaf --- /dev/null +++ b/frame/bounties/src/benchmarking.rs @@ -0,0 +1,247 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! bounties pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use sp_runtime::traits::Bounded; +use frame_system::{EventRecord, RawOrigin}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; +use frame_support::traits::OnInitialize; + +use crate::Module as Bounties; +use pallet_treasury::Module as Treasury; + +const SEED: u32 = 0; + +// Create bounties that are approved for use in `on_initialize`. +fn create_approved_bounties(n: u32) -> Result<(), &'static str> { + for i in 0 .. n { + let (caller, _curator, _fee, value, reason) = setup_bounty::(i, MAX_BYTES); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + Bounties::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; + } + ensure!(BountyApprovals::get().len() == n as usize, "Not all bounty approved"); + Ok(()) +} + +// Create the pre-requisite information needed to create a treasury `propose_bounty`. +fn setup_bounty(u: u32, d: u32) -> ( + T::AccountId, + T::AccountId, + BalanceOf, + BalanceOf, + Vec, +) { + let caller = account("caller", u, SEED); + let value: BalanceOf = T::BountyValueMinimum::get().saturating_mul(100u32.into()); + let fee = value / 2u32.into(); + let deposit = T::BountyDepositBase::get() + T::DataDepositPerByte::get() * MAX_BYTES.into(); + let _ = T::Currency::make_free_balance_be(&caller, deposit); + let curator = account("curator", u, SEED); + let _ = T::Currency::make_free_balance_be(&curator, fee / 2u32.into()); + let reason = vec![0; d as usize]; + (caller, curator, fee, value, reason) +} + +fn create_bounty() -> Result<( + ::Source, + BountyIndex, +), &'static str> { + let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); + let curator_lookup = T::Lookup::unlookup(curator.clone()); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + Bounties::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; + Treasury::::on_initialize(T::BlockNumber::zero()); + Bounties::::propose_curator(RawOrigin::Root.into(), bounty_id, curator_lookup.clone(), fee)?; + Bounties::::accept_curator(RawOrigin::Signed(curator).into(), bounty_id)?; + Ok((curator_lookup, bounty_id)) +} + +fn setup_pod_account() { + let pot_account = Bounties::::account_id(); + let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); + let _ = T::Currency::make_free_balance_be(&pot_account, value); +} + +fn assert_last_event(generic_event: ::Event) { + let events = frame_system::Module::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +const MAX_BYTES: u32 = 16384; + +benchmarks! { + _ { } + + propose_bounty { + let d in 0 .. MAX_BYTES; + + let (caller, curator, fee, value, description) = setup_bounty::(0, d); + }: _(RawOrigin::Signed(caller), value, description) + + approve_bounty { + let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + }: _(RawOrigin::Root, bounty_id) + + propose_curator { + setup_pod_account::(); + let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); + let curator_lookup = T::Lookup::unlookup(curator.clone()); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + Bounties::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; + Bounties::::on_initialize(T::BlockNumber::zero()); + }: _(RawOrigin::Root, bounty_id, curator_lookup, fee) + + // Worst case when curator is inactive and any sender unassigns the curator. + unassign_curator { + setup_pod_account::(); + let (curator_lookup, bounty_id) = create_bounty::()?; + Bounties::::on_initialize(T::BlockNumber::zero()); + let bounty_id = BountyCount::get() - 1; + frame_system::Module::::set_block_number(T::BountyUpdatePeriod::get() + 1u32.into()); + let caller = whitelisted_caller(); + }: _(RawOrigin::Signed(caller), bounty_id) + + accept_curator { + setup_pod_account::(); + let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); + let curator_lookup = T::Lookup::unlookup(curator.clone()); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + Bounties::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; + Bounties::::on_initialize(T::BlockNumber::zero()); + Bounties::::propose_curator(RawOrigin::Root.into(), bounty_id, curator_lookup, fee)?; + }: _(RawOrigin::Signed(curator), bounty_id) + + award_bounty { + setup_pod_account::(); + let (curator_lookup, bounty_id) = create_bounty::()?; + Bounties::::on_initialize(T::BlockNumber::zero()); + + let bounty_id = BountyCount::get() - 1; + let curator = T::Lookup::lookup(curator_lookup)?; + let beneficiary = T::Lookup::unlookup(account("beneficiary", 0, SEED)); + }: _(RawOrigin::Signed(curator), bounty_id, beneficiary) + + claim_bounty { + setup_pod_account::(); + let (curator_lookup, bounty_id) = create_bounty::()?; + Bounties::::on_initialize(T::BlockNumber::zero()); + + let bounty_id = BountyCount::get() - 1; + let curator = T::Lookup::lookup(curator_lookup)?; + + let beneficiary_account: T::AccountId = account("beneficiary", 0, SEED); + let beneficiary = T::Lookup::unlookup(beneficiary_account.clone()); + Bounties::::award_bounty(RawOrigin::Signed(curator.clone()).into(), bounty_id, beneficiary)?; + + frame_system::Module::::set_block_number(T::BountyDepositPayoutDelay::get()); + ensure!(T::Currency::free_balance(&beneficiary_account).is_zero(), "Beneficiary already has balance"); + + }: _(RawOrigin::Signed(curator), bounty_id) + verify { + ensure!(!T::Currency::free_balance(&beneficiary_account).is_zero(), "Beneficiary didn't get paid"); + } + + close_bounty_proposed { + setup_pod_account::(); + let (caller, curator, fee, value, reason) = setup_bounty::(0, 0); + Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; + let bounty_id = BountyCount::get() - 1; + }: close_bounty(RawOrigin::Root, bounty_id) + + close_bounty_active { + setup_pod_account::(); + let (curator_lookup, bounty_id) = create_bounty::()?; + Bounties::::on_initialize(T::BlockNumber::zero()); + let bounty_id = BountyCount::get() - 1; + }: close_bounty(RawOrigin::Root, bounty_id) + verify { + assert_last_event::(RawEvent::BountyCanceled(bounty_id).into()) + } + + extend_bounty_expiry { + setup_pod_account::(); + let (curator_lookup, bounty_id) = create_bounty::()?; + Bounties::::on_initialize(T::BlockNumber::zero()); + + let bounty_id = BountyCount::get() - 1; + let curator = T::Lookup::lookup(curator_lookup)?; + }: _(RawOrigin::Signed(curator), bounty_id, Vec::new()) + verify { + assert_last_event::(RawEvent::BountyExtended(bounty_id).into()) + } + + spend_funds { + let b in 1 .. 100; + setup_pod_account::(); + create_approved_bounties::(b)?; + + let mut budget_remaining = BalanceOf::::max_value(); + let mut imbalance = PositiveImbalanceOf::::zero(); + let mut total_weight = Weight::zero(); + let mut missed_any = false; + }: { + as pallet_treasury::SpendFunds>::spend_funds( + &mut budget_remaining, + &mut imbalance, + &mut total_weight, + &mut missed_any, + ); + } + verify { + ensure!(budget_remaining < BalanceOf::::max_value(), "Budget not used"); + ensure!(missed_any == false, "Missed some"); + assert_last_event::(RawEvent::BountyBecameActive(b - 1).into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_propose_bounty::()); + assert_ok!(test_benchmark_approve_bounty::()); + assert_ok!(test_benchmark_propose_curator::()); + assert_ok!(test_benchmark_unassign_curator::()); + assert_ok!(test_benchmark_accept_curator::()); + assert_ok!(test_benchmark_award_bounty::()); + assert_ok!(test_benchmark_claim_bounty::()); + assert_ok!(test_benchmark_close_bounty_proposed::()); + assert_ok!(test_benchmark_close_bounty_active::()); + assert_ok!(test_benchmark_extend_bounty_expiry::()); + assert_ok!(test_benchmark_spend_funds::()); + }); + } +} diff --git a/frame/bounties/src/lib.rs b/frame/bounties/src/lib.rs new file mode 100644 index 00000000000..32a37747262 --- /dev/null +++ b/frame/bounties/src/lib.rs @@ -0,0 +1,757 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! # Bounties Module ( pallet-bounties ) +//! +//! ## Bounty +//! +//! > NOTE: This pallet is tightly coupled with pallet-treasury. +//! +//! A Bounty Spending is a reward for a specified body of work - or specified set of objectives - +//! that needs to be executed for a predefined Treasury amount to be paid out. A curator is assigned +//! after the bounty is approved and funded by Council, to be delegated with the responsibility of +//! assigning a payout address once the specified set of objectives is completed. +//! +//! After the Council has activated a bounty, it delegates the work that requires expertise to a +//! curator in exchange of a deposit. Once the curator accepts the bounty, they get to close the +//! active bounty. Closing the active bounty enacts a delayed payout to the payout address, the +//! curator fee and the return of the curator deposit. The delay allows for intervention through +//! regular democracy. The Council gets to unassign the curator, resulting in a new curator +//! election. The Council also gets to cancel the bounty if deemed necessary before assigning a +//! curator or once the bounty is active or payout is pending, resulting in the slash of the +//! curator's deposit. +//! +//! +//! ### Terminology +//! +//! Bounty: +//! - **Bounty spending proposal:** A proposal to reward a predefined body of work upon completion +//! by the Treasury. +//! - **Proposer:** An account proposing a bounty spending. +//! - **Curator:** An account managing the bounty and assigning a payout address receiving the +//! reward for the completion of work. +//! - **Deposit:** The amount held on deposit for placing a bounty proposal plus the amount held on +//! deposit per byte within the bounty description. +//! - **Curator deposit:** The payment from a candidate willing to curate an approved bounty. The +//! deposit is returned when/if the bounty is completed. +//! - **Bounty value:** The total amount that should be paid to the Payout Address if the bounty is +//! rewarded. +//! - **Payout address:** The account to which the total or part of the bounty is assigned to. +//! - **Payout Delay:** The delay period for which a bounty beneficiary needs to wait before +//! claiming. +//! - **Curator fee:** The reserved upfront payment for a curator for work related to the bounty. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! Bounty protocol: +//! - `propose_bounty` - Propose a specific treasury amount to be earmarked for a predefined set of +//! tasks and stake the required deposit. +//! - `approve_bounty` - Accept a specific treasury amount to be earmarked for a predefined body of +//! work. +//! - `propose_curator` - Assign an account to a bounty as candidate curator. +//! - `accept_curator` - Accept a bounty assignment from the Council, setting a curator deposit. +//! - `extend_bounty_expiry` - Extend the expiry block number of the bounty and stay active. +//! - `award_bounty` - Close and pay out the specified amount for the completed work. +//! - `claim_bounty` - Claim a specific bounty amount from the Payout Address. +//! - `unassign_curator` - Unassign an accepted curator from a specific earmark. +//! - `close_bounty` - Cancel the earmark for a specific treasury amount and close the bounty. + +#![cfg_attr(not(feature = "std"), no_std)] + +mod tests; +mod benchmarking; +pub mod weights; + +use sp_std::prelude::*; + +use frame_support::{decl_module, decl_storage, decl_event, ensure, decl_error}; + +use frame_support::traits::{ + Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::{AllowDeath}, + ReservableCurrency}; + +use sp_runtime::{Permill, RuntimeDebug, DispatchResult, traits::{ + Zero, StaticLookup, AccountIdConversion, Saturating, BadOrigin +}}; + +use frame_support::dispatch::DispatchResultWithPostInfo; +use frame_support::traits::{EnsureOrigin}; + +use frame_support::weights::{Weight}; + +use codec::{Encode, Decode}; +use frame_system::{self as system, ensure_signed}; +pub use weights::WeightInfo; + +type BalanceOf = pallet_treasury::BalanceOf; + +type PositiveImbalanceOf = pallet_treasury::PositiveImbalanceOf; + +pub trait Config: frame_system::Config + pallet_treasury::Config { + + /// The amount held on deposit for placing a bounty proposal. + type BountyDepositBase: Get>; + + /// The delay period for which a bounty beneficiary need to wait before claim the payout. + type BountyDepositPayoutDelay: Get; + + /// Bounty duration in blocks. + type BountyUpdatePeriod: Get; + + /// Percentage of the curator fee that will be reserved upfront as deposit for bounty curator. + type BountyCuratorDeposit: Get; + + /// Minimum value for a bounty. + type BountyValueMinimum: Get>; + + /// The amount held on deposit per byte within the tip report reason or bounty description. + type DataDepositPerByte: Get>; + + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// Maximum acceptable reason length. + type MaximumReasonLength: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; +} + +/// An index of a bounty. Just a `u32`. +pub type BountyIndex = u32; + +/// A bounty proposal. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct Bounty { + /// The account proposing it. + proposer: AccountId, + /// The (total) amount that should be paid if the bounty is rewarded. + value: Balance, + /// The curator fee. Included in value. + fee: Balance, + /// The deposit of curator. + curator_deposit: Balance, + /// The amount held on deposit (reserved) for making this proposal. + bond: Balance, + /// The status of this bounty. + status: BountyStatus, +} + +/// The status of a bounty proposal. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub enum BountyStatus { + /// The bounty is proposed and waiting for approval. + Proposed, + /// The bounty is approved and waiting to become active at next spend period. + Approved, + /// The bounty is funded and waiting for curator assignment. + Funded, + /// A curator has been proposed by the `ApproveOrigin`. Waiting for acceptance from the curator. + CuratorProposed { + /// The assigned curator of this bounty. + curator: AccountId, + }, + /// The bounty is active and waiting to be awarded. + Active { + /// The curator of this bounty. + curator: AccountId, + /// An update from the curator is due by this block, else they are considered inactive. + update_due: BlockNumber, + }, + /// The bounty is awarded and waiting to released after a delay. + PendingPayout { + /// The curator of this bounty. + curator: AccountId, + /// The beneficiary of the bounty. + beneficiary: AccountId, + /// When the bounty can be claimed. + unlock_at: BlockNumber, + }, +} + +// Note :: For backward compatability reasons, +// pallet-bounties uses Treasury for storage. +// This is temporary solution, soon will get replaced with +// Own storage identifier. +decl_storage! { + trait Store for Module as Treasury { + + /// Number of bounty proposals that have been made. + pub BountyCount get(fn bounty_count): BountyIndex; + + /// Bounties that have been made. + pub Bounties get(fn bounties): + map hasher(twox_64_concat) BountyIndex + => Option, T::BlockNumber>>; + + /// The description of each bounty. + pub BountyDescriptions get(fn bounty_descriptions): map hasher(twox_64_concat) BountyIndex => Option>; + + /// Bounty indices that have been approved but not yet funded. + pub BountyApprovals get(fn bounty_approvals): Vec; + } +} + +decl_event!( + pub enum Event + where + Balance = BalanceOf, + ::AccountId, + { + /// New bounty proposal. \[index\] + BountyProposed(BountyIndex), + /// A bounty proposal was rejected; funds were slashed. \[index, bond\] + BountyRejected(BountyIndex, Balance), + /// A bounty proposal is funded and became active. \[index\] + BountyBecameActive(BountyIndex), + /// A bounty is awarded to a beneficiary. \[index, beneficiary\] + BountyAwarded(BountyIndex, AccountId), + /// A bounty is claimed by beneficiary. \[index, payout, beneficiary\] + BountyClaimed(BountyIndex, Balance, AccountId), + /// A bounty is cancelled. \[index\] + BountyCanceled(BountyIndex), + /// A bounty expiry is extended. \[index\] + BountyExtended(BountyIndex), + } +); + +decl_error! { + /// Error for the treasury module. + pub enum Error for Module { + /// Proposer's balance is too low. + InsufficientProposersBalance, + /// No proposal or bounty at that index. + InvalidIndex, + /// The reason given is just too big. + ReasonTooBig, + /// The bounty status is unexpected. + UnexpectedStatus, + /// Require bounty curator. + RequireCurator, + /// Invalid bounty value. + InvalidValue, + /// Invalid bounty fee. + InvalidFee, + /// A bounty payout is pending. + /// To cancel the bounty, you must unassign and slash the curator. + PendingPayout, + /// The bounties cannot be claimed/closed because it's still in the countdown period. + Premature, + } +} + +decl_module! { + pub struct Module + for enum Call + where origin: T::Origin + { + /// The amount held on deposit per byte within bounty description. + const DataDepositPerByte: BalanceOf = T::DataDepositPerByte::get(); + + /// The amount held on deposit for placing a bounty proposal. + const BountyDepositBase: BalanceOf = T::BountyDepositBase::get(); + + /// The delay period for which a bounty beneficiary need to wait before claim the payout. + const BountyDepositPayoutDelay: T::BlockNumber = T::BountyDepositPayoutDelay::get(); + + /// Percentage of the curator fee that will be reserved upfront as deposit for bounty curator. + const BountyCuratorDeposit: Permill = T::BountyCuratorDeposit::get(); + + /// Minimum value for a bounty. + const BountyValueMinimum: BalanceOf = T::BountyValueMinimum::get(); + + /// Maximum acceptable reason length. + const MaximumReasonLength: u32 = T::MaximumReasonLength::get(); + + type Error = Error; + + fn deposit_event() = default; + + /// Propose a new bounty. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Payment: `TipReportDepositBase` will be reserved from the origin account, as well as + /// `DataDepositPerByte` for each byte in `reason`. It will be unreserved upon approval, + /// or slashed when rejected. + /// + /// - `curator`: The curator account whom will manage this bounty. + /// - `fee`: The curator fee. + /// - `value`: The total payment amount of this bounty, curator fee included. + /// - `description`: The description of this bounty. + #[weight = ::WeightInfo::propose_bounty(description.len() as u32)] + fn propose_bounty( + origin, + #[compact] value: BalanceOf, + description: Vec, + ) { + let proposer = ensure_signed(origin)?; + Self::create_bounty(proposer, description, value)?; + } + + /// Approve a bounty proposal. At a later time, the bounty will be funded and become active + /// and the original deposit will be returned. + /// + /// May only be called from `T::ApproveOrigin`. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::approve_bounty()] + fn approve_bounty(origin, #[compact] bounty_id: BountyIndex) { + T::ApproveOrigin::ensure_origin(origin)?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + ensure!(bounty.status == BountyStatus::Proposed, Error::::UnexpectedStatus); + + bounty.status = BountyStatus::Approved; + + BountyApprovals::append(bounty_id); + + Ok(()) + })?; + } + + /// Assign a curator to a funded bounty. + /// + /// May only be called from `T::ApproveOrigin`. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::propose_curator()] + fn propose_curator( + origin, + #[compact] bounty_id: BountyIndex, + curator: ::Source, + #[compact] fee: BalanceOf, + ) { + T::ApproveOrigin::ensure_origin(origin)?; + + let curator = T::Lookup::lookup(curator)?; + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + + let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + match bounty.status { + BountyStatus::Proposed | BountyStatus::Approved | BountyStatus::Funded => {}, + _ => return Err(Error::::UnexpectedStatus.into()), + }; + + ensure!(fee < bounty.value, Error::::InvalidFee); + + bounty.status = BountyStatus::CuratorProposed { curator }; + bounty.fee = fee; + + Ok(()) + })?; + } + + /// Unassign curator from a bounty. + /// + /// This function can only be called by the `RejectOrigin` a signed origin. + /// + /// If this function is called by the `RejectOrigin`, we assume that the curator is malicious + /// or inactive. As a result, we will slash the curator when possible. + /// + /// If the origin is the curator, we take this as a sign they are unable to do their job and + /// they willingly give up. We could slash them, but for now we allow them to recover their + /// deposit and exit without issue. (We may want to change this if it is abused.) + /// + /// Finally, the origin can be anyone if and only if the curator is "inactive". This allows + /// anyone in the community to call out that a curator is not doing their due diligence, and + /// we should pick a new curator. In this case the curator should also be slashed. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::unassign_curator()] + fn unassign_curator( + origin, + #[compact] bounty_id: BountyIndex, + ) { + let maybe_sender = ensure_signed(origin.clone()) + .map(Some) + .or_else(|_| T::RejectOrigin::ensure_origin(origin).map(|_| None))?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + + let slash_curator = |curator: &T::AccountId, curator_deposit: &mut BalanceOf| { + let imbalance = T::Currency::slash_reserved(curator, *curator_deposit).0; + T::OnSlash::on_unbalanced(imbalance); + *curator_deposit = Zero::zero(); + }; + + match bounty.status { + BountyStatus::Proposed | BountyStatus::Approved | BountyStatus::Funded => { + // No curator to unassign at this point. + return Err(Error::::UnexpectedStatus.into()) + } + BountyStatus::CuratorProposed { ref curator } => { + // A curator has been proposed, but not accepted yet. + // Either `RejectOrigin` or the proposed curator can unassign the curator. + ensure!(maybe_sender.map_or(true, |sender| sender == *curator), BadOrigin); + }, + BountyStatus::Active { ref curator, ref update_due } => { + // The bounty is active. + match maybe_sender { + // If the `RejectOrigin` is calling this function, slash the curator. + None => { + slash_curator(curator, &mut bounty.curator_deposit); + // Continue to change bounty status below... + }, + Some(sender) => { + // If the sender is not the curator, and the curator is inactive, + // slash the curator. + if sender != *curator { + let block_number = system::Module::::block_number(); + if *update_due < block_number { + slash_curator(curator, &mut bounty.curator_deposit); + // Continue to change bounty status below... + } else { + // Curator has more time to give an update. + return Err(Error::::Premature.into()) + } + } else { + // Else this is the curator, willingly giving up their role. + // Give back their deposit. + let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); + // Continue to change bounty status below... + } + }, + } + }, + BountyStatus::PendingPayout { ref curator, .. } => { + // The bounty is pending payout, so only council can unassign a curator. + // By doing so, they are claiming the curator is acting maliciously, so + // we slash the curator. + ensure!(maybe_sender.is_none(), BadOrigin); + slash_curator(curator, &mut bounty.curator_deposit); + // Continue to change bounty status below... + } + }; + + bounty.status = BountyStatus::Funded; + Ok(()) + })?; + } + + /// Accept the curator role for a bounty. + /// A deposit will be reserved from curator and refund upon successful payout. + /// + /// May only be called from the curator. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::accept_curator()] + fn accept_curator(origin, #[compact] bounty_id: BountyIndex) { + let signer = ensure_signed(origin)?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + + match bounty.status { + BountyStatus::CuratorProposed { ref curator } => { + ensure!(signer == *curator, Error::::RequireCurator); + + let deposit = T::BountyCuratorDeposit::get() * bounty.fee; + T::Currency::reserve(curator, deposit)?; + bounty.curator_deposit = deposit; + + let update_due = system::Module::::block_number() + T::BountyUpdatePeriod::get(); + bounty.status = BountyStatus::Active { curator: curator.clone(), update_due }; + + Ok(()) + }, + _ => Err(Error::::UnexpectedStatus.into()), + } + })?; + } + + /// Award bounty to a beneficiary account. The beneficiary will be able to claim the funds after a delay. + /// + /// The dispatch origin for this call must be the curator of this bounty. + /// + /// - `bounty_id`: Bounty ID to award. + /// - `beneficiary`: The beneficiary account whom will receive the payout. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::award_bounty()] + fn award_bounty(origin, #[compact] bounty_id: BountyIndex, beneficiary: ::Source) { + let signer = ensure_signed(origin)?; + let beneficiary = T::Lookup::lookup(beneficiary)?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + match &bounty.status { + BountyStatus::Active { + curator, + .. + } => { + ensure!(signer == *curator, Error::::RequireCurator); + }, + _ => return Err(Error::::UnexpectedStatus.into()), + } + bounty.status = BountyStatus::PendingPayout { + curator: signer, + beneficiary: beneficiary.clone(), + unlock_at: system::Module::::block_number() + T::BountyDepositPayoutDelay::get(), + }; + + Ok(()) + })?; + + Self::deposit_event(Event::::BountyAwarded(bounty_id, beneficiary)); + } + + /// Claim the payout from an awarded bounty after payout delay. + /// + /// The dispatch origin for this call must be the beneficiary of this bounty. + /// + /// - `bounty_id`: Bounty ID to claim. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::claim_bounty()] + fn claim_bounty(origin, #[compact] bounty_id: BountyIndex) { + let _ = ensure_signed(origin)?; // anyone can trigger claim + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let bounty = maybe_bounty.take().ok_or(Error::::InvalidIndex)?; + if let BountyStatus::PendingPayout { curator, beneficiary, unlock_at } = bounty.status { + ensure!(system::Module::::block_number() >= unlock_at, Error::::Premature); + let bounty_account = Self::bounty_account_id(bounty_id); + let balance = T::Currency::free_balance(&bounty_account); + let fee = bounty.fee.min(balance); // just to be safe + let payout = balance.saturating_sub(fee); + let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); + let _ = T::Currency::transfer(&bounty_account, &curator, fee, AllowDeath); // should not fail + let _ = T::Currency::transfer(&bounty_account, &beneficiary, payout, AllowDeath); // should not fail + *maybe_bounty = None; + + BountyDescriptions::remove(bounty_id); + + Self::deposit_event(Event::::BountyClaimed(bounty_id, payout, beneficiary)); + Ok(()) + } else { + Err(Error::::UnexpectedStatus.into()) + } + })?; + } + + /// Cancel a proposed or active bounty. All the funds will be sent to treasury and + /// the curator deposit will be unreserved if possible. + /// + /// Only `T::RejectOrigin` is able to cancel a bounty. + /// + /// - `bounty_id`: Bounty ID to cancel. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::close_bounty_proposed().max(::WeightInfo::close_bounty_active())] + fn close_bounty(origin, #[compact] bounty_id: BountyIndex) -> DispatchResultWithPostInfo { + T::RejectOrigin::ensure_origin(origin)?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResultWithPostInfo { + let bounty = maybe_bounty.as_ref().ok_or(Error::::InvalidIndex)?; + + match &bounty.status { + BountyStatus::Proposed => { + // The reject origin would like to cancel a proposed bounty. + BountyDescriptions::remove(bounty_id); + let value = bounty.bond; + let imbalance = T::Currency::slash_reserved(&bounty.proposer, value).0; + T::OnSlash::on_unbalanced(imbalance); + *maybe_bounty = None; + + Self::deposit_event(Event::::BountyRejected(bounty_id, value)); + // Return early, nothing else to do. + return Ok(Some(::WeightInfo::close_bounty_proposed()).into()) + }, + BountyStatus::Approved => { + // For weight reasons, we don't allow a council to cancel in this phase. + // We ask for them to wait until it is funded before they can cancel. + return Err(Error::::UnexpectedStatus.into()) + }, + BountyStatus::Funded | + BountyStatus::CuratorProposed { .. } => { + // Nothing extra to do besides the removal of the bounty below. + }, + BountyStatus::Active { curator, .. } => { + // Cancelled by council, refund deposit of the working curator. + let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); + // Then execute removal of the bounty below. + }, + BountyStatus::PendingPayout { .. } => { + // Bounty is already pending payout. If council wants to cancel + // this bounty, it should mean the curator was acting maliciously. + // So the council should first unassign the curator, slashing their + // deposit. + return Err(Error::::PendingPayout.into()) + } + } + + let bounty_account = Self::bounty_account_id(bounty_id); + + BountyDescriptions::remove(bounty_id); + + let balance = T::Currency::free_balance(&bounty_account); + let _ = T::Currency::transfer(&bounty_account, &Self::account_id(), balance, AllowDeath); // should not fail + *maybe_bounty = None; + + Self::deposit_event(Event::::BountyCanceled(bounty_id)); + Ok(Some(::WeightInfo::close_bounty_active()).into()) + }) + } + + /// Extend the expiry time of an active bounty. + /// + /// The dispatch origin for this call must be the curator of this bounty. + /// + /// - `bounty_id`: Bounty ID to extend. + /// - `remark`: additional information. + /// + /// # + /// - O(1). + /// # + #[weight = ::WeightInfo::extend_bounty_expiry()] + fn extend_bounty_expiry(origin, #[compact] bounty_id: BountyIndex, _remark: Vec) { + let signer = ensure_signed(origin)?; + + Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { + let bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; + + match bounty.status { + BountyStatus::Active { ref curator, ref mut update_due } => { + ensure!(*curator == signer, Error::::RequireCurator); + *update_due = (system::Module::::block_number() + T::BountyUpdatePeriod::get()).max(*update_due); + }, + _ => return Err(Error::::UnexpectedStatus.into()), + } + + Ok(()) + })?; + + Self::deposit_event(Event::::BountyExtended(bounty_id)); + } + } +} + +impl Module { + // Add public immutables and private mutables. + + /// The account ID of the treasury pot. + /// + /// This actually does computation. If you need to keep using it, then make sure you cache the + /// value and only call this once. + pub fn account_id() -> T::AccountId { + T::ModuleId::get().into_account() + } + + /// The account ID of a bounty account + pub fn bounty_account_id(id: BountyIndex) -> T::AccountId { + // only use two byte prefix to support 16 byte account id (used by test) + // "modl" ++ "py/trsry" ++ "bt" is 14 bytes, and two bytes remaining for bounty index + T::ModuleId::get().into_sub_account(("bt", id)) + } + + fn create_bounty( + proposer: T::AccountId, + description: Vec, + value: BalanceOf, + ) -> DispatchResult { + ensure!(description.len() <= T::MaximumReasonLength::get() as usize, Error::::ReasonTooBig); + ensure!(value >= T::BountyValueMinimum::get(), Error::::InvalidValue); + + let index = Self::bounty_count(); + + // reserve deposit for new bounty + let bond = T::BountyDepositBase::get() + + T::DataDepositPerByte::get() * (description.len() as u32).into(); + T::Currency::reserve(&proposer, bond) + .map_err(|_| Error::::InsufficientProposersBalance)?; + + BountyCount::put(index + 1); + + let bounty = Bounty { + proposer, + value, + fee: 0u32.into(), + curator_deposit: 0u32.into(), + bond, + status: BountyStatus::Proposed, + }; + + Bounties::::insert(index, &bounty); + BountyDescriptions::insert(index, description); + + Self::deposit_event(RawEvent::BountyProposed(index)); + + Ok(()) + } + +} + +impl pallet_treasury::SpendFunds for Module { + fn spend_funds( + budget_remaining: &mut BalanceOf, + imbalance: &mut PositiveImbalanceOf, + total_weight: &mut Weight, + missed_any: &mut bool + ) { + let bounties_len = BountyApprovals::mutate(|v| { + let bounties_approval_len = v.len() as u32; + v.retain(|&index| { + Bounties::::mutate(index, |bounty| { + // Should always be true, but shouldn't panic if false or we're screwed. + if let Some(bounty) = bounty { + if bounty.value <= *budget_remaining { + *budget_remaining -= bounty.value; + + bounty.status = BountyStatus::Funded; + + // return their deposit. + let _ = T::Currency::unreserve(&bounty.proposer, bounty.bond); + + // fund the bounty account + imbalance.subsume(T::Currency::deposit_creating(&Self::bounty_account_id(index), bounty.value)); + + Self::deposit_event(RawEvent::BountyBecameActive(index)); + false + } else { + *missed_any = true; + true + } + } else { + false + } + }) + }); + bounties_approval_len + }); + + *total_weight += ::WeightInfo::spend_funds(bounties_len); + } +} diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs new file mode 100644 index 00000000000..4ebff64b4e4 --- /dev/null +++ b/frame/bounties/src/tests.rs @@ -0,0 +1,903 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! bounties pallet tests. + +#![cfg(test)] + +use super::*; +use std::cell::RefCell; + +use frame_support::{ + assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight, + impl_outer_event, traits::{OnInitialize} +}; + +use sp_core::H256; +use sp_runtime::{ + Perbill, ModuleId, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, BadOrigin}, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +mod bounties { + // Re-export needed for `impl_outer_event!`. + pub use crate::*; +} + +impl_outer_event! { + pub enum Event for Test { + system, + pallet_balances, + pallet_treasury, + bounties, + } +} + +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Config for Test { + type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u128; // u64 is not enough to hold bytes used to generate bounty account + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Config for Test { + type MaxLocks = (); + type Balance = u64; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} +thread_local! { + static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![10,11,12,13,14]); +} +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: u64 = 1; + pub const SpendPeriod: u64 = 2; + pub const Burn: Permill = Permill::from_percent(50); + pub const DataDepositPerByte: u64 = 1; + pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry"); +} +// impl pallet_treasury::Config for Test { +impl pallet_treasury::Config for Test { + type ModuleId = TreasuryModuleId; + type Currency = pallet_balances::Module; + type ApproveOrigin = frame_system::EnsureRoot; + type RejectOrigin = frame_system::EnsureRoot; + type Event = Event; + type OnSlash = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); // Just gets burned. + type WeightInfo = (); + type SpendFunds = Bounties; +} +parameter_types! { + pub const BountyDepositBase: u64 = 80; + pub const BountyDepositPayoutDelay: u64 = 3; + pub const BountyUpdatePeriod: u32 = 20; + pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); + pub const BountyValueMinimum: u64 = 1; + pub const MaximumReasonLength: u32 = 16384; +} +impl Config for Test { + type Event = Event; + type BountyDepositBase = BountyDepositBase; + type BountyDepositPayoutDelay = BountyDepositPayoutDelay; + type BountyUpdatePeriod = BountyUpdatePeriod; + type BountyCuratorDeposit = BountyCuratorDeposit; + type BountyValueMinimum = BountyValueMinimum; + type DataDepositPerByte = DataDepositPerByte; + type MaximumReasonLength = MaximumReasonLength; + type WeightInfo = (); +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Treasury = pallet_treasury::Module; +type Bounties = Module; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + // Total issuance will be 200 with treasury account initialized at ED. + balances: vec![(0, 100), (1, 98), (2, 1)], + }.assimilate_storage(&mut t).unwrap(); + pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + t.into() +} + +fn last_event() -> RawEvent { + System::events().into_iter().map(|r| r.event) + .filter_map(|e| { + if let Event::bounties(inner) = e { Some(inner) } else { None } + }) + .last() + .unwrap() +} + +#[test] +fn genesis_config_works() { + new_test_ext().execute_with(|| { + assert_eq!(Treasury::pot(), 0); + assert_eq!(Treasury::proposal_count(), 0); + }); +} + +#[test] +fn minting_works() { + new_test_ext().execute_with(|| { + // Check that accumulate works when we have Some value in Dummy already. + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + }); +} + +#[test] +fn spend_proposal_takes_min_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_eq!(Balances::free_balance(0), 99); + assert_eq!(Balances::reserved_balance(0), 1); + }); +} + +#[test] +fn spend_proposal_takes_proportional_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_eq!(Balances::free_balance(0), 95); + assert_eq!(Balances::reserved_balance(0), 5); + }); +} + +#[test] +fn spend_proposal_fails_when_proposer_poor() { + new_test_ext().execute_with(|| { + assert_noop!( + Treasury::propose_spend(Origin::signed(2), 100, 3), + Error::::InsufficientProposersBalance, + ); + }); +} + +#[test] +fn accepted_spend_proposal_ignored_outside_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); + + >::on_initialize(1); + assert_eq!(Balances::free_balance(3), 0); + assert_eq!(Treasury::pot(), 100); + }); +} + +#[test] +fn unused_pot_should_diminish() { + new_test_ext().execute_with(|| { + let init_total_issuance = Balances::total_issuance(); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Balances::total_issuance(), init_total_issuance + 100); + + >::on_initialize(2); + assert_eq!(Treasury::pot(), 50); + assert_eq!(Balances::total_issuance(), init_total_issuance + 50); + }); +} + +#[test] +fn rejected_spend_proposal_ignored_on_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); + + >::on_initialize(2); + assert_eq!(Balances::free_balance(3), 0); + assert_eq!(Treasury::pot(), 50); + }); +} + +#[test] +fn reject_already_rejected_spend_proposal_fails() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); + assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::::InvalidIndex); + }); +} + +#[test] +fn reject_non_existent_spend_proposal_fails() { + new_test_ext().execute_with(|| { + assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::::InvalidIndex); + }); +} + +#[test] +fn accept_non_existent_spend_proposal_fails() { + new_test_ext().execute_with(|| { + assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::::InvalidIndex); + }); +} + +#[test] +fn accept_already_rejected_spend_proposal_fails() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); + assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::::InvalidIndex); + }); +} + +#[test] +fn accepted_spend_proposal_enacted_on_spend_period() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); + + >::on_initialize(2); + assert_eq!(Balances::free_balance(3), 100); + assert_eq!(Treasury::pot(), 0); + }); +} + +#[test] +fn pot_underflow_should_not_diminish() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); + + >::on_initialize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + let _ = Balances::deposit_into_existing(&Treasury::account_id(), 100).unwrap(); + >::on_initialize(4); + assert_eq!(Balances::free_balance(3), 150); // Fund has been spent + assert_eq!(Treasury::pot(), 25); // Pot has finally changed + }); +} + +// Treasury account doesn't get deleted if amount approved to spend is all its free balance. +// i.e. pot should not include existential deposit needed for account survival. +#[test] +fn treasury_account_doesnt_get_deleted() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + let treasury_balance = Balances::free_balance(&Treasury::account_id()); + + assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); + + >::on_initialize(2); + assert_eq!(Treasury::pot(), 100); // Pot hasn't changed + + assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 1)); + + >::on_initialize(4); + assert_eq!(Treasury::pot(), 0); // Pot is emptied + assert_eq!(Balances::free_balance(Treasury::account_id()), 1); // but the account is still there + }); +} + +// In case treasury account is not existing then it works fine. +// This is useful for chain that will just update runtime. +#[test] +fn inexistent_account_works() { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + balances: vec![(0, 100), (1, 99), (2, 1)], + }.assimilate_storage(&mut t).unwrap(); + // Treasury genesis config is not build thus treasury account does not exist + let mut t: sp_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(Treasury::account_id()), 0); // Account does not exist + assert_eq!(Treasury::pot(), 0); // Pot is empty + + assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 1)); + >::on_initialize(2); + assert_eq!(Treasury::pot(), 0); // Pot hasn't changed + assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed + + Balances::make_free_balance_be(&Treasury::account_id(), 100); + assert_eq!(Treasury::pot(), 99); // Pot now contains funds + assert_eq!(Balances::free_balance(Treasury::account_id()), 100); // Account does exist + + >::on_initialize(4); + + assert_eq!(Treasury::pot(), 0); // Pot has changed + assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed + }); +} + +#[test] +fn propose_bounty_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 10, b"1234567890".to_vec())); + + assert_eq!(last_event(), RawEvent::BountyProposed(0)); + + let deposit: u64 = 85 + 5; + assert_eq!(Balances::reserved_balance(0), deposit); + assert_eq!(Balances::free_balance(0), 100 - deposit); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 0, + curator_deposit: 0, + value: 10, + bond: deposit, + status: BountyStatus::Proposed, + }); + + assert_eq!(Bounties::bounty_descriptions(0).unwrap(), b"1234567890".to_vec()); + + assert_eq!(Bounties::bounty_count(), 1); + }); +} + +#[test] +fn propose_bounty_validation_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_noop!( + Bounties::propose_bounty(Origin::signed(1), 0, [0; 17_000].to_vec()), + Error::::ReasonTooBig + ); + + assert_noop!( + Bounties::propose_bounty(Origin::signed(1), 10, b"12345678901234567890".to_vec()), + Error::::InsufficientProposersBalance + ); + + assert_noop!( + Bounties::propose_bounty(Origin::signed(1), 0, b"12345678901234567890".to_vec()), + Error::::InvalidValue + ); + }); +} + +#[test] +fn close_bounty_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_noop!(Bounties::close_bounty(Origin::root(), 0), Error::::InvalidIndex); + + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 10, b"12345".to_vec())); + + assert_ok!(Bounties::close_bounty(Origin::root(), 0)); + + let deposit: u64 = 80 + 5; + + assert_eq!(last_event(), RawEvent::BountyRejected(0, deposit)); + + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 100 - deposit); + + assert_eq!(Bounties::bounties(0), None); + assert!(!pallet_treasury::Proposals::::contains_key(0)); + + assert_eq!(Bounties::bounty_descriptions(0), None); + }); +} + +#[test] +fn approve_bounty_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_noop!(Bounties::approve_bounty(Origin::root(), 0), Error::::InvalidIndex); + + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + let deposit: u64 = 80 + 5; + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 0, + value: 50, + curator_deposit: 0, + bond: deposit, + status: BountyStatus::Approved, + }); + assert_eq!(Bounties::bounty_approvals(), vec![0]); + + assert_noop!(Bounties::close_bounty(Origin::root(), 0), Error::::UnexpectedStatus); + + // deposit not returned yet + assert_eq!(Balances::reserved_balance(0), deposit); + assert_eq!(Balances::free_balance(0), 100 - deposit); + + >::on_initialize(2); + + // return deposit + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 100); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 0, + curator_deposit: 0, + value: 50, + bond: deposit, + status: BountyStatus::Funded, + }); + + assert_eq!(Treasury::pot(), 100 - 50 - 25); // burn 25 + assert_eq!(Balances::free_balance(Bounties::bounty_account_id(0)), 50); + }); +} + +#[test] +fn assign_curator_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_noop!(Bounties::propose_curator(Origin::root(), 0, 4, 4), Error::::InvalidIndex); + + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_noop!(Bounties::propose_curator(Origin::root(), 0, 4, 50), Error::::InvalidFee); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 4)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 4, + curator_deposit: 0, + value: 50, + bond: 85, + status: BountyStatus::CuratorProposed { + curator: 4, + }, + }); + + assert_noop!(Bounties::accept_curator(Origin::signed(1), 0), Error::::RequireCurator); + assert_noop!(Bounties::accept_curator(Origin::signed(4), 0), pallet_balances::Error::::InsufficientBalance); + + Balances::make_free_balance_be(&4, 10); + + assert_ok!(Bounties::accept_curator(Origin::signed(4), 0)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 4, + curator_deposit: 2, + value: 50, + bond: 85, + status: BountyStatus::Active { + curator: 4, + update_due: 22, + }, + }); + + assert_eq!(Balances::free_balance(&4), 8); + assert_eq!(Balances::reserved_balance(&4), 2); + }); +} + +#[test] +fn unassign_curator_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 4)); + + assert_noop!(Bounties::unassign_curator(Origin::signed(1), 0), BadOrigin); + + assert_ok!(Bounties::unassign_curator(Origin::signed(4), 0)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 4, + curator_deposit: 0, + value: 50, + bond: 85, + status: BountyStatus::Funded, + }); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 4)); + + Balances::make_free_balance_be(&4, 10); + + assert_ok!(Bounties::accept_curator(Origin::signed(4), 0)); + + assert_ok!(Bounties::unassign_curator(Origin::root(), 0)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 4, + curator_deposit: 0, + value: 50, + bond: 85, + status: BountyStatus::Funded, + }); + + assert_eq!(Balances::free_balance(&4), 8); + assert_eq!(Balances::reserved_balance(&4), 0); // slashed 2 + }); +} + + +#[test] +fn award_and_claim_bounty_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + Balances::make_free_balance_be(&4, 10); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 4)); + assert_ok!(Bounties::accept_curator(Origin::signed(4), 0)); + + assert_eq!(Balances::free_balance(4), 8); // inital 10 - 2 deposit + + assert_noop!(Bounties::award_bounty(Origin::signed(1), 0, 3), Error::::RequireCurator); + + assert_ok!(Bounties::award_bounty(Origin::signed(4), 0, 3)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 4, + curator_deposit: 2, + value: 50, + bond: 85, + status: BountyStatus::PendingPayout { + curator: 4, + beneficiary: 3, + unlock_at: 5 + }, + }); + + assert_noop!(Bounties::claim_bounty(Origin::signed(1), 0), Error::::Premature); + + System::set_block_number(5); + >::on_initialize(5); + + assert_ok!(Balances::transfer(Origin::signed(0), Bounties::bounty_account_id(0), 10)); + + assert_ok!(Bounties::claim_bounty(Origin::signed(1), 0)); + + assert_eq!(last_event(), RawEvent::BountyClaimed(0, 56, 3)); + + assert_eq!(Balances::free_balance(4), 14); // initial 10 + fee 4 + + assert_eq!(Balances::free_balance(3), 56); + assert_eq!(Balances::free_balance(Bounties::bounty_account_id(0)), 0); + + assert_eq!(Bounties::bounties(0), None); + assert_eq!(Bounties::bounty_descriptions(0), None); + }); +} + +#[test] +fn claim_handles_high_fee() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + Balances::make_free_balance_be(&4, 30); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 49)); + assert_ok!(Bounties::accept_curator(Origin::signed(4), 0)); + + assert_ok!(Bounties::award_bounty(Origin::signed(4), 0, 3)); + + System::set_block_number(5); + >::on_initialize(5); + + // make fee > balance + let _ = Balances::slash(&Bounties::bounty_account_id(0), 10); + + assert_ok!(Bounties::claim_bounty(Origin::signed(1), 0)); + + assert_eq!(last_event(), RawEvent::BountyClaimed(0, 0, 3)); + + assert_eq!(Balances::free_balance(4), 70); // 30 + 50 - 10 + assert_eq!(Balances::free_balance(3), 0); + assert_eq!(Balances::free_balance(Bounties::bounty_account_id(0)), 0); + + assert_eq!(Bounties::bounties(0), None); + assert_eq!(Bounties::bounty_descriptions(0), None); + }); +} + +#[test] +fn cancel_and_refund() { + new_test_ext().execute_with(|| { + + System::set_block_number(1); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Balances::transfer(Origin::signed(0), Bounties::bounty_account_id(0), 10)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 0, + curator_deposit: 0, + value: 50, + bond: 85, + status: BountyStatus::Funded, + }); + + assert_eq!(Balances::free_balance(Bounties::bounty_account_id(0)), 60); + + assert_noop!(Bounties::close_bounty(Origin::signed(0), 0), BadOrigin); + + assert_ok!(Bounties::close_bounty(Origin::root(), 0)); + + assert_eq!(Treasury::pot(), 85); // - 25 + 10 + + }); + +} + +#[test] +fn award_and_cancel() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 0, 10)); + assert_ok!(Bounties::accept_curator(Origin::signed(0), 0)); + + assert_eq!(Balances::free_balance(0), 95); + assert_eq!(Balances::reserved_balance(0), 5); + + assert_ok!(Bounties::award_bounty(Origin::signed(0), 0, 3)); + + // Cannot close bounty directly when payout is happening... + assert_noop!(Bounties::close_bounty(Origin::root(), 0), Error::::PendingPayout); + + // Instead unassign the curator to slash them and then close. + assert_ok!(Bounties::unassign_curator(Origin::root(), 0)); + assert_ok!(Bounties::close_bounty(Origin::root(), 0)); + + assert_eq!(last_event(), RawEvent::BountyCanceled(0)); + + assert_eq!(Balances::free_balance(Bounties::bounty_account_id(0)), 0); + + // Slashed. + assert_eq!(Balances::free_balance(0), 95); + assert_eq!(Balances::reserved_balance(0), 0); + + assert_eq!(Bounties::bounties(0), None); + assert_eq!(Bounties::bounty_descriptions(0), None); + }); +} + +#[test] +fn expire_and_unassign() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 1, 10)); + assert_ok!(Bounties::accept_curator(Origin::signed(1), 0)); + + assert_eq!(Balances::free_balance(1), 93); + assert_eq!(Balances::reserved_balance(1), 5); + + System::set_block_number(22); + >::on_initialize(22); + + assert_noop!(Bounties::unassign_curator(Origin::signed(0), 0), Error::::Premature); + + System::set_block_number(23); + >::on_initialize(23); + + assert_ok!(Bounties::unassign_curator(Origin::signed(0), 0)); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 10, + curator_deposit: 0, + value: 50, + bond: 85, + status: BountyStatus::Funded, + }); + + assert_eq!(Balances::free_balance(1), 93); + assert_eq!(Balances::reserved_balance(1), 0); // slashed + + }); +} + +#[test] +fn extend_expiry() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + Balances::make_free_balance_be(&4, 10); + assert_ok!(Bounties::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); + + assert_ok!(Bounties::approve_bounty(Origin::root(), 0)); + + assert_noop!(Bounties::extend_bounty_expiry(Origin::signed(1), 0, Vec::new()), Error::::UnexpectedStatus); + + System::set_block_number(2); + >::on_initialize(2); + + assert_ok!(Bounties::propose_curator(Origin::root(), 0, 4, 10)); + assert_ok!(Bounties::accept_curator(Origin::signed(4), 0)); + + assert_eq!(Balances::free_balance(4), 5); + assert_eq!(Balances::reserved_balance(4), 5); + + System::set_block_number(10); + >::on_initialize(10); + + assert_noop!(Bounties::extend_bounty_expiry(Origin::signed(0), 0, Vec::new()), Error::::RequireCurator); + assert_ok!(Bounties::extend_bounty_expiry(Origin::signed(4), 0, Vec::new())); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 10, + curator_deposit: 5, + value: 50, + bond: 85, + status: BountyStatus::Active { curator: 4, update_due: 30 }, + }); + + assert_ok!(Bounties::extend_bounty_expiry(Origin::signed(4), 0, Vec::new())); + + assert_eq!(Bounties::bounties(0).unwrap(), Bounty { + proposer: 0, + fee: 10, + curator_deposit: 5, + value: 50, + bond: 85, + status: BountyStatus::Active { curator: 4, update_due: 30 }, // still the same + }); + + System::set_block_number(25); + >::on_initialize(25); + + assert_noop!(Bounties::unassign_curator(Origin::signed(0), 0), Error::::Premature); + assert_ok!(Bounties::unassign_curator(Origin::signed(4), 0)); + + assert_eq!(Balances::free_balance(4), 10); // not slashed + assert_eq!(Balances::reserved_balance(4), 0); + }); +} + +#[test] +fn genesis_funding_works() { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let initial_funding = 100; + pallet_balances::GenesisConfig::{ + // Total issuance will be 200 with treasury account initialized with 100. + balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], + }.assimilate_storage(&mut t).unwrap(); + pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + let mut t: sp_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(Treasury::account_id()), initial_funding); + assert_eq!(Treasury::pot(), initial_funding - Balances::minimum_balance()); + }); +} diff --git a/frame/bounties/src/weights.rs b/frame/bounties/src/weights.rs new file mode 100644 index 00000000000..6ba1b9d32b1 --- /dev/null +++ b/frame/bounties/src/weights.rs @@ -0,0 +1,189 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Autogenerated weights for pallet_bounties +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 +//! DATE: 2020-12-16, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// ./target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_bounties +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/bounties/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_bounties. +pub trait WeightInfo { + fn propose_bounty(d: u32, ) -> Weight; + fn approve_bounty() -> Weight; + fn propose_curator() -> Weight; + fn unassign_curator() -> Weight; + fn accept_curator() -> Weight; + fn award_bounty() -> Weight; + fn claim_bounty() -> Weight; + fn close_bounty_proposed() -> Weight; + fn close_bounty_active() -> Weight; + fn extend_bounty_expiry() -> Weight; + fn spend_funds(b: u32, ) -> Weight; +} + +/// Weights for pallet_bounties using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn propose_bounty(d: u32, ) -> Weight { + (64_778_000 as Weight) + // Standard Error: 0 + .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn approve_bounty() -> Weight { + (18_293_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn propose_curator() -> Weight { + (14_248_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn unassign_curator() -> Weight { + (52_100_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn accept_curator() -> Weight { + (52_564_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn award_bounty() -> Weight { + (37_426_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn claim_bounty() -> Weight { + (176_077_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + fn close_bounty_proposed() -> Weight { + (51_162_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn close_bounty_active() -> Weight { + (116_907_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn extend_bounty_expiry() -> Weight { + (36_419_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn spend_funds(b: u32, ) -> Weight { + (7_562_000 as Weight) + // Standard Error: 16_000 + .saturating_add((77_328_000 as Weight).saturating_mul(b as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(b as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight))) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn propose_bounty(d: u32, ) -> Weight { + (64_778_000 as Weight) + // Standard Error: 0 + .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn approve_bounty() -> Weight { + (18_293_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn propose_curator() -> Weight { + (14_248_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn unassign_curator() -> Weight { + (52_100_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn accept_curator() -> Weight { + (52_564_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn award_bounty() -> Weight { + (37_426_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn claim_bounty() -> Weight { + (176_077_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + fn close_bounty_proposed() -> Weight { + (51_162_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn close_bounty_active() -> Weight { + (116_907_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn extend_bounty_expiry() -> Weight { + (36_419_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn spend_funds(b: u32, ) -> Weight { + (7_562_000 as Weight) + // Standard Error: 16_000 + .saturating_add((77_328_000 as Weight).saturating_mul(b as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(b as Weight))) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight))) + } +} diff --git a/frame/tips/Cargo.toml b/frame/tips/Cargo.toml new file mode 100644 index 00000000000..386d49372c7 --- /dev/null +++ b/frame/tips/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "pallet-tips" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME pallet to manage tips" +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-treasury = { version = "2.0.0", default-features = false, path = "../treasury" } + +frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true } + +[dev-dependencies] +sp-io ={ version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-storage = { version = "2.0.0", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-treasury/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/tips/README.md b/frame/tips/README.md new file mode 100644 index 00000000000..457e5b3bd0e --- /dev/null +++ b/frame/tips/README.md @@ -0,0 +1,32 @@ +# Tipping Module ( pallet-tips ) + +**Note :: This pallet is tightly coupled to pallet-treasury** + +A subsystem to allow for an agile "tipping" process, whereby a reward may be given without first +having a pre-determined stakeholder group come to consensus on how much should be paid. + +A group of `Tippers` is determined through the config `Trait`. After half of these have declared +some amount that they believe a particular reported reason deserves, then a countdown period is +entered where any remaining members can declare their tip amounts also. After the close of the +countdown period, the median of all declared tips is paid to the reported beneficiary, along with +any finders fee, in case of a public (and bonded) original report. + +### Terminology + +- **Tipping:** The process of gathering declarations of amounts to tip and taking the median amount + to be transferred from the treasury to a beneficiary account. +- **Tip Reason:** The reason for a tip; generally a URL which embodies or explains why a particular + individual (identified by an account ID) is worthy of a recognition by the treasury. +- **Finder:** The original public reporter of some reason for tipping. +- **Finders Fee:** Some proportion of the tip amount that is paid to the reporter of the tip, + rather than the main beneficiary. + +## Interface + +### Dispatchable Functions + +- `report_awesome` - Report something worthy of a tip and register for a finders fee. +- `retract_tip` - Retract a previous (finders fee registered) report. +- `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. +- `tip` - Declare or redeclare an amount to tip for a particular reason. +- `close_tip` - Close and pay out a tip. diff --git a/frame/tips/src/benchmarking.rs b/frame/tips/src/benchmarking.rs new file mode 100644 index 00000000000..71f9002b9bf --- /dev/null +++ b/frame/tips/src/benchmarking.rs @@ -0,0 +1,193 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Treasury tips benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; +use sp_runtime::{traits::{Saturating}}; + +use crate::Module as TipsMod; + +const SEED: u32 = 0; + +// Create the pre-requisite information needed to create a `report_awesome`. +fn setup_awesome(length: u32) -> (T::AccountId, Vec, T::AccountId) { + let caller = whitelisted_caller(); + let value = T::TipReportDepositBase::get() + + T::DataDepositPerByte::get() * length.into() + + T::Currency::minimum_balance(); + let _ = T::Currency::make_free_balance_be(&caller, value); + let reason = vec![0; length as usize]; + let awesome_person = account("awesome", 0, SEED); + (caller, reason, awesome_person) +} + +// Create the pre-requisite information needed to call `tip_new`. +fn setup_tip(r: u32, t: u32) -> + Result<(T::AccountId, Vec, T::AccountId, BalanceOf), &'static str> +{ + let tippers_count = T::Tippers::count(); + + for i in 0 .. t { + let member = account("member", i, SEED); + T::Tippers::add(&member); + ensure!(T::Tippers::contains(&member), "failed to add tipper"); + } + + ensure!(T::Tippers::count() == tippers_count + t as usize, "problem creating tippers"); + let caller = account("member", t - 1, SEED); + let reason = vec![0; r as usize]; + let beneficiary = account("beneficiary", t, SEED); + let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); + Ok((caller, reason, beneficiary, value)) +} + +// Create `t` new tips for the tip proposal with `hash`. +// This function automatically makes the tip able to close. +fn create_tips(t: u32, hash: T::Hash, value: BalanceOf) -> + Result<(), &'static str> +{ + for i in 0 .. t { + let caller = account("member", i, SEED); + ensure!(T::Tippers::contains(&caller), "caller is not a tipper"); + TipsMod::::tip(RawOrigin::Signed(caller).into(), hash, value)?; + } + Tips::::mutate(hash, |maybe_tip| { + if let Some(open_tip) = maybe_tip { + open_tip.closes = Some(T::BlockNumber::zero()); + } + }); + Ok(()) +} + +fn setup_pod_account() { + let pot_account = TipsMod::::account_id(); + let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); + let _ = T::Currency::make_free_balance_be(&pot_account, value); +} + +const MAX_BYTES: u32 = 16384; +const MAX_TIPPERS: u32 = 100; + +benchmarks! { + _ { } + + report_awesome { + let r in 0 .. MAX_BYTES; + let (caller, reason, awesome_person) = setup_awesome::(r); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + }: _(RawOrigin::Signed(caller), reason, awesome_person) + + retract_tip { + let r = MAX_BYTES; + let (caller, reason, awesome_person) = setup_awesome::(r); + TipsMod::::report_awesome( + RawOrigin::Signed(caller.clone()).into(), + reason.clone(), + awesome_person.clone() + )?; + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &awesome_person)); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + }: _(RawOrigin::Signed(caller), hash) + + tip_new { + let r in 0 .. MAX_BYTES; + let t in 1 .. MAX_TIPPERS; + + let (caller, reason, beneficiary, value) = setup_tip::(r, t)?; + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + }: _(RawOrigin::Signed(caller), reason, beneficiary, value) + + tip { + let t in 1 .. MAX_TIPPERS; + let (member, reason, beneficiary, value) = setup_tip::(0, t)?; + let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); + TipsMod::::tip_new( + RawOrigin::Signed(member).into(), + reason.clone(), + beneficiary.clone(), + value + )?; + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); + ensure!(Tips::::contains_key(hash), "tip does not exist"); + create_tips::(t - 1, hash.clone(), value)?; + let caller = account("member", t - 1, SEED); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + }: _(RawOrigin::Signed(caller), hash, value) + + close_tip { + let t in 1 .. MAX_TIPPERS; + + // Make sure pot is funded + setup_pod_account::(); + + // Set up a new tip proposal + let (member, reason, beneficiary, value) = setup_tip::(0, t)?; + let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); + TipsMod::::tip_new( + RawOrigin::Signed(member).into(), + reason.clone(), + beneficiary.clone(), + value + )?; + + // Create a bunch of tips + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); + ensure!(Tips::::contains_key(hash), "tip does not exist"); + create_tips::(t, hash.clone(), value)?; + + let caller = account("caller", t, SEED); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + }: _(RawOrigin::Signed(caller), hash) + +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_report_awesome::()); + assert_ok!(test_benchmark_retract_tip::()); + assert_ok!(test_benchmark_tip_new::()); + assert_ok!(test_benchmark_tip::()); + assert_ok!(test_benchmark_close_tip::()); + }); + } +} diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs new file mode 100644 index 00000000000..3507b220d5d --- /dev/null +++ b/frame/tips/src/lib.rs @@ -0,0 +1,576 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! # Tipping Module ( pallet-tips ) +//! +//! > NOTE: This pallet is tightly coupled with pallet-treasury. +//! +//! A subsystem to allow for an agile "tipping" process, whereby a reward may be given without first +//! having a pre-determined stakeholder group come to consensus on how much should be paid. +//! +//! A group of `Tippers` is determined through the config `Config`. After half of these have declared +//! some amount that they believe a particular reported reason deserves, then a countdown period is +//! entered where any remaining members can declare their tip amounts also. After the close of the +//! countdown period, the median of all declared tips is paid to the reported beneficiary, along +//! with any finders fee, in case of a public (and bonded) original report. +//! +//! +//! ### Terminology +//! +//! Tipping protocol: +//! - **Tipping:** The process of gathering declarations of amounts to tip and taking the median +//! amount to be transferred from the treasury to a beneficiary account. +//! - **Tip Reason:** The reason for a tip; generally a URL which embodies or explains why a +//! particular individual (identified by an account ID) is worthy of a recognition by the +//! treasury. +//! - **Finder:** The original public reporter of some reason for tipping. +//! - **Finders Fee:** Some proportion of the tip amount that is paid to the reporter of the tip, +//! rather than the main beneficiary. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! Tipping protocol: +//! - `report_awesome` - Report something worthy of a tip and register for a finders fee. +//! - `retract_tip` - Retract a previous (finders fee registered) report. +//! - `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. +//! - `tip` - Declare or redeclare an amount to tip for a particular reason. +//! - `close_tip` - Close and pay out a tip. + +#![cfg_attr(not(feature = "std"), no_std)] + +mod tests; +mod benchmarking; +pub mod weights; + +use sp_std::if_std; + +use sp_std::prelude::*; +use frame_support::{decl_module, decl_storage, decl_event, ensure, decl_error, Parameter}; +use frame_support::traits::{ + Currency, Get, ExistenceRequirement::{KeepAlive}, + ReservableCurrency +}; + +use sp_runtime::{ Percent, RuntimeDebug, traits::{ + Zero, AccountIdConversion, Hash, BadOrigin +}}; + +use frame_support::traits::{Contains, ContainsLengthBound}; +use codec::{Encode, Decode}; +use frame_system::{self as system, ensure_signed}; +pub use weights::WeightInfo; + +pub type BalanceOf = pallet_treasury::BalanceOf; +pub type NegativeImbalanceOf = pallet_treasury::NegativeImbalanceOf; + +pub trait Config: frame_system::Config + pallet_treasury::Config { + /// Maximum acceptable reason length. + type MaximumReasonLength: Get; + + /// The amount held on deposit per byte within the tip report reason or bounty description. + type DataDepositPerByte: Get>; + + /// Origin from which tippers must come. + /// + /// `ContainsLengthBound::max_len` must be cost free (i.e. no storage read or heavy operation). + type Tippers: Contains + ContainsLengthBound; + + /// The period for which a tip remains open after is has achieved threshold tippers. + type TipCountdown: Get; + + /// The percent of the final tip which goes to the original reporter of the tip. + type TipFindersFee: Get; + + /// The amount held on deposit for placing a tip report. + type TipReportDepositBase: Get>; + + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; +} + +/// An open tipping "motion". Retains all details of a tip including information on the finder +/// and the members who have voted. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] +pub struct OpenTip< + AccountId: Parameter, + Balance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, +> { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip. + finder: AccountId, + /// The amount held on deposit for this tip. + deposit: Balance, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, Balance)>, + /// Whether this tip should result in the finder taking a fee. + finders_fee: bool, +} + +// Note :: For backward compatability reasons, +// pallet-tips uses Treasury for storage. +// This is temporary solution, soon will get replaced with +// Own storage identifier. +decl_storage! { + trait Store for Module as Treasury { + + /// TipsMap that are not yet completed. Keyed by the hash of `(reason, who)` from the value. + /// This has the insecure enumerable hash function since the key itself is already + /// guaranteed to be a secure hash. + pub Tips get(fn tips): + map hasher(twox_64_concat) T::Hash + => Option, T::BlockNumber, T::Hash>>; + + /// Simple preimage lookup from the reason's hash to the original data. Again, has an + /// insecure enumerable hash since the key is guaranteed to be the result of a secure hash. + pub Reasons get(fn reasons): map hasher(identity) T::Hash => Option>; + + } +} + +decl_event!( + pub enum Event + where + Balance = BalanceOf, + ::AccountId, + ::Hash, + { + /// A new tip suggestion has been opened. \[tip_hash\] + NewTip(Hash), + /// A tip suggestion has reached threshold and is closing. \[tip_hash\] + TipClosing(Hash), + /// A tip suggestion has been closed. \[tip_hash, who, payout\] + TipClosed(Hash, AccountId, Balance), + /// A tip suggestion has been retracted. \[tip_hash\] + TipRetracted(Hash), + } +); + +decl_error! { + /// Error for the tips module. + pub enum Error for Module { + /// The reason given is just too big. + ReasonTooBig, + /// The tip was already found/started. + AlreadyKnown, + /// The tip hash is unknown. + UnknownTip, + /// The account attempting to retract the tip is not the finder of the tip. + NotFinder, + /// The tip cannot be claimed/closed because there are not enough tippers yet. + StillOpen, + /// The tip cannot be claimed/closed because it's still in the countdown period. + Premature, + } +} + +decl_module! { + pub struct Module + for enum Call + where origin: T::Origin + { + + /// The period for which a tip remains open after is has achieved threshold tippers. + const TipCountdown: T::BlockNumber = T::TipCountdown::get(); + + /// The amount of the final tip which goes to the original reporter of the tip. + const TipFindersFee: Percent = T::TipFindersFee::get(); + + /// The amount held on deposit for placing a tip report. + const TipReportDepositBase: BalanceOf = T::TipReportDepositBase::get(); + + /// The amount held on deposit per byte within the tip report reason. + const DataDepositPerByte: BalanceOf = T::DataDepositPerByte::get(); + + /// Maximum acceptable reason length. + const MaximumReasonLength: u32 = T::MaximumReasonLength::get(); + + type Error = Error; + + fn deposit_event() = default; + + /// Report something `reason` that deserves a tip and claim any eventual the finder's fee. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Payment: `TipReportDepositBase` will be reserved from the origin account, as well as + /// `DataDepositPerByte` for each byte in `reason`. + /// + /// - `reason`: The reason for, or the thing that deserves, the tip; generally this will be + /// a UTF-8-encoded URL. + /// - `who`: The account which should be credited for the tip. + /// + /// Emits `NewTip` if successful. + /// + /// # + /// - Complexity: `O(R)` where `R` length of `reason`. + /// - encoding and hashing of 'reason' + /// - DbReads: `Reasons`, `Tips` + /// - DbWrites: `Reasons`, `Tips` + /// # + #[weight = ::WeightInfo::report_awesome(reason.len() as u32)] + fn report_awesome(origin, reason: Vec, who: T::AccountId) { + let finder = ensure_signed(origin)?; + + ensure!(reason.len() <= T::MaximumReasonLength::get() as usize, Error::::ReasonTooBig); + + let reason_hash = T::Hashing::hash(&reason[..]); + ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); + let hash = T::Hashing::hash_of(&(&reason_hash, &who)); + ensure!(!Tips::::contains_key(&hash), Error::::AlreadyKnown); + + let deposit = T::TipReportDepositBase::get() + + T::DataDepositPerByte::get() * (reason.len() as u32).into(); + T::Currency::reserve(&finder, deposit)?; + + Reasons::::insert(&reason_hash, &reason); + let tip = OpenTip { + reason: reason_hash, + who, + finder, + deposit, + closes: None, + tips: vec![], + finders_fee: true + }; + Tips::::insert(&hash, tip); + Self::deposit_event(RawEvent::NewTip(hash)); + } + + /// Retract a prior tip-report from `report_awesome`, and cancel the process of tipping. + /// + /// If successful, the original deposit will be unreserved. + /// + /// The dispatch origin for this call must be _Signed_ and the tip identified by `hash` + /// must have been reported by the signing account through `report_awesome` (and not + /// through `tip_new`). + /// + /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed + /// as the hash of the tuple of the original tip `reason` and the beneficiary account ID. + /// + /// Emits `TipRetracted` if successful. + /// + /// # + /// - Complexity: `O(1)` + /// - Depends on the length of `T::Hash` which is fixed. + /// - DbReads: `Tips`, `origin account` + /// - DbWrites: `Reasons`, `Tips`, `origin account` + /// # + #[weight = ::WeightInfo::retract_tip()] + fn retract_tip(origin, hash: T::Hash) { + let who = ensure_signed(origin)?; + let tip = Tips::::get(&hash).ok_or(Error::::UnknownTip)?; + ensure!(tip.finder == who, Error::::NotFinder); + + Reasons::::remove(&tip.reason); + Tips::::remove(&hash); + if !tip.deposit.is_zero() { + let _ = T::Currency::unreserve(&who, tip.deposit); + } + Self::deposit_event(RawEvent::TipRetracted(hash)); + } + + /// Give a tip for something new; no finder's fee will be taken. + /// + /// The dispatch origin for this call must be _Signed_ and the signing account must be a + /// member of the `Tippers` set. + /// + /// - `reason`: The reason for, or the thing that deserves, the tip; generally this will be + /// a UTF-8-encoded URL. + /// - `who`: The account which should be credited for the tip. + /// - `tip_value`: The amount of tip that the sender would like to give. The median tip + /// value of active tippers will be given to the `who`. + /// + /// Emits `NewTip` if successful. + /// + /// # + /// - Complexity: `O(R + T)` where `R` length of `reason`, `T` is the number of tippers. + /// - `O(T)`: decoding `Tipper` vec of length `T` + /// `T` is charged as upper bound given by `ContainsLengthBound`. + /// The actual cost depends on the implementation of `T::Tippers`. + /// - `O(R)`: hashing and encoding of reason of length `R` + /// - DbReads: `Tippers`, `Reasons` + /// - DbWrites: `Reasons`, `Tips` + /// # + #[weight = ::WeightInfo::tip_new(reason.len() as u32, T::Tippers::max_len() as u32)] + fn tip_new(origin, reason: Vec, who: T::AccountId, #[compact] tip_value: BalanceOf) { + let tipper = ensure_signed(origin)?; + ensure!(T::Tippers::contains(&tipper), BadOrigin); + let reason_hash = T::Hashing::hash(&reason[..]); + ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); + let hash = T::Hashing::hash_of(&(&reason_hash, &who)); + + Reasons::::insert(&reason_hash, &reason); + Self::deposit_event(RawEvent::NewTip(hash.clone())); + let tips = vec![(tipper.clone(), tip_value)]; + let tip = OpenTip { + reason: reason_hash, + who, + finder: tipper, + deposit: Zero::zero(), + closes: None, + tips, + finders_fee: false, + }; + Tips::::insert(&hash, tip); + } + + /// Declare a tip value for an already-open tip. + /// + /// The dispatch origin for this call must be _Signed_ and the signing account must be a + /// member of the `Tippers` set. + /// + /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed + /// as the hash of the tuple of the hash of the original tip `reason` and the beneficiary + /// account ID. + /// - `tip_value`: The amount of tip that the sender would like to give. The median tip + /// value of active tippers will be given to the `who`. + /// + /// Emits `TipClosing` if the threshold of tippers has been reached and the countdown period + /// has started. + /// + /// # + /// - Complexity: `O(T)` where `T` is the number of tippers. + /// decoding `Tipper` vec of length `T`, insert tip and check closing, + /// `T` is charged as upper bound given by `ContainsLengthBound`. + /// The actual cost depends on the implementation of `T::Tippers`. + /// + /// Actually weight could be lower as it depends on how many tips are in `OpenTip` but it + /// is weighted as if almost full i.e of length `T-1`. + /// - DbReads: `Tippers`, `Tips` + /// - DbWrites: `Tips` + /// # + #[weight = ::WeightInfo::tip(T::Tippers::max_len() as u32)] + fn tip(origin, hash: T::Hash, #[compact] tip_value: BalanceOf) { + let tipper = ensure_signed(origin)?; + ensure!(T::Tippers::contains(&tipper), BadOrigin); + + let mut tip = Tips::::get(hash).ok_or(Error::::UnknownTip)?; + if Self::insert_tip_and_check_closing(&mut tip, tipper, tip_value) { + Self::deposit_event(RawEvent::TipClosing(hash.clone())); + } + Tips::::insert(&hash, tip); + } + + /// Close and payout a tip. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// The tip identified by `hash` must have finished its countdown period. + /// + /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed + /// as the hash of the tuple of the original tip `reason` and the beneficiary account ID. + /// + /// # + /// - Complexity: `O(T)` where `T` is the number of tippers. + /// decoding `Tipper` vec of length `T`. + /// `T` is charged as upper bound given by `ContainsLengthBound`. + /// The actual cost depends on the implementation of `T::Tippers`. + /// - DbReads: `Tips`, `Tippers`, `tip finder` + /// - DbWrites: `Reasons`, `Tips`, `Tippers`, `tip finder` + /// # + #[weight = ::WeightInfo::close_tip(T::Tippers::max_len() as u32)] + fn close_tip(origin, hash: T::Hash) { + ensure_signed(origin)?; + + let tip = Tips::::get(hash).ok_or(Error::::UnknownTip)?; + let n = tip.closes.as_ref().ok_or(Error::::StillOpen)?; + ensure!(system::Module::::block_number() >= *n, Error::::Premature); + // closed. + Reasons::::remove(&tip.reason); + Tips::::remove(hash); + Self::payout_tip(hash, tip); + } + } +} + +impl Module { + // Add public immutables and private mutables. + + /// The account ID of the treasury pot. + /// + /// This actually does computation. If you need to keep using it, then make sure you cache the + /// value and only call this once. + pub fn account_id() -> T::AccountId { + T::ModuleId::get().into_account() + } + + /// Given a mutable reference to an `OpenTip`, insert the tip into it and check whether it + /// closes, if so, then deposit the relevant event and set closing accordingly. + /// + /// `O(T)` and one storage access. + fn insert_tip_and_check_closing( + tip: &mut OpenTip, T::BlockNumber, T::Hash>, + tipper: T::AccountId, + tip_value: BalanceOf, + ) -> bool { + match tip.tips.binary_search_by_key(&&tipper, |x| &x.0) { + Ok(pos) => tip.tips[pos] = (tipper, tip_value), + Err(pos) => tip.tips.insert(pos, (tipper, tip_value)), + } + Self::retain_active_tips(&mut tip.tips); + let threshold = (T::Tippers::count() + 1) / 2; + if tip.tips.len() >= threshold && tip.closes.is_none() { + tip.closes = Some(system::Module::::block_number() + T::TipCountdown::get()); + true + } else { + false + } + } + + /// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`. + fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf)>) { + let members = T::Tippers::sorted_members(); + let mut members_iter = members.iter(); + let mut member = members_iter.next(); + tips.retain(|(ref a, _)| loop { + match member { + None => break false, + Some(m) if m > a => break false, + Some(m) => { + member = members_iter.next(); + if m < a { + continue + } else { + break true; + } + } + } + }); + } + + /// Execute the payout of a tip. + /// + /// Up to three balance operations. + /// Plus `O(T)` (`T` is Tippers length). + fn payout_tip(hash: T::Hash, tip: OpenTip, T::BlockNumber, T::Hash>) { + let mut tips = tip.tips; + Self::retain_active_tips(&mut tips); + tips.sort_by_key(|i| i.1); + + let treasury = Self::account_id(); + let max_payout = pallet_treasury::Module::::pot(); + + let mut payout = tips[tips.len() / 2].1.min(max_payout); + if !tip.deposit.is_zero() { + let _ = T::Currency::unreserve(&tip.finder, tip.deposit); + } + + if tip.finders_fee && tip.finder != tip.who { + // pay out the finder's fee. + let finders_fee = T::TipFindersFee::get() * payout; + payout -= finders_fee; + // this should go through given we checked it's at most the free balance, but still + // we only make a best-effort. + let _ = T::Currency::transfer(&treasury, &tip.finder, finders_fee, KeepAlive); + } + + // same as above: best-effort only. + let _ = T::Currency::transfer(&treasury, &tip.who, payout, KeepAlive); + Self::deposit_event(RawEvent::TipClosed(hash, tip.who, payout)); + } + + pub fn migrate_retract_tip_for_tip_new() { + /// An open tipping "motion". Retains all details of a tip including information on the finder + /// and the members who have voted. + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + Balance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, Balance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, Balance)>, + } + + use frame_support::{Twox64Concat, migration::StorageKeyIterator}; + + if_std! { + println!("Inside migrate_retract_tip_for_tip_new()!"); + } + + for (hash, old_tip) in StorageKeyIterator::< + T::Hash, + OldOpenTip, T::BlockNumber, T::Hash>, + Twox64Concat, + >::new(b"Treasury", b"Tips").drain() + { + + if_std! { + println!("Inside loop migrate_retract_tip_for_tip_new()!"); + } + + let (finder, deposit, finders_fee) = match old_tip.finder { + Some((finder, deposit)) => { + if_std! { + // This code is only being compiled and executed when the `std` feature is enabled. + println!("OK case!"); + println!("value is: {:#?},{:#?}", finder, deposit); + } + (finder, deposit, true) + }, + None => { + if_std! { + // This code is only being compiled and executed when the `std` feature is enabled. + println!("None case!"); + // println!("value is: {:#?},{:#?}", T::AccountId::default(), Zero::zero()); + } + (T::AccountId::default(), Zero::zero(), false) + }, + }; + let new_tip = OpenTip { + reason: old_tip.reason, + who: old_tip.who, + finder, + deposit, + closes: old_tip.closes, + tips: old_tip.tips, + finders_fee + }; + Tips::::insert(hash, new_tip) + } + + if_std! { + println!("Exit migrate_retract_tip_for_tip_new()!"); + } + + } +} diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs new file mode 100644 index 00000000000..e6f9cd4e66b --- /dev/null +++ b/frame/tips/src/tests.rs @@ -0,0 +1,465 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Treasury pallet tests. + +#![cfg(test)] + +use super::*; +use std::cell::RefCell; +use frame_support::{ + assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight, + impl_outer_event, traits::{Contains} +}; +use sp_runtime::{Permill}; +use sp_core::H256; +use sp_runtime::{ + Perbill, ModuleId, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, BadOrigin}, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +mod tips { + // Re-export needed for `impl_outer_event!`. + pub use crate::*; +} + +impl_outer_event! { + pub enum Event for Test { + system, + pallet_balances, + pallet_treasury, + tips, + } +} + +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Config for Test { + type BaseCallFilter = (); + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = (); + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u128; // u64 is not enough to hold bytes used to generate bounty account + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Config for Test { + type MaxLocks = (); + type Balance = u64; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} +thread_local! { + static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![10,11,12,13,14]); +} +pub struct TenToFourteen; +impl Contains for TenToFourteen { + fn sorted_members() -> Vec { + TEN_TO_FOURTEEN.with(|v| { + v.borrow().clone() + }) + } + #[cfg(feature = "runtime-benchmarks")] + fn add(new: &u128) { + TEN_TO_FOURTEEN.with(|v| { + let mut members = v.borrow_mut(); + members.push(*new); + members.sort(); + }) + } +} +impl ContainsLengthBound for TenToFourteen { + fn max_len() -> usize { + TEN_TO_FOURTEEN.with(|v| v.borrow().len()) + } + fn min_len() -> usize { 0 } +} +parameter_types! { + pub const ProposalBond: Permill = Permill::from_percent(5); + pub const ProposalBondMinimum: u64 = 1; + pub const SpendPeriod: u64 = 2; + pub const Burn: Permill = Permill::from_percent(50); + pub const DataDepositPerByte: u64 = 1; + pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry"); + pub const MaximumReasonLength: u32 = 16384; +} +impl pallet_treasury::Config for Test { + type ModuleId = TreasuryModuleId; + type Currency = pallet_balances::Module; + type ApproveOrigin = frame_system::EnsureRoot; + type RejectOrigin = frame_system::EnsureRoot; + type Event = Event; + type OnSlash = (); + type ProposalBond = ProposalBond; + type ProposalBondMinimum = ProposalBondMinimum; + type SpendPeriod = SpendPeriod; + type Burn = Burn; + type BurnDestination = (); // Just gets burned. + type WeightInfo = (); + type SpendFunds = (); +} +parameter_types! { + pub const TipCountdown: u64 = 1; + pub const TipFindersFee: Percent = Percent::from_percent(20); + pub const TipReportDepositBase: u64 = 1; +} +impl Config for Test { + type MaximumReasonLength = MaximumReasonLength; + type Tippers = TenToFourteen; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type DataDepositPerByte = DataDepositPerByte; + type Event = Event; + type WeightInfo = (); +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Treasury = pallet_treasury::Module; +type TipsModTestInst = Module; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ + // Total issuance will be 200 with treasury account initialized at ED. + balances: vec![(0, 100), (1, 98), (2, 1)], + }.assimilate_storage(&mut t).unwrap(); + pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + t.into() +} + +fn last_event() -> RawEvent { + System::events().into_iter().map(|r| r.event) + .filter_map(|e| { + if let Event::tips(inner) = e { Some(inner) } else { None } + }) + .last() + .unwrap() +} + +#[test] +fn genesis_config_works() { + new_test_ext().execute_with(|| { + assert_eq!(Treasury::pot(), 0); + assert_eq!(Treasury::proposal_count(), 0); + }); +} + +fn tip_hash() -> H256 { + BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 3u128)) +} + +#[test] +fn tip_new_cannot_be_used_twice() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + assert_noop!( + TipsModTestInst::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10), + Error::::AlreadyKnown + ); + }); +} + +#[test] +fn report_awesome_and_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); + + // other reports don't count. + assert_noop!( + TipsModTestInst::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3), + Error::::AlreadyKnown + ); + + let h = tip_hash(); + assert_ok!(TipsModTestInst::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(TipsModTestInst::tip(Origin::signed(9), h.clone(), 10), BadOrigin); + System::set_block_number(2); + assert_ok!(TipsModTestInst::close_tip(Origin::signed(100), h.into())); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 102); + assert_eq!(Balances::free_balance(3), 8); + }); +} + +#[test] +fn report_awesome_from_beneficiary_and_tip_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 0)); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); + let h = BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 0u128)); + assert_ok!(TipsModTestInst::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10)); + System::set_block_number(2); + assert_ok!(TipsModTestInst::close_tip(Origin::signed(100), h.into())); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 110); + }); +} + +#[test] +fn close_tip_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_ok!(TipsModTestInst::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + + let h = tip_hash(); + + assert_eq!(last_event(), RawEvent::NewTip(h)); + + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + + assert_noop!(TipsModTestInst::close_tip(Origin::signed(0), h.into()), Error::::StillOpen); + + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10)); + + assert_eq!(last_event(), RawEvent::TipClosing(h)); + + assert_noop!(TipsModTestInst::close_tip(Origin::signed(0), h.into()), Error::::Premature); + + System::set_block_number(2); + assert_noop!(TipsModTestInst::close_tip(Origin::none(), h.into()), BadOrigin); + assert_ok!(TipsModTestInst::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + + assert_eq!(last_event(), RawEvent::TipClosed(h, 3, 10)); + + assert_noop!(TipsModTestInst::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); + }); +} + +#[test] +fn retract_tip_works() { + new_test_ext().execute_with(|| { + // with report awesome + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); + let h = tip_hash(); + assert_ok!(TipsModTestInst::tip(Origin::signed(10), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(TipsModTestInst::retract_tip(Origin::signed(10), h.clone()), Error::::NotFinder); + assert_ok!(TipsModTestInst::retract_tip(Origin::signed(0), h.clone())); + System::set_block_number(2); + assert_noop!(TipsModTestInst::close_tip(Origin::signed(0), h.into()), Error::::UnknownTip); + + // with tip new + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + let h = tip_hash(); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(TipsModTestInst::retract_tip(Origin::signed(0), h.clone()), Error::::NotFinder); + assert_ok!(TipsModTestInst::retract_tip(Origin::signed(10), h.clone())); + System::set_block_number(2); + assert_noop!(TipsModTestInst::close_tip(Origin::signed(10), h.into()), Error::::UnknownTip); + }); +} + +#[test] +fn tip_median_calculation_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 0)); + let h = tip_hash(); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 1000000)); + System::set_block_number(2); + assert_ok!(TipsModTestInst::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + }); +} + +#[test] +fn tip_changing_works() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(TipsModTestInst::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); + let h = tip_hash(); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 10000)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 10000)); + assert_ok!(TipsModTestInst::tip(Origin::signed(13), h.clone(), 0)); + assert_ok!(TipsModTestInst::tip(Origin::signed(14), h.clone(), 0)); + assert_ok!(TipsModTestInst::tip(Origin::signed(12), h.clone(), 1000)); + assert_ok!(TipsModTestInst::tip(Origin::signed(11), h.clone(), 100)); + assert_ok!(TipsModTestInst::tip(Origin::signed(10), h.clone(), 10)); + System::set_block_number(2); + assert_ok!(TipsModTestInst::close_tip(Origin::signed(0), h.into())); + assert_eq!(Balances::free_balance(3), 10); + }); +} + +#[test] +fn test_last_reward_migration() { + use sp_storage::Storage; + + let mut s = Storage::default(); + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + Balance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, Balance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, Balance)>, + } + + let reason1 = BlakeTwo256::hash(b"reason1"); + let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); + + let old_tip_finder = OldOpenTip:: { + reason: reason1, + who: 10, + finder: Some((20, 30)), + closes: Some(13), + tips: vec![(40, 50), (60, 70)] + }; + + let reason2 = BlakeTwo256::hash(b"reason2"); + let hash2 = BlakeTwo256::hash_of(&(reason2, 20u64)); + + let old_tip_no_finder = OldOpenTip:: { + reason: reason2, + who: 20, + finder: None, + closes: Some(13), + tips: vec![(40, 50), (60, 70)] + }; + + let data = vec![ + ( + Tips::::hashed_key_for(hash1), + old_tip_finder.encode().to_vec() + ), + ( + Tips::::hashed_key_for(hash2), + old_tip_no_finder.encode().to_vec() + ), + ]; + + s.top = data.into_iter().collect(); + + println!("Executing the test!"); + + sp_io::TestExternalities::new(s).execute_with(|| { + + println!("Calling migrate_retract_tip_for_tip_new()!"); + + TipsModTestInst::migrate_retract_tip_for_tip_new(); + + // Test w/ finder + assert_eq!( + Tips::::get(hash1), + Some(OpenTip { + reason: reason1, + who: 10, + finder: 20, + deposit: 30, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: true, + }) + ); + + // Test w/o finder + assert_eq!( + Tips::::get(hash2), + Some(OpenTip { + reason: reason2, + who: 20, + finder: Default::default(), + deposit: 0, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: false, + }) + ); + }); +} + +#[test] +fn genesis_funding_works() { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let initial_funding = 100; + pallet_balances::GenesisConfig::{ + // Total issuance will be 200 with treasury account initialized with 100. + balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], + }.assimilate_storage(&mut t).unwrap(); + pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + let mut t: sp_io::TestExternalities = t.into(); + + t.execute_with(|| { + assert_eq!(Balances::free_balance(Treasury::account_id()), initial_funding); + assert_eq!(Treasury::pot(), initial_funding - Balances::minimum_balance()); + }); +} diff --git a/frame/tips/src/weights.rs b/frame/tips/src/weights.rs new file mode 100644 index 00000000000..ad2d3104caf --- /dev/null +++ b/frame/tips/src/weights.rs @@ -0,0 +1,131 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Autogenerated weights for pallet_tips +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 +//! DATE: 2020-12-16, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// ./target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_tips +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/tips/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_tips. +pub trait WeightInfo { + fn report_awesome(r: u32, ) -> Weight; + fn retract_tip() -> Weight; + fn tip_new(r: u32, t: u32, ) -> Weight; + fn tip(t: u32, ) -> Weight; + fn close_tip(t: u32, ) -> Weight; +} + +/// Weights for pallet_tips using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn report_awesome(r: u32, ) -> Weight { + (74_814_000 as Weight) + // Standard Error: 0 + .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn retract_tip() -> Weight { + (62_962_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn tip_new(r: u32, t: u32, ) -> Weight { + (48_132_000 as Weight) + // Standard Error: 0 + .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 0 + .saturating_add((155_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn tip(t: u32, ) -> Weight { + (36_168_000 as Weight) + // Standard Error: 1_000 + .saturating_add((695_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + fn close_tip(t: u32, ) -> Weight { + (119_313_000 as Weight) + // Standard Error: 1_000 + .saturating_add((372_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn report_awesome(r: u32, ) -> Weight { + (74_814_000 as Weight) + // Standard Error: 0 + .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn retract_tip() -> Weight { + (62_962_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn tip_new(r: u32, t: u32, ) -> Weight { + (48_132_000 as Weight) + // Standard Error: 0 + .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 0 + .saturating_add((155_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn tip(t: u32, ) -> Weight { + (36_168_000 as Weight) + // Standard Error: 1_000 + .saturating_add((695_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + fn close_tip(t: u32, ) -> Weight { + (119_313_000 as Weight) + // Standard Error: 1_000 + .saturating_add((372_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } +} diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index fd2d103e9f3..7570d2a499c 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -20,6 +20,7 @@ sp-runtime = { version = "2.0.0", default-features = false, path = "../../primit frame-support = { version = "2.0.0", default-features = false, path = "../support" } frame-system = { version = "2.0.0", default-features = false, path = "../system" } pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } +impl-trait-for-tuples = "0.1.3" frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true } diff --git a/frame/treasury/README.md b/frame/treasury/README.md index c8e1a57350d..4b061359fea 100644 --- a/frame/treasury/README.md +++ b/frame/treasury/README.md @@ -1,118 +1,31 @@ # Treasury Module -The Treasury module provides a "pot" of funds that can be managed by stakeholders in the -system and a structure for making spending proposals from this pot. - -- [`treasury::Trait`](https://docs.rs/pallet-treasury/latest/pallet_treasury/trait.Trait.html) -- [`Call`](https://docs.rs/pallet-treasury/latest/pallet_treasury/enum.Call.html) +The Treasury module provides a "pot" of funds that can be managed by stakeholders in the system and +a structure for making spending proposals from this pot. ## Overview -The Treasury Module itself provides the pot to store funds, and a means for stakeholders to -propose, approve, and deny expenditures. The chain will need to provide a method (e.g. -inflation, fees) for collecting funds. - -By way of example, the Council could vote to fund the Treasury with a portion of the block -reward and use the funds to pay developers. - -### Tipping - -A separate subsystem exists to allow for an agile "tipping" process, whereby a reward may be -given without first having a pre-determined stakeholder group come to consensus on how much -should be paid. - -A group of `Tippers` is determined through the config `Config`. After half of these have declared -some amount that they believe a particular reported reason deserves, then a countdown period is -entered where any remaining members can declare their tip amounts also. After the close of the -countdown period, the median of all declared tips is paid to the reported beneficiary, along -with any finders fee, in case of a public (and bonded) original report. - -### Bounty - -A Bounty Spending is a reward for a specified body of work - or specified set of objectives - that -needs to be executed for a predefined Treasury amount to be paid out. A curator is assigned after -the bounty is approved and funded by Council, to be delegated -with the responsibility of assigning a payout address once the specified set of objectives is completed. - -After the Council has activated a bounty, it delegates the work that requires expertise to a curator -in exchange of a deposit. Once the curator accepts the bounty, they -get to close the Active bounty. Closing the Active bounty enacts a delayed payout to the payout -address, the curator fee and the return of the curator deposit. The -delay allows for intervention through regular democracy. The Council gets to unassign the curator, -resulting in a new curator election. The Council also gets to cancel -the bounty if deemed necessary before assigning a curator or once the bounty is active or payout -is pending, resulting in the slash of the curator's deposit. +The Treasury Module itself provides the pot to store funds, and a means for stakeholders to propose, +approve, and deny expenditures. The chain will need to provide a method (e.g.inflation, fees) for +collecting funds. +By way of example, the Council could vote to fund the Treasury with a portion of the block reward +and use the funds to pay developers. ### Terminology - **Proposal:** A suggestion to allocate funds from the pot to a beneficiary. -- **Beneficiary:** An account who will receive the funds from a proposal iff -the proposal is approved. -- **Deposit:** Funds that a proposer must lock when making a proposal. The -deposit will be returned or slashed if the proposal is approved or rejected -respectively. +- **Beneficiary:** An account who will receive the funds from a proposal if the proposal is + approved. +- **Deposit:** Funds that a proposer must lock when making a proposal. The deposit will be returned + or slashed if the proposal is approved or rejected respectively. - **Pot:** Unspent funds accumulated by the treasury module. -Tipping protocol: -- **Tipping:** The process of gathering declarations of amounts to tip and taking the median - amount to be transferred from the treasury to a beneficiary account. -- **Tip Reason:** The reason for a tip; generally a URL which embodies or explains why a - particular individual (identified by an account ID) is worthy of a recognition by the - treasury. -- **Finder:** The original public reporter of some reason for tipping. -- **Finders Fee:** Some proportion of the tip amount that is paid to the reporter of the tip, - rather than the main beneficiary. - -Bounty: -- **Bounty spending proposal:** A proposal to reward a predefined body of work upon completion by -the Treasury. -- **Proposer:** An account proposing a bounty spending. -- **Curator:** An account managing the bounty and assigning a payout address receiving the reward -for the completion of work. -- **Deposit:** The amount held on deposit for placing a bounty proposal plus the amount held on -deposit per byte within the bounty description. -- **Curator deposit:** The payment from a candidate willing to curate an approved bounty. The deposit -is returned when/if the bounty is completed. -- **Bounty value:** The total amount that should be paid to the Payout Address if the bounty is -rewarded. -- **Payout address:** The account to which the total or part of the bounty is assigned to. -- **Payout Delay:** The delay period for which a bounty beneficiary needs to wait before claiming. -- **Curator fee:** The reserved upfront payment for a curator for work related to the bounty. - ## Interface ### Dispatchable Functions General spending/proposal protocol: - `propose_spend` - Make a spending proposal and stake the required deposit. -- `set_pot` - Set the spendable balance of funds. -- `configure` - Configure the module's proposal requirements. - `reject_proposal` - Reject a proposal, slashing the deposit. - `approve_proposal` - Accept the proposal, returning the deposit. - -Tipping protocol: -- `report_awesome` - Report something worthy of a tip and register for a finders fee. -- `retract_tip` - Retract a previous (finders fee registered) report. -- `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. -- `tip` - Declare or redeclare an amount to tip for a particular reason. -- `close_tip` - Close and pay out a tip. - -Bounty protocol: -- `propose_bounty` - Propose a specific treasury amount to be earmarked for a predefined set of -tasks and stake the required deposit. -- `approve_bounty` - Accept a specific treasury amount to be earmarked for a predefined body of work. -- `propose_curator` - Assign an account to a bounty as candidate curator. -- `accept_curator` - Accept a bounty assignment from the Council, setting a curator deposit. -- `extend_bounty_expiry` - Extend the expiry block number of the bounty and stay active. -- `award_bounty` - Close and pay out the specified amount for the completed work. -- `claim_bounty` - Claim a specific bounty amount from the Payout Address. -- `unassign_curator` - Unassign an accepted curator from a specific earmark. -- `close_bounty` - Cancel the earmark for a specific treasury amount and close the bounty. - - -## GenesisConfig - -The Treasury module depends on the [`GenesisConfig`](https://docs.rs/pallet-treasury/latest/pallet_treasury/struct.GenesisConfig.html). - -License: Apache-2.0 diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 4606689e86d..16ed1b01ae0 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -22,7 +22,7 @@ use super::*; use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks_instance, account, whitelisted_caller}; +use frame_benchmarking::{benchmarks_instance, account}; use frame_support::traits::OnInitialize; use crate::Module as Treasury; @@ -43,56 +43,6 @@ fn setup_proposal, I: Instance>(u: u32) -> ( (caller, value, beneficiary_lookup) } -// Create the pre-requisite information needed to create a `report_awesome`. -fn setup_awesome, I: Instance>(length: u32) -> (T::AccountId, Vec, T::AccountId) { - let caller = whitelisted_caller(); - let value = T::TipReportDepositBase::get() - + T::DataDepositPerByte::get() * length.into() - + T::Currency::minimum_balance(); - let _ = T::Currency::make_free_balance_be(&caller, value); - let reason = vec![0; length as usize]; - let awesome_person = account("awesome", 0, SEED); - (caller, reason, awesome_person) -} - -// Create the pre-requisite information needed to call `tip_new`. -fn setup_tip, I: Instance>(r: u32, t: u32) -> - Result<(T::AccountId, Vec, T::AccountId, BalanceOf), &'static str> -{ - let tippers_count = T::Tippers::count(); - - for i in 0 .. t { - let member = account("member", i, SEED); - T::Tippers::add(&member); - ensure!(T::Tippers::contains(&member), "failed to add tipper"); - } - - ensure!(T::Tippers::count() == tippers_count + t as usize, "problem creating tippers"); - let caller = account("member", t - 1, SEED); - let reason = vec![0; r as usize]; - let beneficiary = account("beneficiary", t, SEED); - let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); - Ok((caller, reason, beneficiary, value)) -} - -// Create `t` new tips for the tip proposal with `hash`. -// This function automatically makes the tip able to close. -fn create_tips, I: Instance>(t: u32, hash: T::Hash, value: BalanceOf) -> - Result<(), &'static str> -{ - for i in 0 .. t { - let caller = account("member", i, SEED); - ensure!(T::Tippers::contains(&caller), "caller is not a tipper"); - Treasury::::tip(RawOrigin::Signed(caller).into(), hash, value)?; - } - Tips::::mutate(hash, |maybe_tip| { - if let Some(open_tip) = maybe_tip { - open_tip.closes = Some(T::BlockNumber::zero()); - } - }); - Ok(()) -} - // Create proposals that are approved for use in `on_initialize`. fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &'static str> { for i in 0 .. n { @@ -109,61 +59,12 @@ fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &' Ok(()) } -// Create bounties that are approved for use in `on_initialize`. -fn create_approved_bounties, I: Instance>(n: u32) -> Result<(), &'static str> { - for i in 0 .. n { - let (caller, _curator, _fee, value, reason) = setup_bounty::(i, MAX_BYTES); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - Treasury::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; - } - ensure!(BountyApprovals::::get().len() == n as usize, "Not all bounty approved"); - Ok(()) -} - -// Create the pre-requisite information needed to create a treasury `propose_bounty`. -fn setup_bounty, I: Instance>(u: u32, d: u32) -> ( - T::AccountId, - T::AccountId, - BalanceOf, - BalanceOf, - Vec, -) { - let caller = account("caller", u, SEED); - let value: BalanceOf = T::BountyValueMinimum::get().saturating_mul(100u32.into()); - let fee = value / 2u32.into(); - let deposit = T::BountyDepositBase::get() + T::DataDepositPerByte::get() * MAX_BYTES.into(); - let _ = T::Currency::make_free_balance_be(&caller, deposit); - let curator = account("curator", u, SEED); - let _ = T::Currency::make_free_balance_be(&curator, fee / 2u32.into()); - let reason = vec![0; d as usize]; - (caller, curator, fee, value, reason) -} - -fn create_bounty, I: Instance>() -> Result<( - ::Source, - BountyIndex, -), &'static str> { - let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); - let curator_lookup = T::Lookup::unlookup(curator.clone()); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - Treasury::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; - Treasury::::on_initialize(T::BlockNumber::zero()); - Treasury::::propose_curator(RawOrigin::Root.into(), bounty_id, curator_lookup.clone(), fee)?; - Treasury::::accept_curator(RawOrigin::Signed(curator).into(), bounty_id)?; - Ok((curator_lookup, bounty_id)) -} - fn setup_pod_account, I: Instance>() { let pot_account = Treasury::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); } -const MAX_BYTES: u32 = 16384; -const MAX_TIPPERS: u32 = 100; - benchmarks_instance! { _ { } @@ -194,178 +95,6 @@ benchmarks_instance! { let proposal_id = Treasury::::proposal_count() - 1; }: _(RawOrigin::Root, proposal_id) - report_awesome { - let r in 0 .. MAX_BYTES; - let (caller, reason, awesome_person) = setup_awesome::(r); - // Whitelist caller account from further DB operations. - let caller_key = frame_system::Account::::hashed_key_for(&caller); - frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: _(RawOrigin::Signed(caller), reason, awesome_person) - - retract_tip { - let r = MAX_BYTES; - let (caller, reason, awesome_person) = setup_awesome::(r); - Treasury::::report_awesome( - RawOrigin::Signed(caller.clone()).into(), - reason.clone(), - awesome_person.clone() - )?; - let reason_hash = T::Hashing::hash(&reason[..]); - let hash = T::Hashing::hash_of(&(&reason_hash, &awesome_person)); - // Whitelist caller account from further DB operations. - let caller_key = frame_system::Account::::hashed_key_for(&caller); - frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: _(RawOrigin::Signed(caller), hash) - - tip_new { - let r in 0 .. MAX_BYTES; - let t in 1 .. MAX_TIPPERS; - - let (caller, reason, beneficiary, value) = setup_tip::(r, t)?; - // Whitelist caller account from further DB operations. - let caller_key = frame_system::Account::::hashed_key_for(&caller); - frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: _(RawOrigin::Signed(caller), reason, beneficiary, value) - - tip { - let t in 1 .. MAX_TIPPERS; - let (member, reason, beneficiary, value) = setup_tip::(0, t)?; - let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); - Treasury::::tip_new( - RawOrigin::Signed(member).into(), - reason.clone(), - beneficiary.clone(), - value - )?; - let reason_hash = T::Hashing::hash(&reason[..]); - let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); - ensure!(Tips::::contains_key(hash), "tip does not exist"); - create_tips::(t - 1, hash.clone(), value)?; - let caller = account("member", t - 1, SEED); - // Whitelist caller account from further DB operations. - let caller_key = frame_system::Account::::hashed_key_for(&caller); - frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: _(RawOrigin::Signed(caller), hash, value) - - close_tip { - let t in 1 .. MAX_TIPPERS; - - // Make sure pot is funded - setup_pod_account::(); - - // Set up a new tip proposal - let (member, reason, beneficiary, value) = setup_tip::(0, t)?; - let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); - Treasury::::tip_new( - RawOrigin::Signed(member).into(), - reason.clone(), - beneficiary.clone(), - value - )?; - - // Create a bunch of tips - let reason_hash = T::Hashing::hash(&reason[..]); - let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); - ensure!(Tips::::contains_key(hash), "tip does not exist"); - create_tips::(t, hash.clone(), value)?; - - let caller = account("caller", t, SEED); - // Whitelist caller account from further DB operations. - let caller_key = frame_system::Account::::hashed_key_for(&caller); - frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: _(RawOrigin::Signed(caller), hash) - - propose_bounty { - let d in 0 .. MAX_BYTES; - - let (caller, curator, fee, value, description) = setup_bounty::(0, d); - }: _(RawOrigin::Signed(caller), value, description) - - approve_bounty { - let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - }: _(RawOrigin::Root, bounty_id) - - propose_curator { - setup_pod_account::(); - let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); - let curator_lookup = T::Lookup::unlookup(curator.clone()); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - Treasury::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; - Treasury::::on_initialize(T::BlockNumber::zero()); - }: _(RawOrigin::Root, bounty_id, curator_lookup, fee) - - // Worst case when curator is inactive and any sender unassigns the curator. - unassign_curator { - setup_pod_account::(); - let (curator_lookup, bounty_id) = create_bounty::()?; - Treasury::::on_initialize(T::BlockNumber::zero()); - let bounty_id = BountyCount::::get() - 1; - frame_system::Module::::set_block_number(T::BountyUpdatePeriod::get() + 1u32.into()); - let caller = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), bounty_id) - - accept_curator { - setup_pod_account::(); - let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); - let curator_lookup = T::Lookup::unlookup(curator.clone()); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - Treasury::::approve_bounty(RawOrigin::Root.into(), bounty_id)?; - Treasury::::on_initialize(T::BlockNumber::zero()); - Treasury::::propose_curator(RawOrigin::Root.into(), bounty_id, curator_lookup, fee)?; - }: _(RawOrigin::Signed(curator), bounty_id) - - award_bounty { - setup_pod_account::(); - let (curator_lookup, bounty_id) = create_bounty::()?; - Treasury::::on_initialize(T::BlockNumber::zero()); - - let bounty_id = BountyCount::::get() - 1; - let curator = T::Lookup::lookup(curator_lookup)?; - let beneficiary = T::Lookup::unlookup(account("beneficiary", 0, SEED)); - }: _(RawOrigin::Signed(curator), bounty_id, beneficiary) - - claim_bounty { - setup_pod_account::(); - let (curator_lookup, bounty_id) = create_bounty::()?; - Treasury::::on_initialize(T::BlockNumber::zero()); - - let bounty_id = BountyCount::::get() - 1; - let curator = T::Lookup::lookup(curator_lookup)?; - - let beneficiary = T::Lookup::unlookup(account("beneficiary", 0, SEED)); - Treasury::::award_bounty(RawOrigin::Signed(curator.clone()).into(), bounty_id, beneficiary)?; - - frame_system::Module::::set_block_number(T::BountyDepositPayoutDelay::get()); - - }: _(RawOrigin::Signed(curator), bounty_id) - - close_bounty_proposed { - setup_pod_account::(); - let (caller, curator, fee, value, reason) = setup_bounty::(0, 0); - Treasury::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; - let bounty_id = BountyCount::::get() - 1; - }: close_bounty(RawOrigin::Root, bounty_id) - - close_bounty_active { - setup_pod_account::(); - let (curator_lookup, bounty_id) = create_bounty::()?; - Treasury::::on_initialize(T::BlockNumber::zero()); - let bounty_id = BountyCount::::get() - 1; - }: close_bounty(RawOrigin::Root, bounty_id) - - extend_bounty_expiry { - setup_pod_account::(); - let (curator_lookup, bounty_id) = create_bounty::()?; - Treasury::::on_initialize(T::BlockNumber::zero()); - - let bounty_id = BountyCount::::get() - 1; - let curator = T::Lookup::lookup(curator_lookup)?; - }: _(RawOrigin::Signed(curator), bounty_id, Vec::new()) - on_initialize_proposals { let p in 0 .. 100; setup_pod_account::(); @@ -373,14 +102,6 @@ benchmarks_instance! { }: { Treasury::::on_initialize(T::BlockNumber::zero()); } - - on_initialize_bounties { - let b in 0 .. 100; - setup_pod_account::(); - create_approved_bounties::(b)?; - }: { - Treasury::::on_initialize(T::BlockNumber::zero()); - } } #[cfg(test)] @@ -395,23 +116,7 @@ mod tests { assert_ok!(test_benchmark_propose_spend::()); assert_ok!(test_benchmark_reject_proposal::()); assert_ok!(test_benchmark_approve_proposal::()); - assert_ok!(test_benchmark_report_awesome::()); - assert_ok!(test_benchmark_retract_tip::()); - assert_ok!(test_benchmark_tip_new::()); - assert_ok!(test_benchmark_tip::()); - assert_ok!(test_benchmark_close_tip::()); - assert_ok!(test_benchmark_propose_bounty::()); - assert_ok!(test_benchmark_approve_bounty::()); - assert_ok!(test_benchmark_propose_curator::()); - assert_ok!(test_benchmark_unassign_curator::()); - assert_ok!(test_benchmark_accept_curator::()); - assert_ok!(test_benchmark_award_bounty::()); - assert_ok!(test_benchmark_claim_bounty::()); - assert_ok!(test_benchmark_close_bounty_proposed::()); - assert_ok!(test_benchmark_close_bounty_active::()); - assert_ok!(test_benchmark_extend_bounty_expiry::()); assert_ok!(test_benchmark_on_initialize_proposals::()); - assert_ok!(test_benchmark_on_initialize_bounties::()); }); } } diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 6ccd8f03a15..835cf11d721 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -17,8 +17,8 @@ //! # Treasury Module //! -//! The Treasury module provides a "pot" of funds that can be managed by stakeholders in the -//! system and a structure for making spending proposals from this pot. +//! The Treasury module provides a "pot" of funds that can be managed by stakeholders in the system +//! and a structure for making spending proposals from this pot. //! //! - [`treasury::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) @@ -32,71 +32,16 @@ //! By way of example, the Council could vote to fund the Treasury with a portion of the block //! reward and use the funds to pay developers. //! -//! ### Tipping -//! -//! A separate subsystem exists to allow for an agile "tipping" process, whereby a reward may be -//! given without first having a pre-determined stakeholder group come to consensus on how much -//! should be paid. -//! -//! A group of `Tippers` is determined through the config `Config`. After half of these have declared -//! some amount that they believe a particular reported reason deserves, then a countdown period is -//! entered where any remaining members can declare their tip amounts also. After the close of the -//! countdown period, the median of all declared tips is paid to the reported beneficiary, along -//! with any finders fee, in case of a public (and bonded) original report. -//! -//! ### Bounty -//! -//! A Bounty Spending is a reward for a specified body of work - or specified set of objectives - that -//! needs to be executed for a predefined Treasury amount to be paid out. A curator is assigned after -//! the bounty is approved and funded by Council, to be delegated -//! with the responsibility of assigning a payout address once the specified set of objectives is completed. -//! -//! After the Council has activated a bounty, it delegates the work that requires expertise to a curator -//! in exchange of a deposit. Once the curator accepts the bounty, they -//! get to close the Active bounty. Closing the Active bounty enacts a delayed payout to the payout -//! address, the curator fee and the return of the curator deposit. The -//! delay allows for intervention through regular democracy. The Council gets to unassign the curator, -//! resulting in a new curator election. The Council also gets to cancel -//! the bounty if deemed necessary before assigning a curator or once the bounty is active or payout -//! is pending, resulting in the slash of the curator's deposit. -//! //! //! ### Terminology //! //! - **Proposal:** A suggestion to allocate funds from the pot to a beneficiary. -//! - **Beneficiary:** An account who will receive the funds from a proposal iff -//! the proposal is approved. -//! - **Deposit:** Funds that a proposer must lock when making a proposal. The -//! deposit will be returned or slashed if the proposal is approved or rejected -//! respectively. +//! - **Beneficiary:** An account who will receive the funds from a proposal iff the proposal is +//! approved. +//! - **Deposit:** Funds that a proposer must lock when making a proposal. The deposit will be +//! returned or slashed if the proposal is approved or rejected respectively. //! - **Pot:** Unspent funds accumulated by the treasury module. //! -//! Tipping protocol: -//! - **Tipping:** The process of gathering declarations of amounts to tip and taking the median -//! amount to be transferred from the treasury to a beneficiary account. -//! - **Tip Reason:** The reason for a tip; generally a URL which embodies or explains why a -//! particular individual (identified by an account ID) is worthy of a recognition by the -//! treasury. -//! - **Finder:** The original public reporter of some reason for tipping. -//! - **Finders Fee:** Some proportion of the tip amount that is paid to the reporter of the tip, -//! rather than the main beneficiary. -//! -//! Bounty: -//! - **Bounty spending proposal:** A proposal to reward a predefined body of work upon completion by -//! the Treasury. -//! - **Proposer:** An account proposing a bounty spending. -//! - **Curator:** An account managing the bounty and assigning a payout address receiving the reward -//! for the completion of work. -//! - **Deposit:** The amount held on deposit for placing a bounty proposal plus the amount held on -//! deposit per byte within the bounty description. -//! - **Curator deposit:** The payment from a candidate willing to curate an approved bounty. The deposit -//! is returned when/if the bounty is completed. -//! - **Bounty value:** The total amount that should be paid to the Payout Address if the bounty is -//! rewarded. -//! - **Payout address:** The account to which the total or part of the bounty is assigned to. -//! - **Payout Delay:** The delay period for which a bounty beneficiary needs to wait before claiming. -//! - **Curator fee:** The reserved upfront payment for a curator for work related to the bounty. -//! //! ## Interface //! //! ### Dispatchable Functions @@ -106,59 +51,40 @@ //! - `reject_proposal` - Reject a proposal, slashing the deposit. //! - `approve_proposal` - Accept the proposal, returning the deposit. //! -//! Tipping protocol: -//! - `report_awesome` - Report something worthy of a tip and register for a finders fee. -//! - `retract_tip` - Retract a previous (finders fee registered) report. -//! - `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. -//! - `tip` - Declare or redeclare an amount to tip for a particular reason. -//! - `close_tip` - Close and pay out a tip. -//! -//! Bounty protocol: -//! - `propose_bounty` - Propose a specific treasury amount to be earmarked for a predefined set of -//! tasks and stake the required deposit. -//! - `approve_bounty` - Accept a specific treasury amount to be earmarked for a predefined body of work. -//! - `propose_curator` - Assign an account to a bounty as candidate curator. -//! - `accept_curator` - Accept a bounty assignment from the Council, setting a curator deposit. -//! - `extend_bounty_expiry` - Extend the expiry block number of the bounty and stay active. -//! - `award_bounty` - Close and pay out the specified amount for the completed work. -//! - `claim_bounty` - Claim a specific bounty amount from the Payout Address. -//! - `unassign_curator` - Unassign an accepted curator from a specific earmark. -//! - `close_bounty` - Cancel the earmark for a specific treasury amount and close the bounty. -//! -//! //! ## GenesisConfig //! //! The Treasury module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] mod tests; mod benchmarking; + pub mod weights; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use sp_std::prelude::*; -use frame_support::{decl_module, decl_storage, decl_event, ensure, print, decl_error, Parameter}; +use frame_support::{decl_module, decl_storage, decl_event, ensure, print, decl_error}; use frame_support::traits::{ - Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::{KeepAlive, AllowDeath}, + Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::{KeepAlive}, ReservableCurrency, WithdrawReasons }; -use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, DispatchResult, traits::{ - Zero, StaticLookup, AccountIdConversion, Saturating, Hash, BadOrigin +use sp_runtime::{Permill, ModuleId, RuntimeDebug, traits::{ + Zero, StaticLookup, AccountIdConversion, Saturating }}; -use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::weights::{Weight, DispatchClass}; -use frame_support::traits::{Contains, ContainsLengthBound, EnsureOrigin}; +use frame_support::traits::{EnsureOrigin}; use codec::{Encode, Decode}; -use frame_system::{self as system, ensure_signed}; +use frame_system::{ensure_signed}; pub use weights::WeightInfo; -type BalanceOf = +pub type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type PositiveImbalanceOf = +pub type PositiveImbalanceOf = <>::Currency as Currency<::AccountId>>::PositiveImbalance; -type NegativeImbalanceOf = +pub type NegativeImbalanceOf = <>::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Config: frame_system::Config { @@ -174,23 +100,6 @@ pub trait Config: frame_system::Config { /// Origin from which rejections must come. type RejectOrigin: EnsureOrigin; - /// Origin from which tippers must come. - /// - /// `ContainsLengthBound::max_len` must be cost free (i.e. no storage read or heavy operation). - type Tippers: Contains + ContainsLengthBound; - - /// The period for which a tip remains open after is has achieved threshold tippers. - type TipCountdown: Get; - - /// The percent of the final tip which goes to the original reporter of the tip. - type TipFindersFee: Get; - - /// The amount held on deposit for placing a tip report. - type TipReportDepositBase: Get>; - - /// The amount held on deposit per byte within the tip report reason or bounty description. - type DataDepositPerByte: Get>; - /// The overarching event type. type Event: From> + Into<::Event>; @@ -210,29 +119,36 @@ pub trait Config: frame_system::Config { /// Percentage of spare funds (if any) that are burnt per spend period. type Burn: Get; - /// The amount held on deposit for placing a bounty proposal. - type BountyDepositBase: Get>; - - /// The delay period for which a bounty beneficiary need to wait before claim the payout. - type BountyDepositPayoutDelay: Get; - - /// Bounty duration in blocks. - type BountyUpdatePeriod: Get; - - /// Percentage of the curator fee that will be reserved upfront as deposit for bounty curator. - type BountyCuratorDeposit: Get; - - /// Minimum value for a bounty. - type BountyValueMinimum: Get>; - - /// Maximum acceptable reason length. - type MaximumReasonLength: Get; - /// Handler for the unbalanced decrease when treasury funds are burned. type BurnDestination: OnUnbalanced>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; + + /// Runtime hooks to external pallet using treasury to compute spend funds. + type SpendFunds: SpendFunds; +} + +/// A trait to allow the Treasury Pallet to spend it's funds for other purposes. +/// There is an expectation that the implementer of this trait will correctly manage +/// the mutable variables passed to it: +/// * `budget_remaining`: How much available funds that can be spent by the treasury. +/// As funds are spent, you must correctly deduct from this value. +/// * `imbalance`: Any imbalances that you create should be subsumed in here to +/// maximize efficiency of updating the total issuance. (i.e. `deposit_creating`) +/// * `total_weight`: Track any weight that your `spend_fund` implementation uses by +/// updating this value. +/// * `missed_any`: If there were items that you want to spend on, but there were +/// not enough funds, mark this value as `true`. This will prevent the treasury +/// from burning the excess funds. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait SpendFunds, I=DefaultInstance> { + fn spend_funds( + budget_remaining: &mut BalanceOf, + imbalance: &mut PositiveImbalanceOf, + total_weight: &mut Weight, + missed_any: &mut bool, + ); } /// An index of a proposal. Just a `u32`. @@ -252,122 +168,18 @@ pub struct Proposal { bond: Balance, } -/// An open tipping "motion". Retains all details of a tip including information on the finder -/// and the members who have voted. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] -pub struct OpenTip< - AccountId: Parameter, - Balance: Parameter, - BlockNumber: Parameter, - Hash: Parameter, -> { - /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be - /// sensible. - reason: Hash, - /// The account to be tipped. - who: AccountId, - /// The account who began this tip. - finder: AccountId, - /// The amount held on deposit for this tip. - deposit: Balance, - /// The block number at which this tip will close if `Some`. If `None`, then no closing is - /// scheduled. - closes: Option, - /// The members who have voted for this tip. Sorted by AccountId. - tips: Vec<(AccountId, Balance)>, - /// Whether this tip should result in the finder taking a fee. - finders_fee: bool, -} - -/// An index of a bounty. Just a `u32`. -pub type BountyIndex = u32; - -/// A bounty proposal. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct Bounty { - /// The account proposing it. - proposer: AccountId, - /// The (total) amount that should be paid if the bounty is rewarded. - value: Balance, - /// The curator fee. Included in value. - fee: Balance, - /// The deposit of curator. - curator_deposit: Balance, - /// The amount held on deposit (reserved) for making this proposal. - bond: Balance, - /// The status of this bounty. - status: BountyStatus, -} - -/// The status of a bounty proposal. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub enum BountyStatus { - /// The bounty is proposed and waiting for approval. - Proposed, - /// The bounty is approved and waiting to become active at next spend period. - Approved, - /// The bounty is funded and waiting for curator assignment. - Funded, - /// A curator has been proposed by the `ApproveOrigin`. Waiting for acceptance from the curator. - CuratorProposed { - /// The assigned curator of this bounty. - curator: AccountId, - }, - /// The bounty is active and waiting to be awarded. - Active { - /// The curator of this bounty. - curator: AccountId, - /// An update from the curator is due by this block, else they are considered inactive. - update_due: BlockNumber, - }, - /// The bounty is awarded and waiting to released after a delay. - PendingPayout { - /// The curator of this bounty. - curator: AccountId, - /// The beneficiary of the bounty. - beneficiary: AccountId, - /// When the bounty can be claimed. - unlock_at: BlockNumber, - }, -} - decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Treasury { /// Number of proposals that have been made. ProposalCount get(fn proposal_count): ProposalIndex; /// Proposals that have been made. - Proposals get(fn proposals): + pub Proposals get(fn proposals): map hasher(twox_64_concat) ProposalIndex => Option>>; /// Proposal indices that have been approved but not yet awarded. - Approvals get(fn approvals): Vec; - - /// Tips that are not yet completed. Keyed by the hash of `(reason, who)` from the value. - /// This has the insecure enumerable hash function since the key itself is already - /// guaranteed to be a secure hash. - pub Tips get(fn tips): - map hasher(twox_64_concat) T::Hash - => Option, T::BlockNumber, T::Hash>>; - - /// Simple preimage lookup from the reason's hash to the original data. Again, has an - /// insecure enumerable hash since the key is guaranteed to be the result of a secure hash. - pub Reasons get(fn reasons): map hasher(identity) T::Hash => Option>; - - /// Number of bounty proposals that have been made. - pub BountyCount get(fn bounty_count): BountyIndex; - - /// Bounties that have been made. - pub Bounties get(fn bounties): - map hasher(twox_64_concat) BountyIndex - => Option, T::BlockNumber>>; - - /// The description of each bounty. - pub BountyDescriptions get(fn bounty_descriptions): map hasher(twox_64_concat) BountyIndex => Option>; - - /// Bounty indices that have been approved but not yet funded. - pub BountyApprovals get(fn bounty_approvals): Vec; + pub Approvals get(fn approvals): Vec; } add_extra_genesis { build(|_config| { @@ -389,7 +201,6 @@ decl_event!( where Balance = BalanceOf, ::AccountId, - ::Hash, { /// New proposal. \[proposal_index\] Proposed(ProposalIndex), @@ -406,28 +217,6 @@ decl_event!( Rollover(Balance), /// Some funds have been deposited. \[deposit\] Deposit(Balance), - /// A new tip suggestion has been opened. \[tip_hash\] - NewTip(Hash), - /// A tip suggestion has reached threshold and is closing. \[tip_hash\] - TipClosing(Hash), - /// A tip suggestion has been closed. \[tip_hash, who, payout\] - TipClosed(Hash, AccountId, Balance), - /// A tip suggestion has been retracted. \[tip_hash\] - TipRetracted(Hash), - /// New bounty proposal. \[index\] - BountyProposed(BountyIndex), - /// A bounty proposal was rejected; funds were slashed. [index, bond] - BountyRejected(BountyIndex, Balance), - /// A bounty proposal is funded and became active. \[index\] - BountyBecameActive(BountyIndex), - /// A bounty is awarded to a beneficiary. [index, beneficiary] - BountyAwarded(BountyIndex, AccountId), - /// A bounty is claimed by beneficiary. [index, payout, beneficiary] - BountyClaimed(BountyIndex, Balance, AccountId), - /// A bounty is cancelled. \[index\] - BountyCanceled(BountyIndex), - /// A bounty expiry is extended. \[index\] - BountyExtended(BountyIndex), } ); @@ -438,29 +227,6 @@ decl_error! { InsufficientProposersBalance, /// No proposal or bounty at that index. InvalidIndex, - /// The reason given is just too big. - ReasonTooBig, - /// The tip was already found/started. - AlreadyKnown, - /// The tip hash is unknown. - UnknownTip, - /// The account attempting to retract the tip is not the finder of the tip. - NotFinder, - /// The tip cannot be claimed/closed because there are not enough tippers yet. - StillOpen, - /// The tip cannot be claimed/closed because it's still in the countdown period. - Premature, - /// The bounty status is unexpected. - UnexpectedStatus, - /// Require bounty curator. - RequireCurator, - /// Invalid bounty value. - InvalidValue, - /// Invalid bounty fee. - InvalidFee, - /// A bounty payout is pending. - /// To cancel the bounty, you must unassign and slash the curator. - PendingPayout, } } @@ -482,35 +248,9 @@ decl_module! { /// Percentage of spare funds (if any) that are burnt per spend period. const Burn: Permill = T::Burn::get(); - /// The period for which a tip remains open after is has achieved threshold tippers. - const TipCountdown: T::BlockNumber = T::TipCountdown::get(); - - /// The amount of the final tip which goes to the original reporter of the tip. - const TipFindersFee: Percent = T::TipFindersFee::get(); - - /// The amount held on deposit for placing a tip report. - const TipReportDepositBase: BalanceOf = T::TipReportDepositBase::get(); - - /// The amount held on deposit per byte within the tip report reason or bounty description. - const DataDepositPerByte: BalanceOf = T::DataDepositPerByte::get(); - /// The treasury's module id, used for deriving its sovereign account ID. const ModuleId: ModuleId = T::ModuleId::get(); - /// The amount held on deposit for placing a bounty proposal. - const BountyDepositBase: BalanceOf = T::BountyDepositBase::get(); - - /// The delay period for which a bounty beneficiary need to wait before claim the payout. - const BountyDepositPayoutDelay: T::BlockNumber = T::BountyDepositPayoutDelay::get(); - - /// Percentage of the curator fee that will be reserved upfront as deposit for bounty curator. - const BountyCuratorDeposit: Permill = T::BountyCuratorDeposit::get(); - - const BountyValueMinimum: BalanceOf = T::BountyValueMinimum::get(); - - /// Maximum acceptable reason length. - const MaximumReasonLength: u32 = T::MaximumReasonLength::get(); - type Error = Error; fn deposit_event() = default; @@ -525,7 +265,7 @@ decl_module! { /// - DbWrites: `ProposalCount`, `Proposals`, `origin account` /// # #[weight = T::WeightInfo::propose_spend()] - fn propose_spend( + pub fn propose_spend( origin, #[compact] value: BalanceOf, beneficiary: ::Source @@ -554,7 +294,7 @@ decl_module! { /// - DbWrites: `Proposals`, `rejected proposer account` /// # #[weight = (T::WeightInfo::reject_proposal(), DispatchClass::Operational)] - fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { + pub fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::RejectOrigin::ensure_origin(origin)?; let proposal = >::take(&proposal_id).ok_or(Error::::InvalidIndex)?; @@ -576,571 +316,13 @@ decl_module! { /// - DbWrite: `Approvals` /// # #[weight = (T::WeightInfo::approve_proposal(), DispatchClass::Operational)] - fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { + pub fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::ApproveOrigin::ensure_origin(origin)?; ensure!(>::contains_key(proposal_id), Error::::InvalidIndex); Approvals::::append(proposal_id); } - /// Report something `reason` that deserves a tip and claim any eventual the finder's fee. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// Payment: `TipReportDepositBase` will be reserved from the origin account, as well as - /// `DataDepositPerByte` for each byte in `reason`. - /// - /// - `reason`: The reason for, or the thing that deserves, the tip; generally this will be - /// a UTF-8-encoded URL. - /// - `who`: The account which should be credited for the tip. - /// - /// Emits `NewTip` if successful. - /// - /// # - /// - Complexity: `O(R)` where `R` length of `reason`. - /// - encoding and hashing of 'reason' - /// - DbReads: `Reasons`, `Tips` - /// - DbWrites: `Reasons`, `Tips` - /// # - #[weight = T::WeightInfo::report_awesome(reason.len() as u32)] - fn report_awesome(origin, reason: Vec, who: T::AccountId) { - let finder = ensure_signed(origin)?; - - ensure!(reason.len() <= T::MaximumReasonLength::get() as usize, Error::::ReasonTooBig); - - let reason_hash = T::Hashing::hash(&reason[..]); - ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); - let hash = T::Hashing::hash_of(&(&reason_hash, &who)); - ensure!(!Tips::::contains_key(&hash), Error::::AlreadyKnown); - - let deposit = T::TipReportDepositBase::get() - + T::DataDepositPerByte::get() * (reason.len() as u32).into(); - T::Currency::reserve(&finder, deposit)?; - - Reasons::::insert(&reason_hash, &reason); - let tip = OpenTip { - reason: reason_hash, - who, - finder, - deposit, - closes: None, - tips: vec![], - finders_fee: true - }; - Tips::::insert(&hash, tip); - Self::deposit_event(RawEvent::NewTip(hash)); - } - - /// Retract a prior tip-report from `report_awesome`, and cancel the process of tipping. - /// - /// If successful, the original deposit will be unreserved. - /// - /// The dispatch origin for this call must be _Signed_ and the tip identified by `hash` - /// must have been reported by the signing account through `report_awesome` (and not - /// through `tip_new`). - /// - /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed - /// as the hash of the tuple of the original tip `reason` and the beneficiary account ID. - /// - /// Emits `TipRetracted` if successful. - /// - /// # - /// - Complexity: `O(1)` - /// - Depends on the length of `T::Hash` which is fixed. - /// - DbReads: `Tips`, `origin account` - /// - DbWrites: `Reasons`, `Tips`, `origin account` - /// # - #[weight = T::WeightInfo::retract_tip()] - fn retract_tip(origin, hash: T::Hash) { - let who = ensure_signed(origin)?; - let tip = Tips::::get(&hash).ok_or(Error::::UnknownTip)?; - ensure!(tip.finder == who, Error::::NotFinder); - - Reasons::::remove(&tip.reason); - Tips::::remove(&hash); - if !tip.deposit.is_zero() { - let _ = T::Currency::unreserve(&who, tip.deposit); - } - Self::deposit_event(RawEvent::TipRetracted(hash)); - } - - /// Give a tip for something new; no finder's fee will be taken. - /// - /// The dispatch origin for this call must be _Signed_ and the signing account must be a - /// member of the `Tippers` set. - /// - /// - `reason`: The reason for, or the thing that deserves, the tip; generally this will be - /// a UTF-8-encoded URL. - /// - `who`: The account which should be credited for the tip. - /// - `tip_value`: The amount of tip that the sender would like to give. The median tip - /// value of active tippers will be given to the `who`. - /// - /// Emits `NewTip` if successful. - /// - /// # - /// - Complexity: `O(R + T)` where `R` length of `reason`, `T` is the number of tippers. - /// - `O(T)`: decoding `Tipper` vec of length `T` - /// `T` is charged as upper bound given by `ContainsLengthBound`. - /// The actual cost depends on the implementation of `T::Tippers`. - /// - `O(R)`: hashing and encoding of reason of length `R` - /// - DbReads: `Tippers`, `Reasons` - /// - DbWrites: `Reasons`, `Tips` - /// # - #[weight = T::WeightInfo::tip_new(reason.len() as u32, T::Tippers::max_len() as u32)] - fn tip_new(origin, reason: Vec, who: T::AccountId, #[compact] tip_value: BalanceOf) { - let tipper = ensure_signed(origin)?; - ensure!(T::Tippers::contains(&tipper), BadOrigin); - let reason_hash = T::Hashing::hash(&reason[..]); - ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); - let hash = T::Hashing::hash_of(&(&reason_hash, &who)); - - Reasons::::insert(&reason_hash, &reason); - Self::deposit_event(RawEvent::NewTip(hash.clone())); - let tips = vec![(tipper.clone(), tip_value)]; - let tip = OpenTip { - reason: reason_hash, - who, - finder: tipper, - deposit: Zero::zero(), - closes: None, - tips, - finders_fee: false, - }; - Tips::::insert(&hash, tip); - } - - /// Declare a tip value for an already-open tip. - /// - /// The dispatch origin for this call must be _Signed_ and the signing account must be a - /// member of the `Tippers` set. - /// - /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed - /// as the hash of the tuple of the hash of the original tip `reason` and the beneficiary - /// account ID. - /// - `tip_value`: The amount of tip that the sender would like to give. The median tip - /// value of active tippers will be given to the `who`. - /// - /// Emits `TipClosing` if the threshold of tippers has been reached and the countdown period - /// has started. - /// - /// # - /// - Complexity: `O(T)` where `T` is the number of tippers. - /// decoding `Tipper` vec of length `T`, insert tip and check closing, - /// `T` is charged as upper bound given by `ContainsLengthBound`. - /// The actual cost depends on the implementation of `T::Tippers`. - /// - /// Actually weight could be lower as it depends on how many tips are in `OpenTip` but it - /// is weighted as if almost full i.e of length `T-1`. - /// - DbReads: `Tippers`, `Tips` - /// - DbWrites: `Tips` - /// # - #[weight = T::WeightInfo::tip(T::Tippers::max_len() as u32)] - fn tip(origin, hash: T::Hash, #[compact] tip_value: BalanceOf) { - let tipper = ensure_signed(origin)?; - ensure!(T::Tippers::contains(&tipper), BadOrigin); - - let mut tip = Tips::::get(hash).ok_or(Error::::UnknownTip)?; - if Self::insert_tip_and_check_closing(&mut tip, tipper, tip_value) { - Self::deposit_event(RawEvent::TipClosing(hash.clone())); - } - Tips::::insert(&hash, tip); - } - - /// Close and payout a tip. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// The tip identified by `hash` must have finished its countdown period. - /// - /// - `hash`: The identity of the open tip for which a tip value is declared. This is formed - /// as the hash of the tuple of the original tip `reason` and the beneficiary account ID. - /// - /// # - /// - Complexity: `O(T)` where `T` is the number of tippers. - /// decoding `Tipper` vec of length `T`. - /// `T` is charged as upper bound given by `ContainsLengthBound`. - /// The actual cost depends on the implementation of `T::Tippers`. - /// - DbReads: `Tips`, `Tippers`, `tip finder` - /// - DbWrites: `Reasons`, `Tips`, `Tippers`, `tip finder` - /// # - #[weight = T::WeightInfo::close_tip(T::Tippers::max_len() as u32)] - fn close_tip(origin, hash: T::Hash) { - ensure_signed(origin)?; - - let tip = Tips::::get(hash).ok_or(Error::::UnknownTip)?; - let n = tip.closes.as_ref().ok_or(Error::::StillOpen)?; - ensure!(system::Module::::block_number() >= *n, Error::::Premature); - // closed. - Reasons::::remove(&tip.reason); - Tips::::remove(hash); - Self::payout_tip(hash, tip); - } - - /// Propose a new bounty. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// Payment: `TipReportDepositBase` will be reserved from the origin account, as well as - /// `DataDepositPerByte` for each byte in `reason`. It will be unreserved upon approval, - /// or slashed when rejected. - /// - /// - `curator`: The curator account whom will manage this bounty. - /// - `fee`: The curator fee. - /// - `value`: The total payment amount of this bounty, curator fee included. - /// - `description`: The description of this bounty. - #[weight = T::WeightInfo::propose_bounty(description.len() as u32)] - fn propose_bounty( - origin, - #[compact] value: BalanceOf, - description: Vec, - ) { - let proposer = ensure_signed(origin)?; - Self::create_bounty(proposer, description, value)?; - } - - /// Approve a bounty proposal. At a later time, the bounty will be funded and become active - /// and the original deposit will be returned. - /// - /// May only be called from `T::ApproveOrigin`. - /// - /// # - /// - O(1). - /// - Limited storage reads. - /// - One DB change. - /// # - #[weight = T::WeightInfo::approve_bounty()] - fn approve_bounty(origin, #[compact] bounty_id: ProposalIndex) { - T::ApproveOrigin::ensure_origin(origin)?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - ensure!(bounty.status == BountyStatus::Proposed, Error::::UnexpectedStatus); - - bounty.status = BountyStatus::Approved; - - BountyApprovals::::append(bounty_id); - - Ok(()) - })?; - } - - /// Assign a curator to a funded bounty. - /// - /// May only be called from `T::ApproveOrigin`. - /// - /// # - /// - O(1). - /// - Limited storage reads. - /// - One DB change. - /// # - #[weight = T::WeightInfo::propose_curator()] - fn propose_curator( - origin, - #[compact] bounty_id: ProposalIndex, - curator: ::Source, - #[compact] fee: BalanceOf, - ) { - T::ApproveOrigin::ensure_origin(origin)?; - - let curator = T::Lookup::lookup(curator)?; - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - match bounty.status { - BountyStatus::Funded | BountyStatus::CuratorProposed { .. } => {}, - _ => return Err(Error::::UnexpectedStatus.into()), - }; - - ensure!(fee < bounty.value, Error::::InvalidFee); - - bounty.status = BountyStatus::CuratorProposed { curator }; - bounty.fee = fee; - - Ok(()) - })?; - } - - /// Unassign curator from a bounty. - /// - /// This function can only be called by the `RejectOrigin` a signed origin. - /// - /// If this function is called by the `RejectOrigin`, we assume that the curator is malicious - /// or inactive. As a result, we will slash the curator when possible. - /// - /// If the origin is the curator, we take this as a sign they are unable to do their job and - /// they willingly give up. We could slash them, but for now we allow them to recover their - /// deposit and exit without issue. (We may want to change this if it is abused.) - /// - /// Finally, the origin can be anyone if and only if the curator is "inactive". This allows - /// anyone in the community to call out that a curator is not doing their due diligence, and - /// we should pick a new curator. In this case the curator should also be slashed. - /// - /// # - /// - O(1). - /// - Limited storage reads. - /// - One DB change. - /// # - #[weight = T::WeightInfo::unassign_curator()] - fn unassign_curator( - origin, - #[compact] bounty_id: ProposalIndex, - ) { - let maybe_sender = ensure_signed(origin.clone()) - .map(Some) - .or_else(|_| T::RejectOrigin::ensure_origin(origin).map(|_| None))?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - - let slash_curator = |curator: &T::AccountId, curator_deposit: &mut BalanceOf| { - let imbalance = T::Currency::slash_reserved(curator, *curator_deposit).0; - T::OnSlash::on_unbalanced(imbalance); - *curator_deposit = Zero::zero(); - }; - - match bounty.status { - BountyStatus::Proposed | BountyStatus::Approved | BountyStatus::Funded => { - // No curator to unassign at this point. - return Err(Error::::UnexpectedStatus.into()) - } - BountyStatus::CuratorProposed { ref curator } => { - // A curator has been proposed, but not accepted yet. - // Either `RejectOrigin` or the proposed curator can unassign the curator. - ensure!(maybe_sender.map_or(true, |sender| sender == *curator), BadOrigin); - }, - BountyStatus::Active { ref curator, ref update_due } => { - // The bounty is active. - match maybe_sender { - // If the `RejectOrigin` is calling this function, slash the curator. - None => { - slash_curator(curator, &mut bounty.curator_deposit); - // Continue to change bounty status below... - }, - Some(sender) => { - // If the sender is not the curator, and the curator is inactive, - // slash the curator. - if sender != *curator { - let block_number = system::Module::::block_number(); - if *update_due < block_number { - slash_curator(curator, &mut bounty.curator_deposit); - // Continue to change bounty status below... - } else { - // Curator has more time to give an update. - return Err(Error::::Premature.into()) - } - } else { - // Else this is the curator, willingly giving up their role. - // Give back their deposit. - let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); - // Continue to change bounty status below... - } - }, - } - }, - BountyStatus::PendingPayout { ref curator, .. } => { - // The bounty is pending payout, so only council can unassign a curator. - // By doing so, they are claiming the curator is acting maliciously, so - // we slash the curator. - ensure!(maybe_sender.is_none(), BadOrigin); - slash_curator(curator, &mut bounty.curator_deposit); - // Continue to change bounty status below... - } - }; - - bounty.status = BountyStatus::Funded; - Ok(()) - })?; - } - - /// Accept the curator role for a bounty. - /// A deposit will be reserved from curator and refund upon successful payout. - /// - /// May only be called from the curator. - /// - /// # - /// - O(1). - /// - Limited storage reads. - /// - One DB change. - /// # - #[weight = T::WeightInfo::accept_curator()] - fn accept_curator(origin, #[compact] bounty_id: ProposalIndex) { - let signer = ensure_signed(origin)?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - - match bounty.status { - BountyStatus::CuratorProposed { ref curator } => { - ensure!(signer == *curator, Error::::RequireCurator); - - let deposit = T::BountyCuratorDeposit::get() * bounty.fee; - T::Currency::reserve(curator, deposit)?; - bounty.curator_deposit = deposit; - - let update_due = system::Module::::block_number() + T::BountyUpdatePeriod::get(); - bounty.status = BountyStatus::Active { curator: curator.clone(), update_due }; - - Ok(()) - }, - _ => Err(Error::::UnexpectedStatus.into()), - } - })?; - } - - /// Award bounty to a beneficiary account. The beneficiary will be able to claim the funds after a delay. - /// - /// The dispatch origin for this call must be the curator of this bounty. - /// - /// - `bounty_id`: Bounty ID to award. - /// - `beneficiary`: The beneficiary account whom will receive the payout. - #[weight = T::WeightInfo::award_bounty()] - fn award_bounty(origin, #[compact] bounty_id: ProposalIndex, beneficiary: ::Source) { - let signer = ensure_signed(origin)?; - let beneficiary = T::Lookup::lookup(beneficiary)?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let mut bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - match &bounty.status { - BountyStatus::Active { - curator, - .. - } => { - ensure!(signer == *curator, Error::::RequireCurator); - }, - _ => return Err(Error::::UnexpectedStatus.into()), - } - bounty.status = BountyStatus::PendingPayout { - curator: signer, - beneficiary: beneficiary.clone(), - unlock_at: system::Module::::block_number() + T::BountyDepositPayoutDelay::get(), - }; - - Ok(()) - })?; - - Self::deposit_event(Event::::BountyAwarded(bounty_id, beneficiary)); - } - - /// Claim the payout from an awarded bounty after payout delay. - /// - /// The dispatch origin for this call must be the beneficiary of this bounty. - /// - /// - `bounty_id`: Bounty ID to claim. - #[weight = T::WeightInfo::claim_bounty()] - fn claim_bounty(origin, #[compact] bounty_id: BountyIndex) { - let _ = ensure_signed(origin)?; // anyone can trigger claim - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let bounty = maybe_bounty.take().ok_or(Error::::InvalidIndex)?; - if let BountyStatus::PendingPayout { curator, beneficiary, unlock_at } = bounty.status { - ensure!(system::Module::::block_number() >= unlock_at, Error::::Premature); - let bounty_account = Self::bounty_account_id(bounty_id); - let balance = T::Currency::free_balance(&bounty_account); - let fee = bounty.fee.min(balance); // just to be safe - let payout = balance.saturating_sub(fee); - let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); - let _ = T::Currency::transfer(&bounty_account, &curator, fee, AllowDeath); // should not fail - let _ = T::Currency::transfer(&bounty_account, &beneficiary, payout, AllowDeath); // should not fail - *maybe_bounty = None; - - BountyDescriptions::::remove(bounty_id); - - Self::deposit_event(Event::::BountyClaimed(bounty_id, payout, beneficiary)); - Ok(()) - } else { - Err(Error::::UnexpectedStatus.into()) - } - })?; - } - - /// Cancel a proposed or active bounty. All the funds will be sent to treasury and - /// the curator deposit will be unreserved if possible. - /// - /// Only `T::RejectOrigin` is able to cancel a bounty. - /// - /// - `bounty_id`: Bounty ID to cancel. - #[weight = T::WeightInfo::close_bounty_proposed().max(T::WeightInfo::close_bounty_active())] - fn close_bounty(origin, #[compact] bounty_id: BountyIndex) -> DispatchResultWithPostInfo { - T::RejectOrigin::ensure_origin(origin)?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResultWithPostInfo { - let bounty = maybe_bounty.as_ref().ok_or(Error::::InvalidIndex)?; - - match &bounty.status { - BountyStatus::Proposed => { - // The reject origin would like to cancel a proposed bounty. - BountyDescriptions::::remove(bounty_id); - let value = bounty.bond; - let imbalance = T::Currency::slash_reserved(&bounty.proposer, value).0; - T::OnSlash::on_unbalanced(imbalance); - *maybe_bounty = None; - - Self::deposit_event(Event::::BountyRejected(bounty_id, value)); - // Return early, nothing else to do. - return Ok(Some(T::WeightInfo::close_bounty_proposed()).into()) - }, - BountyStatus::Approved => { - // For weight reasons, we don't allow a council to cancel in this phase. - // We ask for them to wait until it is funded before they can cancel. - return Err(Error::::UnexpectedStatus.into()) - }, - BountyStatus::Funded | - BountyStatus::CuratorProposed { .. } => { - // Nothing extra to do besides the removal of the bounty below. - }, - BountyStatus::Active { curator, .. } => { - // Cancelled by council, refund deposit of the working curator. - let _ = T::Currency::unreserve(&curator, bounty.curator_deposit); - // Then execute removal of the bounty below. - }, - BountyStatus::PendingPayout { .. } => { - // Bounty is already pending payout. If council wants to cancel - // this bounty, it should mean the curator was acting maliciously. - // So the council should first unassign the curator, slashing their - // deposit. - return Err(Error::::PendingPayout.into()) - } - } - - let bounty_account = Self::bounty_account_id(bounty_id); - - BountyDescriptions::::remove(bounty_id); - - let balance = T::Currency::free_balance(&bounty_account); - let _ = T::Currency::transfer(&bounty_account, &Self::account_id(), balance, AllowDeath); // should not fail - *maybe_bounty = None; - - Self::deposit_event(Event::::BountyCanceled(bounty_id)); - Ok(Some(T::WeightInfo::close_bounty_active()).into()) - }) - } - - /// Extend the expiry time of an active bounty. - /// - /// The dispatch origin for this call must be the curator of this bounty. - /// - /// - `bounty_id`: Bounty ID to extend. - /// - `remark`: additional information. - #[weight = T::WeightInfo::extend_bounty_expiry()] - fn extend_bounty_expiry(origin, #[compact] bounty_id: BountyIndex, _remark: Vec) { - let signer = ensure_signed(origin)?; - - Bounties::::try_mutate_exists(bounty_id, |maybe_bounty| -> DispatchResult { - let bounty = maybe_bounty.as_mut().ok_or(Error::::InvalidIndex)?; - - match bounty.status { - BountyStatus::Active { ref curator, ref mut update_due } => { - ensure!(*curator == signer, Error::::RequireCurator); - *update_due = (system::Module::::block_number() + T::BountyUpdatePeriod::get()).max(*update_due); - }, - _ => return Err(Error::::UnexpectedStatus.into()), - } - - Ok(()) - })?; - - Self::deposit_event(Event::::BountyExtended(bounty_id)); - } - /// # /// - Complexity: `O(A)` where `A` is the number of approvals /// - Db reads and writes: `Approvals`, `pot account data` @@ -1170,93 +352,13 @@ impl, I: Instance> Module { T::ModuleId::get().into_account() } - /// The account ID of a bounty account - pub fn bounty_account_id(id: BountyIndex) -> T::AccountId { - // only use two byte prefix to support 16 byte account id (used by test) - // "modl" ++ "py/trsry" ++ "bt" is 14 bytes, and two bytes remaining for bounty index - T::ModuleId::get().into_sub_account(("bt", id)) - } - /// The needed bond for a proposal whose spend is `value`. fn calculate_bond(value: BalanceOf) -> BalanceOf { T::ProposalBondMinimum::get().max(T::ProposalBond::get() * value) } - /// Given a mutable reference to an `OpenTip`, insert the tip into it and check whether it - /// closes, if so, then deposit the relevant event and set closing accordingly. - /// - /// `O(T)` and one storage access. - fn insert_tip_and_check_closing( - tip: &mut OpenTip, T::BlockNumber, T::Hash>, - tipper: T::AccountId, - tip_value: BalanceOf, - ) -> bool { - match tip.tips.binary_search_by_key(&&tipper, |x| &x.0) { - Ok(pos) => tip.tips[pos] = (tipper, tip_value), - Err(pos) => tip.tips.insert(pos, (tipper, tip_value)), - } - Self::retain_active_tips(&mut tip.tips); - let threshold = (T::Tippers::count() + 1) / 2; - if tip.tips.len() >= threshold && tip.closes.is_none() { - tip.closes = Some(system::Module::::block_number() + T::TipCountdown::get()); - true - } else { - false - } - } - - /// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`. - fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf)>) { - let members = T::Tippers::sorted_members(); - let mut members_iter = members.iter(); - let mut member = members_iter.next(); - tips.retain(|(ref a, _)| loop { - match member { - None => break false, - Some(m) if m > a => break false, - Some(m) => { - member = members_iter.next(); - if m < a { - continue - } else { - break true; - } - } - } - }); - } - - /// Execute the payout of a tip. - /// - /// Up to three balance operations. - /// Plus `O(T)` (`T` is Tippers length). - fn payout_tip(hash: T::Hash, tip: OpenTip, T::BlockNumber, T::Hash>) { - let mut tips = tip.tips; - Self::retain_active_tips(&mut tips); - tips.sort_by_key(|i| i.1); - let treasury = Self::account_id(); - let max_payout = Self::pot(); - let mut payout = tips[tips.len() / 2].1.min(max_payout); - if !tip.deposit.is_zero() { - let _ = T::Currency::unreserve(&tip.finder, tip.deposit); - } - if tip.finders_fee { - if tip.finder != tip.who { - // pay out the finder's fee. - let finders_fee = T::TipFindersFee::get() * payout; - payout -= finders_fee; - // this should go through given we checked it's at most the free balance, but still - // we only make a best-effort. - let _ = T::Currency::transfer(&treasury, &tip.finder, finders_fee, KeepAlive); - } - } - // same as above: best-effort only. - let _ = T::Currency::transfer(&treasury, &tip.who, payout, KeepAlive); - Self::deposit_event(RawEvent::TipClosed(hash, tip.who, payout)); - } - /// Spend some money! returns number of approvals before spend. - fn spend_funds() -> Weight { + pub fn spend_funds() -> Weight { let mut total_weight: Weight = Zero::zero(); let mut budget_remaining = Self::pot(); @@ -1295,38 +397,8 @@ impl, I: Instance> Module { total_weight += T::WeightInfo::on_initialize_proposals(proposals_len); - let bounties_len = BountyApprovals::::mutate(|v| { - let bounties_approval_len = v.len() as u32; - v.retain(|&index| { - Bounties::::mutate(index, |bounty| { - // Should always be true, but shouldn't panic if false or we're screwed. - if let Some(bounty) = bounty { - if bounty.value <= budget_remaining { - budget_remaining -= bounty.value; - - bounty.status = BountyStatus::Funded; - - // return their deposit. - let _ = T::Currency::unreserve(&bounty.proposer, bounty.bond); - - // fund the bounty account - imbalance.subsume(T::Currency::deposit_creating(&Self::bounty_account_id(index), bounty.value)); - - Self::deposit_event(RawEvent::BountyBecameActive(index)); - false - } else { - missed_any = true; - true - } - } else { - false - } - }) - }); - bounties_approval_len - }); - - total_weight += T::WeightInfo::on_initialize_bounties(bounties_len); + // Call Runtime hooks to external pallet using treasury to compute spend funds. + T::SpendFunds::spend_funds( &mut budget_remaining, &mut imbalance, &mut total_weight, &mut missed_any); if !missed_any { // burn some proportion of the remaining budget if we run a surplus. @@ -1361,95 +433,12 @@ impl, I: Instance> Module { /// Return the amount of money in the pot. // The existential deposit is not part of the pot so treasury account never gets deleted. - fn pot() -> BalanceOf { + pub fn pot() -> BalanceOf { T::Currency::free_balance(&Self::account_id()) // Must never be less than 0 but better be safe. .saturating_sub(T::Currency::minimum_balance()) } - fn create_bounty( - proposer: T::AccountId, - description: Vec, - value: BalanceOf, - ) -> DispatchResult { - ensure!(description.len() <= T::MaximumReasonLength::get() as usize, Error::::ReasonTooBig); - ensure!(value >= T::BountyValueMinimum::get(), Error::::InvalidValue); - - let index = Self::bounty_count(); - - // reserve deposit for new bounty - let bond = T::BountyDepositBase::get() - + T::DataDepositPerByte::get() * (description.len() as u32).into(); - T::Currency::reserve(&proposer, bond) - .map_err(|_| Error::::InsufficientProposersBalance)?; - - BountyCount::::put(index + 1); - - let bounty = Bounty { - proposer, - value, - fee: 0u32.into(), - curator_deposit: 0u32.into(), - bond, - status: BountyStatus::Proposed, - }; - - Bounties::::insert(index, &bounty); - BountyDescriptions::::insert(index, description); - - Self::deposit_event(RawEvent::BountyProposed(index)); - - Ok(()) - } - - pub fn migrate_retract_tip_for_tip_new() { - /// An open tipping "motion". Retains all details of a tip including information on the finder - /// and the members who have voted. - #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] - pub struct OldOpenTip< - AccountId: Parameter, - Balance: Parameter, - BlockNumber: Parameter, - Hash: Parameter, - > { - /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be - /// sensible. - reason: Hash, - /// The account to be tipped. - who: AccountId, - /// The account who began this tip and the amount held on deposit. - finder: Option<(AccountId, Balance)>, - /// The block number at which this tip will close if `Some`. If `None`, then no closing is - /// scheduled. - closes: Option, - /// The members who have voted for this tip. Sorted by AccountId. - tips: Vec<(AccountId, Balance)>, - } - - use frame_support::{Twox64Concat, migration::StorageKeyIterator}; - - for (hash, old_tip) in StorageKeyIterator::< - T::Hash, - OldOpenTip, T::BlockNumber, T::Hash>, - Twox64Concat, - >::new(I::PREFIX.as_bytes(), b"Tips").drain() - { - let (finder, deposit, finders_fee) = match old_tip.finder { - Some((finder, deposit)) => (finder, deposit, true), - None => (T::AccountId::default(), Zero::zero(), false), - }; - let new_tip = OpenTip { - reason: old_tip.reason, - who: old_tip.who, - finder, - deposit, - closes: old_tip.closes, - tips: old_tip.tips, - finders_fee - }; - Tips::::insert(hash, new_tip) - } - } } impl, I: Instance> OnUnbalanced> for Module { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 3cf1272a19e..8db303a426d 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -23,20 +23,21 @@ use super::*; use std::cell::RefCell; use frame_support::{ assert_noop, assert_ok, impl_outer_origin, impl_outer_event, parameter_types, - traits::{Contains, OnInitialize} + traits::{OnInitialize} }; +use frame_system::{self as system}; + use sp_core::H256; use sp_runtime::{ ModuleId, testing::Header, - traits::{BlakeTwo256, IdentityLookup, BadOrigin}, + traits::{BlakeTwo256, IdentityLookup}, }; impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } - mod treasury { // Re-export needed for `impl_outer_event!`. pub use super::super::*; @@ -50,7 +51,6 @@ impl_outer_event! { } } - #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -96,42 +96,13 @@ impl pallet_balances::Config for Test { thread_local! { static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![10,11,12,13,14]); } -pub struct TenToFourteen; -impl Contains for TenToFourteen { - fn sorted_members() -> Vec { - TEN_TO_FOURTEEN.with(|v| { - v.borrow().clone() - }) - } - #[cfg(feature = "runtime-benchmarks")] - fn add(new: &u128) { - TEN_TO_FOURTEEN.with(|v| { - let mut members = v.borrow_mut(); - members.push(*new); - members.sort(); - }) - } -} -impl ContainsLengthBound for TenToFourteen { - fn max_len() -> usize { - TEN_TO_FOURTEEN.with(|v| v.borrow().len()) - } - fn min_len() -> usize { 0 } -} parameter_types! { pub const ProposalBond: Permill = Permill::from_percent(5); pub const ProposalBondMinimum: u64 = 1; pub const SpendPeriod: u64 = 2; pub const Burn: Permill = Permill::from_percent(50); - pub const TipCountdown: u64 = 1; - pub const TipFindersFee: Percent = Percent::from_percent(20); - pub const TipReportDepositBase: u64 = 1; - pub const DataDepositPerByte: u64 = 1; - pub const BountyDepositBase: u64 = 80; - pub const BountyDepositPayoutDelay: u64 = 3; pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry"); pub const BountyUpdatePeriod: u32 = 20; - pub const MaximumReasonLength: u32 = 16384; pub const BountyCuratorDeposit: Permill = Permill::from_percent(50); pub const BountyValueMinimum: u64 = 1; } @@ -140,25 +111,15 @@ impl Config for Test { type Currency = pallet_balances::Module; type ApproveOrigin = frame_system::EnsureRoot; type RejectOrigin = frame_system::EnsureRoot; - type Tippers = TenToFourteen; - type TipCountdown = TipCountdown; - type TipFindersFee = TipFindersFee; - type TipReportDepositBase = TipReportDepositBase; - type DataDepositPerByte = DataDepositPerByte; type Event = Event; type OnSlash = (); type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; - type BountyDepositBase = BountyDepositBase; - type BountyDepositPayoutDelay = BountyDepositPayoutDelay; - type BountyUpdatePeriod = BountyUpdatePeriod; - type BountyCuratorDeposit = BountyCuratorDeposit; - type BountyValueMinimum = BountyValueMinimum; - type MaximumReasonLength = MaximumReasonLength; type BurnDestination = (); // Just gets burned. type WeightInfo = (); + type SpendFunds = (); } type System = frame_system::Module; type Balances = pallet_balances::Module; @@ -174,15 +135,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities { t.into() } -fn last_event() -> RawEvent { - System::events().into_iter().map(|r| r.event) - .filter_map(|e| { - if let Event::treasury(inner) = e { Some(inner) } else { None } - }) - .last() - .unwrap() -} - #[test] fn genesis_config_works() { new_test_ext().execute_with(|| { @@ -191,163 +143,6 @@ fn genesis_config_works() { }); } -fn tip_hash() -> H256 { - BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 3u128)) -} - -#[test] -fn tip_new_cannot_be_used_twice() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); - assert_noop!( - Treasury::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10), - Error::::AlreadyKnown - ); - }); -} - -#[test] -fn report_awesome_and_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - assert_eq!(Balances::reserved_balance(0), 12); - assert_eq!(Balances::free_balance(0), 88); - - // other reports don't count. - assert_noop!( - Treasury::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3), - Error::::AlreadyKnown - ); - - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::tip(Origin::signed(9), h.clone(), 10), BadOrigin); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 102); - assert_eq!(Balances::free_balance(3), 8); - }); -} - -#[test] -fn report_awesome_from_beneficiary_and_tip_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 0)); - assert_eq!(Balances::reserved_balance(0), 12); - assert_eq!(Balances::free_balance(0), 88); - let h = BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 0u128)); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 110); - }); -} - -#[test] -fn close_tip_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); - - let h = tip_hash(); - - assert_eq!(last_event(), RawEvent::NewTip(h)); - - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::StillOpen); - - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - - assert_eq!(last_event(), RawEvent::TipClosing(h)); - - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::Premature); - - System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::none(), h.into()), BadOrigin); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - - assert_eq!(last_event(), RawEvent::TipClosed(h, 3, 10)); - - assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); - }); -} - -#[test] -fn retract_tip_works() { - new_test_ext().execute_with(|| { - // with report awesome - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::retract_tip(Origin::signed(10), h.clone()), Error::::NotFinder); - assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone())); - System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::UnknownTip); - - // with tip new - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); - assert_noop!(Treasury::retract_tip(Origin::signed(0), h.clone()), Error::::NotFinder); - assert_ok!(Treasury::retract_tip(Origin::signed(10), h.clone())); - System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::signed(10), h.into()), Error::::UnknownTip); - }); -} - -#[test] -fn tip_median_calculation_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 0)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000000)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - }); -} - -#[test] -fn tip_changing_works() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); - let h = tip_hash(); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10000)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10000)); - assert_ok!(Treasury::tip(Origin::signed(13), h.clone(), 0)); - assert_ok!(Treasury::tip(Origin::signed(14), h.clone(), 0)); - assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000)); - assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 100)); - assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); - System::set_block_number(2); - assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(3), 10); - }); -} - #[test] fn minting_works() { new_test_ext().execute_with(|| { @@ -554,596 +349,6 @@ fn inexistent_account_works() { }); } -#[test] -fn propose_bounty_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 10, b"1234567890".to_vec())); - - assert_eq!(last_event(), RawEvent::BountyProposed(0)); - - let deposit: u64 = 85 + 5; - assert_eq!(Balances::reserved_balance(0), deposit); - assert_eq!(Balances::free_balance(0), 100 - deposit); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 0, - curator_deposit: 0, - value: 10, - bond: deposit, - status: BountyStatus::Proposed, - }); - - assert_eq!(Treasury::bounty_descriptions(0).unwrap(), b"1234567890".to_vec()); - - assert_eq!(Treasury::bounty_count(), 1); - }); -} - -#[test] -fn propose_bounty_validation_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_eq!(Treasury::pot(), 100); - - assert_noop!( - Treasury::propose_bounty(Origin::signed(1), 0, [0; 17_000].to_vec()), - Error::::ReasonTooBig - ); - - assert_noop!( - Treasury::propose_bounty(Origin::signed(1), 10, b"12345678901234567890".to_vec()), - Error::::InsufficientProposersBalance - ); - - assert_noop!( - Treasury::propose_bounty(Origin::signed(1), 0, b"12345678901234567890".to_vec()), - Error::::InvalidValue - ); - }); -} - -#[test] -fn close_bounty_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_noop!(Treasury::close_bounty(Origin::root(), 0), Error::::InvalidIndex); - - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 10, b"12345".to_vec())); - - assert_ok!(Treasury::close_bounty(Origin::root(), 0)); - - let deposit: u64 = 80 + 5; - - assert_eq!(last_event(), RawEvent::BountyRejected(0, deposit)); - - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 100 - deposit); - - assert_eq!(Treasury::bounties(0), None); - assert!(!Bounties::::contains_key(0)); - assert_eq!(Treasury::bounty_descriptions(0), None); - }); -} - -#[test] -fn approve_bounty_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_noop!(Treasury::approve_bounty(Origin::root(), 0), Error::::InvalidIndex); - - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - let deposit: u64 = 80 + 5; - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 0, - value: 50, - curator_deposit: 0, - bond: deposit, - status: BountyStatus::Approved, - }); - assert_eq!(Treasury::bounty_approvals(), vec![0]); - - assert_noop!(Treasury::close_bounty(Origin::root(), 0), Error::::UnexpectedStatus); - - // deposit not returned yet - assert_eq!(Balances::reserved_balance(0), deposit); - assert_eq!(Balances::free_balance(0), 100 - deposit); - - >::on_initialize(2); - - // return deposit - assert_eq!(Balances::reserved_balance(0), 0); - assert_eq!(Balances::free_balance(0), 100); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 0, - curator_deposit: 0, - value: 50, - bond: deposit, - status: BountyStatus::Funded, - }); - assert_eq!(Treasury::pot(), 100 - 50 - 25); // burn 25 - assert_eq!(Balances::free_balance(Treasury::bounty_account_id(0)), 50); - }); -} - -#[test] -fn assign_curator_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - - assert_noop!(Treasury::propose_curator(Origin::root(), 0, 4, 4), Error::::InvalidIndex); - - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_noop!(Treasury::propose_curator(Origin::root(), 0, 4, 50), Error::::InvalidFee); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 4)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 4, - curator_deposit: 0, - value: 50, - bond: 85, - status: BountyStatus::CuratorProposed { - curator: 4, - }, - }); - - assert_noop!(Treasury::accept_curator(Origin::signed(1), 0), Error::::RequireCurator); - assert_noop!(Treasury::accept_curator(Origin::signed(4), 0), pallet_balances::Error::::InsufficientBalance); - - Balances::make_free_balance_be(&4, 10); - - assert_ok!(Treasury::accept_curator(Origin::signed(4), 0)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 4, - curator_deposit: 2, - value: 50, - bond: 85, - status: BountyStatus::Active { - curator: 4, - update_due: 22, - }, - }); - - assert_eq!(Balances::free_balance(&4), 8); - assert_eq!(Balances::reserved_balance(&4), 2); - }); -} - -#[test] -fn unassign_curator_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 4)); - - assert_noop!(Treasury::unassign_curator(Origin::signed(1), 0), BadOrigin); - - assert_ok!(Treasury::unassign_curator(Origin::signed(4), 0)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 4, - curator_deposit: 0, - value: 50, - bond: 85, - status: BountyStatus::Funded, - }); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 4)); - - Balances::make_free_balance_be(&4, 10); - - assert_ok!(Treasury::accept_curator(Origin::signed(4), 0)); - - assert_ok!(Treasury::unassign_curator(Origin::root(), 0)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 4, - curator_deposit: 0, - value: 50, - bond: 85, - status: BountyStatus::Funded, - }); - - assert_eq!(Balances::free_balance(&4), 8); - assert_eq!(Balances::reserved_balance(&4), 0); // slashed 2 - }); -} - -#[test] -fn award_and_claim_bounty_works() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - Balances::make_free_balance_be(&4, 10); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 4)); - assert_ok!(Treasury::accept_curator(Origin::signed(4), 0)); - - assert_eq!(Balances::free_balance(4), 8); // inital 10 - 2 deposit - - assert_noop!(Treasury::award_bounty(Origin::signed(1), 0, 3), Error::::RequireCurator); - - assert_ok!(Treasury::award_bounty(Origin::signed(4), 0, 3)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 4, - curator_deposit: 2, - value: 50, - bond: 85, - status: BountyStatus::PendingPayout { - curator: 4, - beneficiary: 3, - unlock_at: 5 - }, - }); - - assert_noop!(Treasury::claim_bounty(Origin::signed(1), 0), Error::::Premature); - - System::set_block_number(5); - >::on_initialize(5); - - assert_ok!(Balances::transfer(Origin::signed(0), Treasury::bounty_account_id(0), 10)); - - assert_ok!(Treasury::claim_bounty(Origin::signed(1), 0)); - - assert_eq!(last_event(), RawEvent::BountyClaimed(0, 56, 3)); - - assert_eq!(Balances::free_balance(4), 14); // initial 10 + fee 4 - assert_eq!(Balances::free_balance(3), 56); - assert_eq!(Balances::free_balance(Treasury::bounty_account_id(0)), 0); - - assert_eq!(Treasury::bounties(0), None); - assert_eq!(Treasury::bounty_descriptions(0), None); - }); -} - -#[test] -fn claim_handles_high_fee() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - Balances::make_free_balance_be(&4, 30); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 49)); - assert_ok!(Treasury::accept_curator(Origin::signed(4), 0)); - - assert_ok!(Treasury::award_bounty(Origin::signed(4), 0, 3)); - - System::set_block_number(5); - >::on_initialize(5); - - // make fee > balance - let _ = Balances::slash(&Treasury::bounty_account_id(0), 10); - - assert_ok!(Treasury::claim_bounty(Origin::signed(1), 0)); - - assert_eq!(last_event(), RawEvent::BountyClaimed(0, 0, 3)); - - assert_eq!(Balances::free_balance(4), 70); // 30 + 50 - 10 - assert_eq!(Balances::free_balance(3), 0); - assert_eq!(Balances::free_balance(Treasury::bounty_account_id(0)), 0); - - assert_eq!(Treasury::bounties(0), None); - assert_eq!(Treasury::bounty_descriptions(0), None); - }); -} - -#[test] -fn cancel_and_refund() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Balances::transfer(Origin::signed(0), Treasury::bounty_account_id(0), 10)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 0, - curator_deposit: 0, - value: 50, - bond: 85, - status: BountyStatus::Funded, - }); - - assert_eq!(Balances::free_balance(Treasury::bounty_account_id(0)), 60); - - assert_noop!(Treasury::close_bounty(Origin::signed(0), 0), BadOrigin); - - assert_ok!(Treasury::close_bounty(Origin::root(), 0)); - - assert_eq!(Treasury::pot(), 85); // - 25 + 10 - }); -} - -#[test] -fn award_and_cancel() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 0, 10)); - assert_ok!(Treasury::accept_curator(Origin::signed(0), 0)); - - assert_eq!(Balances::free_balance(0), 95); - assert_eq!(Balances::reserved_balance(0), 5); - - assert_ok!(Treasury::award_bounty(Origin::signed(0), 0, 3)); - - // Cannot close bounty directly when payout is happening... - assert_noop!(Treasury::close_bounty(Origin::root(), 0), Error::::PendingPayout); - - // Instead unassign the curator to slash them and then close. - assert_ok!(Treasury::unassign_curator(Origin::root(), 0)); - assert_ok!(Treasury::close_bounty(Origin::root(), 0)); - - assert_eq!(last_event(), RawEvent::BountyCanceled(0)); - - assert_eq!(Balances::free_balance(Treasury::bounty_account_id(0)), 0); - // Slashed. - assert_eq!(Balances::free_balance(0), 95); - assert_eq!(Balances::reserved_balance(0), 0); - - assert_eq!(Treasury::bounties(0), None); - assert_eq!(Treasury::bounty_descriptions(0), None); - }); -} - -#[test] -fn expire_and_unassign() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 1, 10)); - assert_ok!(Treasury::accept_curator(Origin::signed(1), 0)); - - assert_eq!(Balances::free_balance(1), 93); - assert_eq!(Balances::reserved_balance(1), 5); - - System::set_block_number(22); - >::on_initialize(22); - - assert_noop!(Treasury::unassign_curator(Origin::signed(0), 0), Error::::Premature); - - System::set_block_number(23); - >::on_initialize(23); - - assert_ok!(Treasury::unassign_curator(Origin::signed(0), 0)); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 10, - curator_deposit: 0, - value: 50, - bond: 85, - status: BountyStatus::Funded, - }); - - assert_eq!(Balances::free_balance(1), 93); - assert_eq!(Balances::reserved_balance(1), 0); // slashed - - }); -} - -#[test] -fn extend_expiry() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - Balances::make_free_balance_be(&Treasury::account_id(), 101); - Balances::make_free_balance_be(&4, 10); - assert_ok!(Treasury::propose_bounty(Origin::signed(0), 50, b"12345".to_vec())); - - assert_ok!(Treasury::approve_bounty(Origin::root(), 0)); - - assert_noop!(Treasury::extend_bounty_expiry(Origin::signed(1), 0, Vec::new()), Error::::UnexpectedStatus); - - System::set_block_number(2); - >::on_initialize(2); - - assert_ok!(Treasury::propose_curator(Origin::root(), 0, 4, 10)); - assert_ok!(Treasury::accept_curator(Origin::signed(4), 0)); - - assert_eq!(Balances::free_balance(4), 5); - assert_eq!(Balances::reserved_balance(4), 5); - - System::set_block_number(10); - >::on_initialize(10); - - assert_noop!(Treasury::extend_bounty_expiry(Origin::signed(0), 0, Vec::new()), Error::::RequireCurator); - assert_ok!(Treasury::extend_bounty_expiry(Origin::signed(4), 0, Vec::new())); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 10, - curator_deposit: 5, - value: 50, - bond: 85, - status: BountyStatus::Active { curator: 4, update_due: 30 }, - }); - - assert_ok!(Treasury::extend_bounty_expiry(Origin::signed(4), 0, Vec::new())); - - assert_eq!(Treasury::bounties(0).unwrap(), Bounty { - proposer: 0, - fee: 10, - curator_deposit: 5, - value: 50, - bond: 85, - status: BountyStatus::Active { curator: 4, update_due: 30 }, // still the same - }); - - System::set_block_number(25); - >::on_initialize(25); - - assert_noop!(Treasury::unassign_curator(Origin::signed(0), 0), Error::::Premature); - assert_ok!(Treasury::unassign_curator(Origin::signed(4), 0)); - - assert_eq!(Balances::free_balance(4), 10); // not slashed - assert_eq!(Balances::reserved_balance(4), 0); - }); -} - -#[test] -fn test_last_reward_migration() { - use sp_storage::Storage; - - let mut s = Storage::default(); - - #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] - pub struct OldOpenTip< - AccountId: Parameter, - Balance: Parameter, - BlockNumber: Parameter, - Hash: Parameter, - > { - /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be - /// sensible. - reason: Hash, - /// The account to be tipped. - who: AccountId, - /// The account who began this tip and the amount held on deposit. - finder: Option<(AccountId, Balance)>, - /// The block number at which this tip will close if `Some`. If `None`, then no closing is - /// scheduled. - closes: Option, - /// The members who have voted for this tip. Sorted by AccountId. - tips: Vec<(AccountId, Balance)>, - } - - let reason1 = BlakeTwo256::hash(b"reason1"); - let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); - - let old_tip_finder = OldOpenTip:: { - reason: reason1, - who: 10, - finder: Some((20, 30)), - closes: Some(13), - tips: vec![(40, 50), (60, 70)] - }; - - let reason2 = BlakeTwo256::hash(b"reason2"); - let hash2 = BlakeTwo256::hash_of(&(reason2, 20u64)); - - let old_tip_no_finder = OldOpenTip:: { - reason: reason2, - who: 20, - finder: None, - closes: Some(13), - tips: vec![(40, 50), (60, 70)] - }; - - let data = vec![ - ( - Tips::::hashed_key_for(hash1), - old_tip_finder.encode().to_vec() - ), - ( - Tips::::hashed_key_for(hash2), - old_tip_no_finder.encode().to_vec() - ), - ]; - - s.top = data.into_iter().collect(); - sp_io::TestExternalities::new(s).execute_with(|| { - Treasury::migrate_retract_tip_for_tip_new(); - - // Test w/ finder - assert_eq!( - Tips::::get(hash1), - Some(OpenTip { - reason: reason1, - who: 10, - finder: 20, - deposit: 30, - closes: Some(13), - tips: vec![(40, 50), (60, 70)], - finders_fee: true, - }) - ); - - // Test w/o finder - assert_eq!( - Tips::::get(hash2), - Some(OpenTip { - reason: reason2, - who: 20, - finder: Default::default(), - deposit: 0, - closes: Some(13), - tips: vec![(40, 50), (60, 70)], - finders_fee: false, - }) - ); - }); -} - #[test] fn genesis_funding_works() { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/frame/treasury/src/weights.rs b/frame/treasury/src/weights.rs index 013a27a5cdc..3bc1fcd2308 100644 --- a/frame/treasury/src/weights.rs +++ b/frame/treasury/src/weights.rs @@ -15,13 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Weights for pallet_treasury +//! Autogenerated weights for pallet_treasury +//! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-10-27, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2020-12-16, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// target/release/substrate +// ./target/release/substrate // benchmark // --chain=dev // --steps=50 @@ -46,293 +47,62 @@ pub trait WeightInfo { fn propose_spend() -> Weight; fn reject_proposal() -> Weight; fn approve_proposal() -> Weight; - fn report_awesome(r: u32, ) -> Weight; - fn retract_tip() -> Weight; - fn tip_new(r: u32, t: u32, ) -> Weight; - fn tip(t: u32, ) -> Weight; - fn close_tip(t: u32, ) -> Weight; - fn propose_bounty(d: u32, ) -> Weight; - fn approve_bounty() -> Weight; - fn propose_curator() -> Weight; - fn unassign_curator() -> Weight; - fn accept_curator() -> Weight; - fn award_bounty() -> Weight; - fn claim_bounty() -> Weight; - fn close_bounty_proposed() -> Weight; - fn close_bounty_active() -> Weight; - fn extend_bounty_expiry() -> Weight; fn on_initialize_proposals(p: u32, ) -> Weight; - fn on_initialize_bounties(b: u32, ) -> Weight; - } /// Weights for pallet_treasury using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn propose_spend() -> Weight { - (56_844_000 as Weight) + (59_986_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } fn reject_proposal() -> Weight { - (46_098_000 as Weight) + (48_300_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } fn approve_proposal() -> Weight { - (13_622_000 as Weight) + (14_054_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) - - } - fn report_awesome(r: u32, ) -> Weight { - (71_823_000 as Weight) - .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn retract_tip() -> Weight { - (60_150_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn tip_new(r: u32, t: u32, ) -> Weight { - (46_522_000 as Weight) - .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) - .saturating_add((145_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn tip(t: u32, ) -> Weight { - (33_790_000 as Weight) - .saturating_add((713_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - - } - fn close_tip(t: u32, ) -> Weight { - (113_040_000 as Weight) - .saturating_add((375_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - - } - fn propose_bounty(d: u32, ) -> Weight { - (60_887_000 as Weight) - .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - - } - fn approve_bounty() -> Weight { - (17_337_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn propose_curator() -> Weight { - (14_068_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - - } - fn unassign_curator() -> Weight { - (49_717_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn accept_curator() -> Weight { - (50_596_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - - } - fn award_bounty() -> Weight { - (36_030_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - - } - fn claim_bounty() -> Weight { - (167_088_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - - } - fn close_bounty_proposed() -> Weight { - (48_977_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - - } - fn close_bounty_active() -> Weight { - (110_959_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - - } - fn extend_bounty_expiry() -> Weight { - (34_987_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } fn on_initialize_proposals(p: u32, ) -> Weight { - (76_596_000 as Weight) - .saturating_add((73_988_000 as Weight).saturating_mul(p as Weight)) + (86_038_000 as Weight) + // Standard Error: 18_000 + .saturating_add((78_781_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(p as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(p as Weight))) } - fn on_initialize_bounties(b: u32, ) -> Weight { - (75_165_000 as Weight) - .saturating_add((73_634_000 as Weight).saturating_mul(b as Weight)) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(b as Weight))) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight))) - } - } // For backwards compatibility and tests impl WeightInfo for () { fn propose_spend() -> Weight { - (56_844_000 as Weight) + (59_986_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } fn reject_proposal() -> Weight { - (46_098_000 as Weight) + (48_300_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } fn approve_proposal() -> Weight { - (13_622_000 as Weight) + (14_054_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - - } - fn report_awesome(r: u32, ) -> Weight { - (71_823_000 as Weight) - .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn retract_tip() -> Weight { - (60_150_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn tip_new(r: u32, t: u32, ) -> Weight { - (46_522_000 as Weight) - .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) - .saturating_add((145_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn tip(t: u32, ) -> Weight { - (33_790_000 as Weight) - .saturating_add((713_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - - } - fn close_tip(t: u32, ) -> Weight { - (113_040_000 as Weight) - .saturating_add((375_000 as Weight).saturating_mul(t as Weight)) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - - } - fn propose_bounty(d: u32, ) -> Weight { - (60_887_000 as Weight) - .saturating_add((1_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - - } - fn approve_bounty() -> Weight { - (17_337_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn propose_curator() -> Weight { - (14_068_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - - } - fn unassign_curator() -> Weight { - (49_717_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn accept_curator() -> Weight { - (50_596_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - - } - fn award_bounty() -> Weight { - (36_030_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - - } - fn claim_bounty() -> Weight { - (167_088_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().writes(5 as Weight)) - - } - fn close_bounty_proposed() -> Weight { - (48_977_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - - } - fn close_bounty_active() -> Weight { - (110_959_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - - } - fn extend_bounty_expiry() -> Weight { - (34_987_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } fn on_initialize_proposals(p: u32, ) -> Weight { - (76_596_000 as Weight) - .saturating_add((73_988_000 as Weight).saturating_mul(p as Weight)) + (86_038_000 as Weight) + // Standard Error: 18_000 + .saturating_add((78_781_000 as Weight).saturating_mul(p as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(p as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(p as Weight))) } - fn on_initialize_bounties(b: u32, ) -> Weight { - (75_165_000 as Weight) - .saturating_add((73_634_000 as Weight).saturating_mul(b as Weight)) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(b as Weight))) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight))) - } - } -- GitLab From 032bd12b988c61d4de00619a5cd01c28bea403d0 Mon Sep 17 00:00:00 2001 From: Denis Pisarev Date: Thu, 17 Dec 2020 11:05:39 +0100 Subject: [PATCH 123/163] CI: buildah to build images (#7741) * CI: buildah to build images * CI: simplify variables * CI: whitespaces * CI: secure login --- .gitlab-ci.yml | 121 ++++++++----------------------------------------- 1 file changed, 20 insertions(+), 101 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 07b0dd319cf..62e438645e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,8 +24,6 @@ stages: - check - test - build - - chaos-env - - chaos - publish - deploy - flaming-fir @@ -399,12 +397,11 @@ build-linux-substrate: &build-binary <<: *collect-artifacts <<: *docker-env rules: - # .build-refs with manual on PRs and chaos + # .build-refs with manual on PRs - if: $CI_PIPELINE_SOURCE == "web" - if: $CI_COMMIT_REF_NAME == "master" - if: $CI_COMMIT_REF_NAME == "tags" - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - - if: $CI_COMMIT_MESSAGE =~ /\[chaos:(basic|medium|large)\]/ && $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # i.e add [chaos:basic] in commit message to trigger - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs when: manual allow_failure: true @@ -490,118 +487,40 @@ build-rust-doc: - echo "" > ./crate-docs/index.html - sccache -s -#### stage: chaos-env - -build-chaos-docker: - stage: chaos-env - rules: - # .build-refs with chaos - - if: $CI_PIPELINE_SOURCE == "web" - - if: $CI_COMMIT_REF_NAME == "master" - - if: $CI_COMMIT_REF_NAME == "tags" - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - - if: $CI_COMMIT_MESSAGE =~ /\[chaos:(basic|medium|large)\]/ && $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # i.e add [chaos:basic] in commit message to trigger - needs: - - job: build-linux-substrate - image: docker:stable - tags: - - kubernetes-parity-build - variables: - <<: *default-vars - DOCKER_HOST: tcp://localhost:2375 - DOCKER_DRIVER: overlay2 - PRODUCT: substrate - DOCKERFILE: $PRODUCT.Dockerfile - CONTAINER_IMAGE: paritypr/$PRODUCT - environment: - name: parity-simnet - services: - - docker:dind - before_script: - - test "$DOCKER_CHAOS_USER" -a "$DOCKER_CHAOS_TOKEN" - || ( echo "no docker credentials provided"; exit 1 ) - - docker login -u "$DOCKER_CHAOS_USER" -p "$DOCKER_CHAOS_TOKEN" - - docker info - script: - - cd ./artifacts/$PRODUCT/ - - VERSION="ci-${CI_COMMIT_SHORT_SHA}" - - echo "${PRODUCT} version = ${VERSION}" - - test -z "${VERSION}" && exit 1 - - docker build - --build-arg VCS_REF="${CI_COMMIT_SHA}" - --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" - --tag $CONTAINER_IMAGE:$VERSION - --file $DOCKERFILE . - - docker push $CONTAINER_IMAGE:$VERSION - after_script: - - docker logout - -#### stage: chaos - -chaos-test-singlenodeheight: - stage: chaos - rules: - # .build-refs with chaos - - if: $CI_PIPELINE_SOURCE == "web" - - if: $CI_COMMIT_REF_NAME == "master" - - if: $CI_COMMIT_REF_NAME == "tags" - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - - if: $CI_COMMIT_MESSAGE =~ /\[chaos:(basic|medium|large)\]/ && $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # i.e add [chaos:basic] in commit message to trigger - image: paritypr/simnet:latest - needs: - - job: build-chaos-docker - tags: - - parity-simnet - variables: - <<: *default-vars - PRODUCT: substrate - DOCKERFILE: $PRODUCT.Dockerfile - CONTAINER_IMAGE: paritypr/$PRODUCT - KEEP_NAMESPACE: 0 - NAMESPACE: "substrate-ci-${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_ID}" - VERSION: "ci-${CI_COMMIT_SHORT_SHA}" - interruptible: true - environment: - name: parity-simnet - script: - - simnet spawn dev -i $CONTAINER_IMAGE:$VERSION - - simnet singlenodeheight -h 30 - after_script: - - simnet clean - #### stage: publish .build-push-docker-image: &build-push-docker-image <<: *build-refs <<: *kubernetes-build - image: docker:stable - services: - - docker:dind + image: quay.io/buildah/stable variables: &docker-build-vars <<: *default-vars - DOCKER_HOST: tcp://localhost:2375 - DOCKER_DRIVER: overlay2 GIT_STRATEGY: none DOCKERFILE: $PRODUCT.Dockerfile - CONTAINER_IMAGE: parity/$PRODUCT + IMAGE_NAME: docker.io/parity/$PRODUCT before_script: - - test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" - || ( echo "no docker credentials provided"; exit 1 ) - - docker login -u "$Docker_Hub_User_Parity" -p "$Docker_Hub_Pass_Parity" - - docker info + - test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" || + ( echo "no docker credentials provided"; exit 1 ) script: - cd ./artifacts/$PRODUCT/ - VERSION="$(cat ./VERSION)" - echo "${PRODUCT} version = ${VERSION}" - test -z "${VERSION}" && exit 1 - - docker build + - buildah bud + --squash + --format=docker --build-arg VCS_REF="${CI_COMMIT_SHA}" --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" - --tag $CONTAINER_IMAGE:$VERSION - --tag $CONTAINER_IMAGE:latest - --file $DOCKERFILE . - - docker push $CONTAINER_IMAGE:$VERSION - - docker push $CONTAINER_IMAGE:latest + --tag "$IMAGE_NAME:$VERSION" + --tag "$IMAGE_NAME:latest" + --file "$DOCKERFILE" . + - echo "$Docker_Hub_Pass_Parity" | + buildah login --username "$Docker_Hub_User_Parity" --password-stdin docker.io + - buildah info + - buildah push + --format=v2s2 + "$IMAGE_NAME:$VERSION" + "$IMAGE_NAME:latest" publish-docker-substrate: stage: publish @@ -615,7 +534,7 @@ publish-docker-substrate: <<: *docker-build-vars PRODUCT: substrate after_script: - - docker logout + - buildah logout "$IMAGE_NAME" # only VERSION information is needed for the deployment - find ./artifacts/ -depth -not -name VERSION -type f -delete @@ -629,7 +548,7 @@ publish-docker-subkey: <<: *docker-build-vars PRODUCT: subkey after_script: - - docker logout + - buildah logout "$IMAGE_NAME" publish-s3-release: stage: publish -- GitLab From 2bc674a10957a3dd9ed30a5c1256e9134d9a5cab Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Thu, 17 Dec 2020 18:54:05 +0800 Subject: [PATCH 124/163] optimize arithmetic cargo path (#7745) --- primitives/arithmetic/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index b8e482491a7..c8f812215f4 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -20,7 +20,7 @@ integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } sp-std = { version = "2.0.0", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0", default-features = false, path = "../../primitives/debug-derive" } +sp-debug-derive = { version = "2.0.0", default-features = false, path = "../debug-derive" } [dev-dependencies] rand = "0.7.2" -- GitLab From fec28e120a240bcb69fdbe8fd08640335b379b59 Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Thu, 17 Dec 2020 20:00:26 +0800 Subject: [PATCH 125/163] optimize runtime-interface cargo path (#7729) --- primitives/runtime-interface/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 180914e89dd..b8ad0c1261e 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -27,7 +27,7 @@ impl-trait-for-tuples = "0.1.3" [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0", path = "test-wasm" } -sp-state-machine = { version = "0.8.0", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", path = "../state-machine" } sp-core = { version = "2.0.0", path = "../core" } sp-io = { version = "2.0.0", path = "../io" } rustversion = "1.0.0" -- GitLab From ad054e6452f4762d33b3e6e7cd32a8dbb4c3ae29 Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Fri, 18 Dec 2020 01:11:07 +0800 Subject: [PATCH 126/163] delete primitives in Cargo in primitives (#7751) --- primitives/api/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 4 ++-- primitives/application-crypto/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- primitives/io/Cargo.toml | 6 +++--- primitives/npos-elections/Cargo.toml | 2 +- primitives/runtime-interface/test/Cargo.toml | 2 +- primitives/runtime/Cargo.toml | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index 92bf9bea2bd..97f9618fe56 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -19,7 +19,7 @@ sp-core = { version = "2.0.0", default-features = false, path = "../core" } sp-std = { version = "2.0.0", default-features = false, path = "../std" } sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } sp-version = { version = "2.0.0", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", optional = true, path = "../state-machine" } hash-db = { version = "0.15.2", optional = true } thiserror = { version = "1.0.21", optional = true } diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 1110b02020b..f3f698e0ccb 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -17,10 +17,10 @@ substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils sp-version = { version = "2.0.0", path = "../../version" } sp-runtime = { version = "2.0.0", path = "../../runtime" } sp-blockchain = { version = "2.0.0", path = "../../blockchain" } -sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } +sp-consensus = { version = "0.8.0", path = "../../consensus/common" } sc-block-builder = { version = "0.8.0", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.3.1" } -sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", path = "../../state-machine" } trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } rustversion = "1.0.0" diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 2ab68237595..47776d80911 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -19,7 +19,7 @@ sp-core = { version = "2.0.0", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0", default-features = false, path = "../std" } -sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-io = { version = "2.0.0", default-features = false, path = "../io" } [features] default = [ "std" ] diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index dc1550ed295..642e047223b 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -20,7 +20,7 @@ libp2p = { version = "0.32.2", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } -sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", path = "../../state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" sp-std = { version = "2.0.0", path = "../../std" } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index e470461d60b..e65d75146d6 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -21,10 +21,10 @@ sp-core = { version = "2.0.0", default-features = false, path = "../core" } sp-keystore = { version = "0.8.0", default-features = false, optional = true, path = "../keystore" } sp-std = { version = "2.0.0", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0", path = "../../primitives/wasm-interface", default-features = false } +sp-state-machine = { version = "0.8.0", optional = true, path = "../state-machine" } +sp-wasm-interface = { version = "2.0.0", path = "../wasm-interface", default-features = false } sp-runtime-interface = { version = "2.0.0", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0", optional = true, path = "../../primitives/trie" } +sp-trie = { version = "2.0.0", optional = true, path = "../trie" } sp-externalities = { version = "0.8.0", optional = true, path = "../externalities" } sp-tracing = { version = "2.0.0", default-features = false, path = "../tracing" } log = { version = "0.4.8", optional = true } diff --git a/primitives/npos-elections/Cargo.toml b/primitives/npos-elections/Cargo.toml index 4a66743028d..44bcb2af875 100644 --- a/primitives/npos-elections/Cargo.toml +++ b/primitives/npos-elections/Cargo.toml @@ -22,7 +22,7 @@ sp-arithmetic = { version = "2.0.0", default-features = false, path = "../arithm [dev-dependencies] substrate-test-utils = { version = "2.0.0", path = "../../test-utils" } rand = "0.7.3" -sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0", path = "../runtime" } [features] default = ["std"] diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index d6da3db4b69..fb000166ac5 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -16,7 +16,7 @@ sp-runtime-interface = { version = "2.0.0", path = "../" } sc-executor = { version = "0.8.0", path = "../../../client/executor" } sp-runtime-interface-test-wasm = { version = "2.0.0", path = "../test-wasm" } sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0", path = "../test-wasm-deprecated" } -sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", path = "../../state-machine" } sp-runtime = { version = "2.0.0", path = "../../runtime" } sp-core = { version = "2.0.0", path = "../../core" } sp-io = { version = "2.0.0", path = "../../io" } diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 9c3286cd475..0ad05561581 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -33,7 +33,7 @@ either = { version = "1.5", default-features = false } [dev-dependencies] serde_json = "1.0.41" rand = "0.7.2" -sp-state-machine = { version = "0.8.0", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0", path = "../state-machine" } [features] bench = [] -- GitLab From 36d64331b90ab8096dff22390121cb64cd96e5b3 Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Fri, 18 Dec 2020 01:12:27 +0800 Subject: [PATCH 127/163] delete client in Cargo in client (#7752) --- client/basic-authorship/Cargo.toml | 2 +- client/consensus/aura/Cargo.toml | 2 +- client/finality-grandpa/Cargo.toml | 2 +- client/network/test/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- client/rpc/Cargo.toml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index f097d8044f6..c5a67c0a643 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -31,6 +31,6 @@ sc-block-builder = { version = "0.8.0", path = "../block-builder" } sc-proposer-metrics = { version = "0.8.0", path = "../proposer-metrics" } [dev-dependencies] -sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0", path = "../transaction-pool" } substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index ccc4d515a8e..c240fa4cb4d 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-application-crypto = { version = "2.0.0", path = "../../../primitives/application-crypto" } sp-consensus-aura = { version = "0.8.0", path = "../../../primitives/consensus/aura" } sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0", path = "../../../client/block-builder" } +sc-block-builder = { version = "0.8.0", path = "../../block-builder" } sc-client-api = { version = "2.0.0", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.3.4" } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 8966f5e8f65..d19fc18b22b 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -28,7 +28,7 @@ sp-arithmetic = { version = "2.0.0", path = "../../primitives/arithmetic" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } sp-utils = { version = "2.0.0", path = "../../primitives/utils" } sp-consensus = { version = "0.8.0", path = "../../primitives/consensus/common" } -sc-consensus = { version = "0.8.0", path = "../../client/consensus/common" } +sc-consensus = { version = "0.8.0", path = "../consensus/common" } sp-core = { version = "2.0.0", path = "../../primitives/core" } sp-keystore = { version = "0.8.0", path = "../../primitives/keystore" } sp-api = { version = "2.0.0", path = "../../primitives/api" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 880e2c1f04e..d3036742f17 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -21,7 +21,7 @@ futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.32.2", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } -sc-consensus = { version = "0.8.0", path = "../../../client/consensus/common" } +sc-consensus = { version = "0.8.0", path = "../../consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 1a31d278eb5..5c561105f02 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -38,7 +38,7 @@ hyper-rustls = "0.21.0" [dev-dependencies] sc-client-db = { version = "0.8.0", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0", path = "../transaction-pool" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" } substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index e68ac6e4e91..e02d88f158b 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -33,11 +33,11 @@ sp-keystore = { version = "0.8.0", path = "../../primitives/keystore" } sp-state-machine = { version = "0.8.0", path = "../../primitives/state-machine" } sp-chain-spec = { version = "2.0.0", path = "../../primitives/chain-spec" } sc-executor = { version = "0.8.0", path = "../executor" } -sc-block-builder = { version = "0.8.0", path = "../../client/block-builder" } +sc-block-builder = { version = "0.8.0", path = "../block-builder" } sc-keystore = { version = "2.0.0", path = "../keystore" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } -sc-tracing = { version = "2.0.0", path = "../../client/tracing" } +sc-tracing = { version = "2.0.0", path = "../tracing" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" lazy_static = { version = "1.4.0", optional = true } -- GitLab From 039d3ffa69dcd613a5b18535e129f3ce4b276ffc Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 17 Dec 2020 22:17:57 +0000 Subject: [PATCH 128/163] prevent too many genesis council members (#7749) * Prevent too many genesis members in elections-phragmen. * Fix test. * reformat.' --- frame/elections-phragmen/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index db2428971cc..b541303f651 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -213,6 +213,10 @@ decl_storage! { } add_extra_genesis { config(members): Vec<(T::AccountId, BalanceOf)>; build(|config: &GenesisConfig| { + assert!( + config.members.len() as u32 <= T::DesiredMembers::get(), + "Cannot accept more than DesiredMembers genesis member", + ); let members = config.members.iter().map(|(ref member, ref stake)| { // make sure they have enough stake assert!( @@ -1442,10 +1446,20 @@ mod tests { #[should_panic = "Duplicate member in elections phragmen genesis: 2"] fn genesis_members_cannot_be_duplicate() { ExtBuilder::default() + .desired_members(3) .genesis_members(vec![(1, 10), (2, 10), (2, 10)]) .build_and_execute(|| {}); } + #[test] + #[should_panic = "Cannot accept more than DesiredMembers genesis member"] + fn genesis_members_cannot_too_many() { + ExtBuilder::default() + .genesis_members(vec![(1, 10), (2, 10), (3, 30)]) + .desired_members(2) + .build_and_execute(|| {}); + } + #[test] fn term_duration_zero_is_passive() { ExtBuilder::default() -- GitLab From 330f5c0dbfdf4ffbb891251e90880757687a8a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 18 Dec 2020 12:04:17 +0100 Subject: [PATCH 129/163] Update common block in sync after importing blocks of a peer, please read UPDATE (#7733) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update common block in sync after importing blocks of a peer This updates the sync code to update the common block of a peer, after we have imported blocks from this peer. This fixes a bug for when we are connected to one or more nodes that are doing a full sync as our node. Nodes in full sync will not announce new blocks, as we don't send import notifications on full sync. The problem as now that we were connected to some peer that reported some low number as its best and we tried to sync these blocks. But, as we did not update the common block of this peer, we would sync these blocks over and over again. Being captured in some time warp. The solution to this problem is that we increase the common number as we import blocks from this peer. * Test * Test name.. * Fix test * Cleanup some code and write some new regression test * Implement the ancestor search * Check that the common number is smaller than the last finalized block * Update client/network/src/protocol/sync.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/network/src/protocol/sync.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/network/src/protocol/sync.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Change the way we build the status messages * Start some new test... * Finish test * Rename test * Update client/network/src/protocol.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> --- client/network/src/protocol.rs | 54 +- client/network/src/protocol/sync.rs | 550 +++++++++++++++--- .../src/protocol/sync/extra_requests.rs | 5 +- client/network/test/src/block_import.rs | 2 +- client/network/test/src/lib.rs | 2 + client/network/test/src/sync.rs | 36 +- .../consensus/common/src/import_queue.rs | 4 +- 7 files changed, 546 insertions(+), 107 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 41326b6d82a..1a67aec57ab 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -307,27 +307,35 @@ struct BlockAnnouncesHandshake { } impl BlockAnnouncesHandshake { - fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self { - let info = chain.info(); + fn build( + protocol_config: &ProtocolConfig, + best_number: NumberFor, + best_hash: B::Hash, + genesis_hash: B::Hash, + ) -> Self { BlockAnnouncesHandshake { - genesis_hash: info.genesis_hash, + genesis_hash, roles: protocol_config.roles, - best_number: info.best_number, - best_hash: info.best_hash, + best_number, + best_hash, } } } /// Builds a SCALE-encoded "Status" message to send as handshake for the legacy protocol. -fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec { - let info = chain.info(); +fn build_status_message( + protocol_config: &ProtocolConfig, + best_number: NumberFor, + best_hash: B::Hash, + genesis_hash: B::Hash, +) -> Vec { let status = message::generic::Status { version: CURRENT_VERSION, min_supported_version: MIN_VERSION, - genesis_hash: info.genesis_hash, + genesis_hash, roles: protocol_config.roles.into(), - best_number: info.best_number, - best_hash: info.best_hash, + best_number, + best_hash, chain_status: Vec::new(), // TODO: find a way to make this backwards-compatible }; @@ -400,12 +408,22 @@ impl Protocol { let behaviour = { let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); - let block_announces_handshake = BlockAnnouncesHandshake::build(&config, &chain).encode(); + + let best_number = info.best_number; + let best_hash = info.best_hash; + let genesis_hash = info.genesis_hash; + + let block_announces_handshake = BlockAnnouncesHandshake::::build( + &config, + best_number, + best_hash, + genesis_hash, + ).encode(); GenericProto::new( local_peer_id, protocol_id.clone(), versions, - build_status_message(&config, &chain), + build_status_message::(&config, best_number, best_hash, genesis_hash), peerset, // As documented in `GenericProto`, the first protocol in the list is always the // one carrying the handshake reported in the `CustomProtocolOpen` event. @@ -528,13 +546,21 @@ impl Protocol { /// Inform sync about new best imported block. pub fn new_best_block_imported(&mut self, hash: B::Hash, number: NumberFor) { + trace!(target: "sync", "New best block imported {:?}/#{}", hash, number); + self.sync.update_chain_info(&hash, number); + self.behaviour.set_legacy_handshake_message( - build_status_message(&self.config, &self.context_data.chain), + build_status_message::(&self.config, number, hash, self.genesis_hash), ); self.behaviour.set_notif_protocol_handshake( &self.block_announces_protocol, - BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() + BlockAnnouncesHandshake::::build( + &self.config, + number, + hash, + self.genesis_hash, + ).encode() ); } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 1ff8d37afec..712c1300288 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -67,6 +67,10 @@ const MAX_IMPORTING_BLOCKS: usize = 2048; /// Maximum blocks to download ahead of any gap. const MAX_DOWNLOAD_AHEAD: u32 = 2048; +/// Maximum blocks to look backwards. The gap is the difference between the highest block and the +/// common block of a node. +const MAX_BLOCKS_TO_LOOK_BACKWARDS: u32 = MAX_DOWNLOAD_AHEAD / 2; + /// Maximum number of concurrent block announce validations. /// /// If the queue reaches the maximum, we drop any new block @@ -211,6 +215,8 @@ pub struct ChainSync { /// All the data we have about a Peer that we are trying to sync with #[derive(Debug, Clone)] pub struct PeerSync { + /// Peer id of this peer. + pub peer_id: PeerId, /// The common number is the block number that is a common point of /// ancestry for both our chains (as far as we know). pub common_number: NumberFor, @@ -223,6 +229,22 @@ pub struct PeerSync { pub state: PeerSyncState, } +impl PeerSync { + /// Update the `common_number` iff `new_common > common_number`. + fn update_common_number(&mut self, new_common: NumberFor) { + if self.common_number < new_common { + trace!( + target: "sync", + "Updating peer {} common number from={} => to={}.", + self.peer_id, + self.common_number, + new_common, + ); + self.common_number = new_common; + } + } +} + /// The sync status of a peer we are trying to sync with #[derive(Debug)] pub struct PeerInfo { @@ -264,11 +286,7 @@ pub enum PeerSyncState { impl PeerSyncState { pub fn is_available(&self) -> bool { - if let PeerSyncState::Available = self { - true - } else { - false - } + matches!(self, Self::Available) } } @@ -315,6 +333,18 @@ pub enum OnBlockData { Request(PeerId, BlockRequest) } +impl OnBlockData { + /// Returns `self` as request. + #[cfg(test)] + fn into_request(self) -> Option<(PeerId, BlockRequest)> { + if let Self::Request(peer, req) = self { + Some((peer, req)) + } else { + None + } + } +} + /// Result of [`ChainSync::poll_block_announce_validation`]. #[derive(Debug, Clone, PartialEq, Eq)] pub enum PollBlockAnnounceValidation { @@ -512,7 +542,8 @@ impl ChainSync { self.best_queued_hash, self.best_queued_number ); - self.peers.insert(who, PeerSync { + self.peers.insert(who.clone(), PeerSync { + peer_id: who, common_number: self.best_queued_number, best_hash, best_number, @@ -522,43 +553,55 @@ impl ChainSync { } // If we are at genesis, just start downloading. - if self.best_queued_number.is_zero() { - debug!(target:"sync", "New peer with best hash {} ({}).", best_hash, best_number); - self.peers.insert(who.clone(), PeerSync { - common_number: Zero::zero(), + let (state, req) = if self.best_queued_number.is_zero() { + debug!( + target:"sync", + "New peer with best hash {} ({}).", best_hash, best_number, - state: PeerSyncState::Available, - }); - self.pending_requests.add(&who); - return Ok(None) - } + ); - let common_best = std::cmp::min(self.best_queued_number, best_number); + (PeerSyncState::Available, None) + } else { + let common_best = std::cmp::min(self.best_queued_number, best_number); - debug!(target:"sync", - "New peer with unknown best hash {} ({}), searching for common ancestor.", - best_hash, - best_number - ); + debug!( + target:"sync", + "New peer with unknown best hash {} ({}), searching for common ancestor.", + best_hash, + best_number + ); + + ( + PeerSyncState::AncestorSearch { + current: common_best, + start: self.best_queued_number, + state: AncestorSearchState::ExponentialBackoff(One::one()), + }, + Some(ancestry_request::(common_best)) + ) + }; self.pending_requests.add(&who); - self.peers.insert(who, PeerSync { + self.peers.insert(who.clone(), PeerSync { + peer_id: who, common_number: Zero::zero(), best_hash, best_number, - state: PeerSyncState::AncestorSearch { - current: common_best, - start: self.best_queued_number, - state: AncestorSearchState::ExponentialBackoff(One::one()), - }, + state, }); - Ok(Some(ancestry_request::(common_best))) + Ok(req) } Ok(BlockStatus::Queued) | Ok(BlockStatus::InChainWithState) | Ok(BlockStatus::InChainPruned) => { - debug!(target:"sync", "New peer with known best hash {} ({}).", best_hash, best_number); + debug!( + target: "sync", + "New peer with known best hash {} ({}).", + best_hash, + best_number, + ); self.peers.insert(who.clone(), PeerSync { + peer_id: who.clone(), common_number: best_number, best_hash, best_number, @@ -687,7 +730,21 @@ impl ChainSync { return None } - if let Some((range, req)) = peer_block_request( + // If our best queued is more than `MAX_BLOCKS_TO_LOOK_BACKWARDS` blocks away from the + // common number, the peer best number is higher than our best queued and the common + // number is smaller than the last finalized block number, we should do an ancestor + // search to find a better common block. + if best_queued.saturating_sub(peer.common_number) > MAX_BLOCKS_TO_LOOK_BACKWARDS.into() + && best_queued < peer.best_number && peer.common_number < last_finalized + { + let current = std::cmp::min(peer.best_number, best_queued); + peer.state = PeerSyncState::AncestorSearch { + current, + start: best_queued, + state: AncestorSearchState::ExponentialBackoff(One::one()), + }; + Some((id, ancestry_request::(current))) + } else if let Some((range, req)) = peer_block_request( id, peer, blocks, @@ -795,15 +852,29 @@ impl ChainSync { PeerSyncState::AncestorSearch { current, start, state } => { let matching_hash = match (blocks.get(0), self.client.hash(*current)) { (Some(block), Ok(maybe_our_block_hash)) => { - trace!(target: "sync", "Got ancestry block #{} ({}) from peer {}", current, block.hash, who); + trace!( + target: "sync", + "Got ancestry block #{} ({}) from peer {}", + current, + block.hash, + who, + ); maybe_our_block_hash.filter(|x| x == &block.hash) }, (None, _) => { - debug!(target: "sync", "Invalid response when searching for ancestor from {}", who); + debug!( + target: "sync", + "Invalid response when searching for ancestor from {}", + who, + ); return Err(BadPeer(who.clone(), rep::UNKNOWN_ANCESTOR)) }, (_, Err(e)) => { - info!("❌ Error answering legitimate blockchain query: {:?}", e); + info!( + target: "sync", + "❌ Error answering legitimate blockchain query: {:?}", + e, + ); return Err(BadPeer(who.clone(), rep::BLOCKCHAIN_READ_ERROR)) } }; @@ -822,17 +893,23 @@ impl ChainSync { trace!(target:"sync", "Ancestry search: genesis mismatch for peer {}", who); return Err(BadPeer(who.clone(), rep::GENESIS_MISMATCH)) } - if let Some((next_state, next_num)) = handle_ancestor_search_state(state, *current, matching_hash.is_some()) { + if let Some((next_state, next_num)) = + handle_ancestor_search_state(state, *current, matching_hash.is_some()) + { peer.state = PeerSyncState::AncestorSearch { current: next_num, start: *start, state: next_state, }; - return Ok(OnBlockData::Request(who.clone(), ancestry_request::(next_num))) + return Ok( + OnBlockData::Request(who.clone(), ancestry_request::(next_num)) + ) } else { // Ancestry search is complete. Check if peer is on a stale fork unknown to us and // add it to sync targets if necessary. - trace!(target: "sync", "Ancestry search complete. Ours={} ({}), Theirs={} ({}), Common={:?} ({})", + trace!( + target: "sync", + "Ancestry search complete. Ours={} ({}), Theirs={} ({}), Common={:?} ({})", self.best_queued_hash, self.best_queued_number, peer.best_hash, @@ -843,7 +920,12 @@ impl ChainSync { if peer.common_number < peer.best_number && peer.best_number < self.best_queued_number { - trace!(target: "sync", "Added fork target {} for {}" , peer.best_hash, who); + trace!( + target: "sync", + "Added fork target {} for {}", + peer.best_hash, + who, + ); self.fork_targets .entry(peer.best_hash.clone()) .or_insert_with(|| ForkTarget { @@ -991,7 +1073,11 @@ impl ChainSync { } match result { - Ok(BlockImportResult::ImportedKnown(_number)) => {} + Ok(BlockImportResult::ImportedKnown(number, who)) => { + if let Some(peer) = who.and_then(|p| self.peers.get_mut(&p)) { + peer.update_common_number(number); + } + } Ok(BlockImportResult::ImportedUnknown(number, aux, who)) => { if aux.clear_justification_requests { trace!( @@ -1004,38 +1090,61 @@ impl ChainSync { } if aux.needs_justification { - trace!(target: "sync", "Block imported but requires justification {}: {:?}", number, hash); + trace!( + target: "sync", + "Block imported but requires justification {}: {:?}", + number, + hash, + ); self.request_justification(&hash, number); } if aux.bad_justification { - if let Some(peer) = who { + if let Some(ref peer) = who { info!("💔 Sent block with bad justification to import"); - output.push(Err(BadPeer(peer, rep::BAD_JUSTIFICATION))); + output.push(Err(BadPeer(peer.clone(), rep::BAD_JUSTIFICATION))); } } if number > self.best_imported_number { self.best_imported_number = number; } + + if let Some(peer) = who.and_then(|p| self.peers.get_mut(&p)) { + peer.update_common_number(number); + } }, Err(BlockImportError::IncompleteHeader(who)) => { if let Some(peer) = who { - warn!("💔 Peer sent block with incomplete header to import"); + warn!( + target: "sync", + "💔 Peer sent block with incomplete header to import", + ); output.push(Err(BadPeer(peer, rep::INCOMPLETE_HEADER))); output.extend(self.restart()); } }, Err(BlockImportError::VerificationFailed(who, e)) => { if let Some(peer) = who { - warn!("💔 Verification failed for block {:?} received from peer: {}, {:?}", hash, peer, e); + warn!( + target: "sync", + "💔 Verification failed for block {:?} received from peer: {}, {:?}", + hash, + peer, + e, + ); output.push(Err(BadPeer(peer, rep::VERIFICATION_FAIL))); output.extend(self.restart()); } }, Err(BlockImportError::BadBlock(who)) => { if let Some(peer) = who { - info!("💔 Block {:?} received from peer {} has been blacklisted", hash, peer); + info!( + target: "sync", + "💔 Block {:?} received from peer {} has been blacklisted", + hash, + peer, + ); output.push(Err(BadPeer(peer, rep::BAD_BLOCK))); } }, @@ -1074,7 +1183,11 @@ impl ChainSync { }); if let Err(err) = r { - warn!(target: "sync", "💔 Error cleaning up pending extra justification data requests: {:?}", err); + warn!( + target: "sync", + "💔 Error cleaning up pending extra justification data requests: {:?}", + err, + ); } } @@ -1279,6 +1392,12 @@ impl ChainSync { &mut self, pre_validation_result: PreValidateBlockAnnounce, ) -> PollBlockAnnounceValidation { + trace!( + target: "sync", + "Finished block announce validation: {:?}", + pre_validation_result, + ); + let (announce, is_best, who) = match pre_validation_result { PreValidateBlockAnnounce::Nothing { is_best, who, announce } => { self.peer_block_announce_validation_finished(&who); @@ -1316,6 +1435,7 @@ impl ChainSync { } if let PeerSyncState::AncestorSearch {..} = peer.state { + trace!(target: "sync", "Peer state is ancestor search."); return PollBlockAnnounceValidation::Nothing { is_best, who, header } } @@ -1323,11 +1443,11 @@ impl ChainSync { // is either one further ahead or it's the one they just announced, if we know about it. if is_best { if known && self.best_queued_number >= number { - peer.common_number = number + peer.update_common_number(number); } else if header.parent_hash() == &self.best_queued_hash || known_parent && self.best_queued_number >= number { - peer.common_number = number - One::one(); + peer.update_common_number(number - One::one()); } } self.pending_requests.add(&who); @@ -1367,6 +1487,7 @@ impl ChainSync { .peers.insert(who.clone()); } + trace!(target: "sync", "Announce validation result is nothing"); PollBlockAnnounceValidation::Nothing { is_best, who, header } } @@ -1485,7 +1606,7 @@ pub enum AncestorSearchState { fn handle_ancestor_search_state( state: &AncestorSearchState, curr_block_num: NumberFor, - block_hash_match: bool + block_hash_match: bool, ) -> Option<(AncestorSearchState, NumberFor)> { let two = >::one() + >::one(); match state { @@ -1536,44 +1657,41 @@ fn peer_block_request( if best_num >= peer.best_number { // Will be downloaded as alternative fork instead. return None; - } - if peer.common_number < finalized { + } else if peer.common_number < finalized { trace!( target: "sync", "Requesting pre-finalized chain from {:?}, common={}, finalized={}, peer best={}, our best={}", id, peer.common_number, finalized, peer.best_number, best_num, ); } - if let Some(range) = blocks.needed_blocks( + let range = blocks.needed_blocks( id.clone(), MAX_BLOCKS_TO_REQUEST, peer.best_number, peer.common_number, max_parallel_downloads, MAX_DOWNLOAD_AHEAD, - ) { - // The end is not part of the range. - let last = range.end.saturating_sub(One::one()); + )?; - let from = if peer.best_number == last { - message::FromBlock::Hash(peer.best_hash) - } else { - message::FromBlock::Number(last) - }; + // The end is not part of the range. + let last = range.end.saturating_sub(One::one()); - let request = message::generic::BlockRequest { - id: 0, - fields: attrs.clone(), - from, - to: None, - direction: message::Direction::Descending, - max: Some((range.end - range.start).saturated_into::()) - }; - - Some((range, request)) + let from = if peer.best_number == last { + message::FromBlock::Hash(peer.best_hash) } else { - None - } + message::FromBlock::Number(last) + }; + + let request = message::generic::BlockRequest { + id: 0, + fields: attrs.clone(), + from, + to: None, + direction: message::Direction::Descending, + max: Some((range.end - range.start).saturated_into::()) + }; + + Some((range, request)) } /// Get pending fork sync targets for a peer. @@ -1750,7 +1868,7 @@ mod test { use substrate_test_runtime_client::{ runtime::{Block, Hash, Header}, ClientBlockImportExt, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, - BlockBuilderExt, + BlockBuilderExt, TestClient, ClientExt, }; use futures::{future::poll_fn, executor::block_on}; @@ -1948,11 +2066,14 @@ mod test { /// Get a block request from `sync` and check that is matches the expected request. fn get_block_request( sync: &mut ChainSync, - from: message::FromBlock, + from: FromBlock, max: u32, peer: &PeerId, ) -> BlockRequest { let requests = sync.block_requests().collect::>(); + + log::trace!(target: "sync", "Requests: {:?}", requests); + assert_eq!(1, requests.len()); assert_eq!(peer, requests[0].0); @@ -1963,6 +2084,26 @@ mod test { request } + /// Build and import a new best block. + fn build_block(client: &mut Arc, at: Option, fork: bool) -> Block { + let at = at.unwrap_or_else(|| client.info().best_hash); + + let mut block_builder = client.new_block_at( + &BlockId::Hash(at), + Default::default(), + false, + ).unwrap(); + + if fork { + block_builder.push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])).unwrap(); + } + + let block = block_builder.build().unwrap().block; + + client.import(BlockOrigin::Own, block.clone()).unwrap(); + block + } + /// This test is a regression test as observed on a real network. /// /// The node is connected to multiple peers. Both of these peers are having a best block (1) that @@ -1990,14 +2131,6 @@ mod test { let peer_id1 = PeerId::random(); let peer_id2 = PeerId::random(); - let mut client2 = client.clone(); - let mut build_block = || { - let block = client2.new_block(Default::default()).unwrap().build().unwrap().block; - client2.import(BlockOrigin::Own, block.clone()).unwrap(); - - block - }; - let mut client2 = client.clone(); let mut build_block_at = |at, import| { let mut block_builder = client2.new_block_at(&BlockId::Hash(at), Default::default(), false) @@ -2014,9 +2147,9 @@ mod test { block }; - let block1 = build_block(); - let block2 = build_block(); - let block3 = build_block(); + let block1 = build_block(&mut client, None, false); + let block2 = build_block(&mut client, None, false); + let block3 = build_block(&mut client, None, false); let block3_fork = build_block_at(block2.hash(), false); // Add two peers which are on block 1. @@ -2073,4 +2206,253 @@ mod test { // Nothing to import assert!(matches!(res, OnBlockData::Import(_, blocks) if blocks.is_empty())); } + + fn unwrap_from_block_number(from: FromBlock) -> u64 { + if let FromBlock::Number(from) = from { + from + } else { + panic!("Expected a number!"); + } + } + + /// A regression test for a behavior we have seen on a live network. + /// + /// The scenario is that the node is doing a full resync and is connected to some node that is + /// doing a major sync as well. This other node that is doing a major sync will finish before + /// our node and send a block announcement message, but we don't have seen any block announcement + /// from this node in its sync process. Meaning our common number didn't change. It is now expected + /// that we start an ancestor search to find the common number. + #[test] + fn do_ancestor_search_when_common_block_to_best_qeued_gap_is_to_big() { + sp_tracing::try_init_simple(); + + let blocks = { + let mut client = Arc::new(TestClientBuilder::new().build()); + (0..MAX_DOWNLOAD_AHEAD * 2).map(|_| build_block(&mut client, None, false)).collect::>() + }; + + let mut client = Arc::new(TestClientBuilder::new().build()); + let info = client.info(); + + let mut sync = ChainSync::new( + Roles::AUTHORITY, + client.clone(), + &info, + Box::new(DefaultBlockAnnounceValidator), + 5, + ); + + let peer_id1 = PeerId::random(); + let peer_id2 = PeerId::random(); + + let best_block = blocks.last().unwrap().clone(); + // Connect the node we will sync from + sync.new_peer(peer_id1.clone(), best_block.hash(), *best_block.header().number()).unwrap(); + sync.new_peer(peer_id2.clone(), info.best_hash, 0).unwrap(); + + let mut best_block_num = 0; + while best_block_num < MAX_DOWNLOAD_AHEAD { + let request = get_block_request( + &mut sync, + FromBlock::Number(MAX_BLOCKS_TO_REQUEST as u64 + best_block_num as u64), + MAX_BLOCKS_TO_REQUEST as u32, + &peer_id1, + ); + + let from = unwrap_from_block_number(request.from.clone()); + + let mut resp_blocks = blocks[best_block_num as usize..from as usize].to_vec(); + resp_blocks.reverse(); + + let response = create_block_response(resp_blocks.clone()); + + let res = sync.on_block_data(&peer_id1, Some(request), response).unwrap(); + assert!( + matches!( + res, + OnBlockData::Import(_, blocks) if blocks.len() == MAX_BLOCKS_TO_REQUEST + ), + ); + + best_block_num += MAX_BLOCKS_TO_REQUEST as u32; + + resp_blocks.into_iter() + .rev() + .for_each(|b| client.import_as_final(BlockOrigin::Own, b).unwrap()); + } + + // Let peer2 announce that it finished syncing + send_block_announce(best_block.header().clone(), &peer_id2, &mut sync); + + let (peer1_req, peer2_req) = sync.block_requests().fold((None, None), |res, req| { + if req.0 == &peer_id1 { + (Some(req.1), res.1) + } else if req.0 == &peer_id2 { + (res.0, Some(req.1)) + } else { + panic!("Unexpected req: {:?}", req) + } + }); + + // We should now do an ancestor search to find the correct common block. + let peer2_req = peer2_req.unwrap(); + assert_eq!(Some(1), peer2_req.max); + assert_eq!(FromBlock::Number(best_block_num as u64), peer2_req.from); + + let response = create_block_response(vec![blocks[(best_block_num - 1) as usize].clone()]); + let res = sync.on_block_data(&peer_id2, Some(peer2_req), response).unwrap(); + assert!( + matches!( + res, + OnBlockData::Import(_, blocks) if blocks.is_empty() + ), + ); + + let peer1_from = unwrap_from_block_number(peer1_req.unwrap().from); + + // As we are on the same chain, we should directly continue with requesting blocks from + // peer 2 as well. + get_block_request( + &mut sync, + FromBlock::Number(peer1_from + MAX_BLOCKS_TO_REQUEST as u64), + MAX_BLOCKS_TO_REQUEST as u32, + &peer_id2, + ); + } + + /// A test that ensures that we can sync a huge fork. + /// + /// The following scenario: + /// A peer connects to us and we both have the common block 512. The last finalized is 2048. + /// Our best block is 4096. The peer send us a block announcement with 4097 from a fork. + /// + /// We will first do an ancestor search to find the common block. After that we start to sync + /// the fork and finish it ;) + #[test] + fn can_sync_huge_fork() { + sp_tracing::try_init_simple(); + + let mut client = Arc::new(TestClientBuilder::new().build()); + let blocks = (0..MAX_BLOCKS_TO_LOOK_BACKWARDS * 4) + .map(|_| build_block(&mut client, None, false)) + .collect::>(); + + let fork_blocks = { + let mut client = Arc::new(TestClientBuilder::new().build()); + let fork_blocks = blocks[..MAX_BLOCKS_TO_LOOK_BACKWARDS as usize * 2] + .into_iter() + .inspect(|b| client.import(BlockOrigin::Own, (*b).clone()).unwrap()) + .cloned() + .collect::>(); + + fork_blocks.into_iter().chain( + (0..MAX_BLOCKS_TO_LOOK_BACKWARDS * 2 + 1) + .map(|_| build_block(&mut client, None, true)) + ).collect::>() + }; + + let info = client.info(); + + let mut sync = ChainSync::new( + Roles::AUTHORITY, + client.clone(), + &info, + Box::new(DefaultBlockAnnounceValidator), + 5, + ); + + let finalized_block = blocks[MAX_BLOCKS_TO_LOOK_BACKWARDS as usize * 2 - 1].clone(); + client.finalize_block(BlockId::Hash(finalized_block.hash()), Some(Vec::new())).unwrap(); + sync.update_chain_info(&info.best_hash, info.best_number); + + let peer_id1 = PeerId::random(); + + let common_block = blocks[MAX_BLOCKS_TO_LOOK_BACKWARDS as usize / 2].clone(); + // Connect the node we will sync from + sync.new_peer(peer_id1.clone(), common_block.hash(), *common_block.header().number()).unwrap(); + + send_block_announce(fork_blocks.last().unwrap().header().clone(), &peer_id1, &mut sync); + + let mut request = get_block_request( + &mut sync, + FromBlock::Number(info.best_number), + 1, + &peer_id1, + ); + + // Do the ancestor search + loop { + let block = &fork_blocks[unwrap_from_block_number(request.from.clone()) as usize - 1]; + let response = create_block_response(vec![block.clone()]); + + let on_block_data = sync.on_block_data(&peer_id1, Some(request), response).unwrap(); + request = match on_block_data.into_request() { + Some(req) => req.1, + // We found the ancenstor + None => break, + }; + + log::trace!(target: "sync", "Request: {:?}", request); + } + + // Now request and import the fork. + let mut best_block_num = finalized_block.header().number().clone() as u32; + while best_block_num < *fork_blocks.last().unwrap().header().number() as u32 - 1 { + let request = get_block_request( + &mut sync, + FromBlock::Number(MAX_BLOCKS_TO_REQUEST as u64 + best_block_num as u64), + MAX_BLOCKS_TO_REQUEST as u32, + &peer_id1, + ); + + let from = unwrap_from_block_number(request.from.clone()); + + let mut resp_blocks = fork_blocks[best_block_num as usize..from as usize].to_vec(); + resp_blocks.reverse(); + + let response = create_block_response(resp_blocks.clone()); + + let res = sync.on_block_data(&peer_id1, Some(request), response).unwrap(); + assert!( + matches!( + res, + OnBlockData::Import(_, blocks) if blocks.len() == MAX_BLOCKS_TO_REQUEST + ), + ); + + best_block_num += MAX_BLOCKS_TO_REQUEST as u32; + + let _ = sync.on_blocks_processed( + MAX_BLOCKS_TO_REQUEST as usize, + MAX_BLOCKS_TO_REQUEST as usize, + resp_blocks.iter() + .rev() + .map(|b| + ( + Ok( + BlockImportResult::ImportedUnknown( + b.header().number().clone(), + Default::default(), + Some(peer_id1.clone()), + ) + ), + b.hash(), + ) + ) + .collect() + ); + + resp_blocks.into_iter() + .rev() + .for_each(|b| client.import(BlockOrigin::Own, b).unwrap()); + } + + // Request the tip + get_block_request( + &mut sync, + FromBlock::Hash(fork_blocks.last().unwrap().hash()), + 1, + &peer_id1, + ); + } } diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 7a7198aa7a0..84ad308c61e 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -545,6 +545,7 @@ mod tests { impl Arbitrary for ArbitraryPeerSync { fn arbitrary(g: &mut G) -> Self { let ps = PeerSync { + peer_id: PeerId::random(), common_number: g.gen(), best_hash: Hash::random(), best_number: g.gen(), @@ -561,10 +562,10 @@ mod tests { fn arbitrary(g: &mut G) -> Self { let mut peers = HashMap::with_capacity(g.size()); for _ in 0 .. g.size() { - peers.insert(PeerId::random(), ArbitraryPeerSync::arbitrary(g).0); + let ps = ArbitraryPeerSync::arbitrary(g).0; + peers.insert(ps.peer_id.clone(), ps); } ArbitraryPeers(peers) } } - } diff --git a/client/network/test/src/block_import.rs b/client/network/test/src/block_import.rs index a5d0600abef..5f9064d410e 100644 --- a/client/network/test/src/block_import.rs +++ b/client/network/test/src/block_import.rs @@ -76,7 +76,7 @@ fn import_single_good_known_block_is_ignored() { block, &mut PassThroughVerifier::new(true) ) { - Ok(BlockImportResult::ImportedKnown(ref n)) if *n == number => {} + Ok(BlockImportResult::ImportedKnown(ref n, _)) if *n == number => {} _ => panic!() } } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index a70ecb4fb04..428d8390b36 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -696,6 +696,8 @@ pub trait TestNetFactory: Sized { metrics_registry: None, }).unwrap(); + trace!(target: "test_network", "Peer identifier: {}", network.service().local_peer_id()); + self.mut_peers(|peers| { for peer in peers.iter_mut() { peer.network.add_known_address(network.service().local_peer_id().clone(), listen_addr.clone()); diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 9a488ae4fa4..e04ef060f08 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -702,7 +702,7 @@ fn can_sync_to_peers_with_wrong_common_block() { net.block_until_sync(); - assert!(net.peer(1).client().header(&BlockId::Hash(final_hash)).unwrap().is_some()); + assert!(net.peer(1).has_block(&final_hash)); } /// Returns `is_new_best = true` for each validated announcement. @@ -721,7 +721,6 @@ impl BlockAnnounceValidator for NewBestBlockAnnounceValidator { #[test] fn sync_blocks_when_block_announce_validator_says_it_is_new_best() { sp_tracing::try_init_simple(); - log::trace!(target: "sync", "Test"); let mut net = TestNet::with_fork_choice(ForkChoiceStrategy::Custom(false)); net.add_full_peer_with_config(Default::default()); net.add_full_peer_with_config(Default::default()); @@ -763,7 +762,6 @@ impl BlockAnnounceValidator for DeferredBlockAnnounceValidator { #[test] fn wait_until_deferred_block_announce_validation_is_ready() { sp_tracing::try_init_simple(); - log::trace!(target: "sync", "Test"); let mut net = TestNet::with_fork_choice(ForkChoiceStrategy::Custom(false)); net.add_full_peer_with_config(Default::default()); net.add_full_peer_with_config(FullPeerConfig { @@ -785,7 +783,6 @@ fn wait_until_deferred_block_announce_validation_is_ready() { #[test] fn sync_to_tip_requires_that_sync_protocol_is_informed_about_best_block() { sp_tracing::try_init_simple(); - log::trace!(target: "sync", "Test"); let mut net = TestNet::new(1); // Produce some blocks @@ -814,3 +811,34 @@ fn sync_to_tip_requires_that_sync_protocol_is_informed_about_best_block() { // However peer 1 should still not have the block. assert!(!net.peer(1).has_block(&block_hash)); } + +/// Ensures that if we as a syncing node sync to the tip while we are connected to another peer +/// that is currently also doing a major sync. +#[test] +fn sync_to_tip_when_we_sync_together_with_multiple_peers() { + sp_tracing::try_init_simple(); + + let mut net = TestNet::new(3); + + let block_hash = net.peer(0).push_blocks_at_without_informing_sync( + BlockId::Number(0), + 10_000, + false, + ); + + net.peer(1).push_blocks_at_without_informing_sync( + BlockId::Number(0), + 5_000, + false, + ); + + net.block_until_connected(); + net.block_until_idle(); + + assert!(!net.peer(2).has_block(&block_hash)); + + net.peer(0).network_service().new_best_block_imported(block_hash, 10_000); + while !net.peer(2).has_block(&block_hash) && !net.peer(1).has_block(&block_hash) { + net.block_until_idle(); + } +} diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index b32ca0133d9..713c59b07a5 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -138,7 +138,7 @@ pub trait Link: Send { #[derive(Debug, PartialEq)] pub enum BlockImportResult { /// Imported known block. - ImportedKnown(N), + ImportedKnown(N, Option), /// Imported unknown block. ImportedUnknown(N, ImportedAux, Option), } @@ -204,7 +204,7 @@ pub(crate) fn import_single_block_metered, Transaction match import { Ok(ImportResult::AlreadyInChain) => { trace!(target: "sync", "Block already in chain {}: {:?}", number, hash); - Ok(BlockImportResult::ImportedKnown(number)) + Ok(BlockImportResult::ImportedKnown(number, peer.clone())) }, Ok(ImportResult::Imported(aux)) => Ok(BlockImportResult::ImportedUnknown(number, aux, peer.clone())), Ok(ImportResult::MissingState) => { -- GitLab From aa5184d709b8320aff4ca681dee6a12843a1a640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 18 Dec 2020 15:02:08 +0100 Subject: [PATCH 130/163] Remove unnecessary parameter from sync (#7761) --- client/network/src/protocol/sync.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 712c1300288..7e50f586917 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -191,9 +191,6 @@ pub struct ChainSync { /// A set of hashes of blocks that are being downloaded or have been /// downloaded and are queued for import. queue_blocks: HashSet, - /// The best block number that was successfully imported into the chain. - /// This can not decrease. - best_imported_number: NumberFor, /// Fork sync targets. fork_targets: HashMap>, /// A set of peers for which there might be potential block requests @@ -455,7 +452,6 @@ impl ChainSync { blocks: BlockCollection::new(), best_queued_hash: info.best_hash, best_queued_number: info.best_number, - best_imported_number: info.best_number, extra_justifications: ExtraRequests::new("justification"), role, required_block_attributes, @@ -1106,10 +1102,6 @@ impl ChainSync { } } - if number > self.best_imported_number { - self.best_imported_number = number; - } - if let Some(peer) = who.and_then(|p| self.peers.get_mut(&p)) { peer.update_common_number(number); } @@ -1508,7 +1500,7 @@ impl ChainSync { self.blocks.clear(); let info = self.client.info(); self.best_queued_hash = info.best_hash; - self.best_queued_number = std::cmp::max(info.best_number, self.best_imported_number); + self.best_queued_number = info.best_number; self.pending_requests.set_all(); debug!(target:"sync", "Restarted with {} ({})", self.best_queued_number, self.best_queued_hash); let old_peers = std::mem::take(&mut self.peers); -- GitLab From 94c34f3eb0ad201e064e6e356dbd6cb6c1e3dfef Mon Sep 17 00:00:00 2001 From: Zeke Mostov <32168567+emostov@users.noreply.github.com> Date: Fri, 18 Dec 2020 22:59:48 -0800 Subject: [PATCH 131/163] Improve `InvalidTransaction::AncientBirthBlock` doc comment (#7743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve `InvalidTransaction::AncientBirthBlock` doc comment Update Remove stray parentheses Tabs not spaces Improve whoops * Update primitives/runtime/src/transaction_validity.rs Co-authored-by: Bastian Köcher * Possible causes section; Expand example Co-authored-by: Bastian Köcher --- primitives/runtime/src/transaction_validity.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/primitives/runtime/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs index 2191e59b9bb..74709d9ae9c 100644 --- a/primitives/runtime/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -54,6 +54,13 @@ pub enum InvalidTransaction { /// it will only be able to assume a bad signature and cannot express a more meaningful error. BadProof, /// The transaction birth block is ancient. + /// + /// # Possible causes + /// + /// For `FRAME`-based runtimes this would be caused by `current block number + /// - Era::birth block number > BlockHashCount`. (e.g. in Polkadot `BlockHashCount` = 2400, so a + /// transaction with birth block number 1337 would be valid up until block number 1337 + 2400, + /// after which point the transaction would be considered to have an ancient birth block.) AncientBirthBlock, /// The transaction would exhaust the resources of current block. /// -- GitLab From 61cb65ecbda3c5edef5e140a178a2d1aadf3e3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 19 Dec 2020 10:22:08 +0100 Subject: [PATCH 132/163] Switch back to the crates.io release of trybuild (#7764) * Switch back to the crates.io release of trybuild My fix was merged on upstream and this release contains it. So, no more reason to keep the git dependency. * The lock file... --- Cargo.lock | 5 +++-- frame/support/test/Cargo.toml | 2 +- primitives/api/test/Cargo.toml | 2 +- primitives/runtime-interface/Cargo.toml | 2 +- test-utils/Cargo.toml | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c775fbb062e..e1c7673650f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9744,8 +9744,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "trybuild" -version = "1.0.35" -source = "git+https://github.com/bkchr/trybuild.git?branch=bkchr-use-workspace-cargo-lock#0eaad05ba8a32a743751ff52b57a7d9f57da4869" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b06f8610494cbeb9a7665b398306f0109ab8708296d7f24b0bcd89178bb350" dependencies = [ "dissimilar", "glob", diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 01484ccfb88..4175c2e4c93 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -21,7 +21,7 @@ sp-inherents = { version = "2.0.0", default-features = false, path = "../../../p sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } -trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } +trybuild = "1.0.38" pretty_assertions = "0.6.1" rustversion = "1.0.0" frame-metadata = { version = "12.0.0", default-features = false, path = "../../metadata" } diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index f3f698e0ccb..046c923c03b 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -21,7 +21,7 @@ sp-consensus = { version = "0.8.0", path = "../../consensus/common" } sc-block-builder = { version = "0.8.0", path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "1.3.1" } sp-state-machine = { version = "0.8.0", path = "../../state-machine" } -trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } +trybuild = "1.0.38" rustversion = "1.0.0" [dev-dependencies] diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index b8ad0c1261e..cbd26823012 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -31,7 +31,7 @@ sp-state-machine = { version = "0.8.0", path = "../state-machine" } sp-core = { version = "2.0.0", path = "../core" } sp-io = { version = "2.0.0", path = "../io" } rustversion = "1.0.0" -trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock" } +trybuild = "1.0.38" [features] default = [ "std" ] diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 7606b0c1c15..66f5703b2c9 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -18,4 +18,4 @@ tokio = { version = "0.2.13", features = ["macros"] } [dev-dependencies] sc-service = { version = "0.8.0", path = "../client/service" } -trybuild = { git = "https://github.com/bkchr/trybuild.git", branch = "bkchr-use-workspace-cargo-lock", features = [ "diff" ] } +trybuild = { version = "1.0.38", features = [ "diff" ] } -- GitLab From 8b9a441a7ba268612512850f66e25e437d10b591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Sat, 19 Dec 2020 12:34:56 +0100 Subject: [PATCH 133/163] No longer put keys back manually after a failed restoration (#7747) This is no longer necessary with storage transactions. --- frame/contracts/src/rent.rs | 22 +++++++++++----------- frame/contracts/src/tests.rs | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 8b6f81c916b..4b10a0408c1 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -451,14 +451,19 @@ where origin_contract.last_write }; - let key_values_taken = delta.iter() + // We are allowed to eagerly modify storage even though the function can + // fail later due to tombstones not matching. This is because the restoration + // is always called from a contract and therefore in a storage transaction. + // The failure of this function will lead to this transaction's rollback. + let bytes_taken: u32 = delta.iter() .filter_map(|key| { - child::get_raw(&child_trie_info, &blake2_256(key)).map(|value| { - child::kill(&child_trie_info, &blake2_256(key)); - (key, value) + let key = blake2_256(key); + child::get_raw(&child_trie_info, &key).map(|value| { + child::kill(&child_trie_info, &key); + value.len() as u32 }) }) - .collect::>(); + .sum(); let tombstone = >::new( // This operation is cheap enough because last_write (delta not included) @@ -468,15 +473,10 @@ where ); if tombstone != dest_tombstone { - for (key, value) in key_values_taken { - child::put_raw(&child_trie_info, &blake2_256(key), &value); - } return Err(Error::::InvalidTombstone.into()); } - origin_contract.storage_size -= key_values_taken.iter() - .map(|(_, value)| value.len() as u32) - .sum::(); + origin_contract.storage_size -= bytes_taken; >::remove(&origin); >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index c0b9b671068..3a7a8c6436e 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -1221,7 +1221,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, GAS_LIMIT, restoration_code_hash.into(), - ::Balance::from(0u32).encode(), + vec![], vec![], )); let addr_django = Contracts::contract_address(&CHARLIE, &restoration_code_hash, &[]); @@ -1253,6 +1253,15 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: ) }; + // The key that is used in the restorer contract but is not in the target contract. + // Is supplied as delta to the restoration. We need it to check whether the key + // is properly removed on success but still there on failure. + let delta_key = { + let mut key = [0u8; 32]; + key[0] = 1; + key + }; + if test_different_storage || test_restore_to_with_dirty_storage { // Parametrization of the test imply restoration failure. Check that `DJANGO` aka // restoration contract is still in place and also that `BOB` doesn't exist. @@ -1263,6 +1272,10 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(django_contract.storage_size, 8); assert_eq!(django_contract.trie_id, django_trie_id); assert_eq!(django_contract.deduct_block, System::block_number()); + assert_eq!( + Storage::::read(&django_trie_id, &delta_key), + Some(vec![40, 0, 0, 0]), + ); match (test_different_storage, test_restore_to_with_dirty_storage) { (true, false) => { assert_err_ignore_postinfo!( @@ -1321,7 +1334,6 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Here we expect that the restoration is succeeded. Check that the restoration // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(&addr_bob)); let bob_contract = ContractInfoOf::::get(&addr_bob).unwrap() .get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 50); @@ -1329,6 +1341,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(bob_contract.trie_id, django_trie_id); assert_eq!(bob_contract.deduct_block, System::block_number()); assert!(ContractInfoOf::::get(&addr_django).is_none()); + assert_matches!(Storage::::read(&django_trie_id, &delta_key), None); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, -- GitLab From 3c531e291fcc2c315abd3dcf436c487cdd91bd25 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sat, 19 Dec 2020 07:16:34 -0800 Subject: [PATCH 134/163] Fix UI Tests (#7722) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix UI tests * make updates. * Revert "make updates." This reverts commit 3f41979c12e86acb75fd086675ac09659dde533e. * Try to fix companion build * Use some depth * tests: fix UI tests on the latest nightly * tests: fix polkadot companion test, depth * chore: update deps * chore: update deps * chore: sp-io Co-authored-by: kianenigma Co-authored-by: Bastian Köcher Co-authored-by: Denis P --- .../gitlab/check_polkadot_companion_build.sh | 2 +- Cargo.lock | 24 +++++++++---------- bin/node/browser-testing/Cargo.toml | 2 +- .../tests/derive_no_bound_ui/clone.stderr | 6 ++--- .../test/tests/derive_no_bound_ui/eq.stderr | 2 +- .../ui/impl_incorrect_method_signature.stderr | 4 ++-- .../tests/ui/mock_only_one_error_type.stderr | 14 +++++------ .../tests/ui/mock_only_self_reference.stderr | 8 +++---- ...reference_in_impl_runtime_apis_call.stderr | 4 ++-- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index 4a7e9869abf..f2b61c6192d 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -45,7 +45,7 @@ cargo install -f --version 0.2.0 diener # Merge master into our branch before building Polkadot to make sure we don't miss # any commits that are required by Polkadot. -git fetch --depth 20 origin +git fetch --depth 100 origin git merge origin/master # Clone the current Polkadot master branch into ./polkadot. diff --git a/Cargo.lock b/Cargo.lock index e1c7673650f..ff6f679ed78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9764,7 +9764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59" dependencies = [ "cfg-if 0.1.10", - "rand 0.7.3", + "rand 0.6.5", "static_assertions", ] @@ -9979,11 +9979,11 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" +checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "serde", "serde_json", "wasm-bindgen-macro", @@ -9991,9 +9991,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" +checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" dependencies = [ "bumpalo", "lazy_static", @@ -10018,9 +10018,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" +checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10028,9 +10028,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" +checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" dependencies = [ "proc-macro2", "quote", @@ -10041,9 +10041,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.68" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" +checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" [[package]] name = "wasm-bindgen-test" diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index f60dc55b6f7..f297e624ca0 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -12,7 +12,7 @@ libp2p = { version = "0.32.2", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" -wasm-bindgen = { version = "=0.2.68", features = ["serde-serialize"] } +wasm-bindgen = { version = "=0.2.69", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.18" wasm-bindgen-test = "0.3.18" futures = "0.3.4" diff --git a/frame/support/test/tests/derive_no_bound_ui/clone.stderr b/frame/support/test/tests/derive_no_bound_ui/clone.stderr index af322f386ae..4b253ad1245 100644 --- a/frame/support/test/tests/derive_no_bound_ui/clone.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/clone.stderr @@ -1,7 +1,7 @@ -error[E0277]: the trait bound `::C: std::clone::Clone` is not satisfied +error[E0277]: the trait bound `::C: Clone` is not satisfied --> $DIR/clone.rs:7:2 | 7 | c: T::C, - | ^ the trait `std::clone::Clone` is not implemented for `::C` + | ^ the trait `Clone` is not implemented for `::C` | - = note: required by `std::clone::Clone::clone` + = note: required by `clone` diff --git a/frame/support/test/tests/derive_no_bound_ui/eq.stderr b/frame/support/test/tests/derive_no_bound_ui/eq.stderr index bd5df600dc4..bbd907adecb 100644 --- a/frame/support/test/tests/derive_no_bound_ui/eq.stderr +++ b/frame/support/test/tests/derive_no_bound_ui/eq.stderr @@ -4,4 +4,4 @@ error[E0277]: can't compare `Foo` with `Foo` 6 | struct Foo { | ^^^ no implementation for `Foo == Foo` | - = help: the trait `std::cmp::PartialEq` is not implemented for `Foo` + = help: the trait `PartialEq` is not implemented for `Foo` diff --git a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr index 851d2b8a4b6..fcda69533e3 100644 --- a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr +++ b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr @@ -23,8 +23,8 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 17 | sp_api::impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::string::String` | - = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` - found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` + = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &BlockId<__SR_API_BLOCK__>, ExecutionContext, std::option::Option, Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &BlockId<__SR_API_BLOCK__>, ExecutionContext, std::option::Option, Vec<_>) -> std::result::Result<_, _>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types diff --git a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr index 82fd04e8c5e..eccd80ecd82 100644 --- a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr +++ b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr @@ -10,20 +10,20 @@ error: First error type was declared here. 17 | type Error = u32; | ^^^ -error[E0277]: the trait bound `u32: std::convert::From` is not satisfied +error[E0277]: the trait bound `u32: From` is not satisfied --> $DIR/mock_only_one_error_type.rs:17:16 | 17 | type Error = u32; - | ^^^ the trait `std::convert::From` is not implemented for `u32` + | ^^^ the trait `From` is not implemented for `u32` | ::: $WORKSPACE/primitives/api/src/lib.rs | | type Error: std::fmt::Debug + From; - | -------------- required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt` + | -------------- required by this bound in `ApiErrorExt` | = help: the following implementations were found: - > - > - > - > + > + > + > + > and 18 others diff --git a/primitives/api/test/tests/ui/mock_only_self_reference.stderr b/primitives/api/test/tests/ui/mock_only_self_reference.stderr index ed5b64144a6..73cf9361037 100644 --- a/primitives/api/test/tests/ui/mock_only_self_reference.stderr +++ b/primitives/api/test/tests/ui/mock_only_self_reference.stderr @@ -24,8 +24,8 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 12 | sp_api::mock_impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `()` | - = note: expected fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime_client::substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` - found fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime_client::substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<()>, std::vec::Vec<_>) -> std::result::Result<_, _>` + = note: expected fn pointer `fn(&MockApi, &BlockId, Extrinsic>>, ExecutionContext, Option, Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&MockApi, &BlockId, Extrinsic>>, ExecutionContext, Option<()>, Vec<_>) -> std::result::Result<_, _>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0053]: method `Api_test2_runtime_api_impl` has an incompatible type for trait @@ -42,6 +42,6 @@ error[E0053]: method `Api_test2_runtime_api_impl` has an incompatible type for t 12 | sp_api::mock_impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `()` | - = note: expected fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime_client::substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` - found fn pointer `fn(&MockApi, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime_client::substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<()>, std::vec::Vec<_>) -> std::result::Result<_, _>` + = note: expected fn pointer `fn(&MockApi, &BlockId, Extrinsic>>, ExecutionContext, Option, Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&MockApi, &BlockId, Extrinsic>>, ExecutionContext, Option<()>, Vec<_>) -> std::result::Result<_, _>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr index c3e48500360..71f12b415a2 100644 --- a/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr +++ b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr @@ -23,8 +23,8 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 17 | sp_api::impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `&u64` | - = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` - found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec<_>) -> std::result::Result<_, _>` + = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &BlockId<__SR_API_BLOCK__>, ExecutionContext, std::option::Option, Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &BlockId<__SR_API_BLOCK__>, ExecutionContext, std::option::Option<&u64>, Vec<_>) -> std::result::Result<_, _>` = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types -- GitLab From 532cce0118fe7a64168413e638b177e7e144ef72 Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Mon, 21 Dec 2020 11:09:52 +0800 Subject: [PATCH 135/163] update substrate to sc in docs (#7767) --- docs/Structure.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Structure.adoc b/docs/Structure.adoc index c8cd63506a3..6c810a83c51 100644 --- a/docs/Structure.adoc +++ b/docs/Structure.adoc @@ -33,7 +33,7 @@ In the lowest level, Substrate defines primitives, interfaces and traits to impl === Client * _found in_: `/client` -* _crates prefix_: `substrate-` +* _crates prefix_: `sc-` * _constraints_: ** crates may not (dev-)depend on any `frame-`-crates -- GitLab From 9e2d7b74742f7b1db7e09a00d423f613787d19a8 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 21 Dec 2020 09:54:04 +0000 Subject: [PATCH 136/163] Allow Staking tests to run with session length other than 1 (#7719) * fix periodic session * Allow staking tests to run with session lengths other than 1. * Update frame/staking/src/mock.rs Co-authored-by: Guillaume Thiolliere * Fix all tests with session length 5. * Test for active != current * Better doc * Update frame/staking/src/lib.rs Co-authored-by: Guillaume Thiolliere * also set the timestamp properly. * trigger CI * Revert "trigger CI" This reverts commit 0f254944cdad848aa6e63bd8a618db95447a8e68. * Update frame/staking/src/lib.rs Co-authored-by: Guillaume Thiolliere --- frame/session/src/lib.rs | 96 ++--- frame/session/src/tests.rs | 27 +- frame/staking/src/lib.rs | 46 ++- frame/staking/src/mock.rs | 199 ++++++---- frame/staking/src/tests.rs | 732 +++++++++++++++++++++++-------------- 5 files changed, 675 insertions(+), 425 deletions(-) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index dd176219aa7..cd02ddaac49 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -17,8 +17,8 @@ //! # Session Module //! -//! The Session module allows validators to manage their session keys, provides a function for changing -//! the session length, and handles session rotation. +//! The Session module allows validators to manage their session keys, provides a function for +//! changing the session length, and handles session rotation. //! //! - [`session::Config`](./trait.Config.html) //! - [`Call`](./enum.Call.html) @@ -29,34 +29,39 @@ //! ### Terminology //! //! -//! - **Session:** A session is a period of time that has a constant set of validators. Validators can only join -//! or exit the validator set at a session change. It is measured in block numbers. The block where a session is -//! ended is determined by the `ShouldEndSession` trait. When the session is ending, a new validator set -//! can be chosen by `OnSessionEnding` implementations. -//! - **Session key:** A session key is actually several keys kept together that provide the various signing -//! functions required by network authorities/validators in pursuit of their duties. -//! - **Validator ID:** Every account has an associated validator ID. For some simple staking systems, this -//! may just be the same as the account ID. For staking systems using a stash/controller model, -//! the validator ID would be the stash account ID of the controller. +//! - **Session:** A session is a period of time that has a constant set of validators. Validators +//! can only join or exit the validator set at a session change. It is measured in block numbers. +//! The block where a session is ended is determined by the `ShouldEndSession` trait. When the +//! session is ending, a new validator set can be chosen by `OnSessionEnding` implementations. +//! +//! - **Session key:** A session key is actually several keys kept together that provide the various +//! signing functions required by network authorities/validators in pursuit of their duties. +//! - **Validator ID:** Every account has an associated validator ID. For some simple staking +//! systems, this may just be the same as the account ID. For staking systems using a +//! stash/controller model, the validator ID would be the stash account ID of the controller. +//! //! - **Session key configuration process:** Session keys are set using `set_keys` for use not in -//! the next session, but the session after next. They are stored in `NextKeys`, a mapping between -//! the caller's `ValidatorId` and the session keys provided. `set_keys` allows users to set their -//! session key prior to being selected as validator. -//! It is a public call since it uses `ensure_signed`, which checks that the origin is a signed account. -//! As such, the account ID of the origin stored in `NextKeys` may not necessarily be associated with -//! a block author or a validator. The session keys of accounts are removed once their account balance is zero. +//! the next session, but the session after next. They are stored in `NextKeys`, a mapping between +//! the caller's `ValidatorId` and the session keys provided. `set_keys` allows users to set their +//! session key prior to being selected as validator. It is a public call since it uses +//! `ensure_signed`, which checks that the origin is a signed account. As such, the account ID of +//! the origin stored in `NextKeys` may not necessarily be associated with a block author or a +//! validator. The session keys of accounts are removed once their account balance is zero. +//! //! - **Session length:** This pallet does not assume anything about the length of each session. -//! Rather, it relies on an implementation of `ShouldEndSession` to dictate a new session's start. -//! This pallet provides the `PeriodicSessions` struct for simple periodic sessions. -//! - **Session rotation configuration:** Configure as either a 'normal' (rewardable session where rewards are -//! applied) or 'exceptional' (slashable) session rotation. +//! Rather, it relies on an implementation of `ShouldEndSession` to dictate a new session's start. +//! This pallet provides the `PeriodicSessions` struct for simple periodic sessions. +//! +//! - **Session rotation configuration:** Configure as either a 'normal' (rewardable session where +//! rewards are applied) or 'exceptional' (slashable) session rotation. +//! //! - **Session rotation process:** At the beginning of each block, the `on_initialize` function -//! queries the provided implementation of `ShouldEndSession`. If the session is to end the newly -//! activated validator IDs and session keys are taken from storage and passed to the -//! `SessionHandler`. The validator set supplied by `SessionManager::new_session` and the corresponding session -//! keys, which may have been registered via `set_keys` during the previous session, are written -//! to storage where they will wait one session before being passed to the `SessionHandler` -//! themselves. +//! queries the provided implementation of `ShouldEndSession`. If the session is to end the newly +//! activated validator IDs and session keys are taken from storage and passed to the +//! `SessionHandler`. The validator set supplied by `SessionManager::new_session` and the +//! corresponding session keys, which may have been registered via `set_keys` during the previous +//! session, are written to storage where they will wait one session before being passed to the +//! `SessionHandler` themselves. //! //! ### Goals //! @@ -75,7 +80,7 @@ //! ### Public Functions //! //! - `rotate_session` - Change to the next session. Register the new authority set. Queue changes -//! for next session rotation. +//! for next session rotation. //! - `disable_index` - Disable a validator by index. //! - `disable` - Disable a validator by Validator ID //! @@ -83,13 +88,14 @@ //! //! ### Example from the FRAME //! -//! The [Staking pallet](../pallet_staking/index.html) uses the Session pallet to get the validator set. +//! The [Staking pallet](../pallet_staking/index.html) uses the Session pallet to get the validator +//! set. //! //! ``` //! use pallet_session as session; //! //! fn validators() -> Vec<::ValidatorId> { -//! >::validators() +//! >::validators() //! } //! # fn main(){} //! ``` @@ -166,7 +172,7 @@ impl< period.saturating_sub(block_after_last_session) ) } else { - Zero::zero() + now } } else { offset @@ -174,10 +180,10 @@ impl< } fn weight(_now: BlockNumber) -> Weight { - // Weight note: `estimate_next_session_rotation` has no storage reads and trivial computational overhead. - // There should be no risk to the chain having this weight value be zero for now. - // However, this value of zero was not properly calculated, and so it would be reasonable - // to come back here and properly calculate the weight of this function. + // Weight note: `estimate_next_session_rotation` has no storage reads and trivial + // computational overhead. There should be no risk to the chain having this weight value be + // zero for now. However, this value of zero was not properly calculated, and so it would be + // reasonable to come back here and properly calculate the weight of this function. 0 } } @@ -186,17 +192,17 @@ impl< pub trait SessionManager { /// Plan a new session, and optionally provide the new validator set. /// - /// Even if the validator-set is the same as before, if any underlying economic - /// conditions have changed (i.e. stake-weights), the new validator set must be returned. - /// This is necessary for consensus engines making use of the session module to - /// issue a validator-set change so misbehavior can be provably associated with the new - /// economic conditions as opposed to the old. - /// The returned validator set, if any, will not be applied until `new_index`. - /// `new_index` is strictly greater than from previous call. + /// Even if the validator-set is the same as before, if any underlying economic conditions have + /// changed (i.e. stake-weights), the new validator set must be returned. This is necessary for + /// consensus engines making use of the session module to issue a validator-set change so + /// misbehavior can be provably associated with the new economic conditions as opposed to the + /// old. The returned validator set, if any, will not be applied until `new_index`. `new_index` + /// is strictly greater than from previous call. /// /// The first session start at index 0. /// - /// `new_session(session)` is guaranteed to be called before `end_session(session-1)`. + /// `new_session(session)` is guaranteed to be called before `end_session(session-1)`. In other + /// words, a new session must always be planned before an ongoing one can be finished. fn new_session(new_index: SessionIndex) -> Option>; /// End the session. /// @@ -205,7 +211,7 @@ pub trait SessionManager { fn end_session(end_index: SessionIndex); /// Start the session. /// - /// The session start to be used for validation + /// The session start to be used for validation. fn start_session(start_index: SessionIndex); } @@ -242,7 +248,7 @@ pub trait SessionHandler { /// A notification for end of the session. /// - /// Note it is triggered before any `SessionManager::end_session` handlers, + /// Note it is triggered before any [`SessionManager::end_session`] handlers, /// so we can still affect the validator set. fn on_before_session_ending() {} diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 7a33aa5296b..3da5d16caad 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -252,31 +252,32 @@ fn session_changed_flag_works() { #[test] fn periodic_session_works() { - struct Period; - struct Offset; - impl Get for Period { - fn get() -> u64 { 10 } + frame_support::parameter_types! { + const Period: u64 = 10; + const Offset: u64 = 3; } - impl Get for Offset { - fn get() -> u64 { 3 } - } - - type P = PeriodicSessions; - for i in 0..3 { + for i in 0u64..3 { assert!(!P::should_end_session(i)); + assert_eq!(P::estimate_next_session_rotation(i).unwrap(), 3); } - assert!(P::should_end_session(3)); + assert!(P::should_end_session(3u64)); + assert_eq!(P::estimate_next_session_rotation(3u64).unwrap(), 3); - for i in (1..10).map(|i| 3 + i) { + for i in (1u64..10).map(|i| 3 + i) { assert!(!P::should_end_session(i)); + assert_eq!(P::estimate_next_session_rotation(i).unwrap(), 13); } - assert!(P::should_end_session(13)); + assert!(P::should_end_session(13u64)); + assert_eq!(P::estimate_next_session_rotation(13u64).unwrap(), 13); + + assert!(!P::should_end_session(14u64)); + assert_eq!(P::estimate_next_session_rotation(14u64).unwrap(), 23); } #[test] diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index af326e27c62..f70a76cb1ac 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -952,11 +952,14 @@ decl_storage! { /// The active era information, it holds index and start. /// - /// The active era is the era currently rewarded. - /// Validator set of this era must be equal to `SessionInterface::validators`. + /// The active era is the era being currently rewarded. Validator set of this era must be + /// equal to [`SessionInterface::validators`]. pub ActiveEra get(fn active_era): Option; /// The session index at which the era start for the last `HISTORY_DEPTH` eras. + /// + /// Note: This tracks the starting session (i.e. session index when era start being active) + /// for the eras in `[CurrentEra - HISTORY_DEPTH, CurrentEra]`. pub ErasStartSessionIndex get(fn eras_start_session_index): map hasher(twox_64_concat) EraIndex => Option; @@ -2630,14 +2633,17 @@ impl Module { /// Start a session potentially starting an era. fn start_session(start_session: SessionIndex) { let next_active_era = Self::active_era().map(|e| e.index + 1).unwrap_or(0); + // This is only `Some` when current era has already progressed to the next era, while the + // active era is one behind (i.e. in the *last session of the active era*, or *first session + // of the new current era*, depending on how you look at it). if let Some(next_active_era_start_session_index) = Self::eras_start_session_index(next_active_era) { if next_active_era_start_session_index == start_session { Self::start_era(start_session); } else if next_active_era_start_session_index < start_session { - // This arm should never happen, but better handle it than to stall the - // staking pallet. + // This arm should never happen, but better handle it than to stall the staking + // pallet. frame_support::print("Warning: A session appears to have been skipped."); Self::start_era(start_session); } @@ -2893,9 +2899,11 @@ impl Module { /// Self votes are added and nominations before the most recent slashing span are ignored. /// /// No storage item is updated. - pub fn do_phragmen(iterations: usize) - -> Option> - where ExtendedBalance: From> + pub fn do_phragmen( + iterations: usize, + ) -> Option> + where + ExtendedBalance: From>, { let weight_of = Self::slashable_balance_of_fn(); let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = Vec::new(); @@ -2928,7 +2936,11 @@ impl Module { if all_validators.len() < Self::minimum_validator_count().max(1) as usize { // If we don't have enough candidates, nothing to do. - log!(error, "💸 Chain does not have enough staking candidates to operate. Era {:?}.", Self::current_era()); + log!( + warn, + "💸 Chain does not have enough staking candidates to operate. Era {:?}.", + Self::current_era() + ); None } else { seq_phragmen::<_, Accuracy>( @@ -3090,12 +3102,30 @@ impl Module { /// some session can lag in between the newest session planned and the latest session started. impl pallet_session::SessionManager for Module { fn new_session(new_index: SessionIndex) -> Option> { + frame_support::debug::native::trace!( + target: LOG_TARGET, + "[{}] planning new_session({})", + >::block_number(), + new_index + ); Self::new_session(new_index) } fn start_session(start_index: SessionIndex) { + frame_support::debug::native::trace!( + target: LOG_TARGET, + "[{}] starting start_session({})", + >::block_number(), + start_index + ); Self::start_session(start_index) } fn end_session(end_index: SessionIndex) { + frame_support::debug::native::trace!( + target: LOG_TARGET, + "[{}] ending end_session({})", + >::block_number(), + end_index + ); Self::end_session(end_index) } } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 76689503f65..f3c6d50d4cf 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -38,6 +38,7 @@ use sp_staking::offence::{OffenceDetails, OnOffenceHandler}; use std::{cell::RefCell, collections::HashSet}; pub const INIT_TIMESTAMP: u64 = 30_000; +pub const BLOCK_TIME: u64 = 1000; /// The AccountId alias in this test module. pub(crate) type AccountId = u64; @@ -135,10 +136,11 @@ parameter_types! { ); pub const MaxLocks: u32 = 1024; pub static SessionsPerEra: SessionIndex = 3; - pub static ExistentialDeposit: Balance = 0; + pub static ExistentialDeposit: Balance = 1; pub static SlashDeferDuration: EraIndex = 0; pub static ElectionLookahead: BlockNumber = 0; - pub static Period: BlockNumber = 1; + pub static Period: BlockNumber = 5; + pub static Offset: BlockNumber = 0; pub static MaxIterations: u32 = 0; } @@ -175,7 +177,6 @@ impl pallet_balances::Config for Test { type WeightInfo = (); } parameter_types! { - pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } @@ -286,46 +287,36 @@ where pub type Extrinsic = TestXt; pub struct ExtBuilder { - session_length: BlockNumber, - election_lookahead: BlockNumber, - session_per_era: SessionIndex, - existential_deposit: Balance, validator_pool: bool, nominate: bool, validator_count: u32, minimum_validator_count: u32, - slash_defer_duration: EraIndex, fair: bool, num_validators: Option, invulnerables: Vec, has_stakers: bool, - max_offchain_iterations: u32, + initialize_first_session: bool, } impl Default for ExtBuilder { fn default() -> Self { Self { - session_length: 1, - election_lookahead: 0, - session_per_era: 3, - existential_deposit: 1, validator_pool: false, nominate: true, validator_count: 2, minimum_validator_count: 0, - slash_defer_duration: 0, fair: true, num_validators: None, invulnerables: vec![], has_stakers: true, - max_offchain_iterations: 0, + initialize_first_session: true, } } } impl ExtBuilder { - pub fn existential_deposit(mut self, existential_deposit: Balance) -> Self { - self.existential_deposit = existential_deposit; + pub fn existential_deposit(self, existential_deposit: Balance) -> Self { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = existential_deposit); self } pub fn validator_pool(mut self, validator_pool: bool) -> Self { @@ -344,8 +335,8 @@ impl ExtBuilder { self.minimum_validator_count = count; self } - pub fn slash_defer_duration(mut self, eras: EraIndex) -> Self { - self.slash_defer_duration = eras; + pub fn slash_defer_duration(self, eras: EraIndex) -> Self { + SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = eras); self } pub fn fair(mut self, is_fair: bool) -> Self { @@ -360,46 +351,43 @@ impl ExtBuilder { self.invulnerables = invulnerables; self } - pub fn session_per_era(mut self, length: SessionIndex) -> Self { - self.session_per_era = length; + pub fn session_per_era(self, length: SessionIndex) -> Self { + SESSIONS_PER_ERA.with(|v| *v.borrow_mut() = length); self } - pub fn election_lookahead(mut self, look: BlockNumber) -> Self { - self.election_lookahead = look; + pub fn election_lookahead(self, look: BlockNumber) -> Self { + ELECTION_LOOKAHEAD.with(|v| *v.borrow_mut() = look); self } - pub fn session_length(mut self, length: BlockNumber) -> Self { - self.session_length = length; + pub fn period(self, length: BlockNumber) -> Self { + PERIOD.with(|v| *v.borrow_mut() = length); self } pub fn has_stakers(mut self, has: bool) -> Self { self.has_stakers = has; self } - pub fn max_offchain_iterations(mut self, iterations: u32) -> Self { - self.max_offchain_iterations = iterations; + pub fn max_offchain_iterations(self, iterations: u32) -> Self { + MAX_ITERATIONS.with(|v| *v.borrow_mut() = iterations); self } pub fn offchain_election_ext(self) -> Self { - self.session_per_era(4) - .session_length(5) - .election_lookahead(3) - } - pub fn set_associated_constants(&self) { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); - SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = self.slash_defer_duration); - SESSIONS_PER_ERA.with(|v| *v.borrow_mut() = self.session_per_era); - ELECTION_LOOKAHEAD.with(|v| *v.borrow_mut() = self.election_lookahead); - PERIOD.with(|v| *v.borrow_mut() = self.session_length); - MAX_ITERATIONS.with(|v| *v.borrow_mut() = self.max_offchain_iterations); + self.session_per_era(4).period(5).election_lookahead(3) + } + pub fn initialize_first_session(mut self, init: bool) -> Self { + self.initialize_first_session = init; + self + } + pub fn offset(self, offset: BlockNumber) -> Self { + OFFSET.with(|v| *v.borrow_mut() = offset); + self } pub fn build(self) -> sp_io::TestExternalities { sp_tracing::try_init_simple(); - self.set_associated_constants(); let mut storage = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); - let balance_factor = if self.existential_deposit > 1 { + let balance_factor = if ExistentialDeposit::get() > 1 { 256 } else { 1 @@ -475,13 +463,17 @@ impl ExtBuilder { SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new())); }); - // We consider all test to start after timestamp is initialized - // This must be ensured by having `timestamp::on_initialize` called before - // `staking::on_initialize` - ext.execute_with(|| { - System::set_block_number(1); - Timestamp::set_timestamp(INIT_TIMESTAMP); - }); + if self.initialize_first_session { + // We consider all test to start after timestamp is initialized This must be ensured by + // having `timestamp::on_initialize` called before `staking::on_initialize`. Also, if + // session length is 1, then it is already triggered. + ext.execute_with(|| { + System::set_block_number(1); + Session::on_initialize(1); + Staking::on_initialize(1); + Timestamp::set_timestamp(INIT_TIMESTAMP); + }); + } ext } @@ -498,20 +490,12 @@ pub type Session = pallet_session::Module; pub type Timestamp = pallet_timestamp::Module; pub type Staking = Module; -pub(crate) fn current_era() -> EraIndex { - Staking::current_era().unwrap() -} - fn post_conditions() { check_nominators(); check_exposures(); check_ledgers(); } -pub(crate) fn active_era() -> EraIndex { - Staking::active_era().unwrap().index -} - fn check_ledgers() { // check the ledger of all stakers. Bonded::::iter().for_each(|(_, ctrl)| assert_ledger_consistent(ctrl)) @@ -593,6 +577,14 @@ fn assert_ledger_consistent(ctrl: AccountId) { ); } +pub(crate) fn active_era() -> EraIndex { + Staking::active_era().unwrap().index +} + +pub(crate) fn current_era() -> EraIndex { + Staking::current_era().unwrap() +} + pub(crate) fn bond_validator(stash: AccountId, ctrl: AccountId, val: Balance) { let _ = Balances::make_free_balance_be(&stash, val); let _ = Balances::make_free_balance_be(&ctrl, val); @@ -625,52 +617,98 @@ pub(crate) fn bond_nominator( assert_ok!(Staking::nominate(Origin::signed(ctrl), target)); } +/// Progress to the given block, triggering session and era changes as we progress. +/// +/// This will finalize the previous block, initialize up to the given block, essentially simulating +/// a block import/propose process where we first initialize the block, then execute some stuff (not +/// in the function), and then finalize the block. pub(crate) fn run_to_block(n: BlockNumber) { Staking::on_finalize(System::block_number()); - for b in System::block_number() + 1..=n { + for b in (System::block_number() + 1)..=n { System::set_block_number(b); Session::on_initialize(b); Staking::on_initialize(b); + Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP); if b != n { Staking::on_finalize(System::block_number()); } } } +/// Progresses from the current block number (whatever that may be) to the `P * session_index + 1`. +pub(crate) fn start_session(session_index: SessionIndex) { + let end: u64 = if Offset::get().is_zero() { + (session_index as u64) * Period::get() + } else { + Offset::get() + (session_index.saturating_sub(1) as u64) * Period::get() + }; + run_to_block(end); + // session must have progressed properly. + assert_eq!( + Session::current_index(), + session_index, + "current session index = {}, expected = {}", + Session::current_index(), + session_index, + ); +} + +/// Go one session forward. pub(crate) fn advance_session() { let current_index = Session::current_index(); start_session(current_index + 1); } -pub(crate) fn start_session(session_index: SessionIndex) { - assert_eq!(>::get(), 1, "start_session can only be used with session length 1."); - for i in Session::current_index()..session_index { - Staking::on_finalize(System::block_number()); - System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number() * 1000 + INIT_TIMESTAMP); - Session::on_initialize(System::block_number()); - Staking::on_initialize(System::block_number()); - } - - assert_eq!(Session::current_index(), session_index); -} - -// This start and activate the era given. -// Because the mock use pallet-session which delays session by one, this will be one session after -// the election happened, not the first session after the election has happened. -pub(crate) fn start_era(era_index: EraIndex) { +/// Progress until the given era. +pub(crate) fn start_active_era(era_index: EraIndex) { start_session((era_index * >::get()).into()); - assert_eq!(Staking::current_era().unwrap(), era_index); - assert_eq!(Staking::active_era().unwrap().index, era_index); + assert_eq!(active_era(), era_index); + // One way or another, current_era must have changed before the active era, so they must match + // at this point. + assert_eq!(current_era(), active_era()); } pub(crate) fn current_total_payout_for_duration(duration: u64) -> Balance { + let reward = inflation::compute_total_payout( + ::RewardCurve::get(), + Staking::eras_total_stake(active_era()), + Balances::total_issuance(), + duration, + ) + .0; + assert!(reward > 0); + reward +} + +pub(crate) fn maximum_payout_for_duration(duration: u64) -> Balance { inflation::compute_total_payout( ::RewardCurve::get(), - Staking::eras_total_stake(Staking::active_era().unwrap().index), + 0, Balances::total_issuance(), duration, - ).0 + ) + .1 +} + +/// Time it takes to finish a session. +/// +/// Note, if you see `time_per_session() - BLOCK_TIME`, it is fine. This is because we set the +/// timestamp after on_initialize, so the timestamp is always one block old. +pub(crate) fn time_per_session() -> u64 { + Period::get() * BLOCK_TIME +} + +/// Time it takes to finish an era. +/// +/// Note, if you see `time_per_era() - BLOCK_TIME`, it is fine. This is because we set the +/// timestamp after on_initialize, so the timestamp is always one block old. +pub(crate) fn time_per_era() -> u64 { + time_per_session() * SessionsPerEra::get() as u64 +} + +/// Time that will be calculated for the reward per era. +pub(crate) fn reward_time_per_era() -> u64 { + time_per_era() - BLOCK_TIME } pub(crate) fn reward_all_elected() { @@ -939,8 +977,11 @@ pub(crate) fn make_all_reward_payment(era: EraIndex) { // reward validators for validator_controller in validators_with_reward.iter().filter_map(Staking::bonded) { let ledger = >::get(&validator_controller).unwrap(); - - assert_ok!(Staking::payout_stakers(Origin::signed(1337), ledger.stash, era)); + assert_ok!(Staking::payout_stakers( + Origin::signed(1337), + ledger.stash, + era + )); } } diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 79edc012cd3..86186af7d3e 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -158,7 +158,7 @@ fn change_controller_works() { // change controller assert_ok!(Staking::set_controller(Origin::signed(11), 5)); assert_eq!(Staking::bonded(&11), Some(5)); - mock::start_era(1); + mock::start_active_era(1); // 10 is no longer in control. assert_noop!( @@ -171,12 +171,7 @@ fn change_controller_works() { #[test] fn rewards_should_work() { - // should check that: - // * rewards get recorded per session - // * rewards get paid per Era - // * `RewardRemainder::on_unbalanced` is called - // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build_and_execute(|| { + ExtBuilder::default().nominate(true).session_per_era(3).build_and_execute(|| { let init_balance_10 = Balances::total_balance(&10); let init_balance_11 = Balances::total_balance(&11); let init_balance_20 = Balances::total_balance(&20); @@ -184,7 +179,7 @@ fn rewards_should_work() { let init_balance_100 = Balances::total_balance(&100); let init_balance_101 = Balances::total_balance(&101); - // Check state + // Set payees Payee::::insert(11, RewardDestination::Controller); Payee::::insert(21, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); @@ -194,9 +189,9 @@ fn rewards_should_work() { // This is the second validator of the current elected set. >::reward_by_ids(vec![(21, 50)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something + // Compute total payout now for whole duration of the session. + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); + let maximum_payout = maximum_payout_for_duration(reward_time_per_era()); start_session(1); @@ -207,10 +202,13 @@ fn rewards_should_work() { assert_eq!(Balances::total_balance(&100), init_balance_100); assert_eq!(Balances::total_balance(&101), init_balance_101); assert_eq_uvec!(Session::validators(), vec![11, 21]); - assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { - total: 50*3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - }); + assert_eq!( + Staking::eras_reward_points(Staking::active_era().unwrap().index), + EraRewardPoints { + total: 50 * 3, + individual: vec![(11, 100), (21, 50)].into_iter().collect(), + } + ); let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); @@ -220,14 +218,28 @@ fn rewards_should_work() { start_session(3); assert_eq!(Staking::active_era().unwrap().index, 1); - assert_eq!(mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), 7050); - assert_eq!(*mock::staking_events().last().unwrap(), RawEvent::EraPayout(0, 2350, 7050)); + assert_eq!( + mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), + maximum_payout - total_payout_0, + ); + assert_eq!( + *mock::staking_events().last().unwrap(), + RawEvent::EraPayout(0, total_payout_0, maximum_payout - total_payout_0) + ); mock::make_all_reward_payment(0); - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&10), + init_balance_10 + part_for_10 * total_payout_0 * 2 / 3, + 2, + ); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2,); + assert_eq_error_rate!( + Balances::total_balance(&20), + init_balance_20 + part_for_20 * total_payout_0 * 1 / 3, + 2, + ); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2,); assert_eq_error_rate!( Balances::total_balance(&100), init_balance_100 @@ -241,18 +253,31 @@ fn rewards_should_work() { >::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_1 > 10); // Test is meaningful if reward something + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - mock::start_era(2); - assert_eq!(mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), 7050*2); - assert_eq!(*mock::staking_events().last().unwrap(), RawEvent::EraPayout(1, 2350, 7050)); + mock::start_active_era(2); + assert_eq!( + mock::REWARD_REMAINDER_UNBALANCED.with(|v| *v.borrow()), + maximum_payout * 2 - total_payout_0 - total_payout_1, + ); + assert_eq!( + *mock::staking_events().last().unwrap(), + RawEvent::EraPayout(1, total_payout_1, maximum_payout - total_payout_1) + ); mock::make_all_reward_payment(1); - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); + assert_eq_error_rate!( + Balances::total_balance(&10), + init_balance_10 + part_for_10 * (total_payout_0 * 2 / 3 + total_payout_1), + 2, + ); + assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2,); + assert_eq_error_rate!( + Balances::total_balance(&20), + init_balance_20 + part_for_20 * total_payout_0 * 1 / 3, + 2, + ); + assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2,); assert_eq_error_rate!( Balances::total_balance(&100), init_balance_100 @@ -266,18 +291,11 @@ fn rewards_should_work() { #[test] fn staking_should_work() { - // should test: - // * new validators can be added to the default set - // * new ones will be chosen per era - // * either one can unlock the stash and back-down from being a validator via `chill`ing. ExtBuilder::default() .nominate(false) .fair(false) // to give 20 more staked value .build() .execute_with(|| { - // --- Block 1: - start_session(1); - // remember + compare this along with the test. assert_eq_uvec!(validator_controllers(), vec![20, 10]); @@ -359,7 +377,7 @@ fn less_than_needed_candidates_works() { assert_eq!(Staking::minimum_validator_count(), 1); assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); - mock::start_era(1); + mock::start_active_era(1); // Previous set is selected. NO election algorithm is even executed. assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]); @@ -395,7 +413,7 @@ fn no_candidate_emergency_condition() { let _ = Staking::chill(Origin::signed(10)); // trigger era - mock::start_era(1); + mock::start_active_era(1); // Previous ones are elected. chill is invalidates. TODO: #2494 assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]); @@ -435,12 +453,11 @@ fn nominating_and_rewards_should_work() { assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41])); // the total reward for era 0 - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(41, 1)]); >::reward_by_ids(vec![(31, 1)]); - mock::start_era(1); + mock::start_active_era(1); // 10 and 20 have more votes, they will be chosen. assert_eq_uvec!(validator_controllers(), vec![20, 10]); @@ -478,12 +495,11 @@ fn nominating_and_rewards_should_work() { ); // the total reward for era 1 - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningful if reward something + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(21, 2)]); >::reward_by_ids(vec![(11, 1)]); - mock::start_era(2); + mock::start_active_era(2); // nothing else will happen, era ends and rewards are paid again, // it is expected that nominators will also be paid. See below @@ -495,26 +511,26 @@ fn nominating_and_rewards_should_work() { assert_eq_error_rate!( Balances::total_balance(&2), initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), - 1, + 2, ); // Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11 assert_eq_error_rate!( Balances::total_balance(&4), initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11), - 1, + 2, ); // Validator 10: got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9 assert_eq_error_rate!( Balances::total_balance(&10), initial_balance + 5 * payout_for_10 / 9, - 1, + 2, ); // Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11 assert_eq_error_rate!( Balances::total_balance(&20), initial_balance + 5 * payout_for_20 / 11, - 1, + 2, ); }); } @@ -522,7 +538,7 @@ fn nominating_and_rewards_should_work() { #[test] fn nominators_also_get_slashed_pro_rata() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); + mock::start_active_era(1); let slash_percent = Perbill::from_percent(5); let initial_exposure = Staking::eras_stakers(active_era(), 11); // 101 is a nominator for 11 @@ -637,40 +653,87 @@ fn double_controlling_should_fail() { } #[test] -fn session_and_eras_work() { - ExtBuilder::default().build_and_execute(|| { - assert_eq!(Staking::active_era().unwrap().index, 0); - assert_eq!(Session::current_index(), 0); +fn session_and_eras_work_simple() { + ExtBuilder::default().period(1).build_and_execute(|| { + assert_eq!(active_era(), 0); + assert_eq!(current_era(), 0); + assert_eq!(Session::current_index(), 1); + assert_eq!(System::block_number(), 1); - // Session 1: No change. + // Session 1: this is basically a noop. This has already been started. start_session(1); assert_eq!(Session::current_index(), 1); - assert_eq!(Staking::active_era().unwrap().index, 0); + assert_eq!(active_era(), 0); + assert_eq!(System::block_number(), 1); // Session 2: No change. start_session(2); assert_eq!(Session::current_index(), 2); - assert_eq!(Staking::active_era().unwrap().index, 0); + assert_eq!(active_era(), 0); + assert_eq!(System::block_number(), 2); // Session 3: Era increment. start_session(3); assert_eq!(Session::current_index(), 3); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 3); // Session 4: No change. start_session(4); assert_eq!(Session::current_index(), 4); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 4); // Session 5: No change. start_session(5); assert_eq!(Session::current_index(), 5); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 5); // Session 6: Era increment. start_session(6); assert_eq!(Session::current_index(), 6); - assert_eq!(Staking::active_era().unwrap().index, 2); + assert_eq!(active_era(), 2); + assert_eq!(System::block_number(), 6); + }); +} + +#[test] +fn session_and_eras_work_complex() { + ExtBuilder::default().period(5).build_and_execute(|| { + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 0); + assert_eq!(System::block_number(), 1); + + start_session(1); + assert_eq!(Session::current_index(), 1); + assert_eq!(active_era(), 0); + assert_eq!(System::block_number(), 5); + + start_session(2); + assert_eq!(Session::current_index(), 2); + assert_eq!(active_era(), 0); + assert_eq!(System::block_number(), 10); + + start_session(3); + assert_eq!(Session::current_index(), 3); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 15); + + start_session(4); + assert_eq!(Session::current_index(), 4); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 20); + + start_session(5); + assert_eq!(Session::current_index(), 5); + assert_eq!(active_era(), 1); + assert_eq!(System::block_number(), 25); + + start_session(6); + assert_eq!(Session::current_index(), 6); + assert_eq!(active_era(), 2); + assert_eq!(System::block_number(), 30); }); } @@ -678,53 +741,62 @@ fn session_and_eras_work() { fn forcing_new_era_works() { ExtBuilder::default().build_and_execute(|| { // normal flow of session. - assert_eq!(Staking::active_era().unwrap().index, 0); - start_session(0); - assert_eq!(Staking::active_era().unwrap().index, 0); start_session(1); - assert_eq!(Staking::active_era().unwrap().index, 0); + assert_eq!(active_era(), 0); + start_session(2); - assert_eq!(Staking::active_era().unwrap().index, 0); + assert_eq!(active_era(), 0); + start_session(3); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); // no era change. ForceEra::put(Forcing::ForceNone); + start_session(4); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + start_session(5); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + start_session(6); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); + start_session(7); - assert_eq!(Staking::active_era().unwrap().index, 1); + assert_eq!(active_era(), 1); // back to normal. // this immediately starts a new session. ForceEra::put(Forcing::NotForcing); + start_session(8); - assert_eq!(Staking::active_era().unwrap().index, 1); // There is one session delay - start_session(9); - assert_eq!(Staking::active_era().unwrap().index, 2); + assert_eq!(active_era(), 1); + start_session(9); + assert_eq!(active_era(), 2); // forceful change ForceEra::put(Forcing::ForceAlways); + start_session(10); - assert_eq!(Staking::active_era().unwrap().index, 2); // There is one session delay + assert_eq!(active_era(), 2); + start_session(11); - assert_eq!(Staking::active_era().unwrap().index, 3); + assert_eq!(active_era(), 3); + start_session(12); - assert_eq!(Staking::active_era().unwrap().index, 4); + assert_eq!(active_era(), 4); // just one forceful change ForceEra::put(Forcing::ForceNew); start_session(13); - assert_eq!(Staking::active_era().unwrap().index, 5); + assert_eq!(active_era(), 5); assert_eq!(ForceEra::get(), Forcing::NotForcing); + start_session(14); - assert_eq!(Staking::active_era().unwrap().index, 6); + assert_eq!(active_era(), 6); + start_session(15); - assert_eq!(Staking::active_era().unwrap().index, 6); + assert_eq!(active_era(), 6); }); } @@ -738,7 +810,7 @@ fn cannot_transfer_staked_balance() { // Confirm account 11 has some free balance assert_eq!(Balances::free_balance(11), 1000); // Confirm account 11 (via controller 10) is totally staked - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000); + assert_eq!(Staking::eras_stakers(active_era(), 11).total, 1000); // Confirm account 11 cannot transfer as a result assert_noop!( Balances::transfer(Origin::signed(11), 20, 1), @@ -816,11 +888,10 @@ fn reward_destination_works() { })); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(11, 1)]); - mock::start_era(1); + mock::start_active_era(1); mock::make_all_reward_payment(0); // Check that RewardDestination is Staked (default) @@ -840,11 +911,10 @@ fn reward_destination_works() { >::insert(&11, RewardDestination::Stash); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningful if reward something + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(11, 1)]); - mock::start_era(2); + mock::start_active_era(2); mock::make_all_reward_payment(1); // Check that RewardDestination is Stash @@ -869,11 +939,10 @@ fn reward_destination_works() { assert_eq!(Balances::free_balance(10), 1); // Compute total payout now for whole duration as other parameter won't change - let total_payout_2 = current_total_payout_for_duration(3000); - assert!(total_payout_2 > 100); // Test is meaningful if reward something + let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(11, 1)]); - mock::start_era(3); + mock::start_active_era(3); mock::make_all_reward_payment(2); // Check that RewardDestination is Controller @@ -908,19 +977,18 @@ fn validator_payment_prefs_work() { >::insert(&11, RewardDestination::Controller); >::insert(&101, RewardDestination::Controller); - mock::start_era(1); + mock::start_active_era(1); mock::make_all_reward_payment(0); let balance_era_1_10 = Balances::total_balance(&10); let balance_era_1_100 = Balances::total_balance(&100); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningful if reward something + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let exposure_1 = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); >::reward_by_ids(vec![(11, 1)]); - mock::start_era(2); + mock::start_active_era(2); mock::make_all_reward_payment(1); let taken_cut = commission * total_payout_1; @@ -995,13 +1063,12 @@ fn bond_extra_and_withdraw_unbonded_works() { // Initial config should be correct assert_eq!(Staking::active_era().unwrap().index, 0); - assert_eq!(Session::current_index(), 0); // check the balance of a validator accounts. assert_eq!(Balances::total_balance(&10), 1); // confirm that 10 is a normal validator and gets paid at the end of the era. - mock::start_era(1); + mock::start_active_era(1); // Initial state of 10 assert_eq!(Staking::ledger(&10), Some(StakingLedger { @@ -1033,7 +1100,7 @@ fn bond_extra_and_withdraw_unbonded_works() { ); // trigger next era. - mock::start_era(2); + mock::start_active_era(2); assert_eq!(Staking::active_era().unwrap().index, 2); // ledger should be the same. @@ -1077,7 +1144,7 @@ fn bond_extra_and_withdraw_unbonded_works() { ); // trigger next era. - mock::start_era(3); + mock::start_active_era(3); // nothing yet assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); @@ -1093,7 +1160,7 @@ fn bond_extra_and_withdraw_unbonded_works() { ); // trigger next era. - mock::start_era(5); + mock::start_active_era(5); assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); // Now the value is free and the staking ledger is updated. @@ -1118,14 +1185,14 @@ fn too_many_unbond_calls_should_not_work() { assert_ok!(Staking::unbond(Origin::signed(10), 1)); } - mock::start_era(1); + mock::start_active_era(1); // locked at era 1 until 4 assert_ok!(Staking::unbond(Origin::signed(10), 1)); // can't do more. assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); - mock::start_era(3); + mock::start_active_era(3); assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); // free up. @@ -1157,7 +1224,7 @@ fn rebond_works() { let _ = Balances::make_free_balance_be(&11, 1000000); // confirm that 10 is a normal validator and gets paid at the end of the era. - mock::start_era(1); + mock::start_active_era(1); // Initial state of 10 assert_eq!( @@ -1171,7 +1238,7 @@ fn rebond_works() { }) ); - mock::start_era(2); + mock::start_active_era(2); assert_eq!(Staking::active_era().unwrap().index, 2); // Try to rebond some funds. We get an error since no fund is unbonded. @@ -1302,7 +1369,7 @@ fn rebond_is_fifo() { let _ = Balances::make_free_balance_be(&11, 1000000); // confirm that 10 is a normal validator and gets paid at the end of the era. - mock::start_era(1); + mock::start_active_era(1); // Initial state of 10 assert_eq!( @@ -1316,7 +1383,7 @@ fn rebond_is_fifo() { }) ); - mock::start_era(2); + mock::start_active_era(2); // Unbond some of the funds in stash. Staking::unbond(Origin::signed(10), 400).unwrap(); @@ -1333,7 +1400,7 @@ fn rebond_is_fifo() { }) ); - mock::start_era(3); + mock::start_active_era(3); // Unbond more of the funds in stash. Staking::unbond(Origin::signed(10), 300).unwrap(); @@ -1351,7 +1418,7 @@ fn rebond_is_fifo() { }) ); - mock::start_era(4); + mock::start_active_era(4); // Unbond yet more of the funds in stash. Staking::unbond(Origin::signed(10), 200).unwrap(); @@ -1411,13 +1478,12 @@ fn reward_to_stake_works() { >::insert(&20, StakingLedger { stash: 21, total: 69, active: 69, unlocking: vec![], claimed_rewards: vec![] }); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); >::reward_by_ids(vec![(11, 1)]); >::reward_by_ids(vec![(21, 1)]); // New era --> rewards are paid --> stakes are changed - mock::start_era(1); + mock::start_active_era(1); mock::make_all_reward_payment(0); assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000); @@ -1427,7 +1493,7 @@ fn reward_to_stake_works() { assert_eq!(_11_balance, 1000 + total_payout_0 / 2); // Trigger another new era as the info are frozen before the era start. - mock::start_era(2); + mock::start_active_era(2); // -- new infos assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).total, 1000 + total_payout_0 / 2); @@ -1568,7 +1634,7 @@ fn switching_roles() { assert_ok!(Staking::bond(Origin::signed(5), 6, 1000, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(6), ValidatorPrefs::default())); - mock::start_era(1); + mock::start_active_era(1); // with current nominators 10 and 5 have the most stake assert_eq_uvec!(validator_controllers(), vec![6, 10]); @@ -1582,7 +1648,7 @@ fn switching_roles() { // 2 : 2000 self vote + 250 vote. // Winners: 20 and 2 - mock::start_era(2); + mock::start_active_era(2); assert_eq_uvec!(validator_controllers(), vec![2, 20]); }); @@ -1604,7 +1670,7 @@ fn wrong_vote_is_null() { ])); // new block - mock::start_era(1); + mock::start_active_era(1); assert_eq_uvec!(validator_controllers(), vec![20, 10]); }); @@ -1643,15 +1709,15 @@ fn bond_with_no_staked_value() { }) ); - mock::start_era(1); - mock::start_era(2); + mock::start_active_era(1); + mock::start_active_era(2); // not yet removed. assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0)); assert!(Staking::ledger(2).is_some()); assert_eq!(Balances::locks(&1)[0].amount, 5); - mock::start_era(3); + mock::start_active_era(3); // poof. Account 1 is removed from the staking system. assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0)); @@ -1662,8 +1728,6 @@ fn bond_with_no_staked_value() { #[test] fn bond_with_little_staked_value_bounded() { - // Behavior when someone bonds with little staked value. - // Particularly when she votes and the candidate is elected. ExtBuilder::default() .validator_count(3) .nominate(false) @@ -1680,37 +1744,38 @@ fn bond_with_little_staked_value_bounded() { assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); - // reward era 0 - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something + // 1 era worth of reward. BUT, we set the timestamp after on_initialize, so outdated by + // one block. + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); + reward_all_elected(); - mock::start_era(1); + mock::start_active_era(1); mock::make_all_reward_payment(0); // 2 is elected. assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); - // And has minimal stake - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 2).total, 0); + assert_eq!(Staking::eras_stakers(active_era(), 2).total, 0); // Old ones are rewarded. - assert_eq!(Balances::free_balance(10), init_balance_10 + total_payout_0 / 3); + assert_eq_error_rate!(Balances::free_balance(10), init_balance_10 + total_payout_0 / 3, 1); // no rewards paid to 2. This was initial election. assert_eq!(Balances::free_balance(2), init_balance_2); - // reward era 1 - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningful if reward something + // reward era 2 + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); reward_all_elected(); - mock::start_era(2); + mock::start_active_era(2); mock::make_all_reward_payment(1); assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 2).total, 0); + assert_eq!(Staking::eras_stakers(active_era(), 2).total, 0); - assert_eq!(Balances::free_balance(2), init_balance_2 + total_payout_1 / 3); - assert_eq!( + // 2 is now rewarded. + assert_eq_error_rate!(Balances::free_balance(2), init_balance_2 + total_payout_1 / 3, 1); + assert_eq_error_rate!( Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3, + 2, ); }); } @@ -1842,7 +1907,7 @@ fn phragmen_should_not_overflow() { bond_nominator(7, 6, Votes::max_value() as Balance, vec![3, 5]); bond_nominator(9, 8, Votes::max_value() as Balance, vec![3, 5]); - mock::start_era(1); + mock::start_active_era(1); assert_eq_uvec!(validator_controllers(), vec![4, 2]); @@ -1983,10 +2048,10 @@ fn era_is_always_same_length() { ExtBuilder::default().build_and_execute(|| { let session_per_era = >::get(); - mock::start_era(1); + mock::start_active_era(1); assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session_per_era); - mock::start_era(2); + mock::start_active_era(2); assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session_per_era * 2u32); let session = Session::current_index(); @@ -1996,7 +2061,7 @@ fn era_is_always_same_length() { assert_eq!(current_era(), 3); assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session + 2); - mock::start_era(4); + mock::start_active_era(4); assert_eq!(Staking::eras_start_session_index(current_era()).unwrap(), session + 2u32 + session_per_era); }); } @@ -2060,7 +2125,7 @@ fn offence_deselects_validator_even_when_slash_is_zero() { assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); - mock::start_era(1); + mock::start_active_era(1); assert!(!Session::validators().contains(&11)); assert!(!>::contains_key(11)); @@ -2098,7 +2163,7 @@ fn slashing_performed_according_exposure() { #[test] fn slash_in_old_span_does_not_deselect() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); + mock::start_active_era(1); assert!(>::contains_key(11)); assert!(Session::validators().contains(&11)); @@ -2117,14 +2182,14 @@ fn slash_in_old_span_does_not_deselect() { assert_eq!(Staking::force_era(), Forcing::ForceNew); assert!(!>::contains_key(11)); - mock::start_era(2); + mock::start_active_era(2); Staking::validate(Origin::signed(10), Default::default()).unwrap(); assert_eq!(Staking::force_era(), Forcing::NotForcing); assert!(>::contains_key(11)); assert!(!Session::validators().contains(&11)); - mock::start_era(3); + mock::start_active_era(3); // this staker is in a new slashing span now, having re-registered after // their prior slash. @@ -2409,7 +2474,7 @@ fn garbage_collection_on_window_pruning() { // ensures that `ValidatorSlashInEra` and `NominatorSlashInEra` are cleared after // `BondingDuration`. ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); + mock::start_active_era(1); assert_eq!(Balances::free_balance(11), 1000); let now = Staking::active_era().unwrap().index; @@ -2439,7 +2504,7 @@ fn garbage_collection_on_window_pruning() { assert!(::ValidatorSlashInEra::get(&now, &11).is_some()); assert!(::NominatorSlashInEra::get(&now, &101).is_some()); - mock::start_era(era); + mock::start_active_era(era); } assert!(::ValidatorSlashInEra::get(&now, &11).is_none()); @@ -2450,9 +2515,9 @@ fn garbage_collection_on_window_pruning() { #[test] fn slashing_nominators_by_span_max() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); - mock::start_era(2); - mock::start_era(3); + mock::start_active_era(1); + mock::start_active_era(2); + mock::start_active_era(3); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(21), 2000); @@ -2548,9 +2613,9 @@ fn slashing_nominators_by_span_max() { #[test] fn slashes_are_summed_across_spans() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); - mock::start_era(2); - mock::start_era(3); + mock::start_active_era(1); + mock::start_active_era(2); + mock::start_active_era(3); assert_eq!(Balances::free_balance(21), 2000); assert_eq!(Staking::slashable_balance_of(&21), 1000); @@ -2578,7 +2643,7 @@ fn slashes_are_summed_across_spans() { // 21 has been force-chilled. re-signal intent to validate. Staking::validate(Origin::signed(20), Default::default()).unwrap(); - mock::start_era(4); + mock::start_active_era(4); assert_eq!(Staking::slashable_balance_of(&21), 900); @@ -2605,16 +2670,18 @@ fn slashes_are_summed_across_spans() { #[test] fn deferred_slashes_are_deferred() { - ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { - mock::start_era(1); + ExtBuilder::default() + .slash_defer_duration(2) + .build_and_execute(|| { + mock::start_active_era(1); - assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(11), 1000); - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); - assert_eq!(Balances::free_balance(101), 2000); - let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); + assert_eq!(Balances::free_balance(101), 2000); + let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; - on_offence_now( + on_offence_now( &[ OffenceDetails { offender: (11, Staking::eras_stakers(Staking::active_era().unwrap().index, 11)), @@ -2624,40 +2691,42 @@ fn deferred_slashes_are_deferred() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - mock::start_era(2); + mock::start_active_era(2); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - mock::start_era(3); + mock::start_active_era(3); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - // at the start of era 4, slashes from era 1 are processed, - // after being deferred for at least 2 full eras. - mock::start_era(4); + // at the start of era 4, slashes from era 1 are processed, + // after being deferred for at least 2 full eras. + mock::start_active_era(4); - assert_eq!(Balances::free_balance(11), 900); - assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); - }) + assert_eq!(Balances::free_balance(11), 900); + assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); + }) } #[test] fn remove_deferred() { - ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { - mock::start_era(1); + ExtBuilder::default() + .slash_defer_duration(2) + .build_and_execute(|| { + mock::start_active_era(1); - assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(11), 1000); - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); - assert_eq!(Balances::free_balance(101), 2000); - let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); + assert_eq!(Balances::free_balance(101), 2000); + let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; - on_offence_now( + on_offence_now( &[ OffenceDetails { offender: (11, exposure.clone()), @@ -2667,12 +2736,12 @@ fn remove_deferred() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - mock::start_era(2); + mock::start_active_era(2); - on_offence_in_era( + on_offence_in_era( &[ OffenceDetails { offender: (11, exposure.clone()), @@ -2689,32 +2758,32 @@ fn remove_deferred() { Error::::EmptyTargets ); - assert_ok!(Staking::cancel_deferred_slash(Origin::root(), 1, vec![0])); + assert_ok!(Staking::cancel_deferred_slash(Origin::root(), 1, vec![0])); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - mock::start_era(3); + mock::start_active_era(3); - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - // at the start of era 4, slashes from era 1 are processed, - // after being deferred for at least 2 full eras. - mock::start_era(4); + // at the start of era 4, slashes from era 1 are processed, + // after being deferred for at least 2 full eras. + mock::start_active_era(4); - // the first slash for 10% was cancelled, so no effect. - assert_eq!(Balances::free_balance(11), 1000); - assert_eq!(Balances::free_balance(101), 2000); + // the first slash for 10% was cancelled, so no effect. + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); - mock::start_era(5); + mock::start_active_era(5); - let slash_10 = Perbill::from_percent(10); - let slash_15 = Perbill::from_percent(15); - let initial_slash = slash_10 * nominated_value; + let slash_10 = Perbill::from_percent(10); + let slash_15 = Perbill::from_percent(15); + let initial_slash = slash_10 * nominated_value; - let total_slash = slash_15 * nominated_value; - let actual_slash = total_slash - initial_slash; + let total_slash = slash_15 * nominated_value; + let actual_slash = total_slash - initial_slash; // 5% slash (15 - 10) processed now. assert_eq!(Balances::free_balance(11), 950); @@ -2724,15 +2793,17 @@ fn remove_deferred() { #[test] fn remove_multi_deferred() { - ExtBuilder::default().slash_defer_duration(2).build_and_execute(|| { - mock::start_era(1); + ExtBuilder::default() + .slash_defer_duration(2) + .build_and_execute(|| { + mock::start_active_era(1); - assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(11), 1000); - let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); - assert_eq!(Balances::free_balance(101), 2000); + let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11); + assert_eq!(Balances::free_balance(101), 2000); - on_offence_now( + on_offence_now( &[ OffenceDetails { offender: (11, exposure.clone()), @@ -2899,7 +2970,7 @@ mod offchain_election { .session_per_era(3) .build() .execute_with(|| { - mock::start_era(1); + mock::start_active_era(1); assert_eq!(Session::current_index(), 3); assert_eq!(Staking::current_era(), Some(1)); assert_eq!(Staking::is_current_session_final(), false); @@ -2921,7 +2992,7 @@ mod offchain_election { fn offchain_window_is_triggered() { ExtBuilder::default() .session_per_era(5) - .session_length(10) + .period(10) .election_lookahead(3) .build() .execute_with(|| { @@ -2981,7 +3052,7 @@ mod offchain_election { fn offchain_window_is_triggered_when_forcing() { ExtBuilder::default() .session_per_era(5) - .session_length(10) + .period(10) .election_lookahead(3) .build() .execute_with(|| { @@ -3002,11 +3073,10 @@ mod offchain_election { fn offchain_window_is_triggered_when_force_always() { ExtBuilder::default() .session_per_era(5) - .session_length(10) + .period(10) .election_lookahead(3) .build() .execute_with(|| { - ForceEra::put(Forcing::ForceAlways); run_to_block(16); assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); @@ -3029,7 +3099,7 @@ mod offchain_election { fn offchain_window_closes_when_forcenone() { ExtBuilder::default() .session_per_era(5) - .session_length(10) + .period(10) .election_lookahead(3) .build() .execute_with(|| { @@ -4101,7 +4171,7 @@ mod offchain_election { #[test] fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_validator() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); + mock::start_active_era(1); assert_eq_uvec!(Session::validators(), vec![11, 21]); // pre-slash balance @@ -4149,7 +4219,7 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid // actually re-bond the slashed validator assert_ok!(Staking::validate(Origin::signed(10), Default::default())); - mock::start_era(2); + mock::start_active_era(2); let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, &11); let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, &21); @@ -4180,31 +4250,28 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { >::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something + let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - mock::start_era(1); + mock::start_active_era(1); >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 10); // Test is meaningful if reward something + let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); assert!(total_payout_1 != total_payout_0); - mock::start_era(2); + mock::start_active_era(2); >::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change - let total_payout_2 = current_total_payout_for_duration(3000); - assert!(total_payout_2 > 10); // Test is meaningful if reward something + let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); assert!(total_payout_2 != total_payout_0); assert!(total_payout_2 != total_payout_1); - mock::start_era(Staking::history_depth() + 1); + mock::start_active_era(Staking::history_depth() + 1); let active_era = Staking::active_era().unwrap().index; @@ -4248,7 +4315,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { #[test] fn zero_slash_keeps_nominators() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(1); + mock::start_active_era(1); assert_eq!(Balances::free_balance(11), 1000); @@ -4285,12 +4352,13 @@ fn zero_slash_keeps_nominators() { #[test] fn six_session_delay() { - ExtBuilder::default().build_and_execute(|| { + ExtBuilder::default().initialize_first_session(false).build_and_execute(|| { use pallet_session::SessionManager; let val_set = Session::validators(); let init_session = Session::current_index(); let init_active_era = Staking::active_era().unwrap().index; + // pallet-session is delaying session by one, thus the next session to plan is +2. assert_eq!(>::new_session(init_session + 2), None); assert_eq!(>::new_session(init_session + 3), Some(val_set.clone())); @@ -4300,10 +4368,11 @@ fn six_session_delay() { >::end_session(init_session); >::start_session(init_session + 1); - assert_eq!(Staking::active_era().unwrap().index, init_active_era); + assert_eq!(active_era(), init_active_era); + >::end_session(init_session + 1); >::start_session(init_session + 2); - assert_eq!(Staking::active_era().unwrap().index, init_active_era); + assert_eq!(active_era(), init_active_era); // Reward current era Staking::reward_by_ids(vec![(11, 1)]); @@ -4311,13 +4380,15 @@ fn six_session_delay() { // New active era is triggered here. >::end_session(init_session + 2); >::start_session(init_session + 3); - assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1); + assert_eq!(active_era(), init_active_era + 1); + >::end_session(init_session + 3); >::start_session(init_session + 4); - assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1); + assert_eq!(active_era(), init_active_era + 1); + >::end_session(init_session + 4); >::start_session(init_session + 5); - assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1); + assert_eq!(active_era(), init_active_era + 1); // Reward current era Staking::reward_by_ids(vec![(21, 2)]); @@ -4325,7 +4396,7 @@ fn six_session_delay() { // New active era is triggered here. >::end_session(init_session + 5); >::start_session(init_session + 6); - assert_eq!(Staking::active_era().unwrap().index, init_active_era + 2); + assert_eq!(active_era(), init_active_era + 2); // That reward are correct assert_eq!(Staking::eras_reward_points(init_active_era).total, 1); @@ -4335,10 +4406,6 @@ fn six_session_delay() { #[test] fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward() { - // Test: - // * If nominator nomination is below the $MaxNominatorRewardedPerValidator other nominator - // then the nominator can't claim its reward - // * A nominator can't claim another nominator reward ExtBuilder::default().build_and_execute(|| { for i in 0..=::MaxNominatorRewardedPerValidator::get() { let stash = 10_000 + i as AccountId; @@ -4355,14 +4422,13 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( ); assert_ok!(Staking::nominate(Origin::signed(controller), vec![11])); } - mock::start_era(1); + mock::start_active_era(1); >::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); - mock::start_era(2); + mock::start_active_era(2); mock::make_all_reward_payment(1); // Assert only nominators from 1 to Max are rewarded @@ -4381,7 +4447,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( #[test] fn set_history_depth_works() { ExtBuilder::default().build_and_execute(|| { - mock::start_era(10); + mock::start_active_era(10); Staking::set_history_depth(Origin::root(), 20, 0).unwrap(); assert!(::ErasTotalStake::contains_key(10 - 4)); assert!(::ErasTotalStake::contains_key(10 - 5)); @@ -4411,12 +4477,13 @@ fn test_payout_stakers() { bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]); } - mock::start_era(1); + mock::start_active_era(1); Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(2); + + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + + mock::start_active_era(2); assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); // Top 64 nominators of validator 11 automatically paid out, including the validator @@ -4438,10 +4505,11 @@ fn test_payout_stakers() { for i in 3..16 { Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(i); + + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + + mock::start_active_era(i); assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, i - 1)); } @@ -4453,10 +4521,9 @@ fn test_payout_stakers() { for i in 16..100 { Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(i); + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + mock::start_active_era(i); } // We clean it up as history passes @@ -4491,12 +4558,13 @@ fn payout_stakers_handles_basic_errors() { bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]); } - mock::start_era(1); + mock::start_active_era(1); Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(2); + + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + + mock::start_active_era(2); // Wrong Era, too big assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 2), Error::::InvalidEraToReward); @@ -4505,10 +4573,9 @@ fn payout_stakers_handles_basic_errors() { for i in 3..100 { Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(i); + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + mock::start_active_era(i); } // We are at era 99, with history depth of 84 // We should be able to payout era 15 through 98 (84 total eras), but not 14 or 99. @@ -4538,7 +4605,7 @@ fn bond_during_era_correctly_populates_claimed_rewards() { claimed_rewards: vec![], }) ); - mock::start_era(5); + mock::start_active_era(5); bond_validator(11, 10, 1000); assert_eq!( Staking::ledger(&10), @@ -4550,7 +4617,7 @@ fn bond_during_era_correctly_populates_claimed_rewards() { claimed_rewards: (0..5).collect(), }) ); - mock::start_era(99); + mock::start_active_era(99); bond_validator(13, 12, 1000); assert_eq!( Staking::ledger(&12), @@ -4655,12 +4722,11 @@ fn payout_creates_controller() { assert_ok!(Balances::transfer(Origin::signed(1337), 1234, 100)); assert_eq!(Balances::free_balance(1337), 0); - mock::start_era(1); + mock::start_active_era(1); Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(2); + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + mock::start_active_era(2); assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); // Controller is created @@ -4684,12 +4750,11 @@ fn payout_to_any_account_works() { // Reward Destination account doesn't exist assert_eq!(Balances::free_balance(42), 0); - mock::start_era(1); + mock::start_active_era(1); Staking::reward_by_ids(vec![(11, 1)]); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 100); // Test is meaningful if reward something - mock::start_era(2); + // compute and ensure the reward amount is greater than zero. + let _ = current_total_payout_for_duration(reward_time_per_era()); + mock::start_active_era(2); assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); // Payment is successful @@ -4698,7 +4763,111 @@ fn payout_to_any_account_works() { } #[test] -fn cannot_bond_extra_to_lower_than_ed() { +fn session_buffering_with_offset() { + // similar to live-chains, have some offset for the first session + ExtBuilder::default() + .offset(2) + .period(5) + .session_per_era(5) + .build_and_execute(|| { + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 0); + + start_session(1); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 1); + assert_eq!(System::block_number(), 2); + + start_session(2); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 2); + assert_eq!(System::block_number(), 7); + + start_session(3); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 3); + assert_eq!(System::block_number(), 12); + + // active era is lagging behind by one session, because of how session module works. + start_session(4); + assert_eq!(current_era(), 1); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 4); + assert_eq!(System::block_number(), 17); + + start_session(5); + assert_eq!(current_era(), 1); + assert_eq!(active_era(), 1); + assert_eq!(Session::current_index(), 5); + assert_eq!(System::block_number(), 22); + + // go all the way to active 2. + start_active_era(2); + assert_eq!(current_era(), 2); + assert_eq!(active_era(), 2); + assert_eq!(Session::current_index(), 10); + + }); +} + +#[test] +fn session_buffering_no_offset() { + // no offset, first session starts immediately + ExtBuilder::default() + .offset(0) + .period(5) + .session_per_era(5) + .build_and_execute(|| { + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 0); + + start_session(1); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 1); + assert_eq!(System::block_number(), 5); + + start_session(2); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 2); + assert_eq!(System::block_number(), 10); + + start_session(3); + assert_eq!(current_era(), 0); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 3); + assert_eq!(System::block_number(), 15); + + // active era is lagging behind by one session, because of how session module works. + start_session(4); + assert_eq!(current_era(), 1); + assert_eq!(active_era(), 0); + assert_eq!(Session::current_index(), 4); + assert_eq!(System::block_number(), 20); + + start_session(5); + assert_eq!(current_era(), 1); + assert_eq!(active_era(), 1); + assert_eq!(Session::current_index(), 5); + assert_eq!(System::block_number(), 25); + + // go all the way to active 2. + start_active_era(2); + assert_eq!(current_era(), 2); + assert_eq!(active_era(), 2); + assert_eq!(Session::current_index(), 10); + + }); +} + +#[test] +fn cannot_rebond_to_lower_than_ed() { ExtBuilder::default() .existential_deposit(10) .build_and_execute(|| { @@ -4732,14 +4901,14 @@ fn cannot_bond_extra_to_lower_than_ed() { // now bond a wee bit more assert_noop!( - Staking::bond_extra(Origin::signed(21), 5), + Staking::rebond(Origin::signed(20), 5), Error::::InsufficientValue, ); }) } #[test] -fn cannot_rebond_to_lower_than_ed() { +fn cannot_bond_extra_to_lower_than_ed() { ExtBuilder::default() .existential_deposit(10) .build_and_execute(|| { @@ -4766,14 +4935,17 @@ fn cannot_rebond_to_lower_than_ed() { stash: 21, total: 1000, active: 0, - unlocking: vec![UnlockChunk { value: 1000, era: 3 }], + unlocking: vec![UnlockChunk { + value: 1000, + era: 3 + }], claimed_rewards: vec![] } ); // now bond a wee bit more assert_noop!( - Staking::rebond(Origin::signed(20), 5), + Staking::bond_extra(Origin::signed(21), 5), Error::::InsufficientValue, ); }) -- GitLab From 48bf02ad068d4958b186dd2090c215eadf9dacda Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Mon, 21 Dec 2020 22:22:47 +0800 Subject: [PATCH 137/163] optimize biguint div closure (#7754) * optimize biguint div closure * optimize biguint sub and fix note * change and add biguint split test * add biguint div_unit test * update biguint sub v to v1 * add biguint shift_check --- primitives/arithmetic/src/biguint.rs | 36 ++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/primitives/arithmetic/src/biguint.rs b/primitives/arithmetic/src/biguint.rs index 03f2bb1e55f..64418956fcd 100644 --- a/primitives/arithmetic/src/biguint.rs +++ b/primitives/arithmetic/src/biguint.rs @@ -7,7 +7,7 @@ // 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 +// 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, @@ -212,9 +212,9 @@ impl BigUint { let mut needs_borrow = false; let mut t = 0; - if let Some(v) = u.checked_sub(v) { - if let Some(v2) = v.checked_sub(k) { - t = v2 % B; + if let Some(v1) = u.checked_sub(v) { + if let Some(v2) = v1.checked_sub(k) { + t = v2; k = 0; } else { needs_borrow = true; @@ -228,9 +228,9 @@ impl BigUint { } t }; - // PROOF: t either comes from `v2 % B`, or from `u + B - v - k`. The former is + // PROOF: t either comes from `v2`, or from `u + B - v - k`. The former is // trivial. The latter will not overflow this branch will only happen if the sum of - // `u - v - k` part has been negative, hence `u + B - v - k < b`. + // `u - v - k` part has been negative, hence `u + B - v - k < B`. w.set(j, s as Single); } @@ -287,9 +287,9 @@ impl BigUint { let mut out = Self::with_capacity(n); let mut r: Single = 0; // PROOF: (B-1) * B + (B-1) still fits in double - let with_r = |x: Double, r: Single| { Double::from(r) * B + x }; + let with_r = |x: Single, r: Single| { Double::from(r) * B + Double::from(x) }; for d in (0..n).rev() { - let (q, rr) = div_single(with_r(self.get(d).into(), r), other) ; + let (q, rr) = div_single(with_r(self.get(d), r), other) ; out.set(d, q as Single); r = rr; } @@ -580,14 +580,25 @@ pub mod tests { BigUint { digits: vec![1; n] } } + #[test] + fn shift_check() { + let shift = sp_std::mem::size_of::() - sp_std::mem::size_of::(); + assert_eq!(shift * 8, SHIFT); + } + #[test] fn split_works() { let a = SHIFT / 2; let b = SHIFT * 3 / 2; let num: Double = 1 << a | 1 << b; - // example when `Single = u8` - // assert_eq!(num, 0b_0001_0000_0001_0000) + assert_eq!(num, 0x_0001_0000_0001_0000); assert_eq!(split(num), (1 << a, 1 << a)); + + let a = SHIFT / 2 + 4; + let b = SHIFT / 2 - 4; + let num: Double = 1 << (SHIFT + a) | 1 << b; + assert_eq!(num, 0x_0010_0000_0000_1000); + assert_eq!(split(num), (1 << a, 1 << b)); } #[test] @@ -734,6 +745,7 @@ pub mod tests { fn div_unit_works() { let a = BigUint { digits: vec![100] }; let b = BigUint { digits: vec![1, 100] }; + let c = BigUint { digits: vec![14, 28, 100] }; assert_eq!(a.clone().div_unit(1), a); assert_eq!(a.clone().div_unit(0), a); @@ -745,5 +757,9 @@ pub mod tests { assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single)); assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single)); + assert_eq!(c.clone().div_unit(1), c); + assert_eq!(c.clone().div_unit(0), c); + assert_eq!(c.clone().div_unit(2), BigUint { digits: vec![7, 14, 50] }); + assert_eq!(c.clone().div_unit(7), BigUint { digits: vec![2, 4, 14] }); } } -- GitLab From 22b34bbc45521c79d77b07c96ac5e841480ef502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 21 Dec 2020 18:08:22 +0100 Subject: [PATCH 138/163] Make it possible to calculate the storage root as often as you want (#7714) * Make it possible to calculate the storage as often as you want So, until now each Substrate based blockchain has calculated the storage root once, at the end of the block. Now there is Frontier that wants to calculate some intermediate storage root. However this failed on block import. The problem with that was the extrinsics root. When building the block we stored `Default::default()` as extrinsics root, because yeah, we don't know the extrinsics root before finishing the block. At the end this extrinsics root was then calculated. But on block import we passed the already known extrinsics root. This was no problem, as we removed this value at the end of the block. However when you all the storage root in between, that changes the storage root between block building and block import. This pr changes this behavior. It removes the `ExtrinsicsRoot` storage entry and also doesn't pass it anymore to `System::initialize`. By doing it, we remove the difference in the storage and fix the storage root mismatch. * Fix bug with incorrectly calculating the extrinscs root * Review feedback --- frame/authorship/src/lib.rs | 2 - frame/babe/src/mock.rs | 4 +- frame/babe/src/tests.rs | 4 -- frame/contracts/src/tests.rs | 1 - frame/executive/src/lib.rs | 78 +++++++++++++-------- frame/grandpa/src/mock.rs | 2 - frame/merkle-mountain-range/src/tests.rs | 1 - frame/randomness-collective-flip/src/lib.rs | 1 - frame/system/src/lib.rs | 41 ++++------- frame/system/src/tests.rs | 32 +++++++-- 10 files changed, 90 insertions(+), 76 deletions(-) diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index b991beaaa2b..693375e3c50 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -582,7 +582,6 @@ mod tests { &number, &hash, &Default::default(), - &Default::default(), Default::default() ); @@ -681,7 +680,6 @@ mod tests { System::initialize( &1, &Default::default(), - &Default::default(), header.digest(), Default::default(), ); diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 8af92c79e91..77b117db7f3 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -259,7 +259,7 @@ pub fn go_to_block(n: u64, s: u64) { let pre_digest = make_secondary_plain_pre_digest(0, s); - System::initialize(&n, &parent_hash, &Default::default(), &pre_digest, InitKind::Full); + System::initialize(&n, &parent_hash, &pre_digest, InitKind::Full); System::set_block_number(n); Timestamp::set_timestamp(n); @@ -447,7 +447,7 @@ pub fn generate_equivocation_proof( let make_header = || { let parent_hash = System::parent_hash(); let pre_digest = make_secondary_plain_pre_digest(offender_authority_index, slot_number); - System::initialize(¤t_block, &parent_hash, &Default::default(), &pre_digest, InitKind::Full); + System::initialize(¤t_block, &parent_hash, &pre_digest, InitKind::Full); System::set_block_number(current_block); Timestamp::set_timestamp(current_block); System::finalize() diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 29b080493f4..1e522bd83cd 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -77,7 +77,6 @@ fn first_block_epoch_zero_start() { System::initialize( &1, &Default::default(), - &Default::default(), &pre_digest, Default::default(), ); @@ -128,7 +127,6 @@ fn author_vrf_output_for_primary() { System::initialize( &1, &Default::default(), - &Default::default(), &primary_pre_digest, Default::default(), ); @@ -155,7 +153,6 @@ fn author_vrf_output_for_secondary_vrf() { System::initialize( &1, &Default::default(), - &Default::default(), &secondary_vrf_pre_digest, Default::default(), ); @@ -179,7 +176,6 @@ fn no_author_vrf_output_for_secondary_plain() { System::initialize( &1, &Default::default(), - &Default::default(), &secondary_plain_pre_digest, Default::default(), ); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 3a7a8c6436e..6ac2fb0f976 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -698,7 +698,6 @@ fn initialize_block(number: u64) { System::initialize( &number, &[0u8; 32].into(), - &[0u8; 32].into(), &Default::default(), Default::default(), ); diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 59e9cae1983..caba857254d 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -130,7 +130,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use codec::{Codec, Encode}; -use frame_system::{extrinsics_root, DigestOf}; +use frame_system::DigestOf; /// Trait that can be used to execute a block. pub trait ExecuteBlock { @@ -213,7 +213,6 @@ where Self::initialize_block_impl( header.number(), header.parent_hash(), - header.extrinsics_root(), &digests ); } @@ -231,7 +230,6 @@ where fn initialize_block_impl( block_number: &System::BlockNumber, parent_hash: &System::Hash, - extrinsics_root: &System::Hash, digest: &Digest, ) { let mut weight = 0; @@ -244,7 +242,6 @@ where >::initialize( block_number, parent_hash, - extrinsics_root, digest, frame_system::InitKind::Full, ); @@ -286,13 +283,8 @@ where assert!( n > System::BlockNumber::zero() && >::block_hash(n - System::BlockNumber::one()) == *header.parent_hash(), - "Parent hash should be valid." + "Parent hash should be valid.", ); - - // Check that transaction trie root represents the transactions. - let xts_root = extrinsics_root::(&block.extrinsics()); - header.extrinsics_root().check_equal(&xts_root); - assert!(header.extrinsics_root() == &xts_root, "Transaction trie root must be valid."); } /// Actually execute all transitions for `block`. @@ -322,8 +314,14 @@ where } /// Execute given extrinsics and take care of post-extrinsics book-keeping. - fn execute_extrinsics_with_book_keeping(extrinsics: Vec, block_number: NumberFor) { - extrinsics.into_iter().for_each(Self::apply_extrinsic_no_note); + fn execute_extrinsics_with_book_keeping( + extrinsics: Vec, + block_number: NumberFor, + ) { + extrinsics.into_iter().for_each(|e| if let Err(e) = Self::apply_extrinsic(e) { + let err: &'static str = e.into(); + panic!(err) + }); // post-extrinsics book-keeping >::note_finished_extrinsics(); @@ -341,8 +339,6 @@ where as OnFinalize>::on_finalize(block_number); >::on_finalize(block_number); - // set up extrinsics - >::derive_extrinsics(); >::finalize() } @@ -354,23 +350,14 @@ where sp_io::init_tracing(); let encoded = uxt.encode(); let encoded_len = encoded.len(); - Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) - } - - /// Apply an extrinsic inside the block execution function. - fn apply_extrinsic_no_note(uxt: Block::Extrinsic) { - let l = uxt.encode().len(); - match Self::apply_extrinsic_with_len(uxt, l, None) { - Ok(_) => (), - Err(e) => { let err: &'static str = e.into(); panic!(err) }, - } + Self::apply_extrinsic_with_len(uxt, encoded_len, encoded) } /// Actually apply an extrinsic given its `encoded_len`; this doesn't note its hash. fn apply_extrinsic_with_len( uxt: Block::Extrinsic, encoded_len: usize, - to_note: Option>, + to_note: Vec, ) -> ApplyExtrinsicResult { sp_tracing::enter_span!( sp_tracing::info_span!("apply_extrinsic", @@ -382,9 +369,7 @@ where // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either // execute or panic (and revert storage changes). - if let Some(encoded) = to_note { - >::note_extrinsic(encoded); - } + >::note_extrinsic(to_note); // AUDIT: Under no circumstances may this function panic from here onwards. @@ -418,6 +403,11 @@ where let storage_root = new_header.state_root(); header.state_root().check_equal(&storage_root); assert!(header.state_root() == storage_root, "Storage root must match that calculated."); + + assert!( + header.extrinsics_root() == new_header.extrinsics_root(), + "Transaction trie root must be valid.", + ); } /// Check a given signed transaction for validity. This doesn't execute any @@ -462,7 +452,6 @@ where >::initialize( header.number(), header.parent_hash(), - header.extrinsics_root(), &digests, frame_system::InitKind::Inspection, ); @@ -558,6 +547,12 @@ mod tests { fn offchain_worker(n: T::BlockNumber) { assert_eq!(T::BlockNumber::from(1u32), n); } + + #[weight = 0] + fn calculate_storage_root(origin) { + let root = sp_io::storage::root(); + sp_io::storage::set("storage_root".as_bytes(), &root); + } } } @@ -1153,4 +1148,29 @@ mod tests { assert_eq!(header.hash(), System::block_hash(1)); }); } + + #[test] + fn calculating_storage_root_twice_works() { + let call = Call::Custom(custom::Call::calculate_storage_root()); + let xt = TestXt::new(call, sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new( + 1, + H256::default(), + H256::default(), + [69u8; 32].into(), + Digest::default(), + )); + + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt])); + }); + } } diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 4a5de63e839..ae13c946597 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -359,7 +359,6 @@ pub fn start_session(session_index: SessionIndex) { &(i as u64 + 1), &parent_hash, &Default::default(), - &Default::default(), Default::default(), ); System::set_block_number((i + 1).into()); @@ -384,7 +383,6 @@ pub fn initialize_block(number: u64, parent_hash: H256) { &number, &parent_hash, &Default::default(), - &Default::default(), Default::default(), ); } diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 059ff6612f1..34ce96eaba7 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -46,7 +46,6 @@ fn new_block() -> u64 { &number, &hash, &Default::default(), - &Default::default(), frame_system::InitKind::Full, ); MMR::on_initialize(number) diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 7e0e64f3cc0..9332262d687 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -205,7 +205,6 @@ mod tests { &i, &parent_hash, &Default::default(), - &Default::default(), frame_system::InitKind::Full, ); CollectiveFlip::on_initialize(i); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c5586f98566..4bcab6e6c0e 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -107,7 +107,7 @@ use sp_runtime::{ self, CheckEqual, AtLeast32Bit, Zero, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, - Dispatchable, AtLeast32BitUnsigned + Dispatchable, AtLeast32BitUnsigned, Saturating, }, offchain::storage_lock::BlockNumberProvider, }; @@ -405,9 +405,6 @@ decl_storage! { /// Hash of the previous block. ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; - /// Extrinsics root of the current block, also part of the block header. - ExtrinsicsRoot get(fn extrinsics_root): T::Hash; - /// Digest of the current block, also part of the block header. Digest get(fn digest): DigestOf; @@ -989,7 +986,6 @@ impl Module { pub fn initialize( number: &T::BlockNumber, parent_hash: &T::Hash, - txs_root: &T::Hash, digest: &DigestOf, kind: InitKind, ) { @@ -1000,7 +996,6 @@ impl Module { >::put(digest); >::put(parent_hash); >::insert(*number - One::one(), parent_hash); - >::put(txs_root); // Remove previous block data from storage BlockWeight::kill(); @@ -1017,7 +1012,6 @@ impl Module { /// resulting header for this block. pub fn finalize() -> T::Header { ExecutionPhase::kill(); - ExtrinsicCount::kill(); AllExtrinsicsLen::kill(); // The following fields @@ -1034,17 +1028,18 @@ impl Module { let parent_hash = >::get(); let mut digest = >::get(); - let extrinsics_root = >::take(); + let extrinsics = (0..ExtrinsicCount::take().unwrap_or_default()) + .map(ExtrinsicData::take) + .collect(); + let extrinsics_root = extrinsics_data_root::(extrinsics); // move block hash pruning window by one block - let block_hash_count = ::get(); - if number > block_hash_count { - let to_remove = number - block_hash_count - One::one(); + let block_hash_count = T::BlockHashCount::get(); + let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one()); - // keep genesis hash - if to_remove != Zero::zero() { - >::remove(to_remove); - } + // keep genesis hash + if !to_remove.is_zero() { + >::remove(to_remove); } let storage_root = T::Hash::decode(&mut &sp_io::storage::root()[..]) @@ -1138,12 +1133,10 @@ impl Module { Account::::mutate(who, |a| a.nonce += T::Index::one()); } - /// Note what the extrinsic data of the current extrinsic index is. If this - /// is called, then ensure `derive_extrinsics` is also called before - /// block-building is completed. + /// Note what the extrinsic data of the current extrinsic index is. /// - /// NOTE: This function is called only when the block is being constructed locally. - /// `execute_block` doesn't note any extrinsics. + /// This is required to be called before applying an extrinsic. The data will used + /// in [`Self::finalize`] to calculate the correct extrinsics root. pub fn note_extrinsic(encoded_xt: Vec) { ExtrinsicData::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); } @@ -1182,14 +1175,6 @@ impl Module { ExecutionPhase::put(Phase::ApplyExtrinsic(0)) } - /// Remove all extrinsic data and save the extrinsics trie root. - pub fn derive_extrinsics() { - let extrinsics = (0..ExtrinsicCount::get().unwrap_or_default()) - .map(ExtrinsicData::take).collect(); - let xts_root = extrinsics_data_root::(extrinsics); - >::put(xts_root); - } - /// An account is being created. pub fn on_created_account(who: T::AccountId) { T::OnNewAccount::on_new_account(&who); diff --git a/frame/system/src/tests.rs b/frame/system/src/tests.rs index 55286d951cc..58cb0b95e5e 100644 --- a/frame/system/src/tests.rs +++ b/frame/system/src/tests.rs @@ -18,7 +18,7 @@ use crate::*; use mock::{*, Origin}; use sp_core::H256; -use sp_runtime::DispatchError; +use sp_runtime::{DispatchError, traits::{Header, BlakeTwo256}}; use frame_support::weights::WithPostDispatchInfo; #[test] @@ -55,7 +55,6 @@ fn deposit_event_should_work() { System::initialize( &1, &[0u8; 32].into(), - &[0u8; 32].into(), &Default::default(), InitKind::Full, ); @@ -76,7 +75,6 @@ fn deposit_event_should_work() { System::initialize( &2, &[0u8; 32].into(), - &[0u8; 32].into(), &Default::default(), InitKind::Full, ); @@ -133,7 +131,6 @@ fn deposit_event_uses_actual_weight() { System::initialize( &1, &[0u8; 32].into(), - &[0u8; 32].into(), &Default::default(), InitKind::Full, ); @@ -218,7 +215,6 @@ fn deposit_event_topics() { System::initialize( &BLOCK_NUMBER, &[0u8; 32].into(), - &[0u8; 32].into(), &Default::default(), InitKind::Full, ); @@ -284,7 +280,6 @@ fn prunes_block_hash_mappings() { System::initialize( &n, &[n as u8 - 1; 32].into(), - &[0u8; 32].into(), &Default::default(), InitKind::Full, ); @@ -422,3 +417,28 @@ fn ensure_one_of_works() { assert_eq!(ensure_root_or_signed(RawOrigin::Signed(0)).unwrap(), Either::Right(0)); assert!(ensure_root_or_signed(RawOrigin::None).is_err()) } + +#[test] +fn extrinsics_root_is_calculated_correctly() { + new_test_ext().execute_with(|| { + System::initialize( + &1, + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + System::note_finished_initialize(); + System::note_extrinsic(vec![1]); + System::note_applied_extrinsic(&Ok(().into()), Default::default()); + System::note_extrinsic(vec![2]); + System::note_applied_extrinsic( + &Err(DispatchError::BadOrigin.into()), + Default::default() + ); + System::note_finished_extrinsics(); + let header = System::finalize(); + + let ext_root = extrinsics_data_root::(vec![vec![1], vec![2]]); + assert_eq!(ext_root, *header.extrinsics_root()); + }); +} -- GitLab From 5c70d7bb2b78d4ed5e3aa4fd0449cc6c81d3db98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20=C5=A0kvorc?= Date: Mon, 21 Dec 2020 20:52:57 +0100 Subject: [PATCH 139/163] Typo fix: eror => error (#7773) --- primitives/database/src/kvdb.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/database/src/kvdb.rs b/primitives/database/src/kvdb.rs index f436979aaf4..c48bd9c610f 100644 --- a/primitives/database/src/kvdb.rs +++ b/primitives/database/src/kvdb.rs @@ -27,7 +27,7 @@ fn handle_err(result: std::io::Result) -> T { match result { Ok(r) => r, Err(e) => { - panic!("Critical database eror: {:?}", e); + panic!("Critical database error: {:?}", e); } } } -- GitLab From 37a7727353f9bac1258acf59cd81688354c9120d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 22 Dec 2020 15:41:49 +0100 Subject: [PATCH 140/163] Adds `try_get` for `StorageMap` and `StorageDoubleMap` (#7774) * Adds `try_get` for `StorageMap` and `StorageDoubleMap` * Switch to Value as return type --- .../src/storage/generator/double_map.rs | 7 +++++ frame/support/src/storage/generator/map.rs | 4 +++ frame/support/src/storage/mod.rs | 31 +++++++++++++------ frame/support/src/storage/types/double_map.rs | 12 +++++++ frame/support/src/storage/types/map.rs | 9 ++++++ 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 6fb3abca5ca..d8891a5ee67 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -153,6 +153,13 @@ impl storage::StorageDoubleMap for G where G::from_optional_value_to_query(unhashed::get(&Self::storage_double_map_final_key(k1, k2))) } + fn try_get(k1: KArg1, k2: KArg2) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike { + unhashed::get(&Self::storage_double_map_final_key(k1, k2)).ok_or(()) + } + fn take(k1: KArg1, k2: KArg2) -> Self::Query where KArg1: EncodeLike, KArg2: EncodeLike, diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 2c2390865d0..11d895577f6 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -226,6 +226,10 @@ impl> storage::StorageMap G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref())) } + fn try_get>(key: KeyArg) -> Result { + unhashed::get(Self::storage_map_final_key(key).as_ref()).ok_or(()) + } + fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { unhashed::put(Self::storage_map_final_key(key).as_ref(), &val) } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 302f176ef4a..61ba147b091 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -107,8 +107,7 @@ pub fn with_transaction(f: impl FnOnce() -> TransactionOutcome) -> R { /// A trait for working with macro-generated storage values under the substrate storage API. /// -/// Details on implementation can be found at -/// [`generator::StorageValue`] +/// Details on implementation can be found at [`generator::StorageValue`]. pub trait StorageValue { /// The type that get/take return. type Query; @@ -122,8 +121,9 @@ pub trait StorageValue { /// Load the value from the provided storage instance. fn get() -> Self::Query; - /// Try to get the underlying value from the provided storage instance; `Ok` if it exists, - /// `Err` if not. + /// Try to get the underlying value from the provided storage instance. + /// + /// Returns `Ok` if it exists, `Err` if not. fn try_get() -> Result; /// Translate a value from some previous type (`O`) to the current type. @@ -200,8 +200,7 @@ pub trait StorageValue { /// A strongly-typed map in storage. /// -/// Details on implementation can be found at -/// [`generator::StorageMap`] +/// Details on implementation can be found at [`generator::StorageMap`]. pub trait StorageMap { /// The type that get/take return. type Query; @@ -215,6 +214,11 @@ pub trait StorageMap { /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; + /// Try to get the value for the given key from the map. + /// + /// Returns `Ok` if it exists, `Err` if not. + fn try_get>(key: KeyArg) -> Result; + /// Swap the values of two keys. fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2); @@ -233,7 +237,9 @@ pub trait StorageMap { f: F, ) -> Result; - /// Mutate the value under a key. Deletes the item if mutated to a `None`. + /// Mutate the value under a key. + /// + /// Deletes the item if mutated to a `None`. fn mutate_exists, R, F: FnOnce(&mut Option) -> R>(key: KeyArg, f: F) -> R; /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. @@ -354,8 +360,7 @@ pub trait IterableStorageDoubleMap< /// It provides an important ability to efficiently remove all entries /// that have a common first key. /// -/// Details on implementation can be found at -/// [`generator::StorageDoubleMap`] +/// Details on implementation can be found at [`generator::StorageDoubleMap`]. pub trait StorageDoubleMap { /// The type that get/take returns. type Query; @@ -378,6 +383,14 @@ pub trait StorageDoubleMap { KArg1: EncodeLike, KArg2: EncodeLike; + /// Try to get the value for the given key from the double map. + /// + /// Returns `Ok` if it exists, `Err` if not. + fn try_get(k1: KArg1, k2: KArg2) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike; + /// Take a value from storage, removing it afterwards. fn take(k1: KArg1, k2: KArg2) -> Self::Query where diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index 3e37c0522e3..1133dbd84d9 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -141,6 +141,16 @@ where >::get(k1, k2) } + /// Try to get the value for the given key from the double map. + /// + /// Returns `Ok` if it exists, `Err` if not. + pub fn try_get(k1: KArg1, k2: KArg2) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike { + >::try_get(k1, k2) + } + /// Take a value from storage, removing it afterwards. pub fn take(k1: KArg1, k2: KArg2) -> QueryKind::Query where @@ -514,6 +524,7 @@ mod test { }); assert_eq!(A::contains_key(2, 20), true); assert_eq!(A::get(2, 20), Some(100)); + assert_eq!(A::try_get(2, 20), Ok(100)); let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, 20, |v| { *v = Some(v.unwrap() * 10); Err(()) @@ -527,6 +538,7 @@ mod test { assert_eq!(A::contains_key(2, 20), false); assert_eq!(AValueQueryWithAnOnEmpty::take(2, 20), 97); assert_eq!(A::contains_key(2, 20), false); + assert_eq!(A::try_get(2, 20), Err(())); B::insert(2, 20, 10); assert_eq!(A::migrate_keys::(2, 20), Some(10)); diff --git a/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index 64f9ff4b052..8fe11488b11 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -116,6 +116,13 @@ where >::get(key) } + /// Try to get the value for the given key from the map. + /// + /// Returns `Ok` if it exists, `Err` if not. + pub fn try_get>(key: KeyArg) -> Result { + >::try_get(key) + } + /// Swap the values of two keys. pub fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { >::swap(key1, key2) @@ -352,12 +359,14 @@ mod test { A::insert(3, 10); assert_eq!(A::contains_key(3), true); assert_eq!(A::get(3), Some(10)); + assert_eq!(A::try_get(3), Ok(10)); assert_eq!(AValueQueryWithAnOnEmpty::get(3), 10); A::swap(3, 2); assert_eq!(A::contains_key(3), false); assert_eq!(A::contains_key(2), true); assert_eq!(A::get(3), None); + assert_eq!(A::try_get(3), Err(())); assert_eq!(AValueQueryWithAnOnEmpty::get(3), 97); assert_eq!(A::get(2), Some(10)); assert_eq!(AValueQueryWithAnOnEmpty::get(2), 10); -- GitLab From 60225756fd391491f8d8b507d76d705ba8ecd159 Mon Sep 17 00:00:00 2001 From: Daniel Olano Date: Wed, 23 Dec 2020 22:11:32 +0100 Subject: [PATCH 141/163] Add account prefix for Valiu (#7776) --- primitives/core/src/crypto.rs | 2 ++ ss58-registry.json | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index f2101a67124..5a7136b8368 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -502,6 +502,8 @@ ss58_address_format!( (32, "robonomics", "Any Robonomics network standard account (*25519).") DataHighwayAccount => (33, "datahighway", "DataHighway mainnet, standard account (*25519).") + ValiuAccount => + (35, "vln", "Valiu Liquidity Network mainnet, standard account (*25519).") CentrifugeAccount => (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") NodleAccount => diff --git a/ss58-registry.json b/ss58-registry.json index 5c90856505a..30069ab2171 100644 --- a/ss58-registry.json +++ b/ss58-registry.json @@ -280,6 +280,15 @@ "standardAccount": "*25519", "website": null }, + { + "prefix": 35, + "network": "vln", + "displayName": "Valiu Liquidity Network", + "symbols": ["USDv"], + "decimals": [15], + "standardAccount": "*25519", + "website": "https://valiu.com/" + }, { "prefix": 36, "network": "centrifuge", -- GitLab From 3c5bfc05f9299da6da50dd36b701679d5172bdbe Mon Sep 17 00:00:00 2001 From: honeywest <50997103+honeywest@users.noreply.github.com> Date: Thu, 24 Dec 2020 05:52:52 +0800 Subject: [PATCH 142/163] Feat support weight test (#7769) * update support weights_are_correct * add support polynomial_does_not_underflow --- frame/support/src/weights.rs | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index d4dda427ef1..fc0d7854a7d 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -866,7 +866,7 @@ mod tests { fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] - fn f2(_origin) { unimplemented!(); } + fn f20(_origin) { unimplemented!(); } #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000] fn f21(_origin) { unimplemented!(); } @@ -900,13 +900,29 @@ mod tests { assert_eq!(info.class, DispatchClass::Operational); assert_eq!(info.pays_fee, Pays::No); - assert_eq!(Call::::f11(10, 20).get_dispatch_info().weight, 120); - assert_eq!(Call::::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); - assert_eq!(Call::::f12(10, 20).get_dispatch_info().weight, 0); - assert_eq!(Call::::f12(10, 20).get_dispatch_info().class, DispatchClass::Operational); - assert_eq!(Call::::f2().get_dispatch_info().weight, 12300); - assert_eq!(Call::::f21().get_dispatch_info().weight, 45600); - assert_eq!(Call::::f2().get_dispatch_info().class, DispatchClass::Normal); + // #[weight = ((_a * 10 + _eb * 1) as Weight, DispatchClass::Normal, Pays::Yes)] + let info = Call::::f11(13, 20).get_dispatch_info(); + assert_eq!(info.weight, 150); // 13*10 + 20 + assert_eq!(info.class, DispatchClass::Normal); + assert_eq!(info.pays_fee, Pays::Yes); + + // #[weight = (0, DispatchClass::Operational, Pays::Yes)] + let info = Call::::f12(10, 20).get_dispatch_info(); + assert_eq!(info.weight, 0); + assert_eq!(info.class, DispatchClass::Operational); + assert_eq!(info.pays_fee, Pays::Yes); + + // #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] + let info = Call::::f20().get_dispatch_info(); + assert_eq!(info.weight, 12300); // 100*3 + 1000*2 + 10_1000 + assert_eq!(info.class, DispatchClass::Normal); + assert_eq!(info.pays_fee, Pays::Yes); + + // #[weight = T::DbWeight::get().reads_writes(6, 5) + 40_000] + let info = Call::::f21().get_dispatch_info(); + assert_eq!(info.weight, 45600); // 100*6 + 1000*5 + 40_1000 + assert_eq!(info.class, DispatchClass::Normal); + assert_eq!(info.pays_fee, Pays::Yes); } #[test] @@ -938,7 +954,7 @@ mod tests { type Balance = u64; - // 0.5x^3 + 2.333x2 + 7x - 10_000 + // 0.5x^3 + 2.333x^2 + 7x - 10_000 struct Poly; impl WeightToFeePolynomial for Poly { type Balance = Balance; @@ -975,13 +991,16 @@ mod tests { #[test] fn polynomial_works() { + // 100^3/2=500000 100^2*(2+1/3)=23333 700 -10000 assert_eq!(Poly::calc(&100), 514033); + // 10123^3/2=518677865433 10123^2*(2+1/3)=239108634 70861 -10000 assert_eq!(Poly::calc(&10_123), 518917034928); } #[test] fn polynomial_does_not_underflow() { assert_eq!(Poly::calc(&0), 0); + assert_eq!(Poly::calc(&10), 0); } #[test] -- GitLab From 0d6953ccc3e960f86a059578feef3469f25b81c0 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 24 Dec 2020 12:33:40 +0100 Subject: [PATCH 143/163] Add `pallet` attribute macro to declare pallets (#6877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rename system Config to system Trait. command used: ``` find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/system::Trait>::/system::Config>::/g' {} \; find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/impl frame_system::Trait for /impl frame_system::Config for /g' {} \; find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/impl system::Trait for /impl system::Config for /g' {} \; ``` plus some manual ones especially for frame-support tests and frame-system * make construct_runtime handle Pallet and Module pallets can now be implemented on struct named Pallet or Module, both definition are valid. This is because next macro will generate only Pallet placeholder. * introduce pallet attribute macro currently just with tests, frame_system and other example hasn't been upgraded * allow to print some upgrade helper from decl_storage * Improved error msg, typo. Co-authored-by: Shawn Tabrizi * Improved error msg, typo. Co-authored-by: Shawn Tabrizi * Improved error message on unexpected attributes + ui test * add test for transactional * various typo * some tips when spans are lost * allow pallet to depend on other pallet instances * make event type metadata consistent with call and constant * error messages * ignore doc example * fix pallet upgrade template * fixup * fix doc * fix indentation * Apply suggestions code formatting Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * some renames + fix compilation * remove unsupported genesis config type alias * merge fixup * fix ui tests * additional doc * implement StorageInstance with new syntax * fix line width * fix doc: because pallet doc goes below reexport doc * Update frame/support/procedural/src/pallet/parse/event.rs Co-authored-by: Andrew Jones * Update frame/system/src/lib.rs Co-authored-by: Bastian Köcher * Update frame/support/test/tests/pallet_ui.rs Co-authored-by: Bastian Köcher * improve doc as suggested * revert construct_runtime Pallet part. This revert the changes on construct_runtime. Now construct_runtime is unchanged and instead pallet macro create a type alias `type Module<..> = Pallet<..>` to be used by construct_runtime * refactor with less intricated code * fix ui test with new image * fix ui tests * add minor tests Co-authored-by: Shawn Tabrizi Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Andrew Jones Co-authored-by: Bastian Köcher --- frame/support/procedural/src/lib.rs | 8 + .../procedural/src/pallet/expand/call.rs | 201 ++++ .../procedural/src/pallet/expand/constants.rs | 138 +++ .../procedural/src/pallet/expand/error.rs | 141 +++ .../procedural/src/pallet/expand/event.rs | 143 +++ .../src/pallet/expand/genesis_build.rs | 72 ++ .../src/pallet/expand/genesis_config.rs | 49 + .../procedural/src/pallet/expand/hooks.rs | 110 ++ .../procedural/src/pallet/expand/instances.rs | 40 + .../procedural/src/pallet/expand/mod.rs | 81 ++ .../src/pallet/expand/pallet_struct.rs | 117 ++ .../procedural/src/pallet/expand/storage.rs | 267 +++++ .../src/pallet/expand/store_trait.rs | 55 + .../src/pallet/expand/type_value.rs | 55 + frame/support/procedural/src/pallet/mod.rs | 50 + .../procedural/src/pallet/parse/call.rs | 235 ++++ .../procedural/src/pallet/parse/config.rs | 384 +++++++ .../procedural/src/pallet/parse/error.rs | 86 ++ .../procedural/src/pallet/parse/event.rs | 220 ++++ .../src/pallet/parse/extra_constants.rs | 121 ++ .../src/pallet/parse/genesis_build.rs | 56 + .../src/pallet/parse/genesis_config.rs | 78 ++ .../procedural/src/pallet/parse/helper.rs | 600 ++++++++++ .../procedural/src/pallet/parse/hooks.rs | 69 ++ .../procedural/src/pallet/parse/inherent.rs | 59 + .../procedural/src/pallet/parse/mod.rs | 461 ++++++++ .../procedural/src/pallet/parse/origin.rs | 80 ++ .../src/pallet/parse/pallet_struct.rs | 99 ++ .../procedural/src/pallet/parse/storage.rs | 221 ++++ .../procedural/src/pallet/parse/type_value.rs | 101 ++ .../src/pallet/parse/validate_unsigned.rs | 61 + .../support/procedural/src/pallet_version.rs | 2 +- .../src/storage/genesis_config/mod.rs | 4 +- frame/support/procedural/src/storage/mod.rs | 5 + .../src/storage/print_pallet_upgrade.rs | 387 +++++++ frame/support/procedural/src/transactional.rs | 4 +- frame/support/procedural/tools/src/lib.rs | 16 +- frame/support/src/instances.rs | 96 ++ frame/support/src/lib.rs | 1005 ++++++++++++++++- frame/support/src/traits.rs | 73 ++ frame/support/test/tests/pallet.rs | 764 +++++++++++++ .../test/tests/pallet_compatibility.rs | 298 +++++ .../tests/pallet_compatibility_instance.rs | 315 ++++++ frame/support/test/tests/pallet_instance.rs | 708 ++++++++++++ frame/support/test/tests/pallet_ui.rs | 26 + .../test/tests/pallet_ui/attr_non_empty.rs | 6 + .../tests/pallet_ui/attr_non_empty.stderr | 5 + .../pallet_ui/call_argument_invalid_bound.rs | 27 + .../call_argument_invalid_bound.stderr | 28 + .../call_argument_invalid_bound_2.rs | 27 + .../call_argument_invalid_bound_2.stderr | 11 + .../call_argument_invalid_bound_3.rs | 29 + .../call_argument_invalid_bound_3.stderr | 26 + .../tests/pallet_ui/call_invalid_const.rs | 22 + .../tests/pallet_ui/call_invalid_const.stderr | 5 + .../pallet_ui/call_invalid_origin_type.rs | 22 + .../pallet_ui/call_invalid_origin_type.stderr | 11 + .../tests/pallet_ui/call_missing_weight.rs | 22 + .../pallet_ui/call_missing_weight.stderr | 5 + .../test/tests/pallet_ui/call_no_origin.rs | 22 + .../tests/pallet_ui/call_no_origin.stderr | 5 + .../test/tests/pallet_ui/call_no_return.rs | 22 + .../tests/pallet_ui/call_no_return.stderr | 5 + .../tests/pallet_ui/duplicate_call_attr.rs | 28 + .../pallet_ui/duplicate_call_attr.stderr | 5 + .../tests/pallet_ui/duplicate_store_attr.rs | 26 + .../pallet_ui/duplicate_store_attr.stderr | 5 + .../tests/pallet_ui/error_no_fieldless.rs | 25 + .../tests/pallet_ui/error_no_fieldless.stderr | 5 + .../test/tests/pallet_ui/error_wrong_item.rs | 23 + .../tests/pallet_ui/error_wrong_item.stderr | 5 + .../tests/pallet_ui/error_wrong_item_name.rs | 23 + .../pallet_ui/error_wrong_item_name.stderr | 5 + .../tests/pallet_ui/event_field_not_member.rs | 28 + .../pallet_ui/event_field_not_member.stderr | 28 + .../tests/pallet_ui/event_not_in_trait.rs | 27 + .../tests/pallet_ui/event_not_in_trait.stderr | 7 + .../pallet_ui/event_type_invalid_bound.rs | 28 + .../pallet_ui/event_type_invalid_bound.stderr | 5 + .../pallet_ui/event_type_invalid_bound_2.rs | 28 + .../event_type_invalid_bound_2.stderr | 5 + .../test/tests/pallet_ui/event_wrong_item.rs | 23 + .../tests/pallet_ui/event_wrong_item.stderr | 5 + .../tests/pallet_ui/event_wrong_item_name.rs | 23 + .../pallet_ui/event_wrong_item_name.stderr | 5 + .../genesis_default_not_satisfied.rs | 26 + .../genesis_default_not_satisfied.stderr | 10 + .../genesis_inconsistent_build_config.rs | 23 + .../genesis_inconsistent_build_config.stderr | 5 + .../pallet_ui/genesis_invalid_generic.rs | 23 + .../pallet_ui/genesis_invalid_generic.stderr | 13 + .../tests/pallet_ui/genesis_wrong_name.rs | 23 + .../tests/pallet_ui/genesis_wrong_name.stderr | 5 + .../tests/pallet_ui/hooks_invalid_item.rs | 19 + .../tests/pallet_ui/hooks_invalid_item.stderr | 5 + .../pallet_ui/inconsistent_instance_1.rs | 20 + .../pallet_ui/inconsistent_instance_1.stderr | 29 + .../pallet_ui/inconsistent_instance_2.rs | 20 + .../pallet_ui/inconsistent_instance_2.stderr | 29 + .../pallet_ui/inherent_check_inner_span.rs | 23 + .../inherent_check_inner_span.stderr | 10 + .../tests/pallet_ui/inherent_invalid_item.rs | 23 + .../pallet_ui/inherent_invalid_item.stderr | 5 + .../test/tests/pallet_ui/mod_not_inlined.rs | 5 + .../tests/pallet_ui/mod_not_inlined.stderr | 13 + .../pallet_ui/storage_incomplete_item.rs | 23 + .../pallet_ui/storage_incomplete_item.stderr | 13 + .../storage_invalid_first_generic.rs | 23 + .../storage_invalid_first_generic.stderr | 11 + .../pallet_ui/storage_not_storage_type.rs | 23 + .../pallet_ui/storage_not_storage_type.stderr | 5 + .../pallet_ui/storage_value_no_generic.rs | 23 + .../pallet_ui/storage_value_no_generic.stderr | 5 + .../tests/pallet_ui/storage_wrong_item.rs | 23 + .../tests/pallet_ui/storage_wrong_item.stderr | 5 + .../pallet_ui/store_trait_leak_private.rs | 25 + .../pallet_ui/store_trait_leak_private.stderr | 8 + .../pallet_ui/trait_constant_invalid_bound.rs | 23 + .../trait_constant_invalid_bound.stderr | 11 + .../tests/pallet_ui/trait_invalid_item.rs | 23 + .../tests/pallet_ui/trait_invalid_item.stderr | 5 + .../tests/pallet_ui/trait_no_supertrait.rs | 21 + .../pallet_ui/trait_no_supertrait.stderr | 5 + .../pallet_ui/type_value_error_in_block.rs | 25 + .../type_value_error_in_block.stderr | 5 + .../pallet_ui/type_value_invalid_item.rs | 22 + .../pallet_ui/type_value_invalid_item.stderr | 5 + .../tests/pallet_ui/type_value_no_return.rs | 22 + .../pallet_ui/type_value_no_return.stderr | 5 + frame/support/test/tests/pallet_version.rs | 111 +- frame/system/src/lib.rs | 17 + 131 files changed, 9609 insertions(+), 30 deletions(-) create mode 100644 frame/support/procedural/src/pallet/expand/call.rs create mode 100644 frame/support/procedural/src/pallet/expand/constants.rs create mode 100644 frame/support/procedural/src/pallet/expand/error.rs create mode 100644 frame/support/procedural/src/pallet/expand/event.rs create mode 100644 frame/support/procedural/src/pallet/expand/genesis_build.rs create mode 100644 frame/support/procedural/src/pallet/expand/genesis_config.rs create mode 100644 frame/support/procedural/src/pallet/expand/hooks.rs create mode 100644 frame/support/procedural/src/pallet/expand/instances.rs create mode 100644 frame/support/procedural/src/pallet/expand/mod.rs create mode 100644 frame/support/procedural/src/pallet/expand/pallet_struct.rs create mode 100644 frame/support/procedural/src/pallet/expand/storage.rs create mode 100644 frame/support/procedural/src/pallet/expand/store_trait.rs create mode 100644 frame/support/procedural/src/pallet/expand/type_value.rs create mode 100644 frame/support/procedural/src/pallet/mod.rs create mode 100644 frame/support/procedural/src/pallet/parse/call.rs create mode 100644 frame/support/procedural/src/pallet/parse/config.rs create mode 100644 frame/support/procedural/src/pallet/parse/error.rs create mode 100644 frame/support/procedural/src/pallet/parse/event.rs create mode 100644 frame/support/procedural/src/pallet/parse/extra_constants.rs create mode 100644 frame/support/procedural/src/pallet/parse/genesis_build.rs create mode 100644 frame/support/procedural/src/pallet/parse/genesis_config.rs create mode 100644 frame/support/procedural/src/pallet/parse/helper.rs create mode 100644 frame/support/procedural/src/pallet/parse/hooks.rs create mode 100644 frame/support/procedural/src/pallet/parse/inherent.rs create mode 100644 frame/support/procedural/src/pallet/parse/mod.rs create mode 100644 frame/support/procedural/src/pallet/parse/origin.rs create mode 100644 frame/support/procedural/src/pallet/parse/pallet_struct.rs create mode 100644 frame/support/procedural/src/pallet/parse/storage.rs create mode 100644 frame/support/procedural/src/pallet/parse/type_value.rs create mode 100644 frame/support/procedural/src/pallet/parse/validate_unsigned.rs create mode 100644 frame/support/procedural/src/storage/print_pallet_upgrade.rs create mode 100644 frame/support/src/instances.rs create mode 100644 frame/support/test/tests/pallet.rs create mode 100644 frame/support/test/tests/pallet_compatibility.rs create mode 100644 frame/support/test/tests/pallet_compatibility_instance.rs create mode 100644 frame/support/test/tests/pallet_instance.rs create mode 100644 frame/support/test/tests/pallet_ui.rs create mode 100644 frame/support/test/tests/pallet_ui/attr_non_empty.rs create mode 100644 frame/support/test/tests/pallet_ui/attr_non_empty.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_const.rs create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_const.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_missing_weight.rs create mode 100644 frame/support/test/tests/pallet_ui/call_missing_weight.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_no_origin.rs create mode 100644 frame/support/test/tests/pallet_ui/call_no_origin.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_no_return.rs create mode 100644 frame/support/test/tests/pallet_ui/call_no_return.stderr create mode 100644 frame/support/test/tests/pallet_ui/duplicate_call_attr.rs create mode 100644 frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr create mode 100644 frame/support/test/tests/pallet_ui/duplicate_store_attr.rs create mode 100644 frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_no_fieldless.rs create mode 100644 frame/support/test/tests/pallet_ui/error_no_fieldless.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item_name.rs create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_field_not_member.rs create mode 100644 frame/support/test/tests/pallet_ui/event_field_not_member.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_not_in_trait.rs create mode 100644 frame/support/test/tests/pallet_ui/event_not_in_trait.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item_name.rs create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_wrong_name.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/hooks_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs create mode 100644 frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr create mode 100644 frame/support/test/tests/pallet_ui/inherent_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/mod_not_inlined.rs create mode 100644 frame/support/test/tests/pallet_ui/mod_not_inlined.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_incomplete_item.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_not_storage_type.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_value_no_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/store_trait_leak_private.rs create mode 100644 frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_no_supertrait.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_error_in_block.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_no_return.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_no_return.stderr diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 8d3d1ce5900..7adc646c339 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -21,12 +21,14 @@ mod storage; mod construct_runtime; +mod pallet; mod pallet_version; mod transactional; mod debug_no_bound; mod clone_no_bound; mod partial_eq_no_bound; +pub(crate) use storage::INHERENT_INSTANCE_NAME; use proc_macro::TokenStream; /// Declares strongly-typed wrappers around codec-compatible types in storage. @@ -305,6 +307,12 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { construct_runtime::construct_runtime(input) } +/// Macro to define a pallet. Docs are at `frame_support::pallet`. +#[proc_macro_attribute] +pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { + pallet::pallet(attr, item) +} + /// Execute the annotated function in a new storage transaction. /// /// The return type of the annotated function must be `Result`. All changes to storage performed diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs new file mode 100644 index 00000000000..56b8ecf9941 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -0,0 +1,201 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use frame_support_procedural_tools::clean_type_string; +use syn::spanned::Spanned; + +/// * Generate enum call and implement various trait on it. +/// * Implement Callable and call_function on `Pallet` +pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_decl_bounded_gen = &def.type_decl_bounded_generics(); + let type_use_gen = &def.type_use_generics(); + let call_ident = syn::Ident::new("Call", def.call.attr_span.clone()); + let pallet_ident = &def.pallet_struct.pallet; + let where_clause = &def.call.where_clause; + + let fn_name = def.call.methods.iter().map(|method| &method.name).collect::>(); + + let fn_weight = def.call.methods.iter().map(|method| &method.weight); + + let fn_doc = def.call.methods.iter().map(|method| &method.docs).collect::>(); + + let args_name = def.call.methods.iter() + .map(|method| method.args.iter().map(|(_, name, _)| name.clone()).collect::>()) + .collect::>(); + + let args_type = def.call.methods.iter() + .map(|method| method.args.iter().map(|(_, _, type_)| type_.clone()).collect::>()) + .collect::>(); + + let args_compact_attr = def.call.methods.iter().map(|method| { + method.args.iter() + .map(|(is_compact, _, type_)| { + if *is_compact { + quote::quote_spanned!(type_.span() => #[codec(compact)] ) + } else { + quote::quote!() + } + }) + .collect::>() + }); + + let args_metadata_type = def.call.methods.iter().map(|method| { + method.args.iter() + .map(|(is_compact, _, type_)| { + let final_type = if *is_compact { + quote::quote!(Compact<#type_>) + } else { + quote::quote!(#type_) + }; + clean_type_string(&final_type.to_string()) + }) + .collect::>() + }); + + quote::quote_spanned!(def.call.attr_span => + #[derive( + #frame_support::RuntimeDebugNoBound, + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::codec::Encode, + #frame_support::codec::Decode, + )] + #[allow(non_camel_case_types)] + pub enum #call_ident<#type_decl_bounded_gen> #where_clause { + #[doc(hidden)] + #[codec(skip)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen,)>, + #frame_support::Never, + ), + #( #fn_name( #( #args_compact_attr #args_type ),* ), )* + } + + impl<#type_impl_gen> #frame_support::dispatch::GetDispatchInfo + for #call_ident<#type_use_gen> + #where_clause + { + fn get_dispatch_info(&self) -> #frame_support::dispatch::DispatchInfo { + match *self { + #( + Self::#fn_name ( #( ref #args_name, )* ) => { + let base_weight = #fn_weight; + + let weight = < + dyn #frame_support::dispatch::WeighData<( #( & #args_type, )* )> + >::weigh_data(&base_weight, ( #( #args_name, )* )); + + let class = < + dyn #frame_support::dispatch::ClassifyDispatch< + ( #( & #args_type, )* ) + > + >::classify_dispatch(&base_weight, ( #( #args_name, )* )); + + let pays_fee = < + dyn #frame_support::dispatch::PaysFee<( #( & #args_type, )* )> + >::pays_fee(&base_weight, ( #( #args_name, )* )); + + #frame_support::dispatch::DispatchInfo { + weight, + class, + pays_fee, + } + }, + )* + Self::__Ignore(_, _) => unreachable!("__Ignore cannot be used"), + } + } + } + + impl<#type_impl_gen> #frame_support::dispatch::GetCallName for #call_ident<#type_use_gen> + #where_clause + { + fn get_call_name(&self) -> &'static str { + match *self { + #( Self::#fn_name(..) => stringify!(#fn_name), )* + Self::__Ignore(_, _) => unreachable!("__PhantomItem cannot be used."), + } + } + + fn get_call_names() -> &'static [&'static str] { + &[ #( stringify!(#fn_name), )* ] + } + } + + impl<#type_impl_gen> #frame_support::traits::UnfilteredDispatchable + for #call_ident<#type_use_gen> + #where_clause + { + type Origin = #frame_system::pallet_prelude::OriginFor; + fn dispatch_bypass_filter( + self, + origin: Self::Origin + ) -> #frame_support::dispatch::DispatchResultWithPostInfo { + match self { + #( + Self::#fn_name( #( #args_name, )* ) => + <#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* ) + .map(Into::into).map_err(Into::into), + )* + Self::__Ignore(_, _) => { + let _ = origin; // Use origin for empty Call enum + unreachable!("__PhantomItem cannot be used."); + }, + } + } + } + + impl<#type_impl_gen> #frame_support::dispatch::Callable for #pallet_ident<#type_use_gen> + #where_clause + { + type Call = #call_ident<#type_use_gen>; + } + + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #where_clause { + #[doc(hidden)] + pub fn call_functions() -> &'static [#frame_support::dispatch::FunctionMetadata] { + &[ #( + #frame_support::dispatch::FunctionMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode( + stringify!(#fn_name) + ), + arguments: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( + #frame_support::dispatch::FunctionArgumentMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode( + stringify!(#args_name) + ), + ty: #frame_support::dispatch::DecodeDifferent::Encode( + #args_metadata_type + ), + }, + )* ] + ), + documentation: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( #fn_doc ),* ] + ), + }, + )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/constants.rs b/frame/support/procedural/src/pallet/expand/constants.rs new file mode 100644 index 00000000000..25cceb7449e --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/constants.rs @@ -0,0 +1,138 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use frame_support_procedural_tools::clean_type_string; +use quote::ToTokens; + +struct ConstDef { + /// Name of the associated type. + pub ident: syn::Ident, + /// The type in Get, e.g. `u32` in `type Foo: Get;`, but `Self` is replaced by `T` + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, + /// default_byte implementation + pub default_byte_impl: proc_macro2::TokenStream, +} + +/// * Impl fn module_constant_metadata for pallet. +pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_decl_gen = &def.type_decl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.extra_constants.iter().map(|d| &d.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + let config_consts = def.config.consts_metadata.iter().map(|const_| { + let ident = &const_.ident; + let const_type = &const_.type_; + + ConstDef { + ident: const_.ident.clone(), + type_: const_.type_.clone(), + doc: const_.doc.clone(), + default_byte_impl: quote::quote!( + let value = >::get(); + #frame_support::codec::Encode::encode(&value) + ), + } + }); + + let extra_consts = def.extra_constants.iter().flat_map(|d| &d.extra_constants).map(|const_| { + let ident = &const_.ident; + + ConstDef { + ident: const_.ident.clone(), + type_: const_.type_.clone(), + doc: const_.doc.clone(), + default_byte_impl: quote::quote!( + let value = >::#ident(); + #frame_support::codec::Encode::encode(&value) + ), + } + }); + + let consts = config_consts.chain(extra_consts) + .map(|const_| { + let const_type = &const_.type_; + let const_type_str = clean_type_string(&const_type.to_token_stream().to_string()); + let ident = &const_.ident; + let ident_str = format!("{}", ident); + let doc = const_.doc.clone().into_iter(); + let default_byte_impl = &const_.default_byte_impl; + let default_byte_getter = syn::Ident::new( + &format!("{}DefaultByteGetter", ident), + ident.span() + ); + + quote::quote!({ + #[allow(non_upper_case_types)] + #[allow(non_camel_case_types)] + struct #default_byte_getter<#type_decl_gen>( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen)> + ); + + impl<#type_impl_gen> #frame_support::dispatch::DefaultByte for + #default_byte_getter<#type_use_gen> + #completed_where_clause + { + fn default_byte(&self) -> #frame_support::sp_std::vec::Vec { + #default_byte_impl + } + } + + unsafe impl<#type_impl_gen> Send for #default_byte_getter<#type_use_gen> + #completed_where_clause + {} + unsafe impl<#type_impl_gen> Sync for #default_byte_getter<#type_use_gen> + #completed_where_clause + {} + + #frame_support::dispatch::ModuleConstantMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode(#ident_str), + ty: #frame_support::dispatch::DecodeDifferent::Encode(#const_type_str), + value: #frame_support::dispatch::DecodeDifferent::Encode( + #frame_support::dispatch::DefaultByteGetter( + &#default_byte_getter::<#type_use_gen>( + #frame_support::sp_std::marker::PhantomData + ) + ) + ), + documentation: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( #doc ),* ] + ), + } + }) + }); + + quote::quote!( + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause{ + + #[doc(hidden)] + pub fn module_constants_metadata() + -> &'static [#frame_support::dispatch::ModuleConstantMetadata] + { + &[ #( #consts ),* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/error.rs b/frame/support/procedural/src/pallet/expand/error.rs new file mode 100644 index 00000000000..e60d717ff7d --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/error.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// * impl various trait on Error +/// * impl ModuleErrorMetadata for Error +pub fn expand_error(def: &mut Def) -> proc_macro2::TokenStream { + let error = if let Some(error) = &def.error { + error + } else { + return Default::default() + }; + + let error_item_span = + def.item.content.as_mut().expect("Checked by def parser").1[error.index].span(); + let error_ident = &error.error; + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let config_where_clause = &def.config.where_clause; + + let phantom_variant: syn::Variant = syn::parse_quote!( + #[doc(hidden)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen)>, + #frame_support::Never, + ) + ); + + let as_u8_matches = error.variants.iter().enumerate() + .map(|(i, (variant, _))| quote::quote!(Self::#variant => #i as u8,)); + + let as_str_matches = error.variants.iter() + .map(|(variant, _)| { + let variant_str = format!("{}", variant); + quote::quote!(Self::#variant => #variant_str,) + }); + + let metadata = error.variants.iter() + .map(|(variant, doc)| { + let variant_str = format!("{}", variant); + quote::quote!( + #frame_support::error::ErrorMetadata { + name: #frame_support::error::DecodeDifferent::Encode(#variant_str), + documentation: #frame_support::error::DecodeDifferent::Encode(&[ #( #doc, )* ]), + }, + ) + }); + + let error_item = { + let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[error.index]; + if let syn::Item::Enum(item) = item { + item + } else { + unreachable!("Checked by event parser") + } + }; + + error_item.variants.insert(0, phantom_variant); + + quote::quote_spanned!(error_item_span => + impl<#type_impl_gen> #frame_support::sp_std::fmt::Debug for #error_ident<#type_use_gen> + #config_where_clause + { + fn fmt(&self, f: &mut #frame_support::sp_std::fmt::Formatter<'_>) + -> #frame_support::sp_std::fmt::Result + { + f.write_str(self.as_str()) + } + } + + impl<#type_impl_gen> #error_ident<#type_use_gen> #config_where_clause { + pub fn as_u8(&self) -> u8 { + match &self { + Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), + #( #as_u8_matches )* + } + } + + pub fn as_str(&self) -> &'static str { + match &self { + Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), + #( #as_str_matches )* + } + } + } + + impl<#type_impl_gen> From<#error_ident<#type_use_gen>> for &'static str + #config_where_clause + { + fn from(err: #error_ident<#type_use_gen>) -> &'static str { + err.as_str() + } + } + + impl<#type_impl_gen> From<#error_ident<#type_use_gen>> + for #frame_support::sp_runtime::DispatchError + #config_where_clause + { + fn from(err: #error_ident<#type_use_gen>) -> Self { + let index = < + ::PalletInfo + as #frame_support::traits::PalletInfo + >::index::>() + .expect("Every active module has an index in the runtime; qed") as u8; + + #frame_support::sp_runtime::DispatchError::Module { + index, + error: err.as_u8(), + message: Some(err.as_str()), + } + } + } + + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #error_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + &[ #( #metadata )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/event.rs b/frame/support/procedural/src/pallet/expand/event.rs new file mode 100644 index 00000000000..1dc3431f9ba --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/event.rs @@ -0,0 +1,143 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// * Add __Ignore variant on Event +/// * Impl various trait on Event including metadata +/// * if deposit_event is defined, implement deposit_event on module. +pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream { + let event = if let Some(event) = &def.event { + event + } else { + return Default::default() + }; + + let event_where_clause = &event.where_clause; + + // NOTE: actually event where clause must be a subset of config where clause because of + // `type Event: From>`. But we merge either way for potential better error message + let completed_where_clause = super::merge_where_clauses(&[ + &event.where_clause, + &def.config.where_clause, + ]); + + let event_ident = &event.event; + let frame_system = &def.frame_system; + let frame_support = &def.frame_support; + let event_use_gen = &event.gen_kind.type_use_gen(); + let event_impl_gen= &event.gen_kind.type_impl_gen(); + let metadata = event.metadata.iter() + .map(|(ident, args, docs)| { + let name = format!("{}", ident); + quote::quote!( + #frame_support::event::EventMetadata { + name: #frame_support::event::DecodeDifferent::Encode(#name), + arguments: #frame_support::event::DecodeDifferent::Encode(&[ + #( #args, )* + ]), + documentation: #frame_support::event::DecodeDifferent::Encode(&[ + #( #docs, )* + ]), + }, + ) + }); + + let event_item_span = + def.item.content.as_mut().expect("Checked by def parser").1[event.index].span(); + + let event_item = { + let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[event.index]; + if let syn::Item::Enum(item) = item { + item + } else { + unreachable!("Checked by event parser") + } + }; + + // Phantom data is added for generic event. + if event.gen_kind.is_generic() { + let variant = syn::parse_quote!( + #[doc(hidden)] + #[codec(skip)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#event_use_gen)>, + #frame_support::Never, + ) + ); + + // Push ignore variant at the end. + event_item.variants.push(variant); + } + + // derive some traits because system event require Clone, FullCodec, Eq, PartialEq and Debug + event_item.attrs.push(syn::parse_quote!( + #[derive( + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::RuntimeDebugNoBound, + #frame_support::codec::Encode, + #frame_support::codec::Decode, + )] + )); + + + let deposit_event = if let Some((fn_vis, fn_span)) = &event.deposit_event { + let event_use_gen = &event.gen_kind.type_use_gen(); + let trait_use_gen = &def.trait_use_generics(); + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + + quote::quote_spanned!(*fn_span => + impl<#type_impl_gen> Pallet<#type_use_gen> #completed_where_clause { + #fn_vis fn deposit_event(event: Event<#event_use_gen>) { + let event = < + ::Event as + From> + >::from(event); + + let event = < + ::Event as + Into<::Event> + >::into(event); + + <#frame_system::Pallet>::deposit_event(event) + } + } + ) + } else { + Default::default() + }; + + quote::quote_spanned!(event_item_span => + #deposit_event + + impl<#event_impl_gen> From<#event_ident<#event_use_gen>> for () #event_where_clause { + fn from(_: #event_ident<#event_use_gen>) -> () { () } + } + + impl<#event_impl_gen> #event_ident<#event_use_gen> #event_where_clause { + #[allow(dead_code)] + #[doc(hidden)] + pub fn metadata() -> &'static [#frame_support::event::EventMetadata] { + &[ #( #metadata )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/genesis_build.rs b/frame/support/procedural/src/pallet/expand/genesis_build.rs new file mode 100644 index 00000000000..678e89eddf2 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/genesis_build.rs @@ -0,0 +1,72 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// * implement the trait `sp_runtime::BuildModuleGenesisStorage` +/// * add #[cfg(features = "std")] to GenesisBuild implementation. +pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream { + let genesis_config = if let Some(genesis_config) = &def.genesis_config { + genesis_config + } else { + return Default::default() + }; + + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let trait_use_gen = if def.config.has_instance { + quote::quote!(T, I) + } else { + // `__InherentHiddenInstance` used by construct_runtime here is alias for `()` + quote::quote!(T, ()) + }; + let gen_cfg_ident = &genesis_config.genesis_config; + + let gen_cfg_use_gen = genesis_config.gen_kind.type_use_gen(); + + let genesis_build = def.genesis_build.as_ref().expect("Checked by def parser"); + let genesis_build_item = &mut def.item.content.as_mut() + .expect("Checked by def parser").1[genesis_build.index]; + + let genesis_build_item_impl = if let syn::Item::Impl(impl_) = genesis_build_item { + impl_ + } else { + unreachable!("Checked by genesis_build parser") + }; + + genesis_build_item_impl.attrs.push(syn::parse_quote!( #[cfg(feature = "std")] )); + let where_clause = &genesis_build.where_clause; + + quote::quote_spanned!(genesis_build_item.span() => + #[cfg(feature = "std")] + impl<#type_impl_gen> #frame_support::sp_runtime::BuildModuleGenesisStorage<#trait_use_gen> + for #gen_cfg_ident<#gen_cfg_use_gen> #where_clause + { + fn build_module_genesis_storage( + &self, + storage: &mut #frame_support::sp_runtime::Storage, + ) -> std::result::Result<(), std::string::String> { + #frame_support::BasicExternalities::execute_with_storage(storage, || { + >::build(self); + Ok(()) + }) + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/genesis_config.rs b/frame/support/procedural/src/pallet/expand/genesis_config.rs new file mode 100644 index 00000000000..db67eaeaee7 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/genesis_config.rs @@ -0,0 +1,49 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; + +/// * add various derive trait on GenesisConfig struct. +pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream { + let genesis_config = if let Some(genesis_config) = &def.genesis_config { + genesis_config + } else { + return Default::default() + }; + let frame_support = &def.frame_support; + + let genesis_config_item = &mut def.item.content.as_mut() + .expect("Checked by def parser").1[genesis_config.index]; + + match genesis_config_item { + syn::Item::Enum(syn::ItemEnum { attrs, ..}) | + syn::Item::Struct(syn::ItemStruct { attrs, .. }) | + syn::Item::Type(syn::ItemType { attrs, .. }) => { + attrs.push(syn::parse_quote!( #[cfg(feature = "std")] )); + attrs.push(syn::parse_quote!( + #[derive(#frame_support::Serialize, #frame_support::Deserialize)] + )); + attrs.push(syn::parse_quote!( #[serde(rename_all = "camelCase")] )); + attrs.push(syn::parse_quote!( #[serde(deny_unknown_fields)] )); + attrs.push(syn::parse_quote!( #[serde(bound(serialize = ""))] )); + attrs.push(syn::parse_quote!( #[serde(bound(deserialize = ""))] )); + }, + _ => unreachable!("Checked by genesis_config parser"), + } + + Default::default() +} diff --git a/frame/support/procedural/src/pallet/expand/hooks.rs b/frame/support/procedural/src/pallet/expand/hooks.rs new file mode 100644 index 00000000000..8ae7738bcc1 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/hooks.rs @@ -0,0 +1,110 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// * implement the individual traits using the Hooks trait +pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + let where_clause = &def.hooks.where_clause; + let frame_system = &def.frame_system; + + let hooks_item_span = def.item.content.as_mut() + .expect("Checked by def parser").1[def.hooks.index].span(); + + quote::quote_spanned!(hooks_item_span => + impl<#type_impl_gen> + #frame_support::traits::OnFinalize<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_finalize(n: ::BlockNumber) { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_finalize(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OnInitialize<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_initialize( + n: ::BlockNumber + ) -> #frame_support::weights::Weight { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_initialize(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OnRuntimeUpgrade + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_runtime_upgrade() -> #frame_support::weights::Weight { + let result = < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_runtime_upgrade(); + + #frame_support::crate_to_pallet_version!() + .put_into_storage::<::PalletInfo, Self>(); + + let additional_write = < + ::DbWeight as #frame_support::traits::Get<_> + >::get().writes(1); + + result.saturating_add(additional_write) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OffchainWorker<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn offchain_worker(n: ::BlockNumber) { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::offchain_worker(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::IntegrityTest + for #pallet_ident<#type_use_gen> #where_clause + { + fn integrity_test() { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::integrity_test() + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/instances.rs b/frame/support/procedural/src/pallet/expand/instances.rs new file mode 100644 index 00000000000..1b05be4f61f --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/instances.rs @@ -0,0 +1,40 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 proc_macro2::Span; +use crate::pallet::Def; + +/// * Provide inherent instance to be used by construct_runtime +/// * Provide Instance0 .. Instance16 for instantiable pallet +pub fn expand_instances(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let inherent_ident = syn::Ident::new(crate::INHERENT_INSTANCE_NAME, Span::call_site()); + let instances = if def.config.has_instance { + (0..16).map(|i| syn::Ident::new(&format!("Instance{}", i), Span::call_site())).collect() + } else { + vec![] + }; + + quote::quote!( + /// Hidden instance generated to be internally used when module is used without + /// instance. + #[doc(hidden)] + pub type #inherent_ident = (); + + #( pub use #frame_support::instances::#instances; )* + ) +} diff --git a/frame/support/procedural/src/pallet/expand/mod.rs b/frame/support/procedural/src/pallet/expand/mod.rs new file mode 100644 index 00000000000..6bfc1f9a9ee --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/mod.rs @@ -0,0 +1,81 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +mod constants; +mod pallet_struct; +mod call; +mod error; +mod event; +mod storage; +mod hooks; +mod store_trait; +mod instances; +mod genesis_build; +mod genesis_config; +mod type_value; + +use crate::pallet::Def; +use quote::ToTokens; + +/// Merge where clause together, `where` token span is taken from the first not none one. +pub fn merge_where_clauses(clauses: &[&Option]) -> Option { + let mut clauses = clauses.iter().filter_map(|f| f.as_ref()); + let mut res = clauses.next()?.clone(); + for other in clauses { + res.predicates.extend(other.predicates.iter().cloned()) + } + Some(res) +} + +/// Expand definition, in particular: +/// * add some bounds and variants to type defined, +/// * create some new types, +/// * impl stuff on them. +pub fn expand(mut def: Def) -> proc_macro2::TokenStream { + let constants = constants::expand_constants(&mut def); + let pallet_struct = pallet_struct::expand_pallet_struct(&mut def); + let call = call::expand_call(&mut def); + let error = error::expand_error(&mut def); + let event = event::expand_event(&mut def); + let storages = storage::expand_storages(&mut def); + let instances = instances::expand_instances(&mut def); + let store_trait = store_trait::expand_store_trait(&mut def); + let hooks = hooks::expand_hooks(&mut def); + let genesis_build = genesis_build::expand_genesis_build(&mut def); + let genesis_config = genesis_config::expand_genesis_config(&mut def); + let type_values = type_value::expand_type_values(&mut def); + + let new_items = quote::quote!( + #constants + #pallet_struct + #call + #error + #event + #storages + #instances + #store_trait + #hooks + #genesis_build + #genesis_config + #type_values + ); + + def.item.content.as_mut().expect("This is checked by parsing").1 + .push(syn::Item::Verbatim(new_items)); + + def.item.into_token_stream() +} diff --git a/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/frame/support/procedural/src/pallet/expand/pallet_struct.rs new file mode 100644 index 00000000000..133e49a85d8 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -0,0 +1,117 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; + +/// * Add derive trait on Pallet +/// * Implement GetPalletVersion on Pallet +/// * Implement OnGenesis on Pallet +/// * Implement ModuleErrorMetadata on Pallet +/// * declare Module type alias for construct_runtime +pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let type_decl_gen = &def.type_decl_generics(); + let pallet_ident = &def.pallet_struct.pallet; + let config_where_clause = &def.config.where_clause; + + let pallet_item = { + let pallet_module_items = &mut def.item.content.as_mut().expect("Checked by def").1; + let item = &mut pallet_module_items[def.pallet_struct.index]; + if let syn::Item::Struct(item) = item { + item + } else { + unreachable!("Checked by pallet struct parser") + } + }; + + pallet_item.attrs.push(syn::parse_quote!( + #[derive( + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::RuntimeDebugNoBound, + )] + )); + + let module_error_metadata = if let Some(error_def) = &def.error { + let error_ident = &error_def.error; + quote::quote!( + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + < + #error_ident<#type_use_gen> as #frame_support::error::ModuleErrorMetadata + >::metadata() + } + } + ) + } else { + quote::quote!( + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + &[] + } + } + ) + }; + + quote::quote!( + #module_error_metadata + + /// Type alias to `Pallet`, to be used by `construct_runtime`. + /// + /// Generated by `pallet` attribute macro. + pub type Module<#type_decl_gen> = #pallet_ident<#type_use_gen>; + + // Implement `GetPalletVersion` for `Pallet` + impl<#type_impl_gen> #frame_support::traits::GetPalletVersion + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn current_version() -> #frame_support::traits::PalletVersion { + #frame_support::crate_to_pallet_version!() + } + + fn storage_version() -> Option<#frame_support::traits::PalletVersion> { + let key = #frame_support::traits::PalletVersion::storage_key::< + ::PalletInfo, Self + >().expect("Every active pallet has a name in the runtime; qed"); + + #frame_support::storage::unhashed::get(&key) + } + } + + // Implement `OnGenesis` for `Pallet` + impl<#type_impl_gen> #frame_support::traits::OnGenesis + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn on_genesis() { + #frame_support::crate_to_pallet_version!() + .put_into_storage::<::PalletInfo, Self>(); + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs new file mode 100644 index 00000000000..a8b6b2f0d7b --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -0,0 +1,267 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use crate::pallet::parse::storage::{Metadata, QueryKind}; +use frame_support_procedural_tools::clean_type_string; + +/// Generate the prefix_ident related the the storage. +/// prefix_ident is used for the prefix struct to be given to storage as first generic param. +fn prefix_ident(storage_ident: &syn::Ident) -> syn::Ident { + syn::Ident::new(&format!("_GeneratedPrefixForStorage{}", storage_ident), storage_ident.span()) +} + +/// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name +/// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait. +/// * replace the first generic `_` by the generated prefix structure +/// * generate metadatas +pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + // Replace first arg `_` by the generated prefix structure. + // Add `#[allow(type_alias_bounds)]` + for storage_def in def.storages.iter_mut() { + let item = &mut def.item.content.as_mut().expect("Checked by def").1[storage_def.index]; + + let typ_item = if let syn::Item::Type(t) = item { + t + } else { + unreachable!("Checked by def"); + }; + + typ_item.attrs.push(syn::parse_quote!(#[allow(type_alias_bounds)])); + + let typ_path = if let syn::Type::Path(p) = &mut *typ_item.ty { + p + } else { + unreachable!("Checked by def"); + }; + + let args = if let syn::PathArguments::AngleBracketed(args) = + &mut typ_path.path.segments[0].arguments + { + args + } else { + unreachable!("Checked by def"); + }; + + let prefix_ident = prefix_ident(&storage_def.ident); + args.args[0] = syn::parse_quote!( #prefix_ident<#type_use_gen> ); + } + + let entries = def.storages.iter() + .map(|storage| { + let docs = &storage.docs; + + let ident = &storage.ident; + let gen = &def.type_use_generics(); + let full_ident = quote::quote!( #ident<#gen> ); + + let metadata_trait = match &storage.metadata { + Metadata::Value { .. } => + quote::quote!(#frame_support::storage::types::StorageValueMetadata), + Metadata::Map { .. } => + quote::quote!(#frame_support::storage::types::StorageMapMetadata), + Metadata::DoubleMap { .. } => + quote::quote!(#frame_support::storage::types::StorageDoubleMapMetadata), + }; + + let ty = match &storage.metadata { + Metadata::Value { value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::Plain( + #frame_support::metadata::DecodeDifferent::Encode(#value) + ) + ) + }, + Metadata::Map { key, value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + let key = clean_type_string("e::quote!(#key).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::Map { + hasher: <#full_ident as #metadata_trait>::HASHER, + key: #frame_support::metadata::DecodeDifferent::Encode(#key), + value: #frame_support::metadata::DecodeDifferent::Encode(#value), + unused: false, + } + ) + }, + Metadata::DoubleMap { key1, key2, value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + let key1 = clean_type_string("e::quote!(#key1).to_string()); + let key2 = clean_type_string("e::quote!(#key2).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::DoubleMap { + hasher: <#full_ident as #metadata_trait>::HASHER1, + key2_hasher: <#full_ident as #metadata_trait>::HASHER2, + key1: #frame_support::metadata::DecodeDifferent::Encode(#key1), + key2: #frame_support::metadata::DecodeDifferent::Encode(#key2), + value: #frame_support::metadata::DecodeDifferent::Encode(#value), + } + ) + } + }; + + quote::quote_spanned!(storage.ident.span() => + #frame_support::metadata::StorageEntryMetadata { + name: #frame_support::metadata::DecodeDifferent::Encode( + <#full_ident as #metadata_trait>::NAME + ), + modifier: <#full_ident as #metadata_trait>::MODIFIER, + ty: #ty, + default: #frame_support::metadata::DecodeDifferent::Encode( + <#full_ident as #metadata_trait>::DEFAULT + ), + documentation: #frame_support::metadata::DecodeDifferent::Encode(&[ + #( #docs, )* + ]), + } + ) + }); + + let getters = def.storages.iter() + .map(|storage| if let Some(getter) = &storage.getter { + let completed_where_clause = super::merge_where_clauses(&[ + &storage.where_clause, + &def.config.where_clause, + ]); + let docs = storage.docs.iter().map(|d| quote::quote!(#[doc = #d])); + + let ident = &storage.ident; + let gen = &def.type_use_generics(); + let full_ident = quote::quote!( #ident<#gen> ); + + match &storage.metadata { + Metadata::Value { value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter() -> #query { + < + #full_ident as #frame_support::storage::StorageValue<#value> + >::get() + } + } + ) + }, + Metadata::Map { key, value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter(k: KArg) -> #query where + KArg: #frame_support::codec::EncodeLike<#key>, + { + < + #full_ident as #frame_support::storage::StorageMap<#key, #value> + >::get(k) + } + } + ) + }, + Metadata::DoubleMap { key1, key2, value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter(k1: KArg1, k2: KArg2) -> #query where + KArg1: #frame_support::codec::EncodeLike<#key1>, + KArg2: #frame_support::codec::EncodeLike<#key2>, + { + < + #full_ident as + #frame_support::storage::StorageDoubleMap<#key1, #key2, #value> + >::get(k1, k2) + } + } + ) + }, + } + } else { + Default::default() + }); + + let prefix_structs = def.storages.iter().map(|storage_def| { + let prefix_struct_ident = prefix_ident(&storage_def.ident); + let prefix_struct_vis = &storage_def.vis; + let prefix_struct_const = storage_def.ident.to_string(); + let config_where_clause = &def.config.where_clause; + + quote::quote_spanned!(storage_def.ident.span() => + #prefix_struct_vis struct #prefix_struct_ident<#type_use_gen>( + core::marker::PhantomData<(#type_use_gen,)> + ); + impl<#type_impl_gen> #frame_support::traits::StorageInstance + for #prefix_struct_ident<#type_use_gen> + #config_where_clause + { + fn pallet_prefix() -> &'static str { + < + ::PalletInfo + as #frame_support::traits::PalletInfo + >::name::>() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = #prefix_struct_const; + } + ) + }); + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + quote::quote!( + impl<#type_impl_gen> #pallet_ident<#type_use_gen> + #completed_where_clause + { + #[doc(hidden)] + pub fn storage_metadata() -> #frame_support::metadata::StorageMetadata { + #frame_support::metadata::StorageMetadata { + prefix: #frame_support::metadata::DecodeDifferent::Encode( + < + ::PalletInfo as + #frame_support::traits::PalletInfo + >::name::<#pallet_ident<#type_use_gen>>() + .expect("Every active pallet has a name in the runtime; qed") + ), + entries: #frame_support::metadata::DecodeDifferent::Encode( + &[ #( #entries, )* ] + ), + } + } + } + + #( #getters )* + #( #prefix_structs )* + ) +} diff --git a/frame/support/procedural/src/pallet/expand/store_trait.rs b/frame/support/procedural/src/pallet/expand/store_trait.rs new file mode 100644 index 00000000000..ceea270bb9f --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/store_trait.rs @@ -0,0 +1,55 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// If attribute `#[pallet::generate_store(..)]` is defined then: +/// * generate Store trait with all storages, +/// * implement Store trait for Pallet. +pub fn expand_store_trait(def: &mut Def) -> proc_macro2::TokenStream { + let (trait_vis, trait_store) = if let Some(store) = &def.pallet_struct.store { + store + } else { + return Default::default() + }; + + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::>(); + + quote::quote_spanned!(trait_store.span() => + #trait_vis trait #trait_store { + #( + type #storage_names; + )* + } + impl<#type_impl_gen> #trait_store for #pallet_ident<#type_use_gen> + #completed_where_clause + { + #( + type #storage_names = #storage_names<#type_use_gen>; + )* + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/type_value.rs b/frame/support/procedural/src/pallet/expand/type_value.rs new file mode 100644 index 00000000000..3de3be8fcf2 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/type_value.rs @@ -0,0 +1,55 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 crate::pallet::Def; +use syn::spanned::Spanned; + +/// * Generate the struct +/// * implement the `Get<..>` on it +pub fn expand_type_values(def: &mut Def) -> proc_macro2::TokenStream { + let mut expand = quote::quote!(); + let frame_support = &def.frame_support; + + for type_value in &def.type_values { + // Remove item from module content + let item = &mut def.item.content.as_mut().expect("Checked by def").1[type_value.index]; + let span = item.span(); + *item = syn::Item::Verbatim(Default::default()); + + let vis = &type_value.vis; + let ident = &type_value.ident; + let block = &type_value.block; + let type_ = &type_value.type_; + let where_clause = &type_value.where_clause; + + let (struct_impl_gen, struct_use_gen) = if type_value.is_generic { + (def.type_impl_generics(), def.type_use_generics()) + } else { + (Default::default(), Default::default()) + }; + + expand.extend(quote::quote_spanned!(span => + #vis struct #ident<#struct_use_gen>(core::marker::PhantomData<((), #struct_use_gen)>); + impl<#struct_impl_gen> #frame_support::traits::Get<#type_> for #ident<#struct_use_gen> + #where_clause + { + fn get() -> #type_ #block + } + )); + } + expand +} diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs new file mode 100644 index 00000000000..7ae5a573d01 --- /dev/null +++ b/frame/support/procedural/src/pallet/mod.rs @@ -0,0 +1,50 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Implementation for pallet attribute macro. +//! +//! General workflow: +//! 1 - parse all pallet attributes: +//! This step remove all attributes `#[pallet::*]` from the ItemMod and build the `Def` struct +//! which holds the ItemMod without `#[pallet::*]` and information given by those attributes +//! 2 - expand from the parsed information +//! This step will modify the ItemMod by adding some derive attributes or phantom data variants +//! to user defined types. And also crate new types and implement block. + +mod parse; +mod expand; + +pub use parse::Def; +use syn::spanned::Spanned; + +pub fn pallet( + attr: proc_macro::TokenStream, + item: proc_macro::TokenStream +) -> proc_macro::TokenStream { + if !attr.is_empty() { + let msg = "Invalid pallet macro call: expected no attributes, e.g. macro call must be just \ + `#[frame_support::pallet]` or `#[pallet]`"; + let span = proc_macro2::TokenStream::from(attr).span(); + return syn::Error::new(span, msg).to_compile_error().into(); + } + + let item = syn::parse_macro_input!(item as syn::ItemMod); + match parse::Def::try_from(item) { + Ok(def) => expand::expand(def).into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs new file mode 100644 index 00000000000..239329639e5 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -0,0 +1,235 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use quote::ToTokens; +use syn::spanned::Spanned; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(DispatchResultWithPostInfo); + syn::custom_keyword!(Call); + syn::custom_keyword!(OriginFor); + syn::custom_keyword!(weight); + syn::custom_keyword!(compact); + syn::custom_keyword!(T); + syn::custom_keyword!(pallet); +} + +/// Definition of dispatchables typically `impl Pallet { ... }` +pub struct CallDef { + /// The where_clause used. + pub where_clause: Option, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The index of call item in pallet module. + pub index: usize, + /// Information on methods (used for expansion). + pub methods: Vec, + /// The span of the attribute. + pub attr_span: proc_macro2::Span, +} + +/// Definition of dispatchable typically: `#[weight...] fn foo(origin .., param1: ...) -> ..` +pub struct CallVariantDef { + /// Function name. + pub name: syn::Ident, + /// Information on args: `(is_compact, name, type)` + pub args: Vec<(bool, syn::Ident, Box)>, + /// Weight formula. + pub weight: syn::Expr, + /// Docs, used for metadata. + pub docs: Vec, +} + +/// Attributes for functions in call impl block. +/// Parse for `#[pallet::weight = expr]` +pub struct FunctionAttr { + weight: syn::Expr, +} + +impl syn::parse::Parse for FunctionAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + content.parse::()?; + + let weight_content; + syn::parenthesized!(weight_content in content); + Ok(FunctionAttr { + weight: weight_content.parse::()?, + }) + } +} + +/// Attribute for arguments in function in call impl block. +/// Parse for `#[pallet::compact]| +pub struct ArgAttrIsCompact; + +impl syn::parse::Parse for ArgAttrIsCompact { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + content.parse::()?; + Ok(ArgAttrIsCompact) + } +} + +/// Check the syntax is `OriginFor` +pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> { + + pub struct CheckDispatchableFirstArg; + impl syn::parse::Parse for CheckDispatchableFirstArg { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + + Ok(Self) + } + } + + syn::parse2::(ty.to_token_stream()) + .map_err(|e| { + let msg = "Invalid type: expected `OriginFor`"; + let mut err = syn::Error::new(ty.span(), msg); + err.combine(e); + err + })?; + + Ok(()) +} + +impl CallDef { + pub fn try_from( + // Span needed for expansion + attr_span: proc_macro2::Span, + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl")); + }; + + let mut instances = vec![]; + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + + if let Some((_, _, for_)) = item.trait_ { + let msg = "Invalid pallet::call, expected no trait ident as in \ + `impl<..> Pallet<..> { .. }`"; + return Err(syn::Error::new(for_.span(), msg)) + } + + let mut methods = vec![]; + for impl_item in &mut item.items { + if let syn::ImplItem::Method(method) = impl_item { + match method.sig.inputs.first() { + None => { + let msg = "Invalid pallet::call, must have at least origin arg"; + return Err(syn::Error::new(method.sig.span(), msg)); + }, + Some(syn::FnArg::Receiver(_)) => { + let msg = "Invalid pallet::call, first argument must be a typed argument, \ + e.g. `origin: OriginFor`"; + return Err(syn::Error::new(method.sig.span(), msg)); + }, + Some(syn::FnArg::Typed(arg)) => { + check_dispatchable_first_arg_type(&*arg.ty)?; + }, + } + + if let syn::ReturnType::Type(_, type_) = &method.sig.output { + syn::parse2::(type_.to_token_stream())?; + } else { + let msg = "Invalid pallet::call, require return type \ + DispatchResultWithPostInfo"; + return Err(syn::Error::new(method.sig.span(), msg)); + } + + let mut call_var_attrs: Vec = + helper::take_item_attrs(&mut method.attrs)?; + + if call_var_attrs.len() != 1 { + let msg = if call_var_attrs.len() == 0 { + "Invalid pallet::call, require weight attribute i.e. `#[pallet::weight = $expr]`" + } else { + "Invalid pallet::call, too many weight attributes given" + }; + return Err(syn::Error::new(method.sig.span(), msg)); + } + let weight = call_var_attrs.pop().unwrap().weight; + + let mut args = vec![]; + for arg in method.sig.inputs.iter_mut().skip(1) { + let arg = if let syn::FnArg::Typed(arg) = arg { + arg + } else { + unreachable!("Only first argument can be receiver"); + }; + + let arg_attrs: Vec = + helper::take_item_attrs(&mut arg.attrs)?; + + if arg_attrs.len() > 1 { + let msg = "Invalid pallet::call, argument has too many attributes"; + return Err(syn::Error::new(arg.span(), msg)); + } + + let arg_ident = if let syn::Pat::Ident(pat) = &*arg.pat { + pat.ident.clone() + } else { + let msg = "Invalid pallet::call, argument must be ident"; + return Err(syn::Error::new(arg.pat.span(), msg)); + }; + + args.push((!arg_attrs.is_empty(), arg_ident, arg.ty.clone())); + } + + let docs = helper::get_doc_literals(&method.attrs); + + methods.push(CallVariantDef { + name: method.sig.ident.clone(), + weight, + args, + docs, + }); + } else { + let msg = "Invalid pallet::call, only method accepted"; + return Err(syn::Error::new(impl_item.span(), msg)); + } + } + + Ok(Self { + index, + attr_span, + instances, + methods, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs new file mode 100644 index 00000000000..46355b0fdb1 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -0,0 +1,384 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Config); + syn::custom_keyword!(From); + syn::custom_keyword!(T); + syn::custom_keyword!(I); + syn::custom_keyword!(Get); + syn::custom_keyword!(config); + syn::custom_keyword!(IsType); + syn::custom_keyword!(Event); + syn::custom_keyword!(constant); + syn::custom_keyword!(frame_system); + syn::custom_keyword!(disable_frame_system_supertrait_check); +} + +/// Input definition for the pallet config. +pub struct ConfigDef { + /// The index of item in pallet module. + pub index: usize, + /// Whether the trait has instance (i.e. define with `Config`) + pub has_instance: bool, + /// Const associated type. + pub consts_metadata: Vec, + /// Whether the trait has the associated type `Event`, note that those bounds are checked: + /// * `IsType::Event` + /// * `From` or `From>` or `From>` + pub has_event_type: bool, + /// The where clause on trait definition but modified so `Self` is `T`. + pub where_clause: Option, + +} + +/// Input definition for a constant in pallet config. +pub struct ConstMetadataDef { + /// Name of the associated type. + pub ident: syn::Ident, + /// The type in Get, e.g. `u32` in `type Foo: Get;`, but `Self` is replaced by `T` + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, +} + +impl syn::parse::Parse for ConstMetadataDef { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let doc = helper::get_doc_literals(&syn::Attribute::parse_outer(input)?); + input.parse::()?; + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + let mut type_ = input.parse::()?; + type_ = syn::parse2::(replace_self_by_t(type_.to_token_stream())) + .expect("Internal error: replacing `Self` by `T` should result in valid type"); + input.parse::]>()?; + input.parse::()?; + + Ok(Self { ident, type_, doc }) + } +} + +/// Parse for `#[pallet::disable_frame_system_supertrait_check]` +pub struct DisableFrameSystemSupertraitCheck; + +impl syn::parse::Parse for DisableFrameSystemSupertraitCheck { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + content.parse::()?; + Ok(Self) + } +} + +/// Parse for `#[pallet::constant]` +pub struct TypeAttrConst(proc_macro2::Span); + +impl Spanned for TypeAttrConst { + fn span(&self) -> proc_macro2::Span { + self.0 + } +} + +impl syn::parse::Parse for TypeAttrConst { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + Ok(TypeAttrConst(content.parse::()?.span())) + } +} + +/// Parse for `$ident::Config` +pub struct ConfigBoundParse(syn::Ident); + +impl syn::parse::Parse for ConfigBoundParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(ident)) + } +} + +/// Parse for `IsType<::Event>` and retrieve `$ident` +pub struct IsTypeBoundEventParse(syn::Ident); + +impl syn::parse::Parse for IsTypeBoundEventParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + + Ok(Self(ident)) + } +} + +/// Parse for `From` or `From>` or `From>` +pub struct FromEventParse { + is_generic: bool, + has_instance: bool, +} + +impl syn::parse::Parse for FromEventParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut is_generic = false; + let mut has_instance = false; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![<]) { + is_generic = true; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + input.parse::()?; + input.parse::()?; + has_instance = true; + } + input.parse::]>()?; + } + input.parse::]>()?; + + Ok(Self { is_generic, has_instance }) + } +} + +/// Check if trait_item is `type Event`, if so checks its bounds are those expected. +/// (Event type is reserved type) +fn check_event_type( + frame_system: &syn::Ident, + trait_item: &syn::TraitItem, + trait_has_instance: bool +) -> syn::Result { + if let syn::TraitItem::Type(type_) = trait_item { + if type_.ident == "Event" { + // Check event has no generics + if !type_.generics.params.is_empty() || type_.generics.where_clause.is_some() { + let msg = "Invalid `type Event`, associated type `Event` is reserved and must have\ + no generics nor where_clause"; + return Err(syn::Error::new(trait_item.span(), msg)); + } + // Check bound contains IsType and From + + let has_is_type_bound = type_.bounds.iter().any(|s| { + syn::parse2::(s.to_token_stream()) + .map_or(false, |b| b.0 == *frame_system) + }); + + if !has_is_type_bound { + let msg = format!( + "Invalid `type Event`, associated type `Event` is reserved and must \ + bound: `IsType<::Event>`", + frame_system, + ); + return Err(syn::Error::new(type_.span(), msg)); + } + + let from_event_bound = type_.bounds.iter().find_map(|s| { + syn::parse2::(s.to_token_stream()).ok() + }); + + let from_event_bound = if let Some(b) = from_event_bound { + b + } else { + let msg = "Invalid `type Event`, associated type `Event` is reserved and must \ + bound: `From` or `From>` or `From>`"; + return Err(syn::Error::new(type_.span(), msg)); + }; + + if from_event_bound.is_generic + && (from_event_bound.has_instance != trait_has_instance) + { + let msg = "Invalid `type Event`, associated type `Event` bounds inconsistent \ + `From`. Config and generic Event must be both with instance or \ + without instance"; + return Err(syn::Error::new(type_.span(), msg)); + } + + Ok(true) + } else { + Ok(false) + } + } else { + Ok(false) + } +} + +/// Replace ident `Self` by `T` +pub fn replace_self_by_t(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { + input.into_iter() + .map(|token_tree| match token_tree { + proc_macro2::TokenTree::Group(group) => + proc_macro2::Group::new( + group.delimiter(), + replace_self_by_t(group.stream()) + ).into(), + proc_macro2::TokenTree::Ident(ident) if ident == "Self" => + proc_macro2::Ident::new("T", ident.span()).into(), + other @ _ => other + }) + .collect() +} + +impl ConfigDef { + pub fn try_from( + frame_system: &syn::Ident, + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Trait(item) = item { + item + } else { + let msg = "Invalid pallet::config, expected trait definition"; + return Err(syn::Error::new(item.span(), msg)); + }; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::config, trait must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + syn::parse2::(item.ident.to_token_stream())?; + + + let where_clause = { + let stream = replace_self_by_t(item.generics.where_clause.to_token_stream()); + syn::parse2::>(stream) + .expect("Internal error: replacing `Self` by `T` should result in valid where + clause") + }; + + if item.generics.params.len() > 1 { + let msg = "Invalid pallet::config, expected no more than one generic"; + return Err(syn::Error::new(item.generics.params[2].span(), msg)); + } + + let has_instance = if let Some(_) = item.generics.params.first() { + helper::check_config_def_gen(&item.generics, item.ident.span())?; + true + } else { + false + }; + + let mut has_event_type = false; + let mut consts_metadata = vec![]; + for trait_item in &mut item.items { + // Parse for event + has_event_type = has_event_type + || check_event_type(frame_system, trait_item, has_instance)?; + + // Parse for constant + let type_attrs_const: Vec = helper::take_item_attrs(trait_item)?; + + if type_attrs_const.len() > 1 { + let msg = "Invalid attribute in pallet::config, only one attribute is expected"; + return Err(syn::Error::new(type_attrs_const[1].span(), msg)); + } + + if type_attrs_const.len() == 1 { + match trait_item { + syn::TraitItem::Type(type_) => { + let constant = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let error_msg = "Invalid usage of `#[pallet::constant]`, syntax \ + must be `type $SomeIdent: Get<$SomeType>;`"; + let mut err = syn::Error::new(type_.span(), error_msg); + err.combine(e); + err + })?; + + consts_metadata.push(constant); + }, + _ => { + let msg = "Invalid pallet::constant in pallet::config, expected type trait \ + item"; + return Err(syn::Error::new(trait_item.span(), msg)); + }, + } + } + } + + let attr: Option = helper::take_first_item_attr( + &mut item.attrs + )?; + + let disable_system_supertrait_check = attr.is_some(); + + let has_frame_system_supertrait = item.supertraits.iter().any(|s| { + syn::parse2::(s.to_token_stream()) + .map_or(false, |b| b.0 == *frame_system) + }); + + if !has_frame_system_supertrait && !disable_system_supertrait_check { + let found = if item.supertraits.is_empty() { + "none".to_string() + } else { + let mut found = item.supertraits.iter() + .fold(String::new(), |acc, s| { + format!("{}`{}`, ", acc, quote::quote!(#s).to_string()) + }); + found.pop(); + found.pop(); + found + }; + + let msg = format!( + "Invalid pallet::trait, expected explicit `{}::Config` as supertrait, \ + found {}. \ + (try `pub trait Config: frame_system::Config {{ ...` or \ + `pub trait Config: frame_system::Config {{ ...`). \ + To disable this check, use `#[pallet::disable_frame_system_supertrait_check]`", + frame_system, + found, + ); + return Err(syn::Error::new(item.span(), msg)); + } + + Ok(Self { + index, + has_instance, + consts_metadata, + has_event_type, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/error.rs b/frame/support/procedural/src/pallet/parse/error.rs new file mode 100644 index 00000000000..0bdf8e73b37 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/error.rs @@ -0,0 +1,86 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Error); +} + +/// This checks error declaration as a enum declaration with only variants without fields nor +/// discriminant. +pub struct ErrorDef { + /// The index of error item in pallet module. + pub index: usize, + /// Variants ident and doc literals (ordered as declaration order) + pub variants: Vec<(syn::Ident, Vec)>, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The keyword error used (contains span). + pub error: keyword::Error +} + +impl ErrorDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Enum(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::error, expected item enum")); + }; + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::error, `Error` must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen_no_bounds(&item.generics, item.ident.span())?); + + if item.generics.where_clause.is_some() { + let msg = "Invalid pallet::error, unexpected where clause"; + return Err(syn::Error::new(item.generics.where_clause.as_ref().unwrap().span(), msg)); + } + + let error = syn::parse2::(item.ident.to_token_stream())?; + + let variants = item.variants.iter() + .map(|variant| { + if !matches!(variant.fields, syn::Fields::Unit) { + let msg = "Invalid pallet::error, unexpected fields, must be `Unit`"; + return Err(syn::Error::new(variant.fields.span(), msg)); + } + if variant.discriminant.is_some() { + let msg = "Invalid pallet::error, unexpected discriminant, discriminant \ + are not supported"; + let span = variant.discriminant.as_ref().unwrap().0.span(); + return Err(syn::Error::new(span, msg)); + } + + Ok((variant.ident.clone(), helper::get_doc_literals(&variant.attrs))) + }) + .collect::>()?; + + Ok(ErrorDef { + index, + variants, + instances, + error, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs new file mode 100644 index 00000000000..6b83ca4bf04 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -0,0 +1,220 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; +use frame_support_procedural_tools::clean_type_string; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(metadata); + syn::custom_keyword!(Event); + syn::custom_keyword!(pallet); + syn::custom_keyword!(generate_deposit); + syn::custom_keyword!(deposit_event); +} + +/// Definition for pallet event enum. +pub struct EventDef { + /// The index of event item in pallet module. + pub index: usize, + /// The keyword Event used (contains span). + pub event: keyword::Event, + /// Event metadatas: `(name, args, docs)`. + pub metadata: Vec<(syn::Ident, Vec, Vec)>, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The kind of generic the type `Event` has. + pub gen_kind: super::GenericKind, + /// Whether the function `deposit_event` must be generated. + pub deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, + /// Where clause used in event definition. + pub where_clause: Option, +} + +/// Attribute for Event: defines metadata name to use. +/// +/// Syntax is: +/// * `#[pallet::metadata(SomeType = MetadataName, ...)]` +/// * `#[pallet::generate_deposit($vis fn deposit_event)]` +enum PalletEventAttr { + Metadata { + metadata: Vec<(syn::Type, String)>, + // Span of the attribute + span: proc_macro2::Span, + }, + DepositEvent { + fn_vis: syn::Visibility, + // Span for the keyword deposit_event + fn_span: proc_macro2::Span, + // Span of the attribute + span: proc_macro2::Span, + }, +} + +impl PalletEventAttr { + fn span(&self) -> proc_macro2::Span { + match self { + Self::Metadata { span, .. } => span.clone(), + Self::DepositEvent { span, .. } => span.clone(), + } + } +} + +/// Parse for syntax `$Type = "$SomeString"`. +fn parse_event_metadata_element( + input: syn::parse::ParseStream +) -> syn::Result<(syn::Type, String)> { + let typ = input.parse::()?; + input.parse::()?; + let ident = input.parse::()?; + Ok((typ, ident.value())) +} + +impl syn::parse::Parse for PalletEventAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + let lookahead = content.lookahead1(); + if lookahead.peek(keyword::metadata) { + let span = content.parse::()?.span(); + let metadata_content; + syn::parenthesized!(metadata_content in content); + + let metadata = metadata_content + .parse_terminated::<_, syn::Token![,]>(parse_event_metadata_element)? + .into_pairs() + .map(syn::punctuated::Pair::into_value) + .collect(); + + Ok(PalletEventAttr::Metadata { metadata, span }) + } else if lookahead.peek(keyword::generate_deposit) { + let span = content.parse::()?.span(); + + let generate_content; + syn::parenthesized!(generate_content in content); + let fn_vis = generate_content.parse::()?; + generate_content.parse::()?; + let fn_span = generate_content.parse::()?.span(); + + + Ok(PalletEventAttr::DepositEvent { fn_vis, span, fn_span }) + } else { + Err(lookahead.error()) + } + } +} + +struct PalletEventAttrInfo { + metadata: Option>, + deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, +} + +impl PalletEventAttrInfo { + fn from_attrs(attrs: Vec) -> syn::Result { + let mut metadata = None; + let mut deposit_event = None; + for attr in attrs { + match attr { + PalletEventAttr::Metadata { metadata: m, .. } if metadata.is_none() => + metadata = Some(m), + PalletEventAttr::DepositEvent { fn_vis, fn_span, .. } if deposit_event.is_none() => + deposit_event = Some((fn_vis, fn_span)), + attr => { + return Err(syn::Error::new(attr.span(), "Duplicate attribute")); + } + } + } + + Ok(PalletEventAttrInfo { metadata, deposit_event }) + } +} + +impl EventDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Enum(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::event, expected item enum")) + }; + + let event_attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + let attr_info = PalletEventAttrInfo::from_attrs(event_attrs)?; + let metadata = attr_info.metadata.unwrap_or_else(|| vec![]); + let deposit_event = attr_info.deposit_event; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::event, `Error` must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + let where_clause = item.generics.where_clause.clone(); + + let mut instances = vec![]; + // NOTE: Event is not allowed to be only generic on I because it is not supported + // by construct_runtime. + if let Some(u) = helper::check_type_def_optional_gen(&item.generics, item.ident.span())? { + instances.push(u); + } else { + // construct_runtime only allow non generic event for non instantiable pallet. + instances.push(helper::InstanceUsage { + has_instance: false, + span: item.ident.span(), + }) + } + + let has_instance = item.generics.type_params().any(|t| t.ident == "I"); + let has_config = item.generics.type_params().any(|t| t.ident == "T"); + let gen_kind = super::GenericKind::from_gens(has_config, has_instance) + .expect("Checked by `helper::check_type_def_optional_gen` above"); + + let event = syn::parse2::(item.ident.to_token_stream())?; + + let metadata = item.variants.iter() + .map(|variant| { + let name = variant.ident.clone(); + let docs = helper::get_doc_literals(&variant.attrs); + let args = variant.fields.iter() + .map(|field| { + metadata.iter().find(|m| m.0 == field.ty) + .map(|m| m.1.clone()) + .unwrap_or_else(|| { + clean_type_string(&field.ty.to_token_stream().to_string()) + }) + }) + .collect(); + + (name, args, docs) + }) + .collect(); + + Ok(EventDef { + index, + metadata, + instances, + deposit_event, + event, + gen_kind, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/extra_constants.rs b/frame/support/procedural/src/pallet/parse/extra_constants.rs new file mode 100644 index 00000000000..f37c7135de8 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/extra_constants.rs @@ -0,0 +1,121 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(DispatchResultWithPostInfo); + syn::custom_keyword!(Call); + syn::custom_keyword!(OriginFor); + syn::custom_keyword!(weight); + syn::custom_keyword!(compact); + syn::custom_keyword!(T); + syn::custom_keyword!(pallet); +} + +/// Definition of extra constants typically `impl Pallet { ... }` +pub struct ExtraConstantsDef { + /// The where_clause used. + pub where_clause: Option, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The index of call item in pallet module. + pub index: usize, + /// The extra constant defined. + pub extra_constants: Vec, +} + +/// Input definition for an constant in pallet. +pub struct ExtraConstantDef { + /// Name of the function + pub ident: syn::Ident, + /// The type returned by the function + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, +} + +impl ExtraConstantsDef { + pub fn try_from( + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl")); + }; + + let mut instances = vec![]; + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + + if let Some((_, _, for_)) = item.trait_ { + let msg = "Invalid pallet::call, expected no trait ident as in \ + `impl<..> Pallet<..> { .. }`"; + return Err(syn::Error::new(for_.span(), msg)) + } + + let mut extra_constants = vec![]; + for impl_item in &mut item.items { + let method = if let syn::ImplItem::Method(method) = impl_item { + method + } else { + let msg = "Invalid pallet::call, only method accepted"; + return Err(syn::Error::new(impl_item.span(), msg)); + }; + + if method.sig.inputs.len() != 0 { + let msg = "Invalid pallet::extra_constants, method must have 0 args"; + return Err(syn::Error::new(method.sig.span(), msg)); + } + + if method.sig.generics.params.len() != 0 { + let msg = "Invalid pallet::extra_constants, method must have 0 generics"; + return Err(syn::Error::new(method.sig.generics.params[0].span(), msg)); + } + + if method.sig.generics.where_clause.is_some() { + let msg = "Invalid pallet::extra_constants, method must have no where clause"; + return Err(syn::Error::new(method.sig.generics.where_clause.span(), msg)); + } + + let type_ = match &method.sig.output { + syn::ReturnType::Default => { + let msg = "Invalid pallet::extra_constants, method must have a return type"; + return Err(syn::Error::new(method.span(), msg)); + }, + syn::ReturnType::Type(_, type_) => *type_.clone(), + }; + + extra_constants.push(ExtraConstantDef { + ident: method.sig.ident.clone(), + type_, + doc: helper::get_doc_literals(&method.attrs), + }); + } + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + extra_constants, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/genesis_build.rs b/frame/support/procedural/src/pallet/parse/genesis_build.rs new file mode 100644 index 00000000000..79c64b8a1a9 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/genesis_build.rs @@ -0,0 +1,56 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// Definition for pallet genesis build implementation. +pub struct GenesisBuildDef { + /// The index of item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The where_clause used. + pub where_clause: Option, +} + +impl GenesisBuildDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::genesis_build, expected item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let item_trait = &item.trait_.as_ref() + .ok_or_else(|| { + let msg = "Invalid pallet::genesis_build, expected impl<..> GenesisBuild<..> \ + for GenesisConfig<..>"; + syn::Error::new(item.span(), msg) + })?.1; + + let mut instances = vec![]; + instances.push(helper::check_genesis_builder_usage(&item_trait)?); + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs new file mode 100644 index 00000000000..f42fcc6dac3 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -0,0 +1,78 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// Definition for pallet genesis config type. +/// +/// Either: +/// * `struct GenesisConfig` +/// * `enum GenesisConfig` +pub struct GenesisConfigDef { + /// The index of item in pallet module. + pub index: usize, + /// The kind of generic the type `GenesisConfig` has. + pub gen_kind: super::GenericKind, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The ident of genesis_config, can be used for span. + pub genesis_config: syn::Ident, +} + +impl GenesisConfigDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item_span = item.span(); + let (vis, ident, generics) = match &item { + syn::Item::Enum(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), + _ => { + let msg = "Invalid pallet::genesis_config, expected enum or struct"; + return Err(syn::Error::new(item.span(), msg)); + }, + }; + + let mut instances = vec![]; + // NOTE: GenesisConfig is not allowed to be only generic on I because it is not supported + // by construct_runtime. + if let Some(u) = helper::check_type_def_optional_gen(&generics, ident.span())? { + instances.push(u); + } + + let has_instance = generics.type_params().any(|t| t.ident == "I"); + let has_config = generics.type_params().any(|t| t.ident == "T"); + let gen_kind = super::GenericKind::from_gens(has_config, has_instance) + .expect("Checked by `helper::check_type_def_optional_gen` above"); + + if !matches!(vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::genesis_config, GenesisConfig must be public"; + return Err(syn::Error::new(item_span, msg)); + } + + if ident != "GenesisConfig" { + let msg = "Invalid pallet::genesis_config, ident must `GenesisConfig`"; + return Err(syn::Error::new(ident.span(), msg)); + } + + Ok(GenesisConfigDef { + index, + genesis_config: ident.clone(), + instances, + gen_kind, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs new file mode 100644 index 00000000000..cbf09ee2317 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -0,0 +1,600 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(I); + syn::custom_keyword!(compact); + syn::custom_keyword!(GenesisBuild); + syn::custom_keyword!(Config); + syn::custom_keyword!(T); + syn::custom_keyword!(Pallet); + syn::custom_keyword!(origin); +} + +/// A usage of instance, either the trait `Config` has been used with instance or without instance. +/// Used to check for consistency. +#[derive(Clone)] +pub struct InstanceUsage { + pub has_instance: bool, + pub span: proc_macro2::Span, +} + +/// Trait implemented for syn items to get mutable references on their attributes. +/// +/// NOTE: verbatim variants are not supported. +pub trait MutItemAttrs { + fn mut_item_attrs(&mut self) -> Option<&mut Vec>; +} + +/// Take the first pallet attribute (e.g. attribute like `#[pallet..]`) and decode it to `Attr` +pub fn take_first_item_attr(item: &mut impl MutItemAttrs) -> syn::Result> where + Attr: syn::parse::Parse, +{ + let attrs = if let Some(attrs) = item.mut_item_attrs() { + attrs + } else { + return Ok(None) + }; + + if let Some(index) = attrs.iter() + .position(|attr| + attr.path.segments.first().map_or(false, |segment| segment.ident == "pallet") + ) + { + let pallet_attr = attrs.remove(index); + Ok(Some(syn::parse2(pallet_attr.into_token_stream())?)) + } else { + Ok(None) + } +} + +/// Take all the pallet attributes (e.g. attribute like `#[pallet..]`) and decode them to `Attr` +pub fn take_item_attrs(item: &mut impl MutItemAttrs) -> syn::Result> where + Attr: syn::parse::Parse, +{ + let mut pallet_attrs = Vec::new(); + + while let Some(attr) = take_first_item_attr(item)? { + pallet_attrs.push(attr) + } + + Ok(pallet_attrs) +} + +impl MutItemAttrs for syn::Item { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + match self { + Self::Const(item) => Some(item.attrs.as_mut()), + Self::Enum(item) => Some(item.attrs.as_mut()), + Self::ExternCrate(item) => Some(item.attrs.as_mut()), + Self::Fn(item) => Some(item.attrs.as_mut()), + Self::ForeignMod(item) => Some(item.attrs.as_mut()), + Self::Impl(item) => Some(item.attrs.as_mut()), + Self::Macro(item) => Some(item.attrs.as_mut()), + Self::Macro2(item) => Some(item.attrs.as_mut()), + Self::Mod(item) => Some(item.attrs.as_mut()), + Self::Static(item) => Some(item.attrs.as_mut()), + Self::Struct(item) => Some(item.attrs.as_mut()), + Self::Trait(item) => Some(item.attrs.as_mut()), + Self::TraitAlias(item) => Some(item.attrs.as_mut()), + Self::Type(item) => Some(item.attrs.as_mut()), + Self::Union(item) => Some(item.attrs.as_mut()), + Self::Use(item) => Some(item.attrs.as_mut()), + Self::Verbatim(_) => None, + Self::__Nonexhaustive => None, + } + } +} + + +impl MutItemAttrs for syn::TraitItem { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + match self { + Self::Const(item) => Some(item.attrs.as_mut()), + Self::Method(item) => Some(item.attrs.as_mut()), + Self::Type(item) => Some(item.attrs.as_mut()), + Self::Macro(item) => Some(item.attrs.as_mut()), + Self::Verbatim(_) => None, + Self::__Nonexhaustive => None, + } + } +} + +impl MutItemAttrs for Vec { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + Some(self) + } +} + +impl MutItemAttrs for syn::ItemMod { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + Some(&mut self.attrs) + } +} + +/// Return all doc attributes literals found. +pub fn get_doc_literals(attrs: &Vec) -> Vec { + attrs.iter() + .filter_map(|attr| { + if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() { + if meta.path.get_ident().map_or(false, |ident| ident == "doc") { + Some(meta.lit.clone()) + } else { + None + } + } else { + None + } + }) + .collect() +} + +/// Parse for `()` +struct Unit; +impl syn::parse::Parse for Unit { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let content; + syn::parenthesized!(content in input); + if !content.is_empty() { + let msg = "unexpected tokens, expected nothing inside parenthesis as `()`"; + return Err(syn::Error::new(content.span(), msg)); + } + Ok(Self) + } +} + +/// Parse for `'static` +struct StaticLifetime; +impl syn::parse::Parse for StaticLifetime { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let lifetime = input.parse::()?; + if lifetime.ident != "static" { + let msg = "unexpected tokens, expected `static`"; + return Err(syn::Error::new(lifetime.ident.span(), msg)); + } + Ok(Self) + } +} + +/// Check the syntax: `I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_config_def_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result<()> { + let expected = "expected `I: 'static = ()`"; + pub struct CheckTraitDefGenerics; + impl syn::parse::Parse for CheckTraitDefGenerics { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self) + } + } + + syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?; + + Ok(()) +} + +/// Check the syntax: +/// * either `T` +/// * or `T, I = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_def_gen_no_bounds( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result { + let expected = "expected `T` or `T, I = ()`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + has_instance: false, + span: input.span(), + }; + + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + } + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * either `` (no generics +/// * or `T` +/// * or `T: Config` +/// * or `T, I = ()` +/// * or `T: Config, I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return some instance usage if there is some generic, or none otherwise. +pub fn check_type_def_optional_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result> { + let expected = "expected `` or `T` or `T: Config` or `T, I = ()` or \ + `T: Config, I: 'static = ()`"; + pub struct Checker(Option); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + if input.is_empty() { + return Ok(Self(None)) + } + + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + let lookahead = input.lookahead1(); + if lookahead.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } else if lookahead.peek(syn::Token![:]) { + input.parse::()?; + input.parse::()?; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } else { + Err(lookahead.error()) + } + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0 + // Span can be call_site if generic is empty. Thus we replace it. + .map(|mut i| { i.span = span; i }); + + Ok(i) +} + +/// Check the syntax: +/// * either `Pallet` +/// * or `Pallet` +/// +/// return the instance if found. +pub fn check_pallet_struct_usage(type_: &Box) -> syn::Result { + let expected = "expected `Pallet` or `Pallet`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + } + input.parse::]>()?; + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid pallet struct: {}", expected); + let mut err = syn::Error::new(type_.span(), msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the generic is: +/// * either `T: Config` +/// * or `T: Config, I: 'static` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return whether it contains instance. +pub fn check_impl_gen( + gen: &syn::Generics, + span: proc_macro2::Span +) -> syn::Result { + let expected = "expected `impl` or `impl, I: 'static>`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![<]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + } + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let mut err = syn::Error::new(span, format!("Invalid generics: {}", expected)); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * or `T` +/// * or `T: Config` +/// * or `T, I = ()` +/// * or `T: Config, I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_def_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result { + let expected = "expected `T` or `T: Config` or `T, I = ()` or \ + `T: Config, I: 'static = ()`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + + if input.is_empty() { + return Ok(Self(instance_usage)) + } + + let lookahead = input.lookahead1(); + if lookahead.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(instance_usage)) + } else if lookahead.peek(syn::Token![:]) { + input.parse::()?; + input.parse::()?; + + if input.is_empty() { + return Ok(Self(instance_usage)) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(instance_usage)) + } else { + Err(lookahead.error()) + } + } + } + + let mut i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0; + + // Span can be call_site if generic is empty. Thus we replace it. + i.span = span; + + Ok(i) +} + +/// Check the syntax: +/// * either `GenesisBuild` +/// * or `GenesisBuild` +/// +/// return the instance if found. +pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result { + let expected = "expected `GenesisBuild` or `GenesisBuild`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + } + input.parse::]>()?; + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid genesis builder: {}", expected); + let mut err = syn::Error::new(type_.span(), msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * either `` (no generics) +/// * or `T: Config` +/// * or `T: Config, I: 'static` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_value_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result> { + let expected = "expected `` or `T: Config` or `T: Config, I: 'static`"; + pub struct Checker(Option); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + if input.is_empty() { + return Ok(Self(None)) + } + + input.parse::()?; + input.parse::()?; + input.parse::()?; + + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0 + // Span can be call_site if generic is empty. Thus we replace it. + .map(|mut i| { i.span = span; i }); + + Ok(i) +} diff --git a/frame/support/procedural/src/pallet/parse/hooks.rs b/frame/support/procedural/src/pallet/parse/hooks.rs new file mode 100644 index 00000000000..93061069f8c --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/hooks.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// Implementation of the pallet hooks. +pub struct HooksDef { + /// The index of item in pallet. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The where_clause used. + pub where_clause: Option, +} + +impl HooksDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::hooks, expected item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + let item_trait = &item.trait_.as_ref() + .ok_or_else(|| { + let msg = "Invalid pallet::hooks, expected impl<..> Hooks \ + for Pallet<..>"; + syn::Error::new(item.span(), msg) + })?.1; + + if item_trait.segments.len() != 1 + || item_trait.segments[0].ident != "Hooks" + { + let msg = format!( + "Invalid pallet::hooks, expected trait to be `Hooks` found `{}`\ + , you can import from `frame_support::pallet_prelude`", + quote::quote!(#item_trait) + ); + + return Err(syn::Error::new(item_trait.span(), msg)); + } + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/inherent.rs b/frame/support/procedural/src/pallet/parse/inherent.rs new file mode 100644 index 00000000000..b4dfd71d8a5 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/inherent.rs @@ -0,0 +1,59 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// The definition of the pallet inherent implementation. +pub struct InherentDef { + /// The index of inherent item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, +} + +impl InherentDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::inherent, expected item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + if item.trait_.is_none() { + let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { + if last.ident != "ProvideInherent" { + let msg = "Invalid pallet::inherent, expected trait ProvideInherent"; + return Err(syn::Error::new(last.span(), msg)); + } + } else { + let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + Ok(InherentDef { index, instances }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs new file mode 100644 index 00000000000..085467bdaa2 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -0,0 +1,461 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Parse for pallet macro. +//! +//! Parse the module into `Def` struct through `Def::try_from` function. + +pub mod config; +pub mod pallet_struct; +pub mod hooks; +pub mod call; +pub mod error; +pub mod origin; +pub mod inherent; +pub mod storage; +pub mod event; +pub mod helper; +pub mod genesis_config; +pub mod genesis_build; +pub mod validate_unsigned; +pub mod type_value; +pub mod extra_constants; + +use syn::spanned::Spanned; +use frame_support_procedural_tools::generate_crate_access_2018; + +/// Parsed definition of a pallet. +pub struct Def { + /// The module items. + /// (their order must not be modified because they are registered in individual definitions). + pub item: syn::ItemMod, + pub config: config::ConfigDef, + pub pallet_struct: pallet_struct::PalletStructDef, + pub hooks: hooks::HooksDef, + pub call: call::CallDef, + pub storages: Vec, + pub error: Option, + pub event: Option, + pub origin: Option, + pub inherent: Option, + pub genesis_config: Option, + pub genesis_build: Option, + pub validate_unsigned: Option, + pub extra_constants: Option, + pub type_values: Vec, + pub frame_system: syn::Ident, + pub frame_support: syn::Ident, +} + +impl Def { + pub fn try_from(mut item: syn::ItemMod) -> syn::Result { + let frame_system = generate_crate_access_2018("frame-system")?; + let frame_support = generate_crate_access_2018("frame-support")?; + + let item_span = item.span().clone(); + let items = &mut item.content.as_mut() + .ok_or_else(|| { + let msg = "Invalid pallet definition, expected mod to be inlined."; + syn::Error::new(item_span, msg) + })?.1; + + let mut config = None; + let mut pallet_struct = None; + let mut hooks = None; + let mut call = None; + let mut error = None; + let mut event = None; + let mut origin = None; + let mut inherent = None; + let mut genesis_config = None; + let mut genesis_build = None; + let mut validate_unsigned = None; + let mut extra_constants = None; + let mut storages = vec![]; + let mut type_values = vec![]; + + for (index, item) in items.iter_mut().enumerate() { + let pallet_attr: Option = helper::take_first_item_attr(item)?; + + match pallet_attr { + Some(PalletAttr::Config(_)) if config.is_none() => + config = Some(config::ConfigDef::try_from(&frame_system, index, item)?), + Some(PalletAttr::Pallet(_)) if pallet_struct.is_none() => + pallet_struct = Some(pallet_struct::PalletStructDef::try_from(index, item)?), + Some(PalletAttr::Hooks(_)) if hooks.is_none() => { + let m = hooks::HooksDef::try_from(index, item)?; + hooks = Some(m); + }, + Some(PalletAttr::Call(span)) if call.is_none() => + call = Some(call::CallDef::try_from(span, index, item)?), + Some(PalletAttr::Error(_)) if error.is_none() => + error = Some(error::ErrorDef::try_from(index, item)?), + Some(PalletAttr::Event(_)) if event.is_none() => + event = Some(event::EventDef::try_from(index, item)?), + Some(PalletAttr::GenesisConfig(_)) if genesis_config.is_none() => { + genesis_config = + Some(genesis_config::GenesisConfigDef::try_from(index, item)?); + }, + Some(PalletAttr::GenesisBuild(_)) if genesis_build.is_none() => + genesis_build = Some(genesis_build::GenesisBuildDef::try_from(index, item)?), + Some(PalletAttr::Origin(_)) if origin.is_none() => + origin = Some(origin::OriginDef::try_from(index, item)?), + Some(PalletAttr::Inherent(_)) if inherent.is_none() => + inherent = Some(inherent::InherentDef::try_from(index, item)?), + Some(PalletAttr::Storage(_)) => + storages.push(storage::StorageDef::try_from(index, item)?), + Some(PalletAttr::ValidateUnsigned(_)) if validate_unsigned.is_none() => { + let v = validate_unsigned::ValidateUnsignedDef::try_from(index, item)?; + validate_unsigned = Some(v); + }, + Some(PalletAttr::TypeValue(_)) => + type_values.push(type_value::TypeValueDef::try_from(index, item)?), + Some(PalletAttr::ExtraConstants(_)) => { + extra_constants = + Some(extra_constants::ExtraConstantsDef::try_from(index, item)?) + }, + Some(attr) => { + let msg = "Invalid duplicated attribute"; + return Err(syn::Error::new(attr.span(), msg)); + }, + None => (), + } + } + + if genesis_config.is_some() != genesis_build.is_some() { + let msg = format!( + "`#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be \ + either both used or both not used, instead genesis_config is {} and genesis_build \ + is {}", + genesis_config.as_ref().map_or("unused", |_| "used"), + genesis_build.as_ref().map_or("unused", |_| "used"), + ); + return Err(syn::Error::new(item_span, msg)); + } + + let def = Def { + item: item, + config: config.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::config]`"))?, + pallet_struct: pallet_struct + .ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::pallet]`"))?, + hooks: hooks + .ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::hooks]`"))?, + call: call.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::call]"))?, + extra_constants, + genesis_config, + genesis_build, + validate_unsigned, + error, + event, + origin, + inherent, + storages, + type_values, + frame_system, + frame_support, + }; + + def.check_instance_usage()?; + def.check_event_usage()?; + + Ok(def) + } + + /// Check that usage of trait `Event` is consistent with the definition, i.e. it is declared + /// and trait defines type Event, or not declared and no trait associated type. + fn check_event_usage(&self) -> syn::Result<()> { + match ( + self.config.has_event_type, + self.event.is_some(), + ) { + (true, false) => { + let msg = "Invalid usage of Event, `Config` contains associated type `Event`, \ + but enum `Event` is not declared (i.e. no use of `#[pallet::event]`). \ + Note that type `Event` in trait is reserved to work alongside pallet event."; + Err(syn::Error::new(proc_macro2::Span::call_site(), msg)) + }, + (false, true) => { + let msg = "Invalid usage of Event, `Config` contains no associated type \ + `Event`, but enum `Event` is declared (in use of `#[pallet::event]`). \ + An Event associated type must be declare on trait `Config`."; + Err(syn::Error::new(proc_macro2::Span::call_site(), msg)) + }, + _ => Ok(()) + } + } + + /// Check that usage of trait `Config` is consistent with the definition, i.e. it is used with + /// instance iff it is defined with instance. + fn check_instance_usage(&self) -> syn::Result<()> { + let mut instances = vec![]; + instances.extend_from_slice(&self.call.instances[..]); + instances.extend_from_slice(&self.pallet_struct.instances[..]); + instances.extend_from_slice(&self.hooks.instances[..]); + instances.extend(&mut self.storages.iter().flat_map(|s| s.instances.clone())); + if let Some(event) = &self.event { + instances.extend_from_slice(&event.instances[..]); + } + if let Some(error) = &self.error { + instances.extend_from_slice(&error.instances[..]); + } + if let Some(inherent) = &self.inherent { + instances.extend_from_slice(&inherent.instances[..]); + } + if let Some(origin) = &self.origin { + instances.extend_from_slice(&origin.instances[..]); + } + if let Some(genesis_config) = &self.genesis_config { + instances.extend_from_slice(&genesis_config.instances[..]); + } + if let Some(genesis_build) = &self.genesis_build { + instances.extend_from_slice(&genesis_build.instances[..]); + } + if let Some(extra_constants) = &self.extra_constants { + instances.extend_from_slice(&extra_constants.instances[..]); + } + + let mut errors = instances.into_iter() + .filter_map(|instances| { + if instances.has_instance == self.config.has_instance { + return None + } + let msg = if self.config.has_instance { + "Invalid generic declaration, trait is defined with instance but generic use none" + } else { + "Invalid generic declaration, trait is defined without instance but generic use \ + some" + }; + Some(syn::Error::new(instances.span, msg)) + }); + + if let Some(mut first_error) = errors.next() { + for error in errors { + first_error.combine(error) + } + Err(first_error) + } else { + Ok(()) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T: Config` + /// * or `T: Config, I: 'static` + pub fn type_impl_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T: Config, I: 'static) + } else { + quote::quote!(T: Config) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T: Config` + /// * or `T: Config, I: 'static = ()` + pub fn type_decl_bounded_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T: Config, I: 'static = ()) + } else { + quote::quote!(T: Config) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T` + /// * or `T, I = ()` + pub fn type_decl_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T, I = ()) + } else { + quote::quote!(T) + } + } + + /// Depending on if pallet is instantiable: + /// * either `` + /// * or `` + /// to be used when using pallet trait `Config` + pub fn trait_use_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!() + } else { + quote::quote!() + } + } + + /// Depending on if pallet is instantiable: + /// * either `T` + /// * or `T, I` + pub fn type_use_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T, I) + } else { + quote::quote!(T) + } + } +} + +/// Some generic kind for type which can be not generic, or generic over config, +/// or generic over config and instance, but not generic only over instance. +pub enum GenericKind { + None, + Config, + ConfigAndInstance, +} + +impl GenericKind { + /// Return Err if it is only generics over instance but not over config. + pub fn from_gens(has_config: bool, has_instance: bool) -> Result { + match (has_config, has_instance) { + (false, false) => Ok(GenericKind::None), + (true, false) => Ok(GenericKind::Config), + (true, true) => Ok(GenericKind::ConfigAndInstance), + (false, true) => Err(()), + } + } + + /// Return the generic to be used when using the type. + /// + /// Depending on its definition it can be: ``, `T` or `T, I` + pub fn type_use_gen(&self) -> proc_macro2::TokenStream { + match self { + GenericKind::None => quote::quote!(), + GenericKind::Config => quote::quote!(T), + GenericKind::ConfigAndInstance => quote::quote!(T, I), + } + } + + /// Return the generic to be used in `impl<..>` when implementing on the type. + pub fn type_impl_gen(&self) -> proc_macro2::TokenStream { + match self { + GenericKind::None => quote::quote!(), + GenericKind::Config => quote::quote!(T: Config), + GenericKind::ConfigAndInstance => quote::quote!(T: Config, I: 'static), + } + } + + /// Return whereas the type has some generic. + pub fn is_generic(&self) -> bool { + match self { + GenericKind::None => false, + GenericKind::Config | GenericKind::ConfigAndInstance => true, + } + } +} + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(origin); + syn::custom_keyword!(call); + syn::custom_keyword!(event); + syn::custom_keyword!(config); + syn::custom_keyword!(hooks); + syn::custom_keyword!(inherent); + syn::custom_keyword!(error); + syn::custom_keyword!(storage); + syn::custom_keyword!(genesis_build); + syn::custom_keyword!(genesis_config); + syn::custom_keyword!(validate_unsigned); + syn::custom_keyword!(type_value); + syn::custom_keyword!(pallet); + syn::custom_keyword!(generate_store); + syn::custom_keyword!(Store); + syn::custom_keyword!(extra_constants); +} + +/// Parse attributes for item in pallet module +/// syntax must be `pallet::` (e.g. `#[pallet::config]`) +enum PalletAttr { + Config(proc_macro2::Span), + Pallet(proc_macro2::Span), + Hooks(proc_macro2::Span), + Call(proc_macro2::Span), + Error(proc_macro2::Span), + Event(proc_macro2::Span), + Origin(proc_macro2::Span), + Inherent(proc_macro2::Span), + Storage(proc_macro2::Span), + GenesisConfig(proc_macro2::Span), + GenesisBuild(proc_macro2::Span), + ValidateUnsigned(proc_macro2::Span), + TypeValue(proc_macro2::Span), + ExtraConstants(proc_macro2::Span), +} + +impl PalletAttr { + fn span(&self) -> proc_macro2::Span { + match self { + Self::Config(span) => span.clone(), + Self::Pallet(span) => span.clone(), + Self::Hooks(span) => span.clone(), + Self::Call(span) => span.clone(), + Self::Error(span) => span.clone(), + Self::Event(span) => span.clone(), + Self::Origin(span) => span.clone(), + Self::Inherent(span) => span.clone(), + Self::Storage(span) => span.clone(), + Self::GenesisConfig(span) => span.clone(), + Self::GenesisBuild(span) => span.clone(), + Self::ValidateUnsigned(span) => span.clone(), + Self::TypeValue(span) => span.clone(), + Self::ExtraConstants(span) => span.clone(), + } + } +} + +impl syn::parse::Parse for PalletAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + let lookahead = content.lookahead1(); + if lookahead.peek(keyword::config) { + Ok(PalletAttr::Config(content.parse::()?.span())) + } else if lookahead.peek(keyword::pallet) { + Ok(PalletAttr::Pallet(content.parse::()?.span())) + } else if lookahead.peek(keyword::hooks) { + Ok(PalletAttr::Hooks(content.parse::()?.span())) + } else if lookahead.peek(keyword::call) { + Ok(PalletAttr::Call(content.parse::()?.span())) + } else if lookahead.peek(keyword::error) { + Ok(PalletAttr::Error(content.parse::()?.span())) + } else if lookahead.peek(keyword::event) { + Ok(PalletAttr::Event(content.parse::()?.span())) + } else if lookahead.peek(keyword::origin) { + Ok(PalletAttr::Origin(content.parse::()?.span())) + } else if lookahead.peek(keyword::inherent) { + Ok(PalletAttr::Inherent(content.parse::()?.span())) + } else if lookahead.peek(keyword::storage) { + Ok(PalletAttr::Storage(content.parse::()?.span())) + } else if lookahead.peek(keyword::genesis_config) { + Ok(PalletAttr::GenesisConfig(content.parse::()?.span())) + } else if lookahead.peek(keyword::genesis_build) { + Ok(PalletAttr::GenesisBuild(content.parse::()?.span())) + } else if lookahead.peek(keyword::validate_unsigned) { + Ok(PalletAttr::ValidateUnsigned(content.parse::()?.span())) + } else if lookahead.peek(keyword::type_value) { + Ok(PalletAttr::TypeValue(content.parse::()?.span())) + } else if lookahead.peek(keyword::extra_constants) { + Ok(PalletAttr::ExtraConstants(content.parse::()?.span())) + } else { + Err(lookahead.error()) + } + } +} diff --git a/frame/support/procedural/src/pallet/parse/origin.rs b/frame/support/procedural/src/pallet/parse/origin.rs new file mode 100644 index 00000000000..00b64c20bc4 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/origin.rs @@ -0,0 +1,80 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// Definition of the pallet origin type. +/// +/// Either: +/// * `type Origin` +/// * `struct Origin` +/// * `enum Origin` +pub struct OriginDef { + /// The index of item in pallet module. + pub index: usize, + pub has_instance: bool, + pub is_generic: bool, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, +} + +impl OriginDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item_span = item.span(); + let (vis, ident, generics) = match &item { + syn::Item::Enum(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), + _ => { + let msg = "Invalid pallet::origin, expected enum or struct or type"; + return Err(syn::Error::new(item.span(), msg)); + }, + }; + + let has_instance = generics.params.len() == 2; + let is_generic = generics.params.len() > 0; + + let mut instances = vec![]; + if let Some(u) = helper::check_type_def_optional_gen(&generics, item.span())? { + instances.push(u); + } else { + // construct_runtime only allow generic event for instantiable pallet. + instances.push(helper::InstanceUsage { + has_instance: false, + span: ident.span(), + }) + } + + if !matches!(vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::origin, Origin must be public"; + return Err(syn::Error::new(item_span, msg)); + } + + if ident != "Origin" { + let msg = "Invalid pallet::origin, ident must `Origin`"; + return Err(syn::Error::new(ident.span(), msg)); + } + + Ok(OriginDef { + index, + has_instance, + is_generic, + instances, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/frame/support/procedural/src/pallet/parse/pallet_struct.rs new file mode 100644 index 00000000000..140355070df --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -0,0 +1,99 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(pallet); + syn::custom_keyword!(Pallet); + syn::custom_keyword!(generate_store); + syn::custom_keyword!(Store); +} + +/// Definition of the pallet pallet. +pub struct PalletStructDef { + /// The index of item in pallet pallet. + pub index: usize, + /// A set of usage of instance, must be check for consistency with config trait. + pub instances: Vec, + /// The keyword Pallet used (contains span). + pub pallet: keyword::Pallet, + /// Whether the trait `Store` must be generated. + pub store: Option<(syn::Visibility, keyword::Store)> +} + +/// Parse for `#[pallet::generate_store($vis trait Store)]` +pub struct PalletStructAttr { + vis: syn::Visibility, + keyword: keyword::Store, +} + +impl syn::parse::Parse for PalletStructAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + content.parse::()?; + + let generate_content; + syn::parenthesized!(generate_content in content); + let vis = generate_content.parse::()?; + generate_content.parse::()?; + let keyword = generate_content.parse::()?; + Ok(Self { vis, keyword }) + } +} + +impl PalletStructDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Struct(item) = item { + item + } else { + let msg = "Invalid pallet::pallet, expected struct definition"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let mut event_attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + if event_attrs.len() > 1 { + let msg = "Invalid pallet::pallet, multiple argument pallet::generate_store found"; + return Err(syn::Error::new(event_attrs[1].keyword.span(), msg)); + } + let store = event_attrs.pop().map(|attr| (attr.vis, attr.keyword)); + + let pallet = syn::parse2::(item.ident.to_token_stream())?; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::pallet, Pallet must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + if item.generics.where_clause.is_some() { + let msg = "Invalid pallet::pallet, where clause not supported on Pallet declaration"; + return Err(syn::Error::new(item.generics.where_clause.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen_no_bounds(&item.generics, item.ident.span())?); + + Ok(Self { index, instances, pallet, store }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs new file mode 100644 index 00000000000..b7ffe3da751 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/storage.rs @@ -0,0 +1,221 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Error); + syn::custom_keyword!(pallet); + syn::custom_keyword!(getter); + syn::custom_keyword!(OptionQuery); + syn::custom_keyword!(ValueQuery); +} + +/// Parse for `#[pallet::getter(fn dummy)]` +pub struct PalletStorageAttr { + getter: syn::Ident, +} + +impl syn::parse::Parse for PalletStorageAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + content.parse::()?; + + let generate_content; + syn::parenthesized!(generate_content in content); + generate_content.parse::()?; + Ok(Self { getter: generate_content.parse::()? }) + } +} + +/// The value and key types used by storages. Needed to expand metadata. +pub enum Metadata{ + Value { value: syn::GenericArgument }, + Map { value: syn::GenericArgument, key: syn::GenericArgument }, + DoubleMap { + value: syn::GenericArgument, + key1: syn::GenericArgument, + key2: syn::GenericArgument + }, +} + +pub enum QueryKind { + OptionQuery, + ValueQuery, +} + +/// Definition of a storage, storage is a storage type like +/// `type MyStorage = StorageValue` +/// The keys and values types are parsed in order to get metadata +pub struct StorageDef { + /// The index of error item in pallet module. + pub index: usize, + /// Visibility of the storage type. + pub vis: syn::Visibility, + /// The type ident, to generate the StoragePrefix for. + pub ident: syn::Ident, + /// The keys and value metadata of the storage. + pub metadata: Metadata, + /// The doc associated to the storage. + pub docs: Vec, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, + /// Optional getter to generate. If some then query_kind is ensured to be some as well. + pub getter: Option, + /// Whereas the querytype of the storage is OptionQuery or ValueQuery. + /// Note that this is best effort as it can't be determined when QueryKind is generic, and + /// result can be false if user do some unexpected type alias. + pub query_kind: Option, + /// Where clause of type definition. + pub where_clause: Option, +} + +/// In `Foo` retrieve the argument at given position, i.e. A is argument at position 0. +fn retrieve_arg( + segment: &syn::PathSegment, + arg_pos: usize, +) -> syn::Result { + if let syn::PathArguments::AngleBracketed(args) = &segment.arguments { + if arg_pos < args.args.len() { + Ok(args.args[arg_pos].clone()) + } else { + let msg = format!("pallet::storage unexpected number of generic argument, expected at \ + least {} args, found {}", arg_pos + 1, args.args.len()); + Err(syn::Error::new(args.span(), msg)) + } + } else { + let msg = format!("pallet::storage unexpected number of generic argument, expected at \ + least {} args, found none", arg_pos + 1); + Err(syn::Error::new(segment.span(), msg)) + } +} + +impl StorageDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Type(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expected item type")); + }; + + let mut attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + if attrs.len() > 1 { + let msg = "Invalid pallet::storage, multiple argument pallet::getter found"; + return Err(syn::Error::new(attrs[1].getter.span(), msg)); + } + let getter = attrs.pop().map(|attr| attr.getter); + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen(&item.generics, item.ident.span())?); + + let where_clause = item.generics.where_clause.clone(); + let docs = helper::get_doc_literals(&item.attrs); + + let typ = if let syn::Type::Path(typ) = &*item.ty { + typ + } else { + let msg = "Invalid pallet::storage, expected type path"; + return Err(syn::Error::new(item.ty.span(), msg)); + }; + + if typ.path.segments.len() != 1 { + let msg = "Invalid pallet::storage, expected type path with one segment"; + return Err(syn::Error::new(item.ty.span(), msg)); + } + + let query_kind; + let metadata = match &*typ.path.segments[0].ident.to_string() { + "StorageValue" => { + query_kind = retrieve_arg(&typ.path.segments[0], 2); + Metadata::Value { + value: retrieve_arg(&typ.path.segments[0], 1)?, + } + } + "StorageMap" => { + query_kind = retrieve_arg(&typ.path.segments[0], 4); + Metadata::Map { + key: retrieve_arg(&typ.path.segments[0], 2)?, + value: retrieve_arg(&typ.path.segments[0], 3)?, + } + } + "StorageDoubleMap" => { + query_kind = retrieve_arg(&typ.path.segments[0], 6); + Metadata::DoubleMap { + key1: retrieve_arg(&typ.path.segments[0], 2)?, + key2: retrieve_arg(&typ.path.segments[0], 4)?, + value: retrieve_arg(&typ.path.segments[0], 5)?, + } + } + found @ _ => { + let msg = format!( + "Invalid pallet::storage, expected ident: `StorageValue` or \ + `StorageMap` or `StorageDoubleMap` in order to expand metadata, found \ + `{}`", + found, + ); + return Err(syn::Error::new(item.ty.span(), msg)); + } + }; + let query_kind = query_kind + .map(|query_kind| match query_kind { + syn::GenericArgument::Type(syn::Type::Path(path)) + if path.path.segments.last().map_or(false, |s| s.ident == "OptionQuery") + => Some(QueryKind::OptionQuery), + syn::GenericArgument::Type(syn::Type::Path(path)) + if path.path.segments.last().map_or(false, |s| s.ident == "ValueQuery") + => Some(QueryKind::ValueQuery), + _ => None, + }) + .unwrap_or(Some(QueryKind::OptionQuery)); // This value must match the default generic. + + if query_kind.is_none() && getter.is_some() { + let msg = "Invalid pallet::storage, cannot generate getter because QueryKind is not \ + identifiable. QueryKind must be `OptionQuery`, `ValueQuery`, or default one to be \ + identifiable."; + return Err(syn::Error::new(getter.unwrap().span(), msg)); + } + + let prefix_arg = retrieve_arg(&typ.path.segments[0], 0)?; + syn::parse2::(prefix_arg.to_token_stream()) + .map_err(|e| { + let msg = "Invalid use of `#[pallet::storage]`, the type first generic argument \ + must be `_`, the final argument is automatically set by macro."; + let mut err = syn::Error::new(prefix_arg.span(), msg); + err.combine(e); + err + })?; + + Ok(StorageDef { + index, + vis: item.vis.clone(), + ident: item.ident.clone(), + instances, + metadata, + docs, + getter, + query_kind, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/type_value.rs b/frame/support/procedural/src/pallet/parse/type_value.rs new file mode 100644 index 00000000000..0313c76c3ec --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/type_value.rs @@ -0,0 +1,101 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 super::helper; +use syn::spanned::Spanned; + +/// Definition of type value. Just a function which is expanded to a struct implementing `Get`. +pub struct TypeValueDef { + /// The index of error item in pallet module. + pub index: usize, + /// Visibility of the struct to generate. + pub vis: syn::Visibility, + /// Ident of the struct to generate. + pub ident: syn::Ident, + /// The type return by Get. + pub type_: Box, + /// The block returning the value to get + pub block: Box, + /// If type value is generic over `T` (or `T` and `I` for instantiable pallet) + pub is_generic: bool, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, + /// The where clause of the function. + pub where_clause: Option, +} + +impl TypeValueDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Fn(item) = item { + item + } else { + let msg = "Invalid pallet::type_value, expected item fn"; + return Err(syn::Error::new(item.span(), msg)); + }; + + + if !item.attrs.is_empty() { + let msg = "Invalid pallet::type_value, unexpected attribute"; + return Err(syn::Error::new(item.attrs[0].span(), msg)); + } + + if let Some(span) = item.sig.constness.as_ref().map(|t| t.span()) + .or(item.sig.asyncness.as_ref().map(|t| t.span())) + .or(item.sig.unsafety.as_ref().map(|t| t.span())) + .or(item.sig.abi.as_ref().map(|t| t.span())) + .or(item.sig.variadic.as_ref().map(|t| t.span())) + { + let msg = "Invalid pallet::type_value, unexpected token"; + return Err(syn::Error::new(span, msg)); + } + + if !item.sig.inputs.is_empty() { + let msg = "Invalid pallet::type_value, unexpected argument"; + return Err(syn::Error::new(item.sig.inputs[0].span(), msg)); + } + + let vis = item.vis.clone(); + let ident = item.sig.ident.clone(); + let block = item.block.clone(); + let type_ = match item.sig.output.clone() { + syn::ReturnType::Type(_, type_) => type_, + syn::ReturnType::Default => { + let msg = "Invalid pallet::type_value, expected return type"; + return Err(syn::Error::new(item.sig.span(), msg)); + }, + }; + + let mut instances = vec![]; + if let Some(usage) = helper::check_type_value_gen(&item.sig.generics, item.sig.span())? { + instances.push(usage); + } + + let is_generic = item.sig.generics.type_params().count() > 0; + let where_clause = item.sig.generics.where_clause.clone(); + + Ok(TypeValueDef { + index, + is_generic, + vis, + ident, + block, + type_, + instances, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs new file mode 100644 index 00000000000..3c460249811 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs @@ -0,0 +1,61 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 syn::spanned::Spanned; +use super::helper; + +/// The definition of the pallet validate unsigned implementation. +pub struct ValidateUnsignedDef { + /// The index of validate unsigned item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, +} + +impl ValidateUnsignedDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::validate_unsigned, expected item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + if item.trait_.is_none() { + let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \ + Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { + if last.ident != "ValidateUnsigned" { + let msg = "Invalid pallet::validate_unsigned, expected trait ValidateUnsigned"; + return Err(syn::Error::new(last.span(), msg)); + } + } else { + let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \ + Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + Ok(ValidateUnsignedDef { index, instances }) + } +} diff --git a/frame/support/procedural/src/pallet_version.rs b/frame/support/procedural/src/pallet_version.rs index ffd4b41208d..f0437d4cb6b 100644 --- a/frame/support/procedural/src/pallet_version.rs +++ b/frame/support/procedural/src/pallet_version.rs @@ -52,7 +52,7 @@ pub fn crate_to_pallet_version(input: proc_macro::TokenStream) -> Result("CARGO_PKG_VERSION_PATCH") .map_err(|_| create_error("Patch version needs to fit into `u8`"))?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; Ok(quote::quote! { #crate_::traits::PalletVersion { diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index 27fbdd2cd38..ebc4c7a7f79 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -21,8 +21,8 @@ use proc_macro2::{TokenStream, Span}; use quote::quote; use super::DeclStorageDefExt; -use genesis_config_def::GenesisConfigDef; -use builder_def::BuilderDef; +pub use genesis_config_def::GenesisConfigDef; +pub use builder_def::BuilderDef; mod genesis_config_def; mod builder_def; diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index bc23dad74bc..265c4b4cd10 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -24,6 +24,9 @@ mod getters; mod metadata; mod instance_trait; mod genesis_config; +mod print_pallet_upgrade; + +pub(crate) use instance_trait::INHERENT_INSTANCE_NAME; use quote::quote; use frame_support_procedural_tools::{ @@ -397,6 +400,8 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr let def = syn::parse_macro_input!(input as DeclStorageDef); let def_ext = DeclStorageDefExt::from(def); + print_pallet_upgrade::maybe_print_pallet_upgrade(&def_ext); + let hidden_crate_name = def_ext.hidden_crate.as_ref().map(|i| i.to_string()) .unwrap_or_else(|| "decl_storage".to_string()); diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs new file mode 100644 index 00000000000..66da5fd01b5 --- /dev/null +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -0,0 +1,387 @@ +use super::StorageLineTypeDef; +use quote::ToTokens; +use frame_support_procedural_tools::clean_type_string; + +/// Environment variable that tells us to print pallet upgrade helper. +const PRINT_PALLET_UPGRADE: &str = "PRINT_PALLET_UPGRADE"; + +fn check_print_pallet_upgrade() -> bool { + std::env::var(PRINT_PALLET_UPGRADE).is_ok() +} + +/// Convert visibilty as now objects are defined in a module. +fn convert_vis(vis: &syn::Visibility) -> &'static str{ + match vis { + syn::Visibility::Inherited => "pub(super)", + syn::Visibility::Public(_) => "pub", + _ => "/* TODO_VISIBILITY */", + } +} + +/// fn to convert to token stream then string using display and then call clean_type_string on it. +fn to_cleaned_string(t: impl quote::ToTokens) -> String { + clean_type_string(&format!("{}", t.into_token_stream())) +} + +/// Print an incomplete upgrade from decl_storage macro to new pallet attribute. +pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) { + if !check_print_pallet_upgrade() { + return + } + + let scrate = "e::quote!(frame_support); + + let config_gen = if def.optional_instance.is_some() { + "" + } else { + Default::default() + }; + + let impl_gen = if def.optional_instance.is_some() { + ", I: 'static>" + } else { + "" + }; + + let decl_gen = if def.optional_instance.is_some() { + "" + } else { + "" + }; + + let full_decl_gen = if def.optional_instance.is_some() { + ", I: 'static = ()>" + } else { + "" + }; + + let use_gen = if def.optional_instance.is_some() { + "" + } else { + "" + }; + + let use_gen_tuple = if def.optional_instance.is_some() { + "<(T, I)>" + } else { + "" + }; + + let mut genesis_config = String::new(); + let mut genesis_build = String::new(); + + let genesis_config_builder_def = super::genesis_config::BuilderDef::from_def(scrate, def); + if !genesis_config_builder_def.blocks.is_empty() { + let genesis_config_def = match super::genesis_config::GenesisConfigDef::from_def(def) { + Ok(g) => g, + Err(err) => { + println!("Could not print upgrade due compile error: {:?}", err); + return + }, + }; + + let genesis_config_impl_gen = if genesis_config_def.is_generic { + impl_gen.clone() + } else { + Default::default() + }; + + let genesis_config_use_gen = if genesis_config_def.is_generic { + use_gen.clone() + } else { + Default::default() + }; + + let genesis_config_decl_gen = if genesis_config_def.is_generic { + if def.optional_instance.is_some() { + ", I: 'static = ()>" + } else { + "" + } + } else { + Default::default() + }; + + let mut genesis_config_decl_fields = String::new(); + let mut genesis_config_default_fields = String::new(); + for field in &genesis_config_def.fields { + genesis_config_decl_fields.push_str(&format!(" + {attrs}pub {name}: {typ},", + attrs = field.attrs.iter() + .fold(String::new(), |res, attr| { + format!("{}#[{}] + ", + res, attr.to_token_stream()) + }), + name = field.name, + typ = to_cleaned_string(&field.typ), + )); + + genesis_config_default_fields.push_str(&format!(" + {name}: {default},", + name = field.name, + default = to_cleaned_string(&field.default), + )); + } + + genesis_config = format!(" + #[pallet::genesis_config] + pub struct GenesisConfig{genesis_config_decl_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{{genesis_config_decl_fields} + }} + + #[cfg(feature = \"std\")] + impl{genesis_config_impl_gen} Default for GenesisConfig{genesis_config_use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + fn default() -> Self {{ + Self {{{genesis_config_default_fields} + }} + }} + }}", + genesis_config_decl_gen = genesis_config_decl_gen, + genesis_config_decl_fields = genesis_config_decl_fields, + genesis_config_impl_gen = genesis_config_impl_gen, + genesis_config_default_fields = genesis_config_default_fields, + genesis_config_use_gen = genesis_config_use_gen, + ); + + let genesis_config_build = genesis_config_builder_def.blocks.iter() + .fold(String::new(), |res, block| { + format!("{} + {}", + res, + to_cleaned_string(block), + ) + }); + + genesis_build = format!(" + #[pallet::genesis_build] + impl{impl_gen} GenesisBuild{use_gen} for GenesisConfig{genesis_config_use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + fn build(&self) {{{genesis_config_build} + }} + }}", + impl_gen = impl_gen, + use_gen = use_gen, + genesis_config_use_gen = genesis_config_use_gen, + genesis_config_build = genesis_config_build, + ); + } + + let mut storages = String::new(); + for line in &def.storage_lines { + let storage_vis = convert_vis(&line.visibility); + + let getter = if let Some(getter) = &line.getter { + format!(" + #[pallet::getter(fn {getter})]", + getter = getter + ) + } else { + Default::default() + }; + + let value_type = &line.value_type; + + let default_value_type_value = line.default_value.as_ref() + .map(|default_expr| { + format!(" + #[pallet::type_value] + {storage_vis} fn DefaultFor{name} /* TODO_MAYBE_GENERICS */ () -> {value_type} {{ + {default_expr} + }} +", + name = line.name, + storage_vis = storage_vis, + value_type = to_cleaned_string(&line.value_type), + default_expr = to_cleaned_string(&default_expr), + ) + }) + .unwrap_or_else(|| String::new()); + + let comma_query_kind = if line.is_option { + if line.default_value.is_some() { + ", OptionQuery" + } else { + Default::default() + } + } else { + ", ValueQuery" + }; + + let comma_default_value_getter_name = line.default_value.as_ref() + .map(|_| format!(", DefaultFor{}", line.name)) + .unwrap_or_else(|| String::new()); + + let typ = match &line.storage_type { + StorageLineTypeDef::Map(map) => { + format!("StorageMap<_, {hasher}, {key}, {value_type}{comma_query_kind}\ + {comma_default_value_getter_name}>", + hasher = &map.hasher.to_storage_hasher_struct(), + key = to_cleaned_string(&map.key), + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + StorageLineTypeDef::DoubleMap(double_map) => { + format!("StorageDoubleMap<_, {hasher1}, {key1}, {hasher2}, {key2}, {value_type}\ + {comma_query_kind}{comma_default_value_getter_name}>", + hasher1 = double_map.hasher1.to_storage_hasher_struct(), + key1 = to_cleaned_string(&double_map.key1), + hasher2 = double_map.hasher2.to_storage_hasher_struct(), + key2 = to_cleaned_string(&double_map.key2), + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + StorageLineTypeDef::Simple(_) => { + format!("StorageValue<_, {value_type}{comma_query_kind}\ + {comma_default_value_getter_name}>", + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + }; + + let additional_comment = if line.is_option && line.default_value.is_some() { + " // TODO: This type of storage is no longer supported: `OptionQuery` cannot be used \ + alongside a not-none value on empty storage. Please use `ValueQuery` instead." + } else { + "" + }; + + storages.push_str(&format!(" +{default_value_type_value}{doc} + #[pallet::storage]{getter} + {storage_vis} type {name}{full_decl_gen} = {typ};{additional_comment}", + default_value_type_value = default_value_type_value, + getter = getter, + storage_vis = storage_vis, + name = line.name, + full_decl_gen = full_decl_gen, + typ = typ, + additional_comment = additional_comment, + doc = line.doc_attrs.iter() + .fold(String::new(), |mut res, attr| { + if let syn::Meta::NameValue(name_value) = attr { + if name_value.path.is_ident("doc") { + if let syn::Lit::Str(string) = &name_value.lit { + res = format!("{} + ///{}", + res, + string.value(), + ); + } + } + } + res + }), + )); + } + + let deprecated_instance_stuff = if def.optional_instance.is_some() { + " + /// Old name for default instance generated by decl_storage. + #[deprecated(note=\"use `()` instead\")] + pub type DefaultInstance = (); + + /// Old name for instance trait used by old macros. + #[deprecated(note=\"use `'static` instead\")] + pub trait Instance: 'static {} + impl Instance for I {}" + } else { + "" + }; + + println!(" +// Template for pallet upgrade for {pallet_name} + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet {{ + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + #[pallet::config] + pub trait Config{config_gen}: frame_system::Config + // TODO_MAYBE_ADDITIONAL_BOUNDS_AND_WHERE_CLAUSE + {{ + // TODO_ASSOCIATED_TYPE_AND_CONSTANTS + }} + + {deprecated_instance_stuff} + + #[pallet::pallet] + #[pallet::generate_store({store_vis} trait Store)] + pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); + + /// Old name for pallet. + #[deprecated(note=\"use `Pallet` instead\")] + pub type Module{decl_gen} = Pallet{use_gen}; + + #[pallet::interface] + impl{impl_gen} Hooks> for Pallet{use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + // TODO_ON_FINALIZE + // TODO_ON_INITIALIZE + // TODO_ON_RUNTIME_UPGRADE + // TODO_INTEGRITY_TEST + // TODO_OFFCHAIN_WORKER + }} + + #[pallet::call] + impl{impl_gen} Pallet{use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + // TODO_UPGRADE_DISPATCHABLES + }} + + #[pallet::inherent] + // TODO_INHERENT + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + // TODO_EVENT + + // TODO_REMOVE_IF_NO_EVENT + /// Old name generated by `decl_event`. + #[deprecated(note=\"use `Event` instead\")] + pub type RawEvent /* TODO_PUT_EVENT_GENERICS */ = Event /* TODO_PUT_EVENT_GENERICS */; + + #[pallet::error] + // TODO_ERROR + + #[pallet::origin] + // TODO_ORIGIN + + #[pallet::validate_unsigned] + // TODO_VALIDATE_UNSIGNED + + {storages} + + {genesis_config} + + {genesis_build} +}}", + config_gen = config_gen, + store_vis = convert_vis(&def.visibility), + impl_gen = impl_gen, + use_gen = use_gen, + use_gen_tuple = use_gen_tuple, + decl_gen = decl_gen, + storages = storages, + genesis_config = genesis_config, + genesis_build = genesis_build, + pallet_name = def.crate_name, + deprecated_instance_stuff = deprecated_instance_stuff, + ); +} diff --git a/frame/support/procedural/src/transactional.rs b/frame/support/procedural/src/transactional.rs index 3c2617a17e5..8c49a8deec1 100644 --- a/frame/support/procedural/src/transactional.rs +++ b/frame/support/procedural/src/transactional.rs @@ -23,7 +23,7 @@ use frame_support_procedural_tools::generate_crate_access_2018; pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result { let ItemFn { attrs, vis, sig, block } = syn::parse(input)?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; let output = quote! { #(#attrs)* #vis #sig { @@ -45,7 +45,7 @@ pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result Result { let ItemFn { attrs, vis, sig, block } = syn::parse(input)?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; let output = quote! { #(#attrs)* #vis #sig { diff --git a/frame/support/procedural/tools/src/lib.rs b/frame/support/procedural/tools/src/lib.rs index c5a27c809af..2cf559eab9b 100644 --- a/frame/support/procedural/tools/src/lib.rs +++ b/frame/support/procedural/tools/src/lib.rs @@ -46,17 +46,17 @@ pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream { } } -/// Generate the crate access for the `frame-support` crate using 2018 syntax. +/// Generate the crate access for the crate using 2018 syntax. /// -/// Output will for example be `frame_support`. -pub fn generate_crate_access_2018() -> Result { - if std::env::var("CARGO_PKG_NAME").unwrap() == "frame-support" { - Ok(quote::quote!( frame_support )) +/// for `frame-support` output will for example be `frame_support`. +pub fn generate_crate_access_2018(def_crate: &str) -> Result { + if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { + let name = def_crate.to_string().replace("-", "_"); + Ok(syn::Ident::new(&name, Span::call_site())) } else { - match crate_name("frame-support") { + match crate_name(def_crate) { Ok(name) => { - let name = Ident::new(&name, Span::call_site()); - Ok(quote!( #name )) + Ok(Ident::new(&name, Span::call_site())) }, Err(e) => { Err(Error::new(Span::call_site(), &e)) diff --git a/frame/support/src/instances.rs b/frame/support/src/instances.rs new file mode 100644 index 00000000000..ee38a6a403e --- /dev/null +++ b/frame/support/src/instances.rs @@ -0,0 +1,96 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! Some instance placeholder to be used in [`frame_support::pallet`] attribute macro. +//! +//! [`frame_support::pallet`] attribute macro does only requires the instance generic `I` to be +//! static (contrary to `decl_*` macro which requires instance generic to implement +//! [`frame_support::traits::Instance`]). +//! +//! Thus support provides some instance types to be used, This allow some instantiable pallet to +//! depend on specific instance of another: +//! ``` +//! # mod another_pallet { pub trait Config {} } +//! pub trait Config: another_pallet::Config {} +//! ``` +//! +//! NOTE: [`frame_support::pallet`] will reexport them inside the module, in order to make them +//! accessible to [`frame_support::construct_runtime`]. + +/// Instance0 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance0; + +/// Instance1 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance1; + +/// Instance2 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance2; + +/// Instance3 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance3; + +/// Instance4 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance4; + +/// Instance5 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance5; + +/// Instance6 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance6; + +/// Instance7 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance7; + +/// Instance8 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance8; + +/// Instance9 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance9; + +/// Instance10 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance10; + +/// Instance11 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance11; + +/// Instance12 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance12; + +/// Instance13 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance13; + +/// Instance14 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance14; + +/// Instance15 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance15; diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 55bca2610a1..c8279dff9ee 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -67,6 +67,7 @@ pub mod unsigned; pub mod error; pub mod traits; pub mod weights; +pub mod instances; pub use self::hash::{ Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, Hashable, @@ -80,7 +81,7 @@ pub use self::dispatch::{Parameter, Callable}; pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; /// A type that cannot be instantiated. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum Never {} /// Create new implementations of the [`Get`](crate::traits::Get) trait. @@ -1012,3 +1013,1005 @@ mod tests { }) } } + +/// Prelude to be used alongside pallet macro, for ease of use. +pub mod pallet_prelude { + pub use sp_std::marker::PhantomData; + #[cfg(feature = "std")] + pub use frame_support::traits::GenesisBuild; + pub use frame_support::{ + EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, DebugNoBound, CloneNoBound, Twox256, + Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, debug, ensure, + RuntimeDebug, storage, + traits::{Get, Hooks, IsType, GetPalletVersion, EnsureOrigin}, + dispatch::{DispatchResultWithPostInfo, Parameter, DispatchError}, + weights::{DispatchClass, Pays, Weight}, + storage::types::{StorageValue, StorageMap, StorageDoubleMap, ValueQuery, OptionQuery}, + }; + pub use codec::{Encode, Decode}; + pub use sp_inherents::{InherentData, InherentIdentifier, ProvideInherent}; + pub use sp_runtime::{ + traits::{MaybeSerializeDeserialize, Member, ValidateUnsigned}, + transaction_validity::{ + TransactionSource, TransactionValidity, ValidTransaction, TransactionPriority, + TransactionTag, TransactionLongevity, TransactionValidityError, InvalidTransaction, + UnknownTransaction, + }, + }; +} + +/// `pallet` attribute macro allows to define a pallet to be used in `construct_runtime!`. +/// +/// It is define by a module item: +/// ```ignore +/// #[pallet] +/// pub mod pallet { +/// ... +/// } +/// ``` +/// +/// Inside the module the macro will parse item with the attribute: `#[pallet::*]`, some attributes +/// are mandatory, some other optional. +/// +/// The attribute are explained with the syntax of non instantiable pallets, to see how pallet with +/// instance work see below example. +/// +/// Note various type can be automatically imported using pallet_prelude in frame_support and +/// frame_system: +/// ```ignore +/// #[pallet] +/// pub mod pallet { +/// use frame_support::pallet_prelude::*; +/// use frame_system::pallet_prelude::*; +/// ... +/// } +/// ``` +/// +/// # Config trait: `#[pallet::config]` mandatory +/// +/// The trait defining generics of the pallet. +/// +/// Item must be defined as +/// ```ignore +/// #[pallet::config] +/// pub trait Config: frame_system::Config + $optionally_some_other_supertraits +/// $optional_where_clause +/// { +/// ... +/// } +/// ``` +/// I.e. a regular trait definition named `Config`, with supertrait `frame_system::Config`, +/// optionally other supertrait and where clause. +/// +/// The associated type `Event` is reserved, if defined it must bounds `From` and +/// `IsType<::Event>`, see `#[pallet::event]` for more information. +/// +/// To put `Get` associated type into metadatas, use the attribute `#[pallet::constant]`, e.g.: +/// ```ignore +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] +/// type Foo: Get; +/// } +/// ``` +/// +/// To bypass the `frame_system::Config` supertrait check, use the attribute +/// `#[pallet::disable_frame_system_supertrait_check]`, e.g.: +/// ```ignore +/// #[pallet::config] +/// #[pallet::disable_frame_system_supertrait_check] +/// pub trait Config: pallet_timestamp::Config {} +/// ``` +/// +/// ### Macro expansion: +/// +/// The macro expand pallet constant metadata with the information given by `#[pallet::constant]`. +/// +/// # Pallet struct placeholder: `#[pallet::pallet]` mandatory +/// +/// The placeholder struct, on which is implemented pallet informations. +/// +/// Item must be defined as followed: +/// ```ignore +/// #[pallet::pallet] +/// pub struct Pallet(PhantomData); +/// ``` +/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause. +/// +/// To generate a `Store` trait associating all storages, use the attribute +/// `#[pallet::generate_store($vis trait Store)]`, e.g.: +/// ```ignore +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData); +/// ``` +/// More precisely the store trait contains an associated type for each storage. It is implemented +/// for `Pallet` allowing to access the storage from pallet struct. +/// +/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using +/// `::Foo`. +/// +/// ### Macro expansion: +/// +/// The macro add this attribute to the struct definition: +/// ```ignore +/// #[derive( +/// frame_support::CloneNoBound, +/// frame_support::EqNoBound, +/// frame_support::PartialEqNoBound, +/// frame_support::RuntimeDebugNoBound, +/// )] +/// ``` +/// +/// It implements on pallet: +/// * [`traits::GetPalletVersion`] +/// * [`traits::OnGenesis`]: contains some logic to write pallet version into storage. +/// * `ModuleErrorMetadata`: using error declared or no metadata. +/// +/// It declare `type Module` type alias for `Pallet`, used by [`construct_runtime`]. +/// +/// If attribute generate_store then macro create the trait `Store` and implement it on `Pallet`. +/// +/// # Hooks: `#[pallet::hooks]` mandatory +/// +/// Implementation of `Hooks` on `Pallet` allowing to define some specific pallet logic. +/// +/// Item must be defined as +/// ```ignore +/// #[pallet::hooks] +/// impl Hooks> for Pallet $optional_where_clause { +/// } +/// ``` +/// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait +/// `Hooks>` (they are defined in preludes), for the type `Pallet` +/// and with an optional where clause. +/// +/// ### Macro expansion: +/// +/// The macro implements the traits `OnInitialize`, `OnFinalize`, `OnRuntimeUpgrade`, +/// `OffchainWorker`, `IntegrityTest` using `Hooks` implementation. +/// +/// NOTE: OnRuntimeUpgrade is implemented with `Hooks::on_runtime_upgrade` and some additional +/// logic. E.g. logic to write pallet version into storage. +/// +/// # Call: `#[pallet::call]` mandatory +/// +/// Implementation of pallet dispatchables. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::call] +/// impl Pallet { +/// /// $some_doc +/// #[pallet::weight($ExpressionResultingInWeight)] +/// $vis fn $fn_name( +/// origin: OriginFor, +/// $some_arg: $some_type, +/// // or with compact attribute: #[pallet::compact] $some_arg: $some_type, +/// ... +/// ) -> DispatchResultWithPostInfo { +/// ... +/// } +/// ... +/// } +/// ``` +/// I.e. a regular type implementation, with generic `T: Config`, on type `Pallet`, with +/// optional where clause. +/// +/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute, +/// the first argument must be `origin: OriginFor`, compact encoding for argument can be used +/// using `#[pallet::compact]`, function must return DispatchResultWithPostInfo. +/// +/// All arguments must implement `Debug`, `PartialEq`, `Eq`, `Decode`, `Encode`, `Clone`. For ease +/// of use just bound trait `Member` available in frame_support::pallet_prelude. +/// +/// **WARNING**: modifying dispatchables, changing their order, removing some must be done with +/// care. Indeed this will change the outer runtime call type (which is an enum with one variant +/// per pallet), this outer runtime call can be stored on-chain (e.g. in pallet-scheduler). +/// Thus migration might be needed. +/// +/// ### Macro expansion +/// +/// The macro create an enum `Call` with one variant per dispatchable. This enum implements: +/// `Clone`, `Eq`, `PartialEq`, `Debug` (with stripped implementation in `not("std")`), `Encode`, +/// `Decode`, `GetDispatchInfo`, `GetCallName`, `UnfilteredDispatchable`. +/// +/// The macro implement on `Pallet`, the `Callable` trait and a function `call_functions` which +/// returns the dispatchable metadatas. +/// +/// # Extra constants: `#[pallet::extra_constants]` optional +/// +/// Allow to define some extra constants to put into constant metadata. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::extra_constants] +/// impl Pallet where $optional_where_clause { +/// /// $some_doc +/// $vis fn $fn_name() -> $some_return_type { +/// ... +/// } +/// ... +/// } +/// ``` +/// I.e. a regular rust implement block with some optional where clause and functions with 0 args, +/// 0 generics, and some return type. +/// +/// ### Macro expansion +/// +/// The macro add some extra constant to pallet constant metadata. +/// +/// # Error: `#[pallet::error]` optional +/// +/// Allow to define an error type to be return from dispatchable on error. +/// This error type informations are put into metadata. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::error] +/// pub enum Error { +/// /// $some_optional_doc +/// $SomeFieldLessVariant, +/// ... +/// } +/// ``` +/// I.e. a regular rust enum named `Error`, with generic `T` and fieldless variants. +/// +/// ### Macro expansion +/// +/// The macro implements `Debug` trait and functions `as_u8` using variant position, and `as_str` +/// using variant doc. +/// +/// The macro implements `From>` for `&'static str`. +/// The macro implements `From>` for `DispatchError`. +/// +/// The macro implements `ModuleErrorMetadata` on `Pallet` defining the `ErrorMetadata` of the +/// pallet. +/// +/// # Event: `#[pallet::event]` optional +/// +/// Allow to define pallet events, pallet events are stored in the block when they deposited (and +/// removed in next block). +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::event] +/// #[pallet::metadata($SomeType = "$Metadata", $SomeOtherType = "$Metadata", ..)] // Optional +/// #[pallet::generate_deposit($visbility fn deposit_event)] // Optional +/// pub enum Event<$some_generic> $optional_where_clause { +/// /// Some doc +/// $SomeName($SomeType, $YetanotherType, ...), +/// ... +/// } +/// ``` +/// I.e. an enum (with named or unnamed fields variant), named Event, with generic: none or `T` or +/// `T: Config`, and optional where clause. +/// +/// Each field must implement `Clone`, `Eq`, `PartialEq`, `Encode`, `Decode`, and `Debug` (on std +/// only). +/// For ease of use just bound trait `Member` available in frame_support::pallet_prelude. +/// +/// Variant documentations and field types are put into metadata. +/// The attribute `#[pallet::metadata(..)]` allows to specify the metadata to put for some types. +/// +/// The metadata of a type is defined by: +/// * if matching a type in `#[pallet::metadata(..)]`, then the corresponding metadata. +/// * otherwise the type stringified. +/// +/// E.g.: +/// ```ignore +/// #[pallet::event] +/// #[pallet::metadata(u32 = "SpecialU32")] +/// pub enum Event { +/// Proposed(u32, T::AccountId), +/// } +/// ``` +/// will write in event variant metadata `"SpecialU32"` and `"T::AccountId"`. +/// +/// The attribute `#[pallet::generate_deposit($visbility fn deposit_event)]` generate a helper +/// function on `Pallet` to deposit event. +/// +/// NOTE: For instantiable pallet, event must be generic over T and I. +/// +/// ### Macro expansion: +/// +/// Macro will add on enum `Event` the attributes: +/// * `#[derive(frame_support::CloneNoBound)]`, +/// * `#[derive(frame_support::EqNoBound)]`, +/// * `#[derive(frame_support::PartialEqNoBound)]`, +/// * `#[derive(codec::Encode)]`, +/// * `#[derive(codec::Decode)]`, +/// * `#[derive(frame_support::RuntimeDebugNoBound)]` +/// +/// Macro implements `From>` for (). +/// +/// Macro implements metadata function on `Event` returning the `EventMetadata`. +/// +/// If `#[pallet::generate_deposit]` then macro implement `fn deposit_event` on `Pallet`. +/// +/// # Storage: `#[pallet::storage]` optional +/// +/// Allow to define some abstract storage inside runtime storage and also set its metadata. +/// This attribute can be used multiple times. +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::storage] +/// #[pallet::getter(fn $getter_name)] // optional +/// $vis type $StorageName<$some_generic> $optional_where_clause +/// = $StorageType<_, $some_generics, ...>; +/// ``` +/// I.e. it must be a type alias, with generics: `T` or `T: Config`, aliased type must be one +/// of `StorageValue`, `StorageMap` or `StorageDoubleMap` (defined in frame_support). +/// Their first generic must be `_` as it is written by the macro itself. +/// +/// The Prefix generic written by the macro is generated using `PalletInfo::name::>()` +/// and the name of the storage type. +/// E.g. if runtime names the pallet "MyExample" then the storage `type Foo = ...` use the +/// prefix: `Twox128(b"MyExample") ++ Twox128(b"Foo")`. +/// +/// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allow to define a +/// getter function on `Pallet`. +/// +/// E.g: +/// ```ignore +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; +/// ``` +/// +/// NOTE: if the querykind generic parameter is still generic at this stage or is using some type +/// alias then the generation of the getter might fail. In this case getter can be implemented +/// manually. +/// +/// ### Macro expansion +/// +/// For each storage the macro generate a struct named +/// `_GeneratedPrefixForStorage$NameOfStorage`, implements `StorageInstance` on it using pallet +/// name and storage name. And use it as first generic of the aliased type. +/// +/// +/// The macro implement the function `storage_metadata` on `Pallet` implementing the metadata for +/// storages. +/// +/// # Type value: `#[pallet::type_value]` optional +/// +/// Helper to define a struct implementing `Get` trait. To ease use of storage types. +/// This attribute can be used multiple time. +/// +/// Item is defined as +/// ```ignore +/// #[pallet::type_value] +/// fn $MyDefaultName<$some_generic>() -> $default_type $optional_where_clause { $expr } +/// ``` +/// I.e.: a function definition with generics none or `T: Config` and a returned type. +/// +/// E.g.: +/// ```ignore +/// #[pallet::type_value] +/// fn MyDefault() -> T::Balance { 3.into() } +/// ``` +/// +/// NOTE: This attribute is meant to be used alongside `#[pallet::storage]` to defined some +/// specific default value in storage. +/// +/// ### Macro expansion +/// +/// Macro generate struct with the name of the function and its generic, and implement +/// `Get<$ReturnType>` on it using the provided function block. +/// +/// # Genesis config: `#[pallet::genesis_config]` optional +/// +/// Allow to define the genesis configuration of the pallet. +/// +/// Item is defined as either an enum or a struct. +/// It needs to be public and implement trait GenesisBuild with `#[pallet::genesis_build]`. +/// The type generics is constrained to be either none, or `T` or `T: Config`. +/// +/// E.g: +/// ```ignore +/// #[pallet::genesis_config] +/// pub struct GenesisConfig { +/// _myfield: BalanceOf, +/// } +/// ``` +/// +/// ### Macro expansion +/// +/// Macro will add the following attribute on it: +/// * `#[cfg(feature = "std")]` +/// * `#[derive(Serialize, Deserialize)]` +/// * `#[serde(rename_all = "camelCase")]` +/// * `#[serde(deny_unknown_fields)]` +/// * `#[serde(bound(serialize = ""))]` +/// * `#[serde(bound(deserialize = ""))]` +/// +/// # Genesis build: `#[pallet::genesis_build]` optional +/// +/// Allow to define how genesis_configuration is built. +/// +/// Item is defined as +/// ```ignore +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig<$maybe_generics> { +/// fn build(&self) { $expr } +/// } +/// ``` +/// I.e. a rust trait implementation with generic `T: Config`, of trait `GenesisBuild` on type +/// `GenesisConfig` with generics none or `T`. +/// +/// E.g.: +/// ```ignore +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// ``` +/// +/// ### Macro expansion +/// +/// Macro will add the following attribute on it: +/// * `#[cfg(feature = "std")]` +/// +/// Macro will implement `sp_runtime::BuildModuleGenesisStorage` using `()` as second generic for +/// non-instantiable pallets. +/// +/// # Inherent: `#[pallet::inherent]` optional +/// +/// Allow the pallet to provide some inherent: +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::inherent] +/// impl ProvideInherent for Pallet { +/// // ... regular trait implementation +/// } +/// ``` +/// I.e. a trait implementation with bound `T: Config`, of trait `ProvideInherent` for type +/// `Pallet`, and some optional where clause. +/// +/// ### Macro expansion +/// +/// Macro make currently no use of this information, but it might use this information in the +/// future to give information directly to construct_runtime. +/// +/// # Validate unsigned: `#[pallet::validate_unsigned]` optional +/// +/// Allow the pallet to validate some unsigned transaction: +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::validate_unsigned] +/// impl ValidateUnsigned for Pallet { +/// // ... regular trait implementation +/// } +/// ``` +/// I.e. a trait implementation with bound `T: Config`, of trait `ValidateUnsigned` for type +/// `Pallet`, and some optional where clause. +/// +/// NOTE: There is also `sp_runtime::traits::SignedExtension` that can be used to add some specific +/// logic for transaction validation. +/// +/// ### Macro expansion +/// +/// Macro make currently no use of this information, but it might use this information in the +/// future to give information directly to construct_runtime. +/// +/// # Origin: `#[pallet::origin]` optional +/// +/// Allow to define some origin for the pallet. +/// +/// Item must be either a type alias or an enum or a struct. It needs to be public. +/// +/// E.g.: +/// ```ignore +/// #[pallet::origin] +/// pub struct Origin(PhantomData<(T)>); +/// ``` +/// +/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin can +/// be stored on-chain (e.g. in pallet-scheduler), thus any change must be done with care as it +/// might require some migration. +/// +/// NOTE: for instantiable pallet, origin must be generic over T and I. +/// +/// # General notes on instantiable pallet +/// +/// An instantiable pallet is one where Config is generic, i.e. `Config`. This allow runtime to +/// implement multiple instance of the pallet, by using different type for the generic. +/// This is the sole purpose of the generic `I`. +/// But because `PalletInfo` requires `Pallet` placeholder to be static it is important to bound +/// `'static` whenever `PalletInfo` can be used. +/// And in order to have instantiable pallet usable as a regular pallet without instance, it is +/// important to bound `= ()` on every types. +/// +/// Thus impl bound look like `impl, I: 'static>`, and types look like +/// `SomeType` or `SomeType, I: 'static = ()>`. +/// +/// # Example for pallet without instance. +/// +/// ``` +/// #[frame_support::pallet] +/// // NOTE: Example is name of the pallet, it will be used as unique identifier for storage +/// pub mod pallet { +/// use frame_support::pallet_prelude::*; // Import various types used in pallet definition +/// use frame_system::pallet_prelude::*; // OriginFor helper type for implementing dispatchables. +/// +/// type BalanceOf = ::Balance; +/// +/// // Define the generic parameter of the pallet +/// // The macro checks trait generics: is expected none or `I = ()`. +/// // The macro parses `#[pallet::constant]` attributes: used to generate constant metadata, +/// // expected syntax is `type $IDENT: Get<$TYPE>;`. +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] // put the constant in metadata +/// type MyGetParam: Get; +/// type Balance: Parameter + From; +/// type Event: From> + IsType<::Event>; +/// } +/// +/// // Define some additional constant to put into the constant metadata. +/// #[pallet::extra_constants] +/// impl Pallet { +/// /// Some description +/// fn exra_constant_name() -> u128 { 4u128 } +/// } +/// +/// // Define the pallet struct placeholder, various pallet function are implemented on it. +/// // The macro checks struct generics: is expected `T` or `T, I = DefaultInstance` +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData); +/// +/// // Implement on the pallet hooks on pallet. +/// // The macro checks: +/// // * trait is `Hooks` (imported from pallet_prelude) +/// // * struct is `Pallet` or `Pallet` +/// #[pallet::hooks] +/// impl Hooks> for Pallet { +/// } +/// +/// // Declare Call struct and implement dispatchables. +/// // +/// // WARNING: Each parameter used in functions must implement: Clone, Debug, Eq, PartialEq, +/// // Codec. +/// // +/// // The macro checks: +/// // * pallet is `Pallet` or `Pallet` +/// // * trait is `Call` +/// // * each dispatchable functions first argument is `origin: OriginFor` (OriginFor is +/// // imported from frame_system. +/// // +/// // The macro parse `#[pallet::compact]` attributes, function parameter with this attribute +/// // will be encoded/decoded using compact codec in implementation of codec for the enum +/// // `Call`. +/// // +/// // The macro generate the enum `Call` with a variant for each dispatchable and implements +/// // codec, Eq, PartialEq, Clone and Debug. +/// #[pallet::call] +/// impl Pallet { +/// /// Doc comment put in metadata +/// #[pallet::weight(0)] // Defines weight for call (function parameters are in scope) +/// fn toto( +/// origin: OriginFor, +/// #[pallet::compact] _foo: u32 +/// ) -> DispatchResultWithPostInfo { +/// let _ = origin; +/// unimplemented!(); +/// } +/// } +/// +/// // Declare pallet Error enum. (this is optional) +/// // The macro checks enum generics and that each variant is unit. +/// // The macro generate error metadata using doc comment on each variant. +/// #[pallet::error] +/// pub enum Error { +/// /// doc comment put into metadata +/// InsufficientProposersBalance, +/// } +/// +/// // Declare pallet Event enum. (this is optional) +/// // +/// // WARNING: Each type used in variants must implement: Clone, Debug, Eq, PartialEq, Codec. +/// // +/// // The macro generates event metadata, and derive Clone, Debug, Eq, PartialEq and Codec +/// #[pallet::event] +/// // Additional argument to specify the metadata to use for given type. +/// #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] +/// // Generate a funciton on Pallet to deposit an event. +/// #[pallet::generate_deposit(pub(super) fn deposit_event)] +/// pub enum Event { +/// /// doc comment put in metadata +/// // `::AccountId` is not defined in metadata list, the last +/// // Thus the metadata is `::AccountId`. +/// Proposed(::AccountId), +/// /// doc +/// // here metadata will be `Balance` as define in metadata list +/// Spending(BalanceOf), +/// // here metadata will be `Other` as define in metadata list +/// Something(u32), +/// } +/// +/// // Define a struct which implements `frame_support::traits::Get` +/// #[pallet::type_value] +/// pub(super) fn MyDefault() -> T::Balance { 3.into() } +/// +/// // Declare a storage, any amount of storage can be declared. +/// // +/// // Is expected either `StorageValue`, `StorageMap` or `StorageDoubleMap`. +/// // The macro generates for struct `$identP` (for storage of name `$ident`) and implement +/// // storage instance on it. +/// // The macro macro expand the metadata for the storage with the type used: +/// // * For storage value the type for value will be copied into metadata +/// // * For storage map the type for value and the type for key will be copied into metadata +/// // * For storage double map the type for value, key1, and key2 will be copied into +/// // metadata. +/// // +/// // NOTE: for storage hasher, the type is not copied because storage hasher trait already +/// // implements metadata. Thus generic storage hasher is supported. +/// #[pallet::storage] +/// pub(super) type MyStorageValue = +/// StorageValue<_, T::Balance, ValueQuery, MyDefault>; +/// +/// // Another declaration +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; +/// +/// // Declare genesis config. (This is optional) +/// // +/// // The macro accept either type alias or struct or enum, it checks generics are consistent. +/// // +/// // Type must implement `Default` traits +/// #[pallet::genesis_config] +/// #[derive(Default)] +/// pub struct GenesisConfig { +/// _myfield: u32, +/// } +/// +/// // Declare genesis builder. (This is need only if GenesisConfig is declared) +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// +/// // Declare a pallet origin. (this is optional) +/// // +/// // The macro accept type alias or struct or enum, it checks generics are consistent. +/// #[pallet::origin] +/// pub struct Origin(PhantomData); +/// +/// // Declare validate_unsigned implementation. +/// #[pallet::validate_unsigned] +/// impl ValidateUnsigned for Pallet { +/// type Call = Call; +/// fn validate_unsigned( +/// source: TransactionSource, +/// call: &Self::Call +/// ) -> TransactionValidity { +/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) +/// } +/// } +/// +/// // Declare inherent provider for pallet. (this is optional) +/// // +/// // The macro checks pallet is `Pallet` or `Pallet` and trait is `ProvideInherent` +/// #[pallet::inherent] +/// impl ProvideInherent for Pallet { +/// type Call = Call; +/// type Error = InherentError; +/// +/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; +/// +/// fn create_inherent(_data: &InherentData) -> Option { +/// unimplemented!(); +/// } +/// } +/// +/// // Regular rust code needed for implementing ProvideInherent trait +/// +/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] +/// #[cfg_attr(feature = "std", derive(codec::Decode))] +/// pub enum InherentError { +/// } +/// +/// impl sp_inherents::IsFatalError for InherentError { +/// fn is_fatal_error(&self) -> bool { +/// unimplemented!(); +/// } +/// } +/// +/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +/// } +/// ``` +/// +/// # Example for pallet with instance. +/// +/// ``` +/// #[frame_support::pallet] +/// pub mod pallet { +/// use frame_support::pallet_prelude::*; +/// use frame_system::pallet_prelude::*; +/// +/// type BalanceOf = >::Balance; +/// +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] +/// type MyGetParam: Get; +/// type Balance: Parameter + From; +/// type Event: From> + IsType<::Event>; +/// } +/// +/// #[pallet::extra_constants] +/// impl, I: 'static> Pallet { +/// /// Some description +/// fn exra_constant_name() -> u128 { 4u128 } +/// } +/// +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData<(T, I)>); +/// +/// #[pallet::hooks] +/// impl, I: 'static> Hooks> for Pallet { +/// } +/// +/// #[pallet::call] +/// impl, I: 'static> Pallet { +/// /// Doc comment put in metadata +/// #[pallet::weight(0)] +/// fn toto(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { +/// let _ = origin; +/// unimplemented!(); +/// } +/// } +/// +/// #[pallet::error] +/// pub enum Error { +/// /// doc comment put into metadata +/// InsufficientProposersBalance, +/// } +/// +/// #[pallet::event] +/// #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] +/// #[pallet::generate_deposit(pub(super) fn deposit_event)] +/// pub enum Event, I: 'static = ()> { +/// /// doc comment put in metadata +/// Proposed(::AccountId), +/// /// doc +/// Spending(BalanceOf), +/// Something(u32), +/// } +/// +/// #[pallet::type_value] +/// pub(super) fn MyDefault, I: 'static>() -> T::Balance { 3.into() } +/// +/// #[pallet::storage] +/// pub(super) type MyStorageValue, I: 'static = ()> = +/// StorageValue<_, T::Balance, ValueQuery, MyDefault>; +/// +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = +/// StorageMap<_, Blake2_128Concat, u32, u32>; +/// +/// #[pallet::genesis_config] +/// #[derive(Default)] +/// pub struct GenesisConfig { +/// _myfield: u32, +/// } +/// +/// #[pallet::genesis_build] +/// impl, I: 'static> GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// +/// #[pallet::origin] +/// pub struct Origin(PhantomData<(T, I)>); +/// +/// #[pallet::validate_unsigned] +/// impl, I: 'static> ValidateUnsigned for Pallet { +/// type Call = Call; +/// fn validate_unsigned( +/// source: TransactionSource, +/// call: &Self::Call +/// ) -> TransactionValidity { +/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) +/// } +/// } +/// +/// #[pallet::inherent] +/// impl, I: 'static> ProvideInherent for Pallet { +/// type Call = Call; +/// type Error = InherentError; +/// +/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; +/// +/// fn create_inherent(_data: &InherentData) -> Option { +/// unimplemented!(); +/// } +/// } +/// +/// // Regular rust code needed for implementing ProvideInherent trait +/// +/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] +/// #[cfg_attr(feature = "std", derive(codec::Decode))] +/// pub enum InherentError { +/// } +/// +/// impl sp_inherents::IsFatalError for InherentError { +/// fn is_fatal_error(&self) -> bool { +/// unimplemented!(); +/// } +/// } +/// +/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +/// } +/// ``` +/// +/// ## Upgrade guidelines: +/// +/// 1. make crate compiling: rename usage of frame_system::Trait to frame_system::Config. +/// 2. export metadata of the pallet for later checks +/// 3. generate the template upgrade for the pallet provided by decl_storage with environment +/// variable `PRINT_PALLET_UPGRADE`: `PRINT_PALLET_UPGRADE=1 cargo check -p my_pallet` +/// This template can be used as information it contains all information for storages, genesis +/// config and genesis build. +/// 4. reorganize pallet to have trait Trait, decl_* macros, ValidateUnsigned, ProvideInherent, +/// Origin all together in one file. suggested order: +/// * trait, +/// * decl_module, +/// * decl_event, +/// * decl_error, +/// * decl_storage, +/// * origin, +/// * validate_unsigned, +/// * provide_inherent, +/// so far it should compile and all be correct. +/// 5. start writing new pallet module +/// ```ignore +/// pub use pallet::*; +/// +/// #[frame_support::pallet] +/// pub mod pallet { +/// pub use frame_support::pallet_prelude::*; +/// pub use frame_system::pallet_prelude::*; +/// use super::*; +/// +/// #[pallet::pallet] +/// #[pallet::generete($visibility_of_trait_store trait Store)] +/// // NOTE: if the visibility of trait store is private but you want to make it available +/// // in super, then use `pub(super)` or `pub(crate)` to make it available in crate. +/// pub struct Pallet(PhantomData); +/// // pub struct Pallet(PhantomData); // for instantiable pallet +/// } +/// ``` +/// 6. **migrate trait**: move trait into the module with +/// * rename `Trait` to `Config` +/// * all const in decl_module to `#[pallet::constant]` +/// 7. **migrate decl_module**: write: +/// ```ignore +/// #[pallet::hooks] +/// impl Hooks for Pallet { +/// } +/// ``` +/// and write inside on_initialize/on_finalize/on_runtime_upgrade/offchain_worker/integrity_test +/// +/// then write: +/// ```ignore +/// #[pallet::call] +/// impl Pallet { +/// } +/// ``` +/// and write inside all the call in decl_module with a few changes in the signature: +/// - origin must now be written completely, e.g. `origin: OriginFor` +/// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you might +/// need to put `Ok(().into())` at the end or the function. +/// - `#[compact]` must now be written `#[pallet::compact]` +/// - `#[weight = ..]` must now be written `#[pallet::weight(..)]` +/// +/// 8. **migrate event**: +/// rewrite as a simple enum under with the attribute `#[pallet::event]`, +/// use `#[pallet::generate_deposit($vis fn deposit_event)]` to generate deposit_event, +/// use `#[pallet::metadata(...)]` to configure the metadata for types in order not to break them. +/// 9. **migrate error**: just rewrite it with attribute `#[pallet::error]`. +/// 10. **migrate storage**: +/// decl_storage provide an upgrade template (see 3.). All storages, genesis config, genesis +/// build and default implementation of genesis config can be taken from it directly. +/// +/// Otherwise here is the manual process: +/// +/// first migrate the genesis logic. write: +/// ```ignore +/// #[pallet::genesis_config] +/// struct GenesisConfig { +/// // fields of add_extra_genesis +/// } +/// impl Default for GenesisConfig { +/// // type default or default provided for fields +/// } +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// // impl GenesisBuild for GenesisConfig { for instantiable pallet +/// fn build() { +/// // The add_extra_genesis build logic +/// } +/// } +/// ``` +/// for each storages, if it contains config(..) then add a fields, and make its default to the +/// value in `= ..;` or the type default if none, if it contains no build then also add the +/// logic to build the value. +/// for each storages if it contains build(..) then add the logic to genesis_build. +/// +/// NOTE: in decl_storage: is executed first the individual config and build and at the end the +/// add_extra_genesis build +/// +/// Once this is done you can migrate storage individually, a few notes: +/// - for private storage use `pub(crate) type ` or `pub(super) type` or nothing, +/// - for storage with `get(fn ..)` use `#[pallet::getter(fn ...)]` +/// - for storage with value being `Option<$something>` make generic `Value` being `$something` +/// and generic `QueryKind` being `OptionQuery` (note: this is default). Otherwise make +/// `Value` the complete value type and `QueryKind` being `ValueQuery`. +/// - for storage with default value: `= $expr;` provide some specific OnEmpty generic. To do so +/// use of `#[pallet::type_value]` to generate the wanted struct to put. +/// example: `MyStorage: u32 = 3u32` would be written: +/// ```ignore +/// #[pallet::type_value] fn MyStorageOnEmpty() -> u32 { 3u32 } +/// #[pallet::storage] +/// pub(super) type MyStorage = StorageValue; +/// ``` +/// +/// NOTE: decl_storage also generates functions `assimilate_storage` and `build_storage` +/// directly on GenesisConfig, those are sometimes used in tests. In order not to break they +/// can be implemented manually, just implement those functions by calling `GenesisBuild` +/// implementation. +/// +/// 11. **migrate origin**: just move the origin to the pallet module under `#[pallet::origin]` +/// 12. **migrate validate_unsigned**: just move the ValidateUnsigned implementation to the pallet +/// module under `#[pallet::validate_unsigned]` +/// 13. **migrate provide_inherent**: just move the ValidateUnsigned implementation to the pallet +/// module under `#[pallet::provide_inherent]` +/// 14. rename the usage of Module to Pallet and the usage of Config to Trait inside the crate. +/// 15. migration is done, now double check migration with the checking migration guidelines. +/// +/// ## Checking upgrade guidelines: +/// +/// * compare metadata. This checks for: +/// * call, names, signature, doc +/// * event names, docs +/// * error names, docs +/// * storage names, hasher, prefixes, default value +/// * error , error, constant, +/// * manually check that: +/// * Origin is moved inside macro unser `#[pallet::origin]` if it exists +/// * ValidateUnsigned is moved inside macro under `#[pallet::validate_unsigned)]` if it exists +/// * ProvideInherent is moved inside macro under `#[pallet::inherent)]` if it exists +/// * on_initialize/on_finalize/on_runtime_upgrade/offchain_worker are moved to Hooks +/// implementation +/// * storages with `config(..)` are converted to genesis_config field, and their default is +/// `= $expr;` if the storage have default value +/// * storages with `build($expr)` or `config(..)` are built in genesis_build +/// * add_extra_genesis fields are converted to genesis_config field with their correct default +/// if specified +/// * add_extra_genesis build is written into genesis_build +/// * storages now use PalletInfo for module_prefix instead of the one given to decl_storage: +/// Thus any use of this pallet in `construct_runtime!` should be careful to update name in +/// order not to break storage or to upgrade storage (moreover for instantiable pallet). +/// If pallet is published, make sure to warn about this breaking change. +/// +/// # Notes when macro fails to show proper error message spans: +/// +/// Rustc loses span for some macro input. Some tips to fix it: +/// * do not use inner attribute: +/// ```ignore +/// #[pallet] +/// pub mod pallet { +/// //! This inner attribute will make span fail +/// .. +/// } +/// ``` +/// * use the newest nightly possible. +/// +pub use frame_support_procedural::pallet; diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 718f1d6354a..1802c302466 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1869,6 +1869,79 @@ pub trait IsSubType { fn is_sub_type(&self) -> Option<&T>; } +/// The pallet hooks trait. Implementing this lets you express some logic to execute. +pub trait Hooks { + /// The block is being finalized. Implement to have something happen. + fn on_finalize(_n: BlockNumber) {} + + /// The block is being initialized. Implement to have something happen. + /// + /// Return the non-negotiable weight consumed in the block. + fn on_initialize(_n: BlockNumber) -> crate::weights::Weight { 0 } + + /// Perform a module upgrade. + /// + /// NOTE: this doesn't include all pallet logic triggered on runtime upgrade. For instance it + /// doesn't include the write of the pallet version in storage. The final complete logic + /// triggered on runtime upgrade is given by implementation of `OnRuntimeUpgrade` trait by + /// `Pallet`. + /// + /// # Warning + /// + /// This function will be called before we initialized any runtime state, aka `on_initialize` + /// wasn't called yet. So, information like the block number and any other + /// block local data are not accessible. + /// + /// Return the non-negotiable weight consumed for runtime upgrade. + fn on_runtime_upgrade() -> crate::weights::Weight { 0 } + + /// Implementing this function on a module allows you to perform long-running tasks + /// that make (by default) validators generate transactions that feed results + /// of those long-running computations back on chain. + /// + /// NOTE: This function runs off-chain, so it can access the block state, + /// but cannot preform any alterations. More specifically alterations are + /// not forbidden, but they are not persisted in any way after the worker + /// has finished. + /// + /// This function is being called after every block import (when fully synced). + /// + /// Implement this and use any of the `Offchain` `sp_io` set of APIs + /// to perform off-chain computations, calls and submit transactions + /// with results to trigger any on-chain changes. + /// Any state alterations are lost and are not persisted. + fn offchain_worker(_n: BlockNumber) {} + + /// Run integrity test. + /// + /// The test is not executed in a externalities provided environment. + fn integrity_test() {} +} + +/// A trait to define the build function of a genesis config, T and I are placeholder for pallet +/// trait and pallet instance. +#[cfg(feature = "std")] +pub trait GenesisBuild: Default + MaybeSerializeDeserialize { + /// The build function is called within an externalities allowing storage APIs. + /// Thus one can write to storage using regular pallet storages. + fn build(&self); + + /// Build the storage using `build` inside default storage. + fn build_storage(&self) -> Result { + let mut storage = Default::default(); + self.assimilate_storage(&mut storage)?; + Ok(storage) + } + + /// Assimilate the storage for this module into pre-existing overlays. + fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + sp_state_machine::BasicExternalities::execute_with_storage(storage, || { + self.build(); + Ok(()) + }) + } +} + /// The storage key postfix that is used to store the [`PalletVersion`] per pallet. /// /// The full storage key is built by using: diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs new file mode 100644 index 00000000000..5d2785ebf26 --- /dev/null +++ b/frame/support/test/tests/pallet.rs @@ -0,0 +1,764 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 frame_support::{ + weights::{DispatchInfo, DispatchClass, Pays, GetDispatchInfo}, + traits::{ + GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade, GetPalletVersion, OnGenesis, + }, + dispatch::{UnfilteredDispatchable, Parameter}, + storage::unhashed, +}; +use sp_runtime::{traits::Block as _, DispatchError}; +use sp_io::{TestExternalities, hashing::{twox_64, twox_128, blake2_128}}; + +pub struct SomeType1; +impl From for u64 { fn from(_t: SomeType1) -> Self { 0u64 } } + +pub struct SomeType2; +impl From for u64 { fn from(_t: SomeType2) -> Self { 100u64 } } + +pub struct SomeType3; +impl From for u64 { fn from(_t: SomeType3) -> Self { 0u64 } } + +pub struct SomeType4; +impl From for u64 { fn from(_t: SomeType4) -> Self { 0u64 } } + +pub struct SomeType5; +impl From for u64 { fn from(_t: SomeType5) -> Self { 0u64 } } + +pub struct SomeType6; +impl From for u64 { fn from(_t: SomeType6) -> Self { 0u64 } } + +pub struct SomeType7; +impl From for u64 { fn from(_t: SomeType7) -> Self { 0u64 } } + +pub trait SomeAssociation1 { type _1: Parameter; } +impl SomeAssociation1 for u64 { type _1 = u64; } + +pub trait SomeAssociation2 { type _2: Parameter; } +impl SomeAssociation2 for u64 { type _2 = u64; } + +#[frame_support::pallet] +pub mod pallet { + use super::{ + SomeType1, SomeType2, SomeType3, SomeType4, SomeType5, SomeType6, SomeType7, + SomeAssociation1, SomeAssociation2, + }; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + type BalanceOf = ::Balance; + + #[pallet::config] + pub trait Config: frame_system::Config + where ::AccountId: From + SomeAssociation1, + { + /// Some comment + /// Some comment + #[pallet::constant] + type MyGetParam: Get; + + /// Some comment + /// Some comment + #[pallet::constant] + type MyGetParam2: Get; + + #[pallet::constant] + type MyGetParam3: Get<::_1>; + + type Balance: Parameter + Default; + + type Event: From> + IsType<::Event>; + } + + #[pallet::extra_constants] + impl Pallet + where T::AccountId: From + SomeAssociation1 + From, + { + /// Some doc + /// Some doc + fn some_extra() -> T::AccountId { SomeType2.into() } + + /// Some doc + fn some_extra_extra() -> T::AccountId { SomeType1.into() } + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet + where T::AccountId: From + From + SomeAssociation1, + { + fn on_initialize(_: BlockNumberFor) -> Weight { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(10)); + 10 + } + fn on_finalize(_: BlockNumberFor) { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(20)); + } + fn on_runtime_upgrade() -> Weight { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(30)); + 30 + } + fn integrity_test() { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + } + } + + #[pallet::call] + impl Pallet + where T::AccountId: From + From + SomeAssociation1 + { + /// Doc comment put in metadata + #[pallet::weight(Weight::from(*_foo))] + fn foo( + origin: OriginFor, + #[pallet::compact] _foo: u32, + _bar: u32, + ) -> DispatchResultWithPostInfo { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType3); // Test for where clause + let _ = origin; + Self::deposit_event(Event::Something(3)); + Ok(().into()) + } + + /// Doc comment put in metadata + #[pallet::weight(1)] + #[frame_support::transactional] + fn foo_transactional( + _origin: OriginFor, + #[pallet::compact] foo: u32, + ) -> DispatchResultWithPostInfo { + Self::deposit_event(Event::Something(0)); + if foo != 0 { + Ok(().into()) + } else { + Err(Error::::InsufficientProposersBalance.into()) + } + } + } + + #[pallet::error] + pub enum Error { + /// doc comment put into metadata + InsufficientProposersBalance, + } + + #[pallet::event] + #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event where T::AccountId: SomeAssociation1 + From{ + /// doc comment put in metadata + Proposed(::AccountId), + /// doc + Spending(BalanceOf), + Something(u32), + SomethingElse(::_1), + } + + #[pallet::storage] + pub type ValueWhereClause where T::AccountId: SomeAssociation2 = + StorageValue<_, ::_2>; + + #[pallet::storage] + pub type Value = StorageValue<_, u32>; + + #[pallet::type_value] + pub fn MyDefault() -> u16 + where T::AccountId: From + From + SomeAssociation1 + { + T::AccountId::from(SomeType7); // Test where clause works + 4u16 + } + + #[pallet::storage] + pub type Map where T::AccountId: From = + StorageMap<_, Blake2_128Concat, u8, u16, ValueQuery, MyDefault>; + + #[pallet::storage] + pub type Map2 = StorageMap<_, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap = StorageDoubleMap<_, Blake2_128Concat, u8, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap2 = StorageDoubleMap<_, Twox64Concat, u16, Blake2_128Concat, u32, u64>; + + #[pallet::genesis_config] + #[derive(Default)] + pub struct GenesisConfig { + _myfield: u32, + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + where T::AccountId: From + SomeAssociation1 + From + { + fn build(&self) { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType4); // Test for where clause + } + } + + #[pallet::origin] + #[derive(EqNoBound, RuntimeDebugNoBound, CloneNoBound, PartialEqNoBound, Encode, Decode)] + pub struct Origin(PhantomData); + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet + where T::AccountId: From + SomeAssociation1 + From + From + { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call + ) -> TransactionValidity { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType5); // Test for where clause + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet + where T::AccountId: From + SomeAssociation1 + From + From + { + type Call = Call; + type Error = InherentError; + + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(_data: &InherentData) -> Option { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType6); // Test for where clause + unimplemented!(); + } + } + + #[derive(codec::Encode, sp_runtime::RuntimeDebug)] + #[cfg_attr(feature = "std", derive(codec::Decode))] + pub enum InherentError { + } + + impl sp_inherents::IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + unimplemented!(); + } + } + + pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +} + +// Test that a pallet with non generic event and generic genesis_config is correctly handled +#[frame_support::pallet] +pub mod pallet2 { + use super::{SomeType1, SomeAssociation1}; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config + where ::AccountId: From + SomeAssociation1, + { + type Event: From + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet + where T::AccountId: From + SomeAssociation1, + { + } + + #[pallet::call] + impl Pallet + where T::AccountId: From + SomeAssociation1, + { + } + + #[pallet::event] + pub enum Event { + /// Something + Something(u32), + } + + #[pallet::genesis_config] + pub struct GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + phantom: PhantomData, + } + + impl Default for GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + fn default() -> Self { + GenesisConfig { + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + fn build(&self) {} + } +} + +frame_support::parameter_types!( + pub const MyGetParam: u32= 10; + pub const MyGetParam2: u32= 11; + pub const MyGetParam3: u32= 12; + pub const BlockHashCount: u32 = 250; +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + 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 Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam = MyGetParam; + type MyGetParam2 = MyGetParam2; + type MyGetParam3 = MyGetParam3; + type Balance = u64; +} + +impl pallet2::Config for Runtime { + type Event = Event; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + Example2: pallet2::{Module, Call, Event, Config, Storage}, + } +); + +#[test] +fn transactional_works() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + + pallet::Call::::foo_transactional(0).dispatch_bypass_filter(None.into()) + .err().unwrap(); + assert!(frame_system::Pallet::::events().is_empty()); + + pallet::Call::::foo_transactional(1).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Pallet::::events().iter().map(|e| &e.event).collect::>(), + vec![&Event::pallet(pallet::Event::Something(0))], + ); + }) +} + +#[test] +fn call_expand() { + let call_foo = pallet::Call::::foo(3, 0); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); +} + +#[test] +fn error_expand() { + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 1, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); +} + +#[test] +fn instance_expand() { + // Assert same type. + let _: pallet::__InherentHiddenInstance = (); +} + +#[test] +fn pallet_expand_deposit_event() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + pallet::Call::::foo(3, 0).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Pallet::::events()[0].event, + Event::pallet(pallet::Event::Something(3)), + ); + }) +} + +#[test] +fn storage_expand() { + use frame_support::pallet_prelude::*; + use frame_support::StoragePrefixedMap; + + fn twox_64_concat(d: &[u8]) -> Vec { + let mut v = twox_64(d).to_vec(); + v.extend_from_slice(d); + v + } + + fn blake2_128_concat(d: &[u8]) -> Vec { + let mut v = blake2_128(d).to_vec(); + v.extend_from_slice(d); + v + } + + TestExternalities::default().execute_with(|| { + pallet::Value::::put(1); + let k = [twox_128(b"Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + pallet::Map::::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::Map2::::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::DoubleMap::::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::DoubleMap2::::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }) +} + +#[test] +fn pallet_hooks_expand() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + + assert_eq!(AllModules::on_initialize(1), 10); + AllModules::on_finalize(1); + + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!(AllModules::on_runtime_upgrade(), 30); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + assert_eq!( + frame_system::Pallet::::events()[0].event, + Event::pallet(pallet::Event::Something(10)), + ); + assert_eq!( + frame_system::Pallet::::events()[1].event, + Event::pallet(pallet::Event::Something(20)), + ); + assert_eq!( + frame_system::Pallet::::events()[2].event, + Event::pallet(pallet::Event::Something(30)), + ); + }) +} + +#[test] +fn pallet_on_genesis() { + TestExternalities::default().execute_with(|| { + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + }) +} + +#[test] +fn metadata() { + use frame_metadata::*; + use codec::{Decode, Encode}; + + let expected_pallet_metadata = ModuleMetadata { + index: 1, + name: DecodeDifferent::Decoded("Example".to_string()), + storage: Some(DecodeDifferent::Decoded(StorageMetadata { + prefix: DecodeDifferent::Decoded("Example".to_string()), + entries: DecodeDifferent::Decoded(vec![ + StorageEntryMetadata { + name: DecodeDifferent::Decoded("ValueWhereClause".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain( + DecodeDifferent::Decoded( + "::_2".to_string() + ), + ), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Value".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Decoded("u32".to_string())), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map".to_string()), + modifier: StorageEntryModifier::Default, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u8".to_string()), + value: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![4, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u16".to_string()), + value: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u32".to_string()), + key1: DecodeDifferent::Decoded("u8".to_string()), + key2: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + key2_hasher: StorageHasher::Twox64Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u64".to_string()), + key1: DecodeDifferent::Decoded("u16".to_string()), + key2: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + key2_hasher: StorageHasher::Blake2_128Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + })), + calls: Some(DecodeDifferent::Decoded(vec![ + FunctionMetadata { + name: DecodeDifferent::Decoded("foo".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + }, + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_bar".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + FunctionMetadata { + name: DecodeDifferent::Decoded("foo_transactional".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + ])), + event: Some(DecodeDifferent::Decoded(vec![ + EventMetadata { + name: DecodeDifferent::Decoded("Proposed".to_string()), + arguments: DecodeDifferent::Decoded(vec!["::AccountId".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put in metadata".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Spending".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Balance".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Something".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Other".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("SomethingElse".to_string()), + arguments: DecodeDifferent::Decoded(vec!["::_1".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ])), + constants: DecodeDifferent::Decoded(vec![ + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![10, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some comment".to_string(), + " Some comment".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam2".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![11, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some comment".to_string(), + " Some comment".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam3".to_string()), + ty: DecodeDifferent::Decoded("::_1".to_string()), + value: DecodeDifferent::Decoded(vec![12, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("some_extra".to_string()), + ty: DecodeDifferent::Decoded("T::AccountId".to_string()), + value: DecodeDifferent::Decoded(vec![100, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some doc".to_string(), + " Some doc".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("some_extra_extra".to_string()), + ty: DecodeDifferent::Decoded("T::AccountId".to_string()), + value: DecodeDifferent::Decoded(vec![0, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some doc".to_string(), + ]), + }, + ]), + errors: DecodeDifferent::Decoded(vec![ + ErrorMetadata { + name: DecodeDifferent::Decoded("InsufficientProposersBalance".to_string()), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put into metadata".to_string(), + ]), + }, + ]), + }; + + let metadata = match Runtime::metadata().1 { + RuntimeMetadata::V12(metadata) => metadata, + _ => panic!("metadata has been bump, test needs to be updated"), + }; + + let modules_metadata = match metadata.modules { + DecodeDifferent::Encode(modules_metadata) => modules_metadata, + _ => unreachable!(), + }; + + let pallet_metadata = ModuleMetadata::decode(&mut &modules_metadata[1].encode()[..]).unwrap(); + + pretty_assertions::assert_eq!(pallet_metadata, expected_pallet_metadata); +} diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs new file mode 100644 index 00000000000..912d68baed1 --- /dev/null +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -0,0 +1,298 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 sp_runtime::traits::Block as _; + +pub trait SomeAssociation { + type A: frame_support::dispatch::Parameter + Default; +} +impl SomeAssociation for u64 { + type A = u64; +} + +mod pallet_old { + use frame_support::{ + decl_storage, decl_error, decl_event, decl_module, weights::Weight, traits::Get, Parameter + }; + use frame_system::ensure_root; + use super::SomeAssociation; + + pub trait Config: frame_system::Config { + type SomeConst: Get; + type Balance: Parameter + codec::HasCompact + From + Into + Default + + SomeAssociation; + type Event: From> + Into<::Event>; + } + + decl_storage! { + trait Store for Module as Example { + /// Some documentation + Dummy get(fn dummy) config(): Option; + Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; + Foo get(fn foo) config(): T::Balance = 3.into(); + Double get(fn double): double_map + hasher(blake2_128_concat) u32, + hasher(twox_64_concat) u64 + => ::A; + } + } + + decl_event!( + pub enum Event where Balance = ::Balance { + /// Dummy event, just here so there's a generic type that's used. + Dummy(Balance), + } + ); + + decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; + const SomeConst: T::Balance = T::SomeConst::get(); + + #[weight = >::into(new_value.clone())] + fn set_dummy(origin, #[compact] new_value: T::Balance) { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(RawEvent::Dummy(new_value)); + } + + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + } + + decl_error! { + pub enum Error for Module { + /// Some wrong behavior + Wrong, + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::SomeAssociation; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use frame_system::ensure_root; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Balance: Parameter + codec::HasCompact + From + Into + Default + + MaybeSerializeDeserialize + SomeAssociation; + #[pallet::constant] + type SomeConst: Get; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::weight(>::into(new_value.clone()))] + fn set_dummy( + origin: OriginFor, + #[pallet::compact] new_value: T::Balance + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(Event::Dummy(new_value)); + + Ok(().into()) + } + } + + #[pallet::error] + pub enum Error { + /// Some wrong behavior + Wrong, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + #[pallet::metadata(T::Balance = "Balance")] + pub enum Event { + /// Dummy event, just here so there's a generic type that's used. + Dummy(T::Balance), + } + + #[pallet::storage] + /// Some documentation + type Dummy = StorageValue<_, T::Balance, OptionQuery>; + + #[pallet::storage] + type Bar = StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>; + + #[pallet::type_value] pub fn OnFooEmpty() -> T::Balance { 3.into() } + #[pallet::storage] + type Foo = StorageValue<_, T::Balance, ValueQuery, OnFooEmpty>; + + #[pallet::storage] + type Double = StorageDoubleMap< + _, Blake2_128Concat, u32, Twox64Concat, u64, ::A, ValueQuery + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + dummy: Option, + bar: Vec<(T::AccountId, T::Balance)>, + foo: T::Balance, + } + + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + dummy: Default::default(), + bar: Default::default(), + foo: OnFooEmpty::::get(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + if let Some(dummy) = self.dummy.as_ref() { + >::put(dummy); + } + for (k, v) in &self.bar { + >::insert(k, v); + } + >::put(&self.foo); + } + } +} + +frame_support::parameter_types!( + pub const SomeConst: u64 = 10; + pub const BlockHashCount: u32 = 250; +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + 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 Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Module, Call, Event}, + // NOTE: name Example here is needed in order to have same module prefix + Example: pallet::{Module, Call, Event, Config, Storage}, + PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, + } +); + +#[cfg(test)] +mod test { + use super::Runtime; + use super::pallet; + use super::pallet_old; + use codec::{Decode, Encode}; + + #[test] + fn metadata() { + let metadata = Runtime::metadata(); + let modules = match metadata.1 { + frame_metadata::RuntimeMetadata::V12(frame_metadata::RuntimeMetadataV12 { + modules: frame_metadata::DecodeDifferent::Encode(m), + .. + }) => m, + _ => unreachable!(), + }; + pretty_assertions::assert_eq!(modules[1].storage, modules[2].storage); + pretty_assertions::assert_eq!(modules[1].calls, modules[2].calls); + pretty_assertions::assert_eq!(modules[1].event, modules[2].event); + pretty_assertions::assert_eq!(modules[1].constants, modules[2].constants); + pretty_assertions::assert_eq!(modules[1].errors, modules[2].errors); + } + + #[test] + fn types() { + assert_eq!( + pallet_old::Event::::decode( + &mut &pallet::Event::::Dummy(10).encode()[..] + ).unwrap(), + pallet_old::Event::::Dummy(10), + ); + + assert_eq!( + pallet_old::Call::::decode( + &mut &pallet::Call::::set_dummy(10).encode()[..] + ).unwrap(), + pallet_old::Call::::set_dummy(10), + ); + } +} diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs new file mode 100644 index 00000000000..d2f7a6668ca --- /dev/null +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -0,0 +1,315 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 sp_runtime::traits::Block as _; + +mod pallet_old { + use frame_support::{ + decl_storage, decl_error, decl_event, decl_module, weights::Weight, traits::Get, Parameter + }; + use frame_system::ensure_root; + + pub trait Config: frame_system::Config { + type SomeConst: Get; + type Balance: Parameter + codec::HasCompact + From + Into + Default; + type Event: From> + Into<::Event>; + } + + decl_storage! { + trait Store for Module, I: Instance = DefaultInstance> as Example { + /// Some documentation + Dummy get(fn dummy) config(): Option; + Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; + Foo get(fn foo) config(): T::Balance = 3.into(); + Double get(fn double): + double_map hasher(blake2_128_concat) u32, hasher(twox_64_concat) u64 => u16; + } + } + + decl_event!( + pub enum Event where Balance = >::Balance { + /// Dummy event, just here so there's a generic type that's used. + Dummy(Balance), + } + ); + + decl_module! { + pub struct Module, I: Instance = DefaultInstance> for enum Call + where origin: T::Origin + { + type Error = Error; + fn deposit_event() = default; + const SomeConst: T::Balance = T::SomeConst::get(); + + #[weight = >::into(new_value.clone())] + fn set_dummy(origin, #[compact] new_value: T::Balance) { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(RawEvent::Dummy(new_value)); + } + + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + } + + decl_error! { + pub enum Error for Module, I: Instance> { + /// Some wrong behavior + Wrong, + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use frame_system::ensure_root; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Balance: Parameter + codec::HasCompact + From + Into + Default + + MaybeSerializeDeserialize; + #[pallet::constant] + type SomeConst: Get; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + #[pallet::weight(>::into(new_value.clone()))] + fn set_dummy( + origin: OriginFor, + #[pallet::compact] new_value: T::Balance + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(Event::Dummy(new_value)); + + Ok(().into()) + } + } + + #[pallet::error] + pub enum Error { + /// Some wrong behavior + Wrong, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + #[pallet::metadata(T::Balance = "Balance")] + pub enum Event, I: 'static = ()> { + /// Dummy event, just here so there's a generic type that's used. + Dummy(T::Balance), + } + + #[pallet::storage] + /// Some documentation + type Dummy, I: 'static = ()> = StorageValue<_, T::Balance, OptionQuery>; + + #[pallet::storage] + type Bar, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>; + + #[pallet::storage] + type Foo, I: 'static = ()> = + StorageValue<_, T::Balance, ValueQuery, OnFooEmpty>; + #[pallet::type_value] pub fn OnFooEmpty, I: 'static>() -> T::Balance { 3.into() } + + #[pallet::storage] + type Double = StorageDoubleMap< + _, Blake2_128Concat, u32, Twox64Concat, u64, u16, ValueQuery + >; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + dummy: Option, + bar: Vec<(T::AccountId, T::Balance)>, + foo: T::Balance, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + dummy: Default::default(), + bar: Default::default(), + foo: OnFooEmpty::::get(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + if let Some(dummy) = self.dummy.as_ref() { + >::put(dummy); + } + for (k, v) in &self.bar { + >::insert(k, v); + } + >::put(&self.foo); + } + } +} + +frame_support::parameter_types!( + pub const SomeConst: u64 = 10; + pub const BlockHashCount: u32 = 250; +); + +impl frame_system::Config for Runtime { + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + 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 Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage}, + PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, + Instance2Example: pallet::::{Module, Call, Event, Config, Storage}, + PalletOld2: pallet_old::::{Module, Call, Event, Config, Storage}, + Instance3Example: pallet::::{Module, Call, Event, Config, Storage}, + PalletOld3: pallet_old::::{Module, Call, Event, Config, Storage}, + } +); + +#[cfg(test)] +mod test { + use super::Runtime; + use super::pallet; + use super::pallet_old; + use codec::{Decode, Encode}; + + #[test] + fn metadata() { + let metadata = Runtime::metadata(); + let modules = match metadata.1 { + frame_metadata::RuntimeMetadata::V12(frame_metadata::RuntimeMetadataV12 { + modules: frame_metadata::DecodeDifferent::Encode(m), + .. + }) => m, + _ => unreachable!(), + }; + for i in vec![1, 3, 5].into_iter() { + pretty_assertions::assert_eq!(modules[i].storage, modules[i+1].storage); + pretty_assertions::assert_eq!(modules[i].calls, modules[i+1].calls); + pretty_assertions::assert_eq!(modules[i].event, modules[i+1].event); + pretty_assertions::assert_eq!(modules[i].constants, modules[i+1].constants); + pretty_assertions::assert_eq!(modules[i].errors, modules[i+1].errors); + } + } + + #[test] + fn types() { + assert_eq!( + pallet_old::Event::::decode( + &mut &pallet::Event::::Dummy(10).encode()[..] + ).unwrap(), + pallet_old::Event::::Dummy(10), + ); + + assert_eq!( + pallet_old::Call::::decode( + &mut &pallet::Call::::set_dummy(10).encode()[..] + ).unwrap(), + pallet_old::Call::::set_dummy(10), + ); + } +} diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs new file mode 100644 index 00000000000..82b058b7bdd --- /dev/null +++ b/frame/support/test/tests/pallet_instance.rs @@ -0,0 +1,708 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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 frame_support::{ + weights::{DispatchInfo, DispatchClass, Pays, GetDispatchInfo}, + traits::{ + GetCallName, GetPalletVersion, OnInitialize, OnFinalize, OnRuntimeUpgrade, OnGenesis, + }, + dispatch::UnfilteredDispatchable, + storage::unhashed, +}; +use sp_runtime::{traits::Block as _, DispatchError}; +use sp_io::{TestExternalities, hashing::{twox_64, twox_128, blake2_128}}; + +#[frame_support::pallet] +pub mod pallet { + use sp_std::any::TypeId; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + type BalanceOf = >::Balance; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + type MyGetParam: Get; + type Balance: Parameter + Default; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn on_initialize(_: BlockNumberFor) -> Weight { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(10)); + 10 + } else { + Self::deposit_event(Event::Something(11)); + 11 + } + } + fn on_finalize(_: BlockNumberFor) { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(20)); + } else { + Self::deposit_event(Event::Something(21)); + } + } + fn on_runtime_upgrade() -> Weight { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(30)); + 30 + } else { + Self::deposit_event(Event::Something(31)); + 31 + } + } + fn integrity_test() { + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + /// Doc comment put in metadata + #[pallet::weight(Weight::from(*_foo))] + fn foo(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { + let _ = origin; + Self::deposit_event(Event::Something(3)); + Ok(().into()) + } + + /// Doc comment put in metadata + #[pallet::weight(1)] + #[frame_support::transactional] + fn foo_transactional( + origin: OriginFor, + #[pallet::compact] _foo: u32 + ) -> DispatchResultWithPostInfo { + let _ = origin; + Ok(().into()) + } + } + + + #[pallet::error] + pub enum Error { + /// doc comment put into metadata + InsufficientProposersBalance, + } + + #[pallet::event] + #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// doc comment put in metadata + Proposed(::AccountId), + /// doc + Spending(BalanceOf), + Something(u32), + } + + #[pallet::storage] + pub type Value = StorageValue<_, u32>; + + #[pallet::storage] + pub type Map = StorageMap<_, Blake2_128Concat, u8, u16>; + + #[pallet::storage] + pub type Map2 = StorageMap<_, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap = + StorageDoubleMap<_, Blake2_128Concat, u8, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap2 = + StorageDoubleMap<_, Twox64Concat, u16, Blake2_128Concat, u32, u64>; + + #[pallet::genesis_config] + #[derive(Default)] + pub struct GenesisConfig { + _myfield: u32, + } + + #[pallet::genesis_build] + impl, I:'static> GenesisBuild for GenesisConfig { + fn build(&self) {} + } + + #[pallet::origin] + #[derive(EqNoBound, RuntimeDebugNoBound, CloneNoBound, PartialEqNoBound, Encode, Decode)] + pub struct Origin(PhantomData<(T, I)>); + + #[pallet::validate_unsigned] + impl, I: 'static> ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } + + #[pallet::inherent] + impl, I: 'static> ProvideInherent for Pallet { + type Call = Call; + type Error = InherentError; + + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(_data: &InherentData) -> Option { + unimplemented!(); + } + } + + #[derive(codec::Encode, sp_runtime::RuntimeDebug)] + #[cfg_attr(feature = "std", derive(codec::Decode))] + pub enum InherentError { + } + + impl sp_inherents::IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + unimplemented!(); + } + } + + pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +} + +// Test that a instantiable pallet with a generic genesis_config is correctly handled +#[frame_support::pallet] +pub mod pallet2 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet {} + + #[pallet::call] + impl, I: 'static> Pallet {} + + #[pallet::event] + pub enum Event, I: 'static = ()> { + /// Something + Something(u32), + } + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + phantom: PhantomData<(T, I)>, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) {} + } +} + +frame_support::parameter_types!( + pub const MyGetParam: u32= 10; + pub const BlockHashCount: u32 = 250; +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + 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 Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam= MyGetParam; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam= MyGetParam; + type Balance = u64; +} +impl pallet2::Config for Runtime { + type Event = Event; +} +impl pallet2::Config for Runtime { + type Event = Event; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + Instance1Example: pallet::::{ + Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned + }, + Example2: pallet2::{Module, Call, Event, Config, Storage}, + Instance1Example2: pallet2::::{Module, Call, Event, Config, Storage}, + } +); + +#[test] +fn call_expand() { + let call_foo = pallet::Call::::foo(3); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); + + let call_foo = pallet::Call::::foo(3); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); +} + +#[test] +fn error_expand() { + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 1, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); + + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 2, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); +} + +#[test] +fn instance_expand() { + // assert same type + let _: pallet::__InherentHiddenInstance = (); +} + +#[test] +fn pallet_expand_deposit_event() { + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + pallet::Call::::foo(3).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet(pallet::Event::Something(3)), + ); + }); + + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + pallet::Call::::foo(3).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet_Instance1(pallet::Event::Something(3)), + ); + }); +} + +#[test] +fn storage_expand() { + use frame_support::pallet_prelude::*; + use frame_support::StoragePrefixedMap; + + fn twox_64_concat(d: &[u8]) -> Vec { + let mut v = twox_64(d).to_vec(); + v.extend_from_slice(d); + v + } + + fn blake2_128_concat(d: &[u8]) -> Vec { + let mut v = blake2_128(d).to_vec(); + v.extend_from_slice(d); + v + } + + TestExternalities::default().execute_with(|| { + >::put(1); + let k = [twox_128(b"Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + >::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }); + + TestExternalities::default().execute_with(|| { + >::put(1); + let k = [twox_128(b"Instance1Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + >::insert(1, 2); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(1, 2); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }); +} + +#[test] +fn pallet_hooks_expand() { + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + + assert_eq!(AllModules::on_initialize(1), 21); + AllModules::on_finalize(1); + + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!(AllModules::on_runtime_upgrade(), 61); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + // The order is indeed reversed due to https://github.com/paritytech/substrate/issues/6280 + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet_Instance1(pallet::Event::Something(11)), + ); + assert_eq!( + frame_system::Module::::events()[1].event, + Event::pallet(pallet::Event::Something(10)), + ); + assert_eq!( + frame_system::Module::::events()[2].event, + Event::pallet_Instance1(pallet::Event::Something(21)), + ); + assert_eq!( + frame_system::Module::::events()[3].event, + Event::pallet(pallet::Event::Something(20)), + ); + assert_eq!( + frame_system::Module::::events()[4].event, + Event::pallet_Instance1(pallet::Event::Something(31)), + ); + assert_eq!( + frame_system::Module::::events()[5].event, + Event::pallet(pallet::Event::Something(30)), + ); + }) +} + +#[test] +fn pallet_on_genesis() { + TestExternalities::default().execute_with(|| { + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + }) +} + +#[test] +fn metadata() { + use frame_metadata::*; + use codec::{Decode, Encode}; + + let expected_pallet_metadata = ModuleMetadata { + index: 1, + name: DecodeDifferent::Decoded("Example".to_string()), + storage: Some(DecodeDifferent::Decoded(StorageMetadata { + prefix: DecodeDifferent::Decoded("Example".to_string()), + entries: DecodeDifferent::Decoded(vec![ + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Value".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Decoded("u32".to_string())), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u8".to_string()), + value: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u16".to_string()), + value: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u32".to_string()), + key1: DecodeDifferent::Decoded("u8".to_string()), + key2: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + key2_hasher: StorageHasher::Twox64Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u64".to_string()), + key1: DecodeDifferent::Decoded("u16".to_string()), + key2: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + key2_hasher: StorageHasher::Blake2_128Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + })), + calls: Some(DecodeDifferent::Decoded(vec![ + FunctionMetadata { + name: DecodeDifferent::Decoded("foo".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + FunctionMetadata { + name: DecodeDifferent::Decoded("foo_transactional".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + ])), + event: Some(DecodeDifferent::Decoded(vec![ + EventMetadata { + name: DecodeDifferent::Decoded("Proposed".to_string()), + arguments: DecodeDifferent::Decoded(vec!["::AccountId".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put in metadata".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Spending".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Balance".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Something".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Other".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ])), + constants: DecodeDifferent::Decoded(vec![ + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![10, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + errors: DecodeDifferent::Decoded(vec![ + ErrorMetadata { + name: DecodeDifferent::Decoded("InsufficientProposersBalance".to_string()), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put into metadata".to_string(), + ]), + }, + ]), + }; + + let mut expected_pallet_instance1_metadata = expected_pallet_metadata.clone(); + expected_pallet_instance1_metadata.name = DecodeDifferent::Decoded("Instance1Example".to_string()); + expected_pallet_instance1_metadata.index = 2; + match expected_pallet_instance1_metadata.storage { + Some(DecodeDifferent::Decoded(ref mut storage_meta)) => { + storage_meta.prefix = DecodeDifferent::Decoded("Instance1Example".to_string()); + }, + _ => unreachable!(), + } + + + let metadata = match Runtime::metadata().1 { + RuntimeMetadata::V12(metadata) => metadata, + _ => panic!("metadata has been bump, test needs to be updated"), + }; + + let modules_metadata = match metadata.modules { + DecodeDifferent::Encode(modules_metadata) => modules_metadata, + _ => unreachable!(), + }; + + let pallet_metadata = ModuleMetadata::decode(&mut &modules_metadata[1].encode()[..]).unwrap(); + let pallet_instance1_metadata = + ModuleMetadata::decode(&mut &modules_metadata[2].encode()[..]).unwrap(); + + pretty_assertions::assert_eq!(pallet_metadata, expected_pallet_metadata); + pretty_assertions::assert_eq!(pallet_instance1_metadata, expected_pallet_instance1_metadata); +} diff --git a/frame/support/test/tests/pallet_ui.rs b/frame/support/test/tests/pallet_ui.rs new file mode 100644 index 00000000000..d323526622a --- /dev/null +++ b/frame/support/test/tests/pallet_ui.rs @@ -0,0 +1,26 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +#[rustversion::attr(not(stable), ignore)] +#[test] +fn pallet_ui() { + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + std::env::set_var("SKIP_WASM_BUILD", "1"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/pallet_ui/*.rs"); +} diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.rs b/frame/support/test/tests/pallet_ui/attr_non_empty.rs new file mode 100644 index 00000000000..5173d983bbd --- /dev/null +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.rs @@ -0,0 +1,6 @@ +#[frame_support::pallet [foo]] +mod foo { +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr new file mode 100644 index 00000000000..144af5a17ea --- /dev/null +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet macro call: expected no attributes, e.g. macro call must be just `#[frame_support::pallet]` or `#[pallet]` + --> $DIR/attr_non_empty.rs:1:26 + | +1 | #[frame_support::pallet [foo]] + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs new file mode 100644 index 00000000000..69d35344d57 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar: codec::Codec; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr new file mode 100644 index 00000000000..64f93cd574e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr @@ -0,0 +1,28 @@ +error[E0369]: binary operation `==` cannot be applied to type `&::Bar` + --> $DIR/call_argument_invalid_bound.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ + | +help: consider further restricting this bound + | +1 | #[frame_support::pallet] + std::cmp::PartialEq + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `::Bar: Clone` is not satisfied + --> $DIR/call_argument_invalid_bound.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ the trait `Clone` is not implemented for `::Bar` + | + = note: required by `clone` + +error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/call_argument_invalid_bound.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ `::Bar` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `::Bar` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&::Bar` + = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs new file mode 100644 index 00000000000..581c72a4240 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr new file mode 100644 index 00000000000..e366061b1c2 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `pallet::Call: Decode` is not satisfied + --> $DIR/call_argument_invalid_bound_2.rs:17:12 + | +17 | #[pallet::call] + | ^^^^ the trait `Decode` is not implemented for `pallet::Call` + +error[E0277]: the trait bound `pallet::Call: pallet::_::_parity_scale_codec::Encode` is not satisfied + --> $DIR/call_argument_invalid_bound_2.rs:17:12 + | +17 | #[pallet::call] + | ^^^^ the trait `pallet::_::_parity_scale_codec::Encode` is not implemented for `pallet::Call` diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs new file mode 100644 index 00000000000..97f36255103 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs @@ -0,0 +1,29 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + use codec::{Encode, Decode}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[derive(Encode, Decode)] + struct Bar; + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr new file mode 100644 index 00000000000..89cee573a27 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr @@ -0,0 +1,26 @@ +error[E0369]: binary operation `==` cannot be applied to type `&Bar` + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ + | + = note: an implementation of `std::cmp::PartialEq` might be missing for `&Bar` + +error[E0277]: the trait bound `Bar: Clone` is not satisfied + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ the trait `Clone` is not implemented for `Bar` + | + = note: required by `clone` + +error[E0277]: `Bar` doesn't implement `std::fmt::Debug` + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ `Bar` cannot be formatted using `{:?}` + | + = help: the trait `std::fmt::Debug` is not implemented for `Bar` + = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&Bar` + = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/frame/support/test/tests/pallet_ui/call_invalid_const.rs b/frame/support/test/tests/pallet_ui/call_invalid_const.rs new file mode 100644 index 00000000000..1a28bc32e65 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_const.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + const Foo: u8 = 3u8; + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_invalid_const.stderr b/frame/support/test/tests/pallet_ui/call_invalid_const.stderr new file mode 100644 index 00000000000..0acb3e864a5 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_const.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, only method accepted + --> $DIR/call_invalid_const.rs:17:3 + | +17 | const Foo: u8 = 3u8; + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs new file mode 100644 index 00000000000..edf953b5976 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: u8) {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr new file mode 100644 index 00000000000..855c59fd8d5 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr @@ -0,0 +1,11 @@ +error: Invalid type: expected `OriginFor` + --> $DIR/call_invalid_origin_type.rs:17:18 + | +17 | fn foo(origin: u8) {} + | ^^ + +error: expected `OriginFor` + --> $DIR/call_invalid_origin_type.rs:17:18 + | +17 | fn foo(origin: u8) {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_missing_weight.rs b/frame/support/test/tests/pallet_ui/call_missing_weight.rs new file mode 100644 index 00000000000..2ce607c53ac --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_missing_weight.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: OriginFor) -> DispatchResultWithPostInfo {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_missing_weight.stderr b/frame/support/test/tests/pallet_ui/call_missing_weight.stderr new file mode 100644 index 00000000000..f499e8a65da --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_missing_weight.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, require weight attribute i.e. `#[pallet::weight = $expr]` + --> $DIR/call_missing_weight.rs:17:3 + | +17 | fn foo(origin: OriginFor) -> DispatchResultWithPostInfo {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_no_origin.rs b/frame/support/test/tests/pallet_ui/call_no_origin.rs new file mode 100644 index 00000000000..83d10b6b08b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_origin.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo() {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_no_origin.stderr b/frame/support/test/tests/pallet_ui/call_no_origin.stderr new file mode 100644 index 00000000000..42afd02c426 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_origin.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, must have at least origin arg + --> $DIR/call_no_origin.rs:17:3 + | +17 | fn foo() {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_no_return.rs b/frame/support/test/tests/pallet_ui/call_no_return.rs new file mode 100644 index 00000000000..a18c30f6d6d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_return.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: OriginFor) {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_no_return.stderr b/frame/support/test/tests/pallet_ui/call_no_return.stderr new file mode 100644 index 00000000000..b16d401355c --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_return.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, require return type DispatchResultWithPostInfo + --> $DIR/call_no_return.rs:17:3 + | +17 | fn foo(origin: OriginFor) {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs b/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs new file mode 100644 index 00000000000..b8a32a0bd9f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr b/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr new file mode 100644 index 00000000000..c2956717bb2 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr @@ -0,0 +1,5 @@ +error: Invalid duplicated attribute + --> $DIR/duplicate_call_attr.rs:23:12 + | +23 | #[pallet::call] + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs b/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs new file mode 100644 index 00000000000..d675ddefe98 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs @@ -0,0 +1,26 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(trait Store)] + #[pallet::generate_store(trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr b/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr new file mode 100644 index 00000000000..eed6ad4494e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::pallet, multiple argument pallet::generate_store found + --> $DIR/duplicate_store_attr.rs:12:33 + | +12 | #[pallet::generate_store(trait Store)] + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/error_no_fieldless.rs b/frame/support/test/tests/pallet_ui/error_no_fieldless.rs new file mode 100644 index 00000000000..c9d444d6f90 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_no_fieldless.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub enum Error { + U8(u8), + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr b/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr new file mode 100644 index 00000000000..1d69fbeff9a --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::error, unexpected fields, must be `Unit` + --> $DIR/error_no_fieldless.rs:20:5 + | +20 | U8(u8), + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item.rs b/frame/support/test/tests/pallet_ui/error_wrong_item.rs new file mode 100644 index 00000000000..50e66dc8c0d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item.stderr b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr new file mode 100644 index 00000000000..8c0496782fb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::error, expected item enum + --> $DIR/error_wrong_item.rs:19:2 + | +19 | pub struct Foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs b/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs new file mode 100644 index 00000000000..14107fafb06 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub enum Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr b/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr new file mode 100644 index 00000000000..d7e54ad8a75 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr @@ -0,0 +1,5 @@ +error: expected `Error` + --> $DIR/error_wrong_item_name.rs:19:11 + | +19 | pub enum Foo {} + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/event_field_not_member.rs b/frame/support/test/tests/pallet_ui/event_field_not_member.rs new file mode 100644 index 00000000000..0ecde4c1308 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, IsType}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event: IsType<::Event> + From>; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_field_not_member.stderr b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr new file mode 100644 index 00000000000..97d4db798e6 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr @@ -0,0 +1,28 @@ +error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ `::Bar` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `::Bar` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&::Bar` + = note: required for the cast to the object type `dyn std::fmt::Debug` + +error[E0369]: binary operation `==` cannot be applied to type `&::Bar` + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ + | +help: consider further restricting this bound + | +22 | pub enum Event { + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `::Bar: Clone` is not satisfied + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ the trait `Clone` is not implemented for `::Bar` + | + = note: required by `clone` diff --git a/frame/support/test/tests/pallet_ui/event_not_in_trait.rs b/frame/support/test/tests/pallet_ui/event_not_in_trait.rs new file mode 100644 index 00000000000..94151ba4c3d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_not_in_trait.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr b/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr new file mode 100644 index 00000000000..dd96c700ce7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr @@ -0,0 +1,7 @@ +error: Invalid usage of Event, `Config` contains no associated type `Event`, but enum `Event` is declared (in use of `#[pallet::event]`). An Event associated type must be declare on trait `Config`. + --> $DIR/event_not_in_trait.rs:1:1 + | +1 | #[frame_support::pallet] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs new file mode 100644 index 00000000000..fa3bf04d353 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr new file mode 100644 index 00000000000..1f58a37576d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr @@ -0,0 +1,5 @@ +error: Invalid `type Event`, associated type `Event` is reserved and must bound: `IsType<::Event>` + --> $DIR/event_type_invalid_bound.rs:9:3 + | +9 | type Event; + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs new file mode 100644 index 00000000000..564a539b89f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, IsType}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event: IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr new file mode 100644 index 00000000000..8b8946f3b25 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr @@ -0,0 +1,5 @@ +error: Invalid `type Event`, associated type `Event` is reserved and must bound: `From` or `From>` or `From>` + --> $DIR/event_type_invalid_bound_2.rs:9:3 + | +9 | type Event: IsType<::Event>; + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item.rs b/frame/support/test/tests/pallet_ui/event_wrong_item.rs new file mode 100644 index 00000000000..d6690557c39 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item.stderr b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr new file mode 100644 index 00000000000..21eb0ed35e9 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::event, expected item enum + --> $DIR/event_wrong_item.rs:19:2 + | +19 | pub struct Foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs b/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs new file mode 100644 index 00000000000..d828965c517 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr b/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr new file mode 100644 index 00000000000..14e8615c561 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr @@ -0,0 +1,5 @@ +error: expected `Event` + --> $DIR/event_wrong_item_name.rs:19:11 + | +19 | pub enum Foo {} + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs new file mode 100644 index 00000000000..da5e8d0c4da --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs @@ -0,0 +1,26 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, GenesisBuild}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_config] + pub struct GenesisConfig; + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr new file mode 100644 index 00000000000..a2998788736 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr @@ -0,0 +1,10 @@ +error[E0277]: the trait bound `pallet::GenesisConfig: std::default::Default` is not satisfied + --> $DIR/genesis_default_not_satisfied.rs:22:18 + | +22 | impl GenesisBuild for GenesisConfig {} + | ^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `pallet::GenesisConfig` + | + ::: $WORKSPACE/frame/support/src/traits.rs + | + | pub trait GenesisBuild: Default + MaybeSerializeDeserialize { + | ------- required by this bound in `GenesisBuild` diff --git a/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs new file mode 100644 index 00000000000..9ae851005ac --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr new file mode 100644 index 00000000000..9afc1037a48 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr @@ -0,0 +1,5 @@ +error: `#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be either both used or both not used, instead genesis_config is unused and genesis_build is used + --> $DIR/genesis_inconsistent_build_config.rs:2:1 + | +2 | mod pallet { + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs new file mode 100644 index 00000000000..f1eae16f496 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr new file mode 100644 index 00000000000..f451f7b16ae --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr @@ -0,0 +1,13 @@ +error: Invalid genesis builder: expected `GenesisBuild` or `GenesisBuild` + --> $DIR/genesis_invalid_generic.rs:19:7 + | +19 | impl GenesisBuild for GenesisConfig {} + | ^^^^^^^^^^^^ + +error: expected `<` + --> $DIR/genesis_invalid_generic.rs:1:1 + | +1 | #[frame_support::pallet] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs b/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs new file mode 100644 index 00000000000..5e8b297ba4c --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr new file mode 100644 index 00000000000..dd2e65588f5 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::genesis_build, expected impl<..> GenesisBuild<..> for GenesisConfig<..> + --> $DIR/genesis_wrong_name.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs b/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs new file mode 100644 index 00000000000..fae12f133b6 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs @@ -0,0 +1,19 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr b/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr new file mode 100644 index 00000000000..0379448f694 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr @@ -0,0 +1,5 @@ +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/hooks_invalid_item.rs:12:18 + | +12 | impl Hooks for Pallet {} + | ^^^^^ expected 1 type argument diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs new file mode 100644 index 00000000000..00b57a01235 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs @@ -0,0 +1,20 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr new file mode 100644 index 00000000000..352c21013ca --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr @@ -0,0 +1,29 @@ +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:16:7 + | +16 | impl Pallet {} + | ^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:16:18 + | +16 | impl Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:10:20 + | +10 | pub struct Pallet(core::marker::PhantomData); + | ^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:13:47 + | +13 | impl Hooks> for Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:13:7 + | +13 | impl Hooks> for Pallet {} + | ^ diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs new file mode 100644 index 00000000000..e7b51cb5ebe --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs @@ -0,0 +1,20 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet {} + + #[pallet::call] + impl, I: 'static> Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr new file mode 100644 index 00000000000..9f5d3c740cb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr @@ -0,0 +1,29 @@ +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:16:7 + | +16 | impl, I: 'static> Pallet {} + | ^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:16:33 + | +16 | impl, I: 'static> Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:10:20 + | +10 | pub struct Pallet(core::marker::PhantomData<(T, I)>); + | ^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:13:62 + | +13 | impl, I: 'static> Hooks> for Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:13:7 + | +13 | impl, I: 'static> Hooks> for Pallet {} + | ^ diff --git a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs new file mode 100644 index 00000000000..9704a7e1a44 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, ProvideInherent}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::inherent] + impl ProvideInherent for Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr new file mode 100644 index 00000000000..75a522889eb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr @@ -0,0 +1,10 @@ +error[E0046]: not all trait items implemented, missing: `Call`, `Error`, `INHERENT_IDENTIFIER`, `create_inherent` + --> $DIR/inherent_check_inner_span.rs:19:2 + | +19 | impl ProvideInherent for Pallet {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Call`, `Error`, `INHERENT_IDENTIFIER`, `create_inherent` in implementation + | + = help: implement the missing item: `type Call = Type;` + = help: implement the missing item: `type Error = Type;` + = help: implement the missing item: `const INHERENT_IDENTIFIER: [u8; 8] = value;` + = help: implement the missing item: `fn create_inherent(_: &InherentData) -> std::option::Option<::Call> { todo!() }` diff --git a/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs b/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs new file mode 100644 index 00000000000..97eda447213 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::inherent] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr new file mode 100644 index 00000000000..b62b1234bde --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..> + --> $DIR/inherent_invalid_item.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/mod_not_inlined.rs b/frame/support/test/tests/pallet_ui/mod_not_inlined.rs new file mode 100644 index 00000000000..c74c7f5ef2a --- /dev/null +++ b/frame/support/test/tests/pallet_ui/mod_not_inlined.rs @@ -0,0 +1,5 @@ +#[frame_support::pallet] +mod foo; + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr new file mode 100644 index 00000000000..9ad93939d8c --- /dev/null +++ b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr @@ -0,0 +1,13 @@ +error[E0658]: non-inline modules in proc macro input are unstable + --> $DIR/mod_not_inlined.rs:2:1 + | +2 | mod foo; + | ^^^^^^^^ + | + = note: see issue #54727 for more information + +error: Invalid pallet definition, expected mod to be inlined. + --> $DIR/mod_not_inlined.rs:2:1 + | +2 | mod foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs b/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs new file mode 100644 index 00000000000..e451df8c78a --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr new file mode 100644 index 00000000000..57f3ab78a53 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr @@ -0,0 +1,13 @@ +error: free type alias without body + --> $DIR/storage_incomplete_item.rs:19:2 + | +19 | type Foo; + | ^^^^^^^^- + | | + | help: provide a definition for the type: `= ;` + +error[E0433]: failed to resolve: use of undeclared crate or module `pallet` + --> $DIR/storage_incomplete_item.rs:18:4 + | +18 | #[pallet::storage] + | ^^^^^^ use of undeclared crate or module `pallet` diff --git a/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs new file mode 100644 index 00000000000..c8df93c9b32 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr new file mode 100644 index 00000000000..d332e6c2d3d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr @@ -0,0 +1,11 @@ +error: Invalid use of `#[pallet::storage]`, the type first generic argument must be `_`, the final argument is automatically set by macro. + --> $DIR/storage_invalid_first_generic.rs:19:29 + | +19 | type Foo = StorageValue; + | ^^ + +error: expected `_` + --> $DIR/storage_invalid_first_generic.rs:19:29 + | +19 | type Foo = StorageValue; + | ^^ diff --git a/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs b/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs new file mode 100644 index 00000000000..03eee6fc8ec --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = u8; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr new file mode 100644 index 00000000000..ec4bde22ac7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::storage, expected ident: `StorageValue` or `StorageMap` or `StorageDoubleMap` in order to expand metadata, found `u8` + --> $DIR/storage_not_storage_type.rs:19:16 + | +19 | type Foo = u8; + | ^^ diff --git a/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs b/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs new file mode 100644 index 00000000000..e62bdafaa26 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr new file mode 100644 index 00000000000..894f7095b2b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr @@ -0,0 +1,5 @@ +error: pallet::storage unexpected number of generic argument, expected at least 2 args, found none + --> $DIR/storage_value_no_generic.rs:19:16 + | +19 | type Foo = StorageValue; + | ^^^^^^^^^^^^ diff --git a/frame/support/test/tests/pallet_ui/storage_wrong_item.rs b/frame/support/test/tests/pallet_ui/storage_wrong_item.rs new file mode 100644 index 00000000000..56c4b86f2b3 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr new file mode 100644 index 00000000000..8cc180b5bfe --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::storage, expected item type + --> $DIR/storage_wrong_item.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs b/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs new file mode 100644 index 00000000000..3ebd1cb9fa6 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(pub trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr b/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr new file mode 100644 index 00000000000..f0f41a75deb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr @@ -0,0 +1,8 @@ +error[E0446]: private type `_GeneratedPrefixForStorageFoo` in public interface + --> $DIR/store_trait_leak_private.rs:11:37 + | +11 | #[pallet::generate_store(pub trait Store)] + | ^^^^^ can't leak private type +... +21 | type Foo = StorageValue<_, u8>; + | - `_GeneratedPrefixForStorageFoo` declared as private diff --git a/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs new file mode 100644 index 00000000000..ce599d5a31e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + type U; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr new file mode 100644 index 00000000000..16c3531140e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr @@ -0,0 +1,11 @@ +error: Invalid usage of `#[pallet::constant]`, syntax must be `type $SomeIdent: Get<$SomeType>;` + --> $DIR/trait_constant_invalid_bound.rs:9:3 + | +9 | type U; + | ^^^^ + +error: expected `:` + --> $DIR/trait_constant_invalid_bound.rs:9:9 + | +9 | type U; + | ^ diff --git a/frame/support/test/tests/pallet_ui/trait_invalid_item.rs b/frame/support/test/tests/pallet_ui/trait_invalid_item.rs new file mode 100644 index 00000000000..8537659dcd0 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_invalid_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + const U: u8 = 3; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr new file mode 100644 index 00000000000..72495d94b30 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::constant in pallet::config, expected type trait item + --> $DIR/trait_invalid_item.rs:9:3 + | +9 | const U: u8 = 3; + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs b/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs new file mode 100644 index 00000000000..0fc987f7bbd --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs @@ -0,0 +1,21 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config { + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr new file mode 100644 index 00000000000..c38f43d28eb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::trait, expected explicit `frame_system::Config` as supertrait, found none. (try `pub trait Config: frame_system::Config { ...` or `pub trait Config: frame_system::Config { ...`). To disable this check, use `#[pallet::disable_frame_system_supertrait_check]` + --> $DIR/trait_no_supertrait.rs:7:2 + | +7 | pub trait Config { + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs b/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs new file mode 100644 index 00000000000..1a1c451ac39 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] fn Foo() -> u32 { + // Just wrong code to see span + u32::new() + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr b/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr new file mode 100644 index 00000000000..f46b89a067b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr @@ -0,0 +1,5 @@ +error[E0599]: no function or associated item named `new` found for type `u32` in the current scope + --> $DIR/type_value_error_in_block.rs:20:8 + | +20 | u32::new() + | ^^^ function or associated item not found in `u32` diff --git a/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs b/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs new file mode 100644 index 00000000000..476a4a8e1e7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr new file mode 100644 index 00000000000..5ae618df883 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::type_value, expected item fn + --> $DIR/type_value_invalid_item.rs:18:24 + | +18 | #[pallet::type_value] struct Foo; + | ^^^^^^ diff --git a/frame/support/test/tests/pallet_ui/type_value_no_return.rs b/frame/support/test/tests/pallet_ui/type_value_no_return.rs new file mode 100644 index 00000000000..eb13436cac7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_no_return.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] fn Foo() {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_no_return.stderr b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr new file mode 100644 index 00000000000..65ac0243f9f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::type_value, expected return type + --> $DIR/type_value_no_return.rs:18:24 + | +18 | #[pallet::type_value] fn Foo() {} + | ^^ diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index 00750c67672..25320597ba4 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -27,22 +27,17 @@ use frame_support::{ }; use sp_core::{H256, sr25519}; -mod system; - /// A version that we will check for in the tests const SOME_TEST_VERSION: PalletVersion = PalletVersion { major: 3000, minor: 30, patch: 13 }; /// Checks that `on_runtime_upgrade` sets the latest pallet version when being called without /// being provided by the user. mod module1 { - use super::*; - - pub trait Config: system::Config {} + pub trait Config: frame_system::Config {} frame_support::decl_module! { pub struct Module for enum Call where - origin: ::Origin, - system = system, + origin: ::Origin, {} } } @@ -52,12 +47,11 @@ mod module1 { mod module2 { use super::*; - pub trait Config: system::Config {} + pub trait Config: frame_system::Config {} frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, - system = system + origin: ::Origin, { fn on_runtime_upgrade() -> Weight { assert_eq!(crate_to_pallet_version!(), Self::current_version()); @@ -82,26 +76,95 @@ mod module2 { } } +#[frame_support::pallet] +mod pallet3 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + return 3; + } + } + + #[pallet::call] + impl Pallet { + } +} + +#[frame_support::pallet] +mod pallet4 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + } + + #[pallet::pallet] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + return 3; + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + } +} + impl module1::Config for Runtime {} impl module2::Config for Runtime {} impl module2::Config for Runtime {} impl module2::Config for Runtime {} +impl pallet3::Config for Runtime {} +impl pallet4::Config for Runtime {} +impl pallet4::Config for Runtime {} +impl pallet4::Config for Runtime {} + pub type Signature = sr25519::Signature; pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Config for Runtime { - type BaseCallFilter= (); - type Hash = H256; +frame_support::parameter_types!( + pub const BlockHashCount: u32 = 250; +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); type Origin = Origin; + type Index = u64; type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; type Event = Event; - type PalletInfo = PalletInfo; - type Call = Call; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); } frame_support::construct_runtime!( @@ -110,11 +173,15 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: frame_system::{Module, Call, Event}, Module1: module1::{Module, Call}, Module2: module2::{Module, Call}, Module2_1: module2::::{Module, Call}, Module2_2: module2::::{Module, Call}, + Pallet3: pallet3::{Module, Call}, + Pallet4: pallet4::{Module, Call}, + Pallet4_1: pallet4::::{Module, Call}, + Pallet4_2: pallet4::::{Module, Call}, } ); @@ -156,6 +223,10 @@ fn on_runtime_upgrade_sets_the_pallet_versions_in_storage() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); }); } @@ -171,6 +242,10 @@ fn on_runtime_upgrade_overwrites_old_version() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); }); } @@ -183,6 +258,10 @@ fn genesis_init_puts_pallet_version_into_storage() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); let system_version = System::storage_version().expect("System version should be set"); assert_eq!(System::current_version(), system_version); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 4bcab6e6c0e..a89577a478b 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -164,6 +164,7 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { /// An object to track the currently used extrinsic weight in a block. pub type ConsumedWeight = PerDispatchClass; +/// System configuration trait. Implemented by runtime. pub trait Config: 'static + Eq + Clone { /// The basic call filter to use in Origin. All origins are built with this filter as base, /// except Root. @@ -497,6 +498,11 @@ decl_error! { } } +/// Pallet struct placeholder on which is implemented the pallet logic. +/// +/// It is currently an alias for `Module` as old macros still generate/use old name. +pub type Pallet = Module; + decl_module! { pub struct Module for enum Call where origin: T::Origin, system=self { type Error = Error; @@ -1343,3 +1349,14 @@ impl Lookup for ChainContext { ::lookup(s) } } + +/// Prelude to be used alongside pallet macro, for ease of use. +pub mod pallet_prelude { + pub use crate::{ensure_signed, ensure_none, ensure_root}; + + /// Type alias for the `Origin` associated type of system config. + pub type OriginFor = ::Origin; + + /// Type alias for the `BlockNumber` associated type of system config. + pub type BlockNumberFor = ::BlockNumber; +} -- GitLab From 281f81c971b720833d01a3c3ab23c0ef21754084 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Sat, 26 Dec 2020 19:34:39 -0500 Subject: [PATCH 144/163] add a `current_epoch` to BabeApi (#7789) * add a `current_epoch` to BabeApi * add current_epoch_start back again * fix node-runtime * bump spec version --- bin/node/runtime/src/lib.rs | 6 +++++- frame/babe/src/lib.rs | 13 ++++++++++++- primitives/consensus/babe/src/lib.rs | 18 ++++++++++++++++++ test-utils/runtime/src/lib.rs | 12 ++++++++++-- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index fb77fd2ebd4..a86b015dbcf 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -111,7 +111,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 260, + spec_version: 261, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 2, @@ -1141,6 +1141,10 @@ impl_runtime_apis! { Babe::current_epoch_start() } + fn current_epoch() -> sp_consensus_babe::Epoch { + Babe::current_epoch() + } + fn generate_key_ownership_proof( _slot_number: sp_consensus_babe::SlotNumber, authority_id: sp_consensus_babe::AuthorityId, diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index a61f1244cbe..fa7954b9512 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -43,7 +43,7 @@ use sp_timestamp::OnTimestampSet; use sp_consensus_babe::{ digests::{NextConfigDescriptor, NextEpochDescriptor, PreDigest}, inherents::{BabeInherentData, INHERENT_IDENTIFIER}, - BabeAuthorityWeight, ConsensusLog, EquivocationProof, SlotNumber, BABE_ENGINE_ID, + BabeAuthorityWeight, ConsensusLog, Epoch, EquivocationProof, SlotNumber, BABE_ENGINE_ID, }; use sp_consensus_vrf::schnorrkel; use sp_inherents::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}; @@ -486,6 +486,17 @@ impl Module { (EpochIndex::get() * T::EpochDuration::get()) + GenesisSlot::get() } + /// Produces information about the current epoch. + pub fn current_epoch() -> Epoch { + Epoch { + epoch_index: EpochIndex::get(), + start_slot: Self::current_epoch_start(), + duration: T::EpochDuration::get(), + authorities: Self::authorities(), + randomness: Self::randomness(), + } + } + fn deposit_consensus(new: U) { let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); >::deposit_log(log.into()) diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 74f2659e6e8..ac75f26a3de 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -350,6 +350,21 @@ impl OpaqueKeyOwnershipProof { } } +/// BABE epoch information +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] +pub struct Epoch { + /// The epoch index. + pub epoch_index: u64, + /// The starting slot of the epoch. + pub start_slot: SlotNumber, + /// The duration of this epoch. + pub duration: SlotNumber, + /// The authorities and their weights. + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + /// Randomness for this epoch. + pub randomness: [u8; VRF_OUTPUT_LENGTH], +} + sp_api::decl_runtime_apis! { /// API necessary for block authorship with BABE. #[api_version(2)] @@ -364,6 +379,9 @@ sp_api::decl_runtime_apis! { /// Returns the slot number that started the current epoch. fn current_epoch_start() -> SlotNumber; + /// Returns information regarding the current epoch. + fn current_epoch() -> Epoch; + /// Generates a proof of key ownership for the given authority in the /// current epoch. An example usage of this module is coupled with the /// session historical module to prove that a given authority key is diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index ea29215a4f7..6bee4b704fc 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -732,10 +732,14 @@ cfg_if! { } } - fn current_epoch_start() -> SlotNumber { + fn current_epoch_start() -> sp_consensus_babe::SlotNumber { >::current_epoch_start() } + fn current_epoch() -> sp_consensus_babe::Epoch { + >::current_epoch() + } + fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: sp_consensus_babe::EquivocationProof< ::Header, @@ -983,10 +987,14 @@ cfg_if! { } } - fn current_epoch_start() -> SlotNumber { + fn current_epoch_start() -> sp_consensus_babe::SlotNumber { >::current_epoch_start() } + fn current_epoch() -> sp_consensus_babe::Epoch { + >::current_epoch() + } + fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: sp_consensus_babe::EquivocationProof< ::Header, -- GitLab From 165b4b59b2e595dc7ecdfc647eefc1a7d5f4bc45 Mon Sep 17 00:00:00 2001 From: chenwei Date: Mon, 28 Dec 2020 06:00:36 +0800 Subject: [PATCH 145/163] Update tests.rs (#7784) Fix testing for number of slashing spans. --- frame/staking/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 86186af7d3e..d4534834d20 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -45,7 +45,7 @@ fn force_unstake_works() { // Force unstake requires root. assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 2), BadOrigin); // Force unstake needs correct number of slashing spans (for weight calculation) - assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 0), BadOrigin); + assert_noop!(Staking::force_unstake(Origin::root(), 11, 0), Error::::IncorrectSlashingSpans); // We now force them to unstake assert_ok!(Staking::force_unstake(Origin::root(), 11, 2)); // No longer bonded. -- GitLab From 6ba867a3b0ed3d19843c27fc3f90aaab5759f211 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Mon, 28 Dec 2020 05:46:47 -0500 Subject: [PATCH 146/163] add a slot-duration getter to babe config (#7793) --- client/consensus/babe/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 3f2a583482a..bf929992db0 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -342,6 +342,11 @@ impl Config { } } } + + /// Get the inner slot duration, in milliseconds. + pub fn slot_duration(&self) -> u64 { + self.0.slot_duration() + } } impl std::ops::Deref for Config { -- GitLab From 54bde60cfd2c544c54e9e8623b6b8725b99557f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 28 Dec 2020 15:08:30 +0100 Subject: [PATCH 147/163] Fix base-path handling in `key insert` (#7775) This fixes the handling of base-path when using `key insert`. Before the base-path wasn't setup correctly, as done when starting a node. This resulted in putting the keys into the wrong directory. This pr fixes this by creating the correct base-path/config dir for the keystore. Besides that it also removes the insert command from `subkey` as it doesn't make that much sense. If requested, we could bring it back later. --- bin/node-template/node/src/command.rs | 2 +- bin/node/cli/src/command.rs | 2 +- bin/utils/subkey/src/lib.rs | 8 +- client/cli/src/commands/insert.rs | 94 ------------ client/cli/src/commands/insert_key.rs | 173 +++++++++++++++++++++++ client/cli/src/commands/key.rs | 10 +- client/cli/src/commands/mod.rs | 4 +- client/cli/src/config.rs | 14 +- client/cli/src/error.rs | 3 - client/cli/src/lib.rs | 5 +- client/cli/src/params/keystore_params.rs | 15 +- client/keystore/src/local.rs | 4 +- client/service/src/config.rs | 7 + primitives/core/src/crypto.rs | 1 + 14 files changed, 206 insertions(+), 136 deletions(-) delete mode 100644 client/cli/src/commands/insert.rs create mode 100644 client/cli/src/commands/insert_key.rs diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 5c41643a293..acf29bd591e 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -66,7 +66,7 @@ pub fn run() -> sc_cli::Result<()> { let cli = Cli::from_args(); match &cli.subcommand { - Some(Subcommand::Key(cmd)) => cmd.run(), + Some(Subcommand::Key(cmd)) => cmd.run(&cli), Some(Subcommand::BuildSpec(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| cmd.run(config.chain_spec, config.network)) diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index f8a0f3f9b3a..bb1bf0169e6 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -94,7 +94,7 @@ pub fn run() -> Result<()> { You can enable it with `--features runtime-benchmarks`.".into()) } } - Some(Subcommand::Key(cmd)) => cmd.run(), + Some(Subcommand::Key(cmd)) => cmd.run(&cli), Some(Subcommand::Sign(cmd)) => cmd.run(), Some(Subcommand::Verify(cmd)) => cmd.run(), Some(Subcommand::Vanity(cmd)) => cmd.run(), diff --git a/bin/utils/subkey/src/lib.rs b/bin/utils/subkey/src/lib.rs index c38a4857652..0fe6f417d1a 100644 --- a/bin/utils/subkey/src/lib.rs +++ b/bin/utils/subkey/src/lib.rs @@ -18,8 +18,8 @@ use structopt::StructOpt; use sc_cli::{ - Error, VanityCmd, SignCmd, VerifyCmd, InsertCmd, - GenerateNodeKeyCmd, GenerateCmd, InspectKeyCmd, InspectNodeKeyCmd + Error, VanityCmd, SignCmd, VerifyCmd, GenerateNodeKeyCmd, GenerateCmd, InspectKeyCmd, + InspectNodeKeyCmd }; use substrate_frame_cli::ModuleIdCmd; use sp_core::crypto::Ss58Codec; @@ -44,9 +44,6 @@ pub enum Subkey { /// Print the peer ID corresponding to the node key in the given file InspectNodeKey(InspectNodeKeyCmd), - /// Insert a key to the keystore of a node. - Insert(InsertCmd), - /// Inspect a module ID address ModuleId(ModuleIdCmd), @@ -71,7 +68,6 @@ pub fn run() -> Result<(), Error> Subkey::Generate(cmd) => cmd.run()?, Subkey::Inspect(cmd) => cmd.run()?, Subkey::InspectNodeKey(cmd) => cmd.run()?, - Subkey::Insert(cmd) => cmd.run()?, Subkey::ModuleId(cmd) => cmd.run::()?, Subkey::Vanity(cmd) => cmd.run()?, Subkey::Verify(cmd) => cmd.run()?, diff --git a/client/cli/src/commands/insert.rs b/client/cli/src/commands/insert.rs deleted file mode 100644 index 8b7fe98fc0b..00000000000 --- a/client/cli/src/commands/insert.rs +++ /dev/null @@ -1,94 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2020 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. - -//! Implementation of the `insert` subcommand - -use crate::{Error, KeystoreParams, CryptoSchemeFlag, SharedParams, utils, with_crypto_scheme}; -use std::sync::Arc; -use structopt::StructOpt; -use sp_core::crypto::KeyTypeId; -use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; -use std::convert::TryFrom; -use sc_service::config::KeystoreConfig; -use sc_keystore::LocalKeystore; -use sp_core::crypto::SecretString; - -/// The `insert` command -#[derive(Debug, StructOpt)] -#[structopt( - name = "insert", - about = "Insert a key to the keystore of a node." -)] -pub struct InsertCmd { - /// The secret key URI. - /// If the value is a file, the file content is used as URI. - /// If not given, you will be prompted for the URI. - #[structopt(long)] - suri: Option, - - /// Key type, examples: "gran", or "imon" - #[structopt(long)] - key_type: String, - - #[allow(missing_docs)] - #[structopt(flatten)] - pub shared_params: SharedParams, - - #[allow(missing_docs)] - #[structopt(flatten)] - pub keystore_params: KeystoreParams, - - #[allow(missing_docs)] - #[structopt(flatten)] - pub crypto_scheme: CryptoSchemeFlag, -} - -impl InsertCmd { - /// Run the command - pub fn run(&self) -> Result<(), Error> { - let suri = utils::read_uri(self.suri.as_ref())?; - let base_path = self.shared_params.base_path.as_ref() - .ok_or_else(|| Error::MissingBasePath)?; - - let (keystore, public) = match self.keystore_params.keystore_config(base_path)? { - (_, KeystoreConfig::Path { path, password }) => { - let public = with_crypto_scheme!( - self.crypto_scheme.scheme, - to_vec(&suri, password.clone()) - )?; - let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::open(path, password)?); - (keystore, public) - }, - _ => unreachable!("keystore_config always returns path and password; qed") - }; - - let key_type = KeyTypeId::try_from(self.key_type.as_str()) - .map_err(|_e| { - Error::KeyTypeInvalid - })?; - - SyncCryptoStore::insert_unknown(&*keystore, key_type, &suri, &public[..]) - .map_err(|_| Error::KeyStoreOperation)?; - - Ok(()) - } -} - -fn to_vec(uri: &str, pass: Option) -> Result, Error> { - let p = utils::pair_from_suri::

(uri, pass)?; - Ok(p.public().as_ref().to_vec()) -} diff --git a/client/cli/src/commands/insert_key.rs b/client/cli/src/commands/insert_key.rs new file mode 100644 index 00000000000..3338b708a4f --- /dev/null +++ b/client/cli/src/commands/insert_key.rs @@ -0,0 +1,173 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Implementation of the `insert` subcommand + +use crate::{ + Error, KeystoreParams, CryptoSchemeFlag, SharedParams, utils, with_crypto_scheme, + SubstrateCli, +}; +use std::{sync::Arc, convert::TryFrom}; +use structopt::StructOpt; +use sp_core::{crypto::KeyTypeId, crypto::SecretString}; +use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore}; +use sc_keystore::LocalKeystore; +use sc_service::config::{KeystoreConfig, BasePath}; + +/// The `insert` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "insert", + about = "Insert a key to the keystore of a node." +)] +pub struct InsertKeyCmd { + /// The secret key URI. + /// If the value is a file, the file content is used as URI. + /// If not given, you will be prompted for the URI. + #[structopt(long)] + suri: Option, + + /// Key type, examples: "gran", or "imon" + #[structopt(long)] + key_type: String, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub shared_params: SharedParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + +impl InsertKeyCmd { + /// Run the command + pub fn run(&self, cli: &C) -> Result<(), Error> { + let suri = utils::read_uri(self.suri.as_ref())?; + let base_path = self.shared_params + .base_path() + .unwrap_or_else(|| BasePath::from_project("", "", &C::executable_name())); + let chain_id = self.shared_params.chain_id(self.shared_params.is_dev()); + let chain_spec = cli.load_spec(&chain_id)?; + let config_dir = base_path.config_dir(chain_spec.id()); + + let (keystore, public) = match self.keystore_params.keystore_config(&config_dir)? { + (_, KeystoreConfig::Path { path, password }) => { + let public = with_crypto_scheme!( + self.crypto_scheme.scheme, + to_vec(&suri, password.clone()) + )?; + let keystore: SyncCryptoStorePtr = Arc::new(LocalKeystore::open(path, password)?); + (keystore, public) + }, + _ => unreachable!("keystore_config always returns path and password; qed") + }; + + let key_type = KeyTypeId::try_from(self.key_type.as_str()).map_err(|_| Error::KeyTypeInvalid)?; + + SyncCryptoStore::insert_unknown(&*keystore, key_type, &suri, &public[..]) + .map_err(|_| Error::KeyStoreOperation)?; + + Ok(()) + } +} + +fn to_vec(uri: &str, pass: Option) -> Result, Error> { + let p = utils::pair_from_suri::

(uri, pass)?; + Ok(p.public().as_ref().to_vec()) +} + +#[cfg(test)] +mod tests { + use super::*; + use structopt::StructOpt; + use tempfile::TempDir; + use sp_core::{sr25519::Pair, Pair as _, Public}; + use sc_service::{ChainSpec, GenericChainSpec, ChainType, NoExtension}; + + struct Cli; + + impl SubstrateCli for Cli { + fn impl_name() -> String { + "test".into() + } + + fn impl_version() -> String { + "2.0".into() + } + + fn description() -> String { + "test".into() + } + + fn support_url() -> String { + "test.test".into() + } + + fn copyright_start_year() -> i32 { + 2020 + } + + fn author() -> String { + "test".into() + } + + fn native_runtime_version(_: &Box) -> &'static sp_version::RuntimeVersion { + unimplemented!("Not required in tests") + } + + fn load_spec(&self, _: &str) -> std::result::Result, String> { + Ok( + Box::new( + GenericChainSpec::from_genesis( + "test", + "test_id", + ChainType::Development, + || unimplemented!("Not required in tests"), + Vec::new(), + None, + None, + None, + NoExtension::None, + ), + ), + ) + } + } + + #[test] + fn insert_with_custom_base_path() { + let path = TempDir::new().unwrap(); + let path_str = format!("{}", path.path().display()); + let (key, uri, _) = Pair::generate_with_phrase(None); + + let inspect = InsertKeyCmd::from_iter( + &["insert-key", "-d", &path_str, "--key-type", "test", "--suri", &uri], + ); + assert!(inspect.run(&Cli).is_ok()); + + let keystore = LocalKeystore::open( + path.path().join("chains").join("test_id").join("keystore"), + None, + ).unwrap(); + assert!(keystore.has_keys(&[(key.public().to_raw_vec(), KeyTypeId(*b"test"))])); + } +} diff --git a/client/cli/src/commands/key.rs b/client/cli/src/commands/key.rs index e5bce08145c..d01e273f0ef 100644 --- a/client/cli/src/commands/key.rs +++ b/client/cli/src/commands/key.rs @@ -17,11 +17,11 @@ //! Key related CLI utilities -use crate::Error; +use crate::{Error, SubstrateCli}; use structopt::StructOpt; use super::{ - insert::InsertCmd, + insert_key::InsertKeyCmd, inspect_key::InspectKeyCmd, generate::GenerateCmd, inspect_node_key::InspectNodeKeyCmd, @@ -45,17 +45,17 @@ pub enum KeySubcommand { InspectNodeKey(InspectNodeKeyCmd), /// Insert a key to the keystore of a node. - Insert(InsertCmd), + Insert(InsertKeyCmd), } impl KeySubcommand { /// run the key subcommands - pub fn run(&self) -> Result<(), Error> { + pub fn run(&self, cli: &C) -> Result<(), Error> { match self { KeySubcommand::GenerateNodeKey(cmd) => cmd.run(), KeySubcommand::Generate(cmd) => cmd.run(), KeySubcommand::InspectKey(cmd) => cmd.run(), - KeySubcommand::Insert(cmd) => cmd.run(), + KeySubcommand::Insert(cmd) => cmd.run(cli), KeySubcommand::InspectNodeKey(cmd) => cmd.run(), } } diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index 9867f61cd27..395d3fa9c5e 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -28,7 +28,7 @@ mod revert_cmd; mod run_cmd; mod generate_node_key; mod generate; -mod insert; +mod insert_key; mod inspect_node_key; mod inspect_key; mod key; @@ -43,7 +43,7 @@ pub use self::{ purge_chain_cmd::PurgeChainCmd, sign::SignCmd, generate::GenerateCmd, - insert::InsertCmd, + insert_key::InsertKeyCmd, inspect_key::InspectKeyCmd, generate_node_key::GenerateNodeKeyCmd, inspect_node_key::InspectNodeKeyCmd, diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 4e1ad19fc46..b631b85f377 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -186,11 +186,11 @@ pub trait CliConfiguration: Sized { /// Get the keystore configuration. /// - /// Bu default this is retrieved from `KeystoreParams` if it is available. Otherwise it uses + /// By default this is retrieved from `KeystoreParams` if it is available. Otherwise it uses /// `KeystoreConfig::InMemory`. - fn keystore_config(&self, base_path: &PathBuf) -> Result<(Option, KeystoreConfig)> { + fn keystore_config(&self, config_dir: &PathBuf) -> Result<(Option, KeystoreConfig)> { self.keystore_params() - .map(|x| x.keystore_config(base_path)) + .map(|x| x.keystore_config(config_dir)) .unwrap_or_else(|| Ok((None, KeystoreConfig::InMemory))) } @@ -454,15 +454,11 @@ pub trait CliConfiguration: Sized { ) -> Result { let is_dev = self.is_dev()?; let chain_id = self.chain_id(is_dev)?; - let chain_spec = cli.load_spec(chain_id.as_str())?; + let chain_spec = cli.load_spec(&chain_id)?; let base_path = self .base_path()? .unwrap_or_else(|| BasePath::from_project("", "", &C::executable_name())); - let config_dir = base_path - .path() - .to_path_buf() - .join("chains") - .join(chain_spec.id()); + let config_dir = base_path.config_dir(chain_spec.id()); let net_config_dir = config_dir.join(DEFAULT_NETWORK_CONFIG_PATH); let client_id = C::client_id(); let database_cache_size = self.database_cache_size()?.unwrap_or(128); diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index 5190cae2c2f..6290f071c98 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -59,9 +59,6 @@ pub enum Error { expected: usize, }, - #[error("The base path is missing, please provide one")] - MissingBasePath, - #[error("Unknown key type, must be a known 4-character sequence")] KeyTypeInvalid, diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 80882924bd3..0efd1582aca 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -112,10 +112,7 @@ pub trait SubstrateCli: Sized { /// /// Gets the struct from the command line arguments. Print the /// error message and quit the program in case of failure. - fn from_args() -> Self - where - Self: StructOpt + Sized, - { + fn from_args() -> Self where Self: StructOpt + Sized { ::from_iter(&mut std::env::args_os()) } diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs index f03fafeb965..751c2bb0700 100644 --- a/client/cli/src/params/keystore_params.rs +++ b/client/cli/src/params/keystore_params.rs @@ -18,8 +18,7 @@ use crate::error::Result; use sc_service::config::KeystoreConfig; -use std::fs; -use std::path::PathBuf; +use std::{fs, path::{PathBuf, Path}}; use structopt::StructOpt; use crate::error; use sp_core::crypto::SecretString; @@ -33,6 +32,7 @@ pub struct KeystoreParams { /// Specify custom URIs to connect to for keystore-services #[structopt(long = "keystore-uri")] pub keystore_uri: Option, + /// Specify custom keystore path. #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] pub keystore_path: Option, @@ -64,15 +64,14 @@ pub struct KeystoreParams { /// Parse a sercret string, returning a displayable error. pub fn secret_string_from_str(s: &str) -> std::result::Result { - Ok(std::str::FromStr::from_str(s) - .map_err(|_e| "Could not get SecretString".to_string())?) + std::str::FromStr::from_str(s).map_err(|_| "Could not get SecretString".to_string()) } impl KeystoreParams { /// Get the keystore configuration for the parameters - /// returns a vector of remote-urls and the local Keystore configuration - pub fn keystore_config(&self, base_path: &PathBuf) -> Result<(Option, KeystoreConfig)> { - + /// + /// Returns a vector of remote-urls and the local Keystore configuration + pub fn keystore_config(&self, config_dir: &Path) -> Result<(Option, KeystoreConfig)> { let password = if self.password_interactive { #[cfg(not(target_os = "unknown"))] { @@ -92,7 +91,7 @@ impl KeystoreParams { let path = self .keystore_path .clone() - .unwrap_or_else(|| base_path.join(DEFAULT_KEYSTORE_CONFIG_PATH)); + .unwrap_or_else(|| config_dir.join(DEFAULT_KEYSTORE_CONFIG_PATH)); Ok((self.keystore_uri.clone(), KeystoreConfig::Path { path, password })) } diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index a31e3e1f1e4..98f8bf6d001 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -167,9 +167,7 @@ impl SyncCryptoStore for LocalKeystore { let all_keys = SyncCryptoStore::keys(self, id)? .into_iter() .collect::>(); - Ok(keys.into_iter() - .filter(|key| all_keys.contains(key)) - .collect::>()) + Ok(keys.into_iter().filter(|key| all_keys.contains(key)).collect::>()) } fn sign_with( diff --git a/client/service/src/config.rs b/client/service/src/config.rs index e360e610d49..2b3eff1371c 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -263,6 +263,13 @@ impl BasePath { BasePath::Permanenent(path) => path.as_path(), } } + + /// Returns the configuration directory inside this base path. + /// + /// The path looks like `$base_path/chains/$chain_id` + pub fn config_dir(&self, chain_id: &str) -> PathBuf { + self.path().join("chains").join(chain_id) + } } impl std::convert::From for BasePath { diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 5a7136b8368..12746a07868 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1052,6 +1052,7 @@ impl From for u32 { impl<'a> TryFrom<&'a str> for KeyTypeId { type Error = (); + fn try_from(x: &'a str) -> Result { let b = x.as_bytes(); if b.len() != 4 { -- GitLab From 264cfcf8e199ed049ec4cd56c3abcaf8d6bbc7c6 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Tue, 29 Dec 2020 02:51:17 -0500 Subject: [PATCH 148/163] Lazily evaluate error string (#7802) --- bin/node-template/node/src/chain_spec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index 41f582fb64a..c5451e81f20 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -39,7 +39,7 @@ pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { } pub fn development_config() -> Result { - let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?; + let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name @@ -78,7 +78,7 @@ pub fn development_config() -> Result { } pub fn local_testnet_config() -> Result { - let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?; + let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; Ok(ChainSpec::from_genesis( // Name -- GitLab From f36ae22040a123b90dcb090f78dcafaf14f83304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Tue, 29 Dec 2020 13:58:23 +0100 Subject: [PATCH 149/163] contracts: Change `define_env!` to expect a `Result` for every function (#7762) * Make host functions return TrapReason This avoids the need to manually store any trap reasons to the `Runtime` from the host function. This adds the following benefits: * It properly composes with the upcoming chain extensions * Missing to set a trap value is now a compile error * review: Remove superflous .into() --- frame/contracts/src/lib.rs | 8 + frame/contracts/src/wasm/env_def/macros.rs | 47 +++-- frame/contracts/src/wasm/mod.rs | 4 +- frame/contracts/src/wasm/prepare.rs | 28 +-- frame/contracts/src/wasm/runtime.rs | 215 +++++++++------------ 5 files changed, 146 insertions(+), 156 deletions(-) diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index f0200fbd15f..a3c2c914cb8 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -378,6 +378,14 @@ decl_error! { /// on the call stack. Those actions are contract self destruction and restoration /// of a tombstone. ReentranceDenied, + /// `seal_input` was called twice from the same contract execution context. + InputAlreadyRead, + /// The subject passed to `seal_random` exceeds the limit. + RandomSubjectTooLong, + /// The amount of topics passed to `seal_deposit_events` exceeds the limit. + TooManyTopics, + /// The topics passed to `seal_deposit_events` contains at least one duplicate. + DuplicateTopics, } } diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index cc61deb074b..e49014ed950 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -96,7 +96,7 @@ macro_rules! unmarshall_then_body { #[inline(always)] pub fn constrain_closure(f: F) -> F where - F: FnOnce() -> Result, + F: FnOnce() -> Result, { f } @@ -109,14 +109,20 @@ macro_rules! unmarshall_then_body_then_marshall { >(|| { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); - let r = body()?; + let r = body().map_err(|reason| { + $ctx.set_trap_reason(reason); + sp_sandbox::HostError + })?; return Ok(sp_sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() })) }); ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ let body = $crate::wasm::env_def::macros::constrain_closure::<(), _>(|| { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); - body()?; + body().map_err(|reason| { + $ctx.set_trap_reason(reason); + sp_sandbox::HostError + })?; return Ok(sp_sandbox::ReturnValue::Unit) }) } @@ -207,15 +213,24 @@ mod tests { use parity_wasm::elements::ValueType; use sp_runtime::traits::Zero; use sp_sandbox::{ReturnValue, Value}; - use crate::wasm::tests::MockExt; - use crate::wasm::Runtime; - use crate::exec::Ext; - use crate::gas::Gas; + use crate::{ + wasm::{Runtime, runtime::TrapReason, tests::MockExt}, + exec::Ext, + gas::Gas, + }; + + struct TestRuntime { + value: u32, + } + + impl TestRuntime { + fn set_trap_reason(&mut self, _reason: TrapReason) {} + } #[test] fn macro_unmarshall_then_body_then_marshall_value_or_trap() { fn test_value( - _ctx: &mut u32, + _ctx: &mut TestRuntime, args: &[sp_sandbox::Value], ) -> Result { let mut args = args.iter(); @@ -224,7 +239,7 @@ mod tests { _ctx, (a: u32, b: u32) -> u32 => { if b == 0 { - Err(sp_sandbox::HostError) + Err(crate::wasm::runtime::TrapReason::Termination) } else { Ok(a / b) } @@ -232,7 +247,7 @@ mod tests { ) } - let ctx = &mut 0; + let ctx = &mut TestRuntime { value: 0 }; assert_eq!( test_value(ctx, &[Value::I32(15), Value::I32(3)]).unwrap(), ReturnValue::Value(Value::I32(5)), @@ -243,7 +258,7 @@ mod tests { #[test] fn macro_unmarshall_then_body_then_marshall_unit() { fn test_unit( - ctx: &mut u32, + ctx: &mut TestRuntime, args: &[sp_sandbox::Value], ) -> Result { let mut args = args.iter(); @@ -251,16 +266,16 @@ mod tests { args, ctx, (a: u32, b: u32) => { - *ctx = a + b; + ctx.value = a + b; Ok(()) } ) } - let ctx = &mut 0; + let ctx = &mut TestRuntime { value: 0 }; let result = test_unit(ctx, &[Value::I32(2), Value::I32(3)]).unwrap(); assert_eq!(result, ReturnValue::Unit); - assert_eq!(*ctx, 5); + assert_eq!(ctx.value, 5); } #[test] @@ -270,7 +285,7 @@ mod tests { if !amount.is_zero() { Ok(()) } else { - Err(sp_sandbox::HostError) + Err(TrapReason::Termination) } }); let _f: fn(&mut Runtime, &[sp_sandbox::Value]) @@ -322,7 +337,7 @@ mod tests { if !amount.is_zero() { Ok(()) } else { - Err(sp_sandbox::HostError) + Err(crate::wasm::runtime::TrapReason::Termination) } }, ); diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 7d7668d5ec6..a10e087cde8 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -1537,7 +1537,7 @@ mod tests { &mut gas_meter ), Err(ExecError { - error: Error::::ContractTrapped.into(), + error: Error::::TooManyTopics.into(), origin: ErrorOrigin::Caller, }) ); @@ -1582,7 +1582,7 @@ mod tests { &mut gas_meter ), Err(ExecError { - error: Error::::ContractTrapped.into(), + error: Error::::DuplicateTopics.into(), origin: ErrorOrigin::Caller, }) ); diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 56e21d2ee66..070e68bc475 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -491,18 +491,24 @@ mod tests { } } - // Define test environment for tests. We need ImportSatisfyCheck - // implementation from it. So actual implementations doesn't matter. - define_env!(TestEnv, , - panic(_ctx) => { unreachable!(); }, + /// Using unreachable statements triggers unreachable warnings in the generated code + #[allow(unreachable_code)] + mod env { + use super::*; - // gas is an implementation defined function and a contract can't import it. - gas(_ctx, _amount: u32) => { unreachable!(); }, + // Define test environment for tests. We need ImportSatisfyCheck + // implementation from it. So actual implementations doesn't matter. + define_env!(Test, , + panic(_ctx) => { unreachable!(); }, - nop(_ctx, _unused: u64) => { unreachable!(); }, + // gas is an implementation defined function and a contract can't import it. + gas(_ctx, _amount: u32) => { unreachable!(); }, - seal_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, - ); + nop(_ctx, _unused: u64) => { unreachable!(); }, + + seal_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, + ); + } macro_rules! prepare_test { ($name:ident, $wat:expr, $($expected:tt)*) => { @@ -520,7 +526,7 @@ mod tests { }, .. Default::default() }; - let r = prepare_contract::(wasm.as_ref(), &schedule); + let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, $($expected)*); } }; @@ -931,7 +937,7 @@ mod tests { ).unwrap(); let mut schedule = Schedule::default(); schedule.enable_println = true; - let r = prepare_contract::(wasm.as_ref(), &schedule); + let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, Ok(_)); } } diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index ac1cb1f54d5..c4365e2cb0f 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -90,7 +90,7 @@ impl From for ReturnCode { } /// The data passed through when a contract uses `seal_return`. -struct ReturnData { +pub struct ReturnData { /// The flags as passed through by the contract. They are still unchecked and /// will later be parsed into a `ReturnFlags` bitflags struct. flags: u32, @@ -104,7 +104,7 @@ struct ReturnData { /// occurred (the SupervisorError variant). /// The other case is where the trap does not constitute an error but rather was invoked /// as a quick way to terminate the application (all other variants). -enum TrapReason { +pub enum TrapReason { /// The supervisor trapped the contract because of an error condition occurred during /// execution in privileged code. SupervisorError(DispatchError), @@ -117,9 +117,15 @@ enum TrapReason { Restoration, } +impl> From for TrapReason { + fn from(from: T) -> Self { + Self::SupervisorError(from.into()) + } +} + #[cfg_attr(test, derive(Debug, PartialEq, Eq))] #[derive(Copy, Clone)] -pub enum RuntimeToken { +enum RuntimeToken { /// Charge the gas meter with the cost of a metering block. The charged costs are /// the supplied cost of the block plus the overhead of the metering itself. MeteringBlock(u32), @@ -369,21 +375,25 @@ where } } + /// Store the reason for a host function triggered trap. + /// + /// This is called by the `define_env` macro in order to store any error returned by + /// the host functions defined through the said macro. It should **not** be called + /// manually. + pub fn set_trap_reason(&mut self, reason: TrapReason) { + self.trap_reason = Some(reason); + } + /// Charge the gas meter with the specified token. /// /// Returns `Err(HostError)` if there is not enough gas. - fn charge_gas(&mut self, token: Tok) -> Result<(), sp_sandbox::HostError> + fn charge_gas(&mut self, token: Tok) -> Result<(), DispatchError> where Tok: Token>, { match self.gas_meter.charge(&self.schedule.host_fn_weights, token) { GasMeterResult::Proceed => Ok(()), - GasMeterResult::OutOfGas => { - self.trap_reason = Some( - TrapReason::SupervisorError(Error::::OutOfGas.into()) - ); - Err(sp_sandbox::HostError) - }, + GasMeterResult::OutOfGas => Err(Error::::OutOfGas.into()) } } @@ -392,12 +402,12 @@ where /// Returns `Err` if one of the following conditions occurs: /// /// - requested buffer is not within the bounds of the sandbox memory. - fn read_sandbox_memory(&mut self, ptr: u32, len: u32) - -> Result, sp_sandbox::HostError> + fn read_sandbox_memory(&self, ptr: u32, len: u32) + -> Result, DispatchError> { let mut buf = vec![0u8; len as usize]; self.memory.get(ptr, buf.as_mut_slice()) - .map_err(|_| self.store_err(Error::::OutOfBounds))?; + .map_err(|_| Error::::OutOfBounds)?; Ok(buf) } @@ -406,10 +416,10 @@ where /// Returns `Err` if one of the following conditions occurs: /// /// - requested buffer is not within the bounds of the sandbox memory. - fn read_sandbox_memory_into_buf(&mut self, ptr: u32, buf: &mut [u8]) - -> Result<(), sp_sandbox::HostError> + fn read_sandbox_memory_into_buf(&self, ptr: u32, buf: &mut [u8]) + -> Result<(), DispatchError> { - self.memory.get(ptr, buf).map_err(|_| self.store_err(Error::::OutOfBounds)) + self.memory.get(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) } /// Read designated chunk from the sandbox memory and attempt to decode into the specified type. @@ -418,11 +428,11 @@ where /// /// - requested buffer is not within the bounds of the sandbox memory. /// - the buffer contents cannot be decoded as the required type. - fn read_sandbox_memory_as(&mut self, ptr: u32, len: u32) - -> Result + fn read_sandbox_memory_as(&self, ptr: u32, len: u32) + -> Result { let buf = self.read_sandbox_memory(ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| self.store_err(Error::::DecodingFailed)) + D::decode(&mut &buf[..]).map_err(|_| Error::::DecodingFailed.into()) } /// Write the given buffer to the designated location in the sandbox memory. @@ -430,8 +440,8 @@ where /// Returns `Err` if one of the following conditions occurs: /// /// - designated area is not within the bounds of the sandbox memory. - fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<(), sp_sandbox::HostError> { - self.memory.set(ptr, buf).map_err(|_| self.store_err(Error::::OutOfBounds)) + fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<(), DispatchError> { + self.memory.set(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) } /// Write the given buffer and its length to the designated locations in sandbox memory and @@ -460,7 +470,7 @@ where buf: &[u8], allow_skip: bool, create_token: impl FnOnce(u32) -> Option, - ) -> Result<(), sp_sandbox::HostError> + ) -> Result<(), DispatchError> { if allow_skip && out_ptr == u32::max_value() { return Ok(()); @@ -470,7 +480,7 @@ where let len: u32 = self.read_sandbox_memory_as(out_len_ptr, 4)?; if len < buf_len { - Err(self.store_err(Error::::OutputBufferTooSmall))? + Err(Error::::OutputBufferTooSmall)? } if let Some(token) = create_token(buf_len) { @@ -480,7 +490,7 @@ where self.memory.set(out_ptr, buf).and_then(|_| { self.memory.set(out_len_ptr, &buf_len.encode()) }) - .map_err(|_| self.store_err(Error::::OutOfBounds))?; + .map_err(|_| Error::::OutOfBounds)?; Ok(()) } @@ -503,7 +513,7 @@ where input_ptr: u32, input_len: u32, output_ptr: u32, - ) -> Result<(), sp_sandbox::HostError> + ) -> Result<(), DispatchError> where F: FnOnce(&[u8]) -> R, R: AsRef<[u8]>, @@ -517,48 +527,6 @@ where Ok(()) } - /// Stores a DispatchError returned from an Ext function into the trap_reason. - /// - /// This allows through supervisor generated errors to the caller. - fn store_err(&mut self, err: Error) -> sp_sandbox::HostError - where - Error: Into, - { - self.trap_reason = Some(TrapReason::SupervisorError(err.into())); - sp_sandbox::HostError - } - - /// Used by Runtime API that calls into other contracts. - /// - /// Those need to transform the the `ExecResult` returned from the execution into - /// a `ReturnCode`. If this conversion fails because the `ExecResult` constitutes a - /// a fatal error then this error is stored in the `ExecutionContext` so it can be - /// extracted for display in the UI. - fn map_exec_result(&mut self, result: ExecResult) -> Result { - match Self::exec_into_return_code(result) { - Ok(code) => Ok(code), - Err(err) => Err(self.store_err(err)), - } - } - - /// Try to convert an error into a `ReturnCode`. - /// - /// Used to decide between fatal and non-fatal errors. - fn map_dispatch_result(&mut self, result: Result) - -> Result - { - let err = if let Err(err) = result { - err - } else { - return Ok(ReturnCode::Success) - }; - - match Self::err_into_return_code(err) { - Ok(code) => Ok(code), - Err(err) => Err(self.store_err(err)), - } - } - /// Fallible conversion of `DispatchError` to `ReturnCode`. fn err_into_return_code(from: DispatchError) -> Result { use ReturnCode::*; @@ -638,7 +606,7 @@ define_env!(Env, , seal_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => { ctx.charge_gas(RuntimeToken::SetStorage(value_len))?; if value_len > ctx.ext.max_value_size() { - Err(ctx.store_err(Error::::ValueTooLarge))?; + Err(Error::::ValueTooLarge)?; } let mut key: StorageKey = [0; 32]; ctx.read_sandbox_memory_into_buf(key_ptr, &mut key)?; @@ -715,7 +683,13 @@ define_env!(Env, , ctx.read_sandbox_memory_as(value_ptr, value_len)?; let result = ctx.ext.transfer(&callee, value); - ctx.map_dispatch_result(result) + match result { + Ok(()) => Ok(ReturnCode::Success), + Err(err) => { + let code = Runtime::::err_into_return_code(err)?; + Ok(code) + } + } }, // Make a call to another contract. @@ -797,7 +771,7 @@ define_env!(Env, , Some(RuntimeToken::CallCopyOut(len)) })?; } - ctx.map_exec_result(call_outcome) + Ok(Runtime::::exec_into_return_code(call_outcome)?) }, // Instantiate a contract with the specified code hash. @@ -899,7 +873,7 @@ define_env!(Env, , Some(RuntimeToken::InstantiateCopyOut(len)) })?; } - ctx.map_exec_result(instantiate_outcome.map(|(_id, retval)| retval)) + Ok(Runtime::::exec_into_return_code(instantiate_outcome.map(|(_id, retval)| retval))?) }, // Remove the calling account and transfer remaining balance. @@ -925,10 +899,8 @@ define_env!(Env, , let beneficiary: <::T as frame_system::Config>::AccountId = ctx.read_sandbox_memory_as(beneficiary_ptr, beneficiary_len)?; - if let Ok(_) = ctx.ext.terminate(&beneficiary).map_err(|e| ctx.store_err(e)) { - ctx.trap_reason = Some(TrapReason::Termination); - } - Err(sp_sandbox::HostError) + ctx.ext.terminate(&beneficiary)?; + Err(TrapReason::Termination) }, seal_input(ctx, buf_ptr: u32, buf_len_ptr: u32) => { @@ -936,9 +908,10 @@ define_env!(Env, , if let Some(input) = ctx.input_data.take() { ctx.write_sandbox_output(buf_ptr, buf_len_ptr, &input, false, |len| { Some(RuntimeToken::InputCopyOut(len)) - }) + })?; + Ok(()) } else { - Err(sp_sandbox::HostError) + Err(Error::::InputAlreadyRead.into()) } }, @@ -961,15 +934,10 @@ define_env!(Env, , // Using a reserved bit triggers a trap. seal_return(ctx, flags: u32, data_ptr: u32, data_len: u32) => { ctx.charge_gas(RuntimeToken::Return(data_len))?; - ctx.trap_reason = Some(TrapReason::Return(ReturnData { + Err(TrapReason::Return(ReturnData { flags, data: ctx.read_sandbox_memory(data_ptr, data_len)?, - })); - - // The trap mechanism is used to immediately terminate the execution. - // This trap should be handled appropriately before returning the result - // to the user of this crate. - Err(sp_sandbox::HostError) + })) }, // Stores the address of the caller into the supplied buffer. @@ -984,9 +952,9 @@ define_env!(Env, , // address of the contract will be returned. The value is encoded as T::AccountId. seal_caller(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::Caller)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.caller().encode(), false, already_charged - ) + )?) }, // Stores the address of the current contract into the supplied buffer. @@ -997,9 +965,9 @@ define_env!(Env, , // space at `out_ptr` is less than the size of the value a trap is triggered. seal_address(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::Address)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.address().encode(), false, already_charged - ) + )?) }, // Stores the price for the specified amount of gas into the supplied buffer. @@ -1017,9 +985,9 @@ define_env!(Env, , // gas can be smaller than one. seal_weight_to_fee(ctx, gas: u64, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::WeightToFee)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.get_weight_price(gas).encode(), false, already_charged - ) + )?) }, // Stores the amount of gas left into the supplied buffer. @@ -1032,9 +1000,9 @@ define_env!(Env, , // The data is encoded as Gas. seal_gas_left(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::GasLeft)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.gas_meter.gas_left().encode(), false, already_charged - ) + )?) }, // Stores the balance of the current account into the supplied buffer. @@ -1047,9 +1015,9 @@ define_env!(Env, , // The data is encoded as T::Balance. seal_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::Balance)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.balance().encode(), false, already_charged - ) + )?) }, // Stores the value transferred along with this call or as endowment into the supplied buffer. @@ -1062,9 +1030,9 @@ define_env!(Env, , // The data is encoded as T::Balance. seal_value_transferred(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::ValueTransferred)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.value_transferred().encode(), false, already_charged - ) + )?) }, // Stores a random number for the current block and the given subject into the supplied buffer. @@ -1078,12 +1046,12 @@ define_env!(Env, , seal_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::Random)?; if subject_len > ctx.schedule.limits.subject_len { - return Err(sp_sandbox::HostError); + Err(Error::::RandomSubjectTooLong)?; } let subject_buf = ctx.read_sandbox_memory(subject_ptr, subject_len)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.random(&subject_buf).encode(), false, already_charged - ) + )?) }, // Load the latest block timestamp into the supplied buffer @@ -1094,9 +1062,9 @@ define_env!(Env, , // space at `out_ptr` is less than the size of the value a trap is triggered. seal_now(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::Now)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.now().encode(), false, already_charged - ) + )?) }, // Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer. @@ -1104,9 +1072,9 @@ define_env!(Env, , // The data is encoded as T::Balance. seal_minimum_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::MinimumBalance)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.minimum_balance().encode(), false, already_charged - ) + )?) }, // Stores the tombstone deposit into the supplied buffer. @@ -1126,9 +1094,9 @@ define_env!(Env, , // is commonly referred as subsistence threshold in code. seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::TombstoneDeposit)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false, already_charged - ) + )?) }, // Try to restore the given destination contract sacrificing the caller. @@ -1189,21 +1157,14 @@ define_env!(Env, , delta.push(delta_key); // Offset key_ptr to the next element. - key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or_else(|| sp_sandbox::HostError)?; + key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or(Error::::OutOfBounds)?; } delta }; - if let Ok(()) = ctx.ext.restore_to( - dest, - code_hash, - rent_allowance, - delta, - ).map_err(|e| ctx.store_err(e)) { - ctx.trap_reason = Some(TrapReason::Restoration); - } - Err(sp_sandbox::HostError) + ctx.ext.restore_to(dest, code_hash, rent_allowance, delta)?; + Err(TrapReason::Restoration) }, // Deposit a contract event with the data buffer and optional list of topics. There is a limit @@ -1217,13 +1178,13 @@ define_env!(Env, , seal_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => { let num_topic = topics_len .checked_div(sp_std::mem::size_of::>() as u32) - .ok_or_else(|| ctx.store_err("Zero sized topics are not allowed"))?; + .ok_or_else(|| "Zero sized topics are not allowed")?; ctx.charge_gas(RuntimeToken::DepositEvent { num_topic, len: data_len, })?; if data_len > ctx.ext.max_value_size() { - Err(ctx.store_err(Error::::ValueTooLarge))?; + Err(Error::::ValueTooLarge)?; } let mut topics: Vec::::T>> = match topics_len { @@ -1233,12 +1194,12 @@ define_env!(Env, , // If there are more than `event_topics`, then trap. if topics.len() > ctx.schedule.limits.event_topics as usize { - return Err(sp_sandbox::HostError); + Err(Error::::TooManyTopics)?; } // Check for duplicate topics. If there are any, then trap. if has_duplicates(&mut topics) { - return Err(sp_sandbox::HostError); + Err(Error::::DuplicateTopics)?; } let event_data = ctx.read_sandbox_memory(data_ptr, data_len)?; @@ -1272,9 +1233,9 @@ define_env!(Env, , // The data is encoded as T::Balance. seal_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::RentAllowance)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.rent_allowance().encode(), false, already_charged - ) + )?) }, // Prints utf8 encoded string from the data buffer. @@ -1296,9 +1257,9 @@ define_env!(Env, , // space at `out_ptr` is less than the size of the value a trap is triggered. seal_block_number(ctx, out_ptr: u32, out_len_ptr: u32) => { ctx.charge_gas(RuntimeToken::BlockNumber)?; - ctx.write_sandbox_output( + Ok(ctx.write_sandbox_output( out_ptr, out_len_ptr, &ctx.ext.block_number().encode(), false, already_charged - ) + )?) }, // Computes the SHA2 256-bit hash on the given input buffer. @@ -1323,7 +1284,7 @@ define_env!(Env, , // directly into this buffer. seal_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { ctx.charge_gas(RuntimeToken::HashSha256(input_len))?; - ctx.compute_hash_on_intermediate_buffer(sha2_256, input_ptr, input_len, output_ptr) + Ok(ctx.compute_hash_on_intermediate_buffer(sha2_256, input_ptr, input_len, output_ptr)?) }, // Computes the KECCAK 256-bit hash on the given input buffer. @@ -1348,7 +1309,7 @@ define_env!(Env, , // directly into this buffer. seal_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { ctx.charge_gas(RuntimeToken::HashKeccak256(input_len))?; - ctx.compute_hash_on_intermediate_buffer(keccak_256, input_ptr, input_len, output_ptr) + Ok(ctx.compute_hash_on_intermediate_buffer(keccak_256, input_ptr, input_len, output_ptr)?) }, // Computes the BLAKE2 256-bit hash on the given input buffer. @@ -1373,7 +1334,7 @@ define_env!(Env, , // directly into this buffer. seal_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { ctx.charge_gas(RuntimeToken::HashBlake256(input_len))?; - ctx.compute_hash_on_intermediate_buffer(blake2_256, input_ptr, input_len, output_ptr) + Ok(ctx.compute_hash_on_intermediate_buffer(blake2_256, input_ptr, input_len, output_ptr)?) }, // Computes the BLAKE2 128-bit hash on the given input buffer. @@ -1398,6 +1359,6 @@ define_env!(Env, , // directly into this buffer. seal_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { ctx.charge_gas(RuntimeToken::HashBlake128(input_len))?; - ctx.compute_hash_on_intermediate_buffer(blake2_128, input_ptr, input_len, output_ptr) + Ok(ctx.compute_hash_on_intermediate_buffer(blake2_128, input_ptr, input_len, output_ptr)?) }, ); -- GitLab From 7c9f9a5a2772565056943552a18088e3772a05c8 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Tue, 29 Dec 2020 14:39:04 +0100 Subject: [PATCH 150/163] Hex Balance deserialize for contracts_call RPC (#7807) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Hex Balance deserialize for contracts_call RPC * Avoid temporary conversion into u128 Co-authored-by: Alexander Theißen --- frame/contracts/rpc/src/lib.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index 6d43ea75c03..a44ba769e96 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -33,7 +33,7 @@ use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, DispatchError, }; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use pallet_contracts_primitives::ContractExecResult; pub use pallet_contracts_rpc_runtime_api::ContractsApi as ContractsRuntimeApi; @@ -76,10 +76,10 @@ impl From for Error { #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] -pub struct CallRequest { +pub struct CallRequest { origin: AccountId, dest: AccountId, - value: Balance, + value: number::NumberOrHex, gas_limit: number::NumberOrHex, input_data: Bytes, } @@ -141,7 +141,7 @@ pub trait ContractsApi { #[rpc(name = "contracts_call")] fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option, ) -> Result; @@ -201,11 +201,11 @@ where <::Header as HeaderT>::Number, >, AccountId: Codec, - Balance: Codec, + Balance: Codec + TryFrom, { fn call( &self, - call_request: CallRequest, + call_request: CallRequest, at: Option<::Hash>, ) -> Result { let api = self.client.runtime_api(); @@ -221,6 +221,13 @@ where input_data, } = call_request; + // Make sure that value fits into the balance type. + let value: Balance = value.try_into().map_err(|_| Error { + code: ErrorCode::InvalidParams, + message: format!("{:?} doesn't fit into the balance type", value), + data: None, + })?; + // Make sure that gas_limit fits into 64 bits. let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error { code: ErrorCode::InvalidParams, @@ -305,17 +312,18 @@ mod tests { #[test] fn call_request_should_serialize_deserialize_properly() { - type Req = CallRequest; + type Req = CallRequest; let req: Req = serde_json::from_str(r#" { "origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", "dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom", - "value": 0, + "value": "0x112210f4B16c1cb1", "gasLimit": 1000000000000, "inputData": "0x8c97db39" } "#).unwrap(); assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64)); + assert_eq!(req.value.into_u256(), U256::from(1234567890987654321u128)); } #[test] -- GitLab From 5d5a3b8b96643fa6b5ce2acb9639fe3ce8f82d65 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 29 Dec 2020 13:31:44 -0400 Subject: [PATCH 151/163] Don't allow self proxies (#7803) --- frame/proxy/src/lib.rs | 3 +++ frame/proxy/src/tests.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 6342f0c052b..93f1d8e80d5 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -168,6 +168,8 @@ decl_error! { NoPermission, /// Announcement, if made at all, was made too recently. Unannounced, + /// Cannot add self as proxy. + NoSelfProxy, } } @@ -567,6 +569,7 @@ impl Module { proxy_type: T::ProxyType, delay: T::BlockNumber, ) -> DispatchResult { + ensure!(delegator != &delegatee, Error::::NoSelfProxy); Proxies::::try_mutate(delegator, |(ref mut proxies, ref mut deposit)| { ensure!(proxies.len() < T::MaxProxies::get() as usize, Error::::TooMany); let proxy_def = ProxyDefinition { delegate: delegatee, proxy_type, delay }; diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index 08211052356..b1dca43b6a7 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -396,6 +396,7 @@ fn add_remove_proxies_works() { assert_eq!(Balances::reserved_balance(1), 2); assert_ok!(Proxy::remove_proxy(Origin::signed(1), 2, ProxyType::JustTransfer, 0)); assert_eq!(Balances::reserved_balance(1), 0); + assert_noop!(Proxy::add_proxy(Origin::signed(1), 1, ProxyType::Any, 0), Error::::NoSelfProxy); }); } -- GitLab From f1d8be84f443b9c6198d8c788118e30ef6e2a646 Mon Sep 17 00:00:00 2001 From: RK Date: Wed, 30 Dec 2020 00:07:19 +0530 Subject: [PATCH 152/163] Allow council to slash treasury tip (#7753) * wk2051 | D4 |Allow council to slash treasury tip | p1 * Update frame/tips/src/lib.rs Co-authored-by: Xiliang Chen * wk2051 | D5 |Allow council to slash treasury tip | p2 * wk2051 | D5 |Allow council to slash treasury tip | p3 * wk2051 | D5 |Allow council to slash treasury tip | p4 * wk2051 | D5 |Allow council to slash treasury tip | p5 * random change * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_tips --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/tips/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix typo * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/tests.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * wk2052 | D1 | Allow council to slash treasury tip | p6 Co-authored-by: Xiliang Chen Co-authored-by: Shawn Tabrizi Co-authored-by: Parity Benchmarking Bot Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/bounties/src/benchmarking.rs | 20 +++++------ frame/tips/README.md | 1 + frame/tips/src/benchmarking.rs | 26 ++++++++++++-- frame/tips/src/lib.rs | 56 ++++++++++++++++-------------- frame/tips/src/tests.rs | 38 +++++++++++++++++--- frame/tips/src/weights.rs | 51 +++++++++++++++++---------- frame/treasury/src/benchmarking.rs | 4 +-- 7 files changed, 133 insertions(+), 63 deletions(-) diff --git a/frame/bounties/src/benchmarking.rs b/frame/bounties/src/benchmarking.rs index 5a323ff0aaf..21f68b07819 100644 --- a/frame/bounties/src/benchmarking.rs +++ b/frame/bounties/src/benchmarking.rs @@ -77,7 +77,7 @@ fn create_bounty() -> Result<( Ok((curator_lookup, bounty_id)) } -fn setup_pod_account() { +fn setup_pot_account() { let pot_account = Bounties::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); @@ -109,7 +109,7 @@ benchmarks! { }: _(RawOrigin::Root, bounty_id) propose_curator { - setup_pod_account::(); + setup_pot_account::(); let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); let curator_lookup = T::Lookup::unlookup(curator.clone()); Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; @@ -120,7 +120,7 @@ benchmarks! { // Worst case when curator is inactive and any sender unassigns the curator. unassign_curator { - setup_pod_account::(); + setup_pot_account::(); let (curator_lookup, bounty_id) = create_bounty::()?; Bounties::::on_initialize(T::BlockNumber::zero()); let bounty_id = BountyCount::get() - 1; @@ -129,7 +129,7 @@ benchmarks! { }: _(RawOrigin::Signed(caller), bounty_id) accept_curator { - setup_pod_account::(); + setup_pot_account::(); let (caller, curator, fee, value, reason) = setup_bounty::(0, MAX_BYTES); let curator_lookup = T::Lookup::unlookup(curator.clone()); Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; @@ -140,7 +140,7 @@ benchmarks! { }: _(RawOrigin::Signed(curator), bounty_id) award_bounty { - setup_pod_account::(); + setup_pot_account::(); let (curator_lookup, bounty_id) = create_bounty::()?; Bounties::::on_initialize(T::BlockNumber::zero()); @@ -150,7 +150,7 @@ benchmarks! { }: _(RawOrigin::Signed(curator), bounty_id, beneficiary) claim_bounty { - setup_pod_account::(); + setup_pot_account::(); let (curator_lookup, bounty_id) = create_bounty::()?; Bounties::::on_initialize(T::BlockNumber::zero()); @@ -170,14 +170,14 @@ benchmarks! { } close_bounty_proposed { - setup_pod_account::(); + setup_pot_account::(); let (caller, curator, fee, value, reason) = setup_bounty::(0, 0); Bounties::::propose_bounty(RawOrigin::Signed(caller).into(), value, reason)?; let bounty_id = BountyCount::get() - 1; }: close_bounty(RawOrigin::Root, bounty_id) close_bounty_active { - setup_pod_account::(); + setup_pot_account::(); let (curator_lookup, bounty_id) = create_bounty::()?; Bounties::::on_initialize(T::BlockNumber::zero()); let bounty_id = BountyCount::get() - 1; @@ -187,7 +187,7 @@ benchmarks! { } extend_bounty_expiry { - setup_pod_account::(); + setup_pot_account::(); let (curator_lookup, bounty_id) = create_bounty::()?; Bounties::::on_initialize(T::BlockNumber::zero()); @@ -200,7 +200,7 @@ benchmarks! { spend_funds { let b in 1 .. 100; - setup_pod_account::(); + setup_pot_account::(); create_approved_bounties::(b)?; let mut budget_remaining = BalanceOf::::max_value(); diff --git a/frame/tips/README.md b/frame/tips/README.md index 457e5b3bd0e..36148e276ed 100644 --- a/frame/tips/README.md +++ b/frame/tips/README.md @@ -30,3 +30,4 @@ any finders fee, in case of a public (and bonded) original report. - `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. - `tip` - Declare or redeclare an amount to tip for a particular reason. - `close_tip` - Close and pay out a tip. +- `slash_tip` - Remove and slash an already-open tip. \ No newline at end of file diff --git a/frame/tips/src/benchmarking.rs b/frame/tips/src/benchmarking.rs index 71f9002b9bf..4f0338b9c5d 100644 --- a/frame/tips/src/benchmarking.rs +++ b/frame/tips/src/benchmarking.rs @@ -79,7 +79,7 @@ fn create_tips(t: u32, hash: T::Hash, value: BalanceOf) -> Ok(()) } -fn setup_pod_account() { +fn setup_pot_account() { let pot_account = TipsMod::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); @@ -148,7 +148,7 @@ benchmarks! { let t in 1 .. MAX_TIPPERS; // Make sure pot is funded - setup_pod_account::(); + setup_pot_account::(); // Set up a new tip proposal let (member, reason, beneficiary, value) = setup_tip::(0, t)?; @@ -164,6 +164,7 @@ benchmarks! { let reason_hash = T::Hashing::hash(&reason[..]); let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); ensure!(Tips::::contains_key(hash), "tip does not exist"); + create_tips::(t, hash.clone(), value)?; let caller = account("caller", t, SEED); @@ -172,6 +173,26 @@ benchmarks! { frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), hash) + slash_tip { + let t in 1 .. MAX_TIPPERS; + + // Make sure pot is funded + setup_pot_account::(); + + // Set up a new tip proposal + let (member, reason, beneficiary, value) = setup_tip::(0, t)?; + let value = T::Currency::minimum_balance().saturating_mul(100u32.into()); + TipsMod::::tip_new( + RawOrigin::Signed(member).into(), + reason.clone(), + beneficiary.clone(), + value + )?; + + let reason_hash = T::Hashing::hash(&reason[..]); + let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); + ensure!(Tips::::contains_key(hash), "tip does not exist"); + }: _(RawOrigin::Root, hash) } #[cfg(test)] @@ -188,6 +209,7 @@ mod tests { assert_ok!(test_benchmark_tip_new::()); assert_ok!(test_benchmark_tip::()); assert_ok!(test_benchmark_close_tip::()); + assert_ok!(test_benchmark_slash_tip::()); }); } } diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs index 3507b220d5d..eaa785a5638 100644 --- a/frame/tips/src/lib.rs +++ b/frame/tips/src/lib.rs @@ -58,8 +58,6 @@ mod tests; mod benchmarking; pub mod weights; -use sp_std::if_std; - use sp_std::prelude::*; use frame_support::{decl_module, decl_storage, decl_event, ensure, decl_error, Parameter}; use frame_support::traits::{ @@ -70,8 +68,7 @@ use frame_support::traits::{ use sp_runtime::{ Percent, RuntimeDebug, traits::{ Zero, AccountIdConversion, Hash, BadOrigin }}; - -use frame_support::traits::{Contains, ContainsLengthBound}; +use frame_support::traits::{Contains, ContainsLengthBound, OnUnbalanced, EnsureOrigin}; use codec::{Encode, Decode}; use frame_system::{self as system, ensure_signed}; pub use weights::WeightInfo; @@ -170,6 +167,8 @@ decl_event!( TipClosed(Hash, AccountId, Balance), /// A tip suggestion has been retracted. \[tip_hash\] TipRetracted(Hash), + /// A tip suggestion has been slashed. \[tip_hash, finder, deposit\] + TipSlashed(Hash, AccountId, Balance), } ); @@ -408,6 +407,32 @@ decl_module! { Tips::::remove(hash); Self::payout_tip(hash, tip); } + + /// Remove and slash an already-open tip. + /// + /// May only be called from `T::RejectOrigin`. + /// + /// As a result, the finder is slashed and the deposits are lost. + /// + /// Emits `TipSlashed` if successful. + /// + /// # + /// `T` is charged as upper bound given by `ContainsLengthBound`. + /// The actual cost depends on the implementation of `T::Tippers`. + /// # + #[weight = ::WeightInfo::slash_tip(T::Tippers::max_len() as u32)] + fn slash_tip(origin, hash: T::Hash) { + T::RejectOrigin::ensure_origin(origin)?; + + let tip = Tips::::take(hash).ok_or(Error::::UnknownTip)?; + + if !tip.deposit.is_zero() { + let imbalance = T::Currency::slash_reserved(&tip.finder, tip.deposit).0; + T::OnSlash::on_unbalanced(imbalance); + } + Reasons::::remove(&tip.reason); + Self::deposit_event(RawEvent::TipSlashed(hash, tip.finder, tip.deposit)); + } } } @@ -523,10 +548,6 @@ impl Module { use frame_support::{Twox64Concat, migration::StorageKeyIterator}; - if_std! { - println!("Inside migrate_retract_tip_for_tip_new()!"); - } - for (hash, old_tip) in StorageKeyIterator::< T::Hash, OldOpenTip, T::BlockNumber, T::Hash>, @@ -534,25 +555,11 @@ impl Module { >::new(b"Treasury", b"Tips").drain() { - if_std! { - println!("Inside loop migrate_retract_tip_for_tip_new()!"); - } - let (finder, deposit, finders_fee) = match old_tip.finder { Some((finder, deposit)) => { - if_std! { - // This code is only being compiled and executed when the `std` feature is enabled. - println!("OK case!"); - println!("value is: {:#?},{:#?}", finder, deposit); - } (finder, deposit, true) }, None => { - if_std! { - // This code is only being compiled and executed when the `std` feature is enabled. - println!("None case!"); - // println!("value is: {:#?},{:#?}", T::AccountId::default(), Zero::zero()); - } (T::AccountId::default(), Zero::zero(), false) }, }; @@ -567,10 +574,5 @@ impl Module { }; Tips::::insert(hash, new_tip) } - - if_std! { - println!("Exit migrate_retract_tip_for_tip_new()!"); - } - } } diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index e6f9cd4e66b..3bfecafeaf9 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -286,6 +286,40 @@ fn close_tip_works() { }); } +#[test] +fn slash_tip_works() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_eq!(Treasury::pot(), 100); + + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 100); + + assert_ok!(TipsModTestInst::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); + + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); + + let h = tip_hash(); + assert_eq!(last_event(), RawEvent::NewTip(h)); + + // can't remove from any origin + assert_noop!( + TipsModTestInst::slash_tip(Origin::signed(0), h.clone()), + BadOrigin, + ); + + // can remove from root. + assert_ok!(TipsModTestInst::slash_tip(Origin::root(), h.clone())); + assert_eq!(last_event(), RawEvent::TipSlashed(h, 0, 12)); + + // tipper slashed + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 88); + }); +} + #[test] fn retract_tip_works() { new_test_ext().execute_with(|| { @@ -409,12 +443,8 @@ fn test_last_reward_migration() { s.top = data.into_iter().collect(); - println!("Executing the test!"); - sp_io::TestExternalities::new(s).execute_with(|| { - println!("Calling migrate_retract_tip_for_tip_new()!"); - TipsModTestInst::migrate_retract_tip_for_tip_new(); // Test w/ finder diff --git a/frame/tips/src/weights.rs b/frame/tips/src/weights.rs index ad2d3104caf..c1d99829100 100644 --- a/frame/tips/src/weights.rs +++ b/frame/tips/src/weights.rs @@ -18,11 +18,11 @@ //! Autogenerated weights for pallet_tips //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-12-16, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2020-12-20, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: -// ./target/release/substrate +// target/release/substrate // benchmark // --chain=dev // --steps=50 @@ -49,83 +49,98 @@ pub trait WeightInfo { fn tip_new(r: u32, t: u32, ) -> Weight; fn tip(t: u32, ) -> Weight; fn close_tip(t: u32, ) -> Weight; + fn slash_tip(t: u32, ) -> Weight; } /// Weights for pallet_tips using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { fn report_awesome(r: u32, ) -> Weight { - (74_814_000 as Weight) + (73_795_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn retract_tip() -> Weight { - (62_962_000 as Weight) + (61_753_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn tip_new(r: u32, t: u32, ) -> Weight { - (48_132_000 as Weight) + (47_731_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) // Standard Error: 0 - .saturating_add((155_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((154_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn tip(t: u32, ) -> Weight { - (36_168_000 as Weight) + (35_215_000 as Weight) // Standard Error: 1_000 - .saturating_add((695_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((712_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn close_tip(t: u32, ) -> Weight { - (119_313_000 as Weight) + (117_027_000 as Weight) // Standard Error: 1_000 - .saturating_add((372_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((375_000 as Weight).saturating_mul(t as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + fn slash_tip(t: u32, ) -> Weight { + (37_184_000 as Weight) + // Standard Error: 0 + .saturating_add((11_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } } // For backwards compatibility and tests impl WeightInfo for () { fn report_awesome(r: u32, ) -> Weight { - (74_814_000 as Weight) + (73_795_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn retract_tip() -> Weight { - (62_962_000 as Weight) + (61_753_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn tip_new(r: u32, t: u32, ) -> Weight { - (48_132_000 as Weight) + (47_731_000 as Weight) // Standard Error: 0 .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) // Standard Error: 0 - .saturating_add((155_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((154_000 as Weight).saturating_mul(t as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn tip(t: u32, ) -> Weight { - (36_168_000 as Weight) + (35_215_000 as Weight) // Standard Error: 1_000 - .saturating_add((695_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((712_000 as Weight).saturating_mul(t as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn close_tip(t: u32, ) -> Weight { - (119_313_000 as Weight) + (117_027_000 as Weight) // Standard Error: 1_000 - .saturating_add((372_000 as Weight).saturating_mul(t as Weight)) + .saturating_add((375_000 as Weight).saturating_mul(t as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + fn slash_tip(t: u32, ) -> Weight { + (37_184_000 as Weight) + // Standard Error: 0 + .saturating_add((11_000 as Weight).saturating_mul(t as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } } diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 16ed1b01ae0..39b398ab891 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -59,7 +59,7 @@ fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &' Ok(()) } -fn setup_pod_account, I: Instance>() { +fn setup_pot_account, I: Instance>() { let pot_account = Treasury::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); @@ -97,7 +97,7 @@ benchmarks_instance! { on_initialize_proposals { let p in 0 .. 100; - setup_pod_account::(); + setup_pot_account::(); create_approved_proposals::(p)?; }: { Treasury::::on_initialize(T::BlockNumber::zero()); -- GitLab From 6abbbd639d07f041255fb326491fea27ece8a490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 30 Dec 2020 00:08:58 +0100 Subject: [PATCH 153/163] Add CLI argument to disable log color output (#7795) --- client/cli/src/config.rs | 15 ++++-- client/cli/src/lib.rs | 66 ++++++++++++++++++-------- client/cli/src/params/shared_params.rs | 9 ++++ client/rpc/src/system/tests.rs | 8 ++-- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index b631b85f377..f0eb84f853b 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -22,7 +22,7 @@ use crate::arg_enums::Database; use crate::error::Result; use crate::{ init_logger, DatabaseParams, ImportParams, KeystoreParams, NetworkParams, NodeKeyParams, - OffchainWorkerParams, PruningParams, SharedParams, SubstrateCli, + OffchainWorkerParams, PruningParams, SharedParams, SubstrateCli, InitLoggerParams, }; use log::warn; use names::{Generator, Name}; @@ -538,6 +538,11 @@ pub trait CliConfiguration: Sized { Ok(self.shared_params().is_log_filter_reloading_disabled()) } + /// Should the log color output be disabled? + fn disable_log_color(&self) -> Result { + Ok(self.shared_params().disable_log_color()) + } + /// Initialize substrate. This must be done only once per process. /// /// This method: @@ -550,15 +555,17 @@ pub trait CliConfiguration: Sized { let tracing_receiver = self.tracing_receiver()?; let tracing_targets = self.tracing_targets()?; let disable_log_reloading = self.is_log_filter_reloading_disabled()?; + let disable_log_color = self.disable_log_color()?; sp_panic_handler::set(&C::support_url(), &C::impl_version()); - init_logger( - &logger_pattern, + init_logger(InitLoggerParams { + pattern: logger_pattern, tracing_receiver, tracing_targets, disable_log_reloading, - )?; + disable_log_color, + })?; if let Some(new_limit) = fdlimit::raise_fd_limit() { if new_limit < RECOMMENDED_OPEN_FILE_DESCRIPTOR_LIMIT { diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 0efd1582aca..0ab26e60647 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -237,30 +237,50 @@ pub trait SubstrateCli: Sized { fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion; } +/// The parameters for [`init_logger`]. +#[derive(Default)] +pub struct InitLoggerParams { + /// A comma seperated list of logging patterns. + /// + /// E.g.: `test-crate=debug` + pub pattern: String, + /// The tracing receiver. + pub tracing_receiver: sc_tracing::TracingReceiver, + /// Optional comma seperated list of tracing targets. + pub tracing_targets: Option, + /// Should log reloading be disabled? + pub disable_log_reloading: bool, + /// Should the log color output be disabled? + pub disable_log_color: bool, +} + /// Initialize the global logger /// /// This sets various global logging and tracing instances and thus may only be called once. pub fn init_logger( - pattern: &str, - tracing_receiver: sc_tracing::TracingReceiver, - profiling_targets: Option, - disable_log_reloading: bool, + InitLoggerParams { + pattern, + tracing_receiver, + tracing_targets, + disable_log_reloading, + disable_log_color, + }: InitLoggerParams, ) -> std::result::Result<(), String> { use sc_tracing::parse_default_directive; // Accept all valid directives and print invalid ones - fn parse_user_directives(mut env_filter: EnvFilter, dirs: &str) -> std::result::Result { + fn parse_user_directives( + mut env_filter: EnvFilter, + dirs: &str, + ) -> std::result::Result { for dir in dirs.split(',') { env_filter = env_filter.add_directive(parse_default_directive(&dir)?); } Ok(env_filter) } - if let Err(e) = tracing_log::LogTracer::init() { - return Err(format!( - "Registering Substrate logger failed: {:}!", e - )) - } + tracing_log::LogTracer::init() + .map_err(|e| format!("Registering Substrate logger failed: {:}!", e))?; // Initialize filter - ensure to use `parse_default_directive` for any defaults to persist // after log filter reloading by RPC @@ -290,7 +310,7 @@ pub fn init_logger( if pattern != "" { // We're not sure if log or tracing is available at this moment, so silently ignore the // parse error. - env_filter = parse_user_directives(env_filter, pattern)?; + env_filter = parse_user_directives(env_filter, &pattern)?; } // If we're only logging `INFO` entries then we'll use a simplified logging format. @@ -308,11 +328,11 @@ pub fn init_logger( ); // Make sure to include profiling targets in the filter - if let Some(profiling_targets) = profiling_targets.clone() { - env_filter = parse_user_directives(env_filter, &profiling_targets)?; + if let Some(tracing_targets) = tracing_targets.clone() { + env_filter = parse_user_directives(env_filter, &tracing_targets)?; } - let enable_color = atty::is(atty::Stream::Stderr); + let enable_color = atty::is(atty::Stream::Stderr) && !disable_log_color; let timer = ChronoLocal::with_format(if simple { "%Y-%m-%d %H:%M:%S".to_string() } else { @@ -333,7 +353,7 @@ pub fn init_logger( let subscriber = subscriber_builder .finish() .with(logging::NodeNameLayer); - initialize_tracing(subscriber, tracing_receiver, profiling_targets) + initialize_tracing(subscriber, tracing_receiver, tracing_targets) } else { let subscriber_builder = subscriber_builder.with_filter_reloading(); let handle = subscriber_builder.reload_handle(); @@ -341,7 +361,7 @@ pub fn init_logger( let subscriber = subscriber_builder .finish() .with(logging::NodeNameLayer); - initialize_tracing(subscriber, tracing_receiver, profiling_targets) + initialize_tracing(subscriber, tracing_receiver, tracing_targets) } } @@ -380,7 +400,9 @@ mod tests { #[test] fn test_logger_filters() { let test_pattern = "afg=debug,sync=trace,client=warn,telemetry,something-with-dash=error"; - init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); + init_logger( + InitLoggerParams { pattern: test_pattern.into(), ..Default::default() }, + ).unwrap(); tracing::dispatcher::get_default(|dispatcher| { let test_filter = |target, level| { @@ -439,7 +461,9 @@ mod tests { fn log_something_with_dash_target_name() { if env::var("ENABLE_LOGGING").is_ok() { let test_pattern = "test-target=info"; - init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); + init_logger( + InitLoggerParams { pattern: test_pattern.into(), ..Default::default() }, + ).unwrap(); log::info!(target: "test-target", "{}", EXPECTED_LOG_MESSAGE); } @@ -475,7 +499,9 @@ mod tests { fn prefix_in_log_lines_entrypoint() { if env::var("ENABLE_LOGGING").is_ok() { let test_pattern = "test-target=info"; - init_logger(&test_pattern, Default::default(), Default::default(), false).unwrap(); + init_logger( + InitLoggerParams { pattern: test_pattern.into(), ..Default::default() }, + ).unwrap(); prefix_in_log_lines_process(); } } @@ -491,7 +517,7 @@ mod tests { #[test] fn do_not_write_with_colors_on_tty_entrypoint() { if env::var("ENABLE_LOGGING").is_ok() { - init_logger("", Default::default(), Default::default(), false).unwrap(); + init_logger(InitLoggerParams::default()).unwrap(); log::info!("{}", ansi_term::Colour::Yellow.paint(EXPECTED_LOG_MESSAGE)); } } diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index 52b1488ea9c..13e24938482 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -46,6 +46,10 @@ pub struct SharedParams { #[structopt(short = "l", long, value_name = "LOG_PATTERN")] pub log: Vec, + /// Disable log color output. + #[structopt(long)] + pub disable_log_color: bool, + /// Disable feature to dynamically update and reload the log filter. /// /// By default this feature is enabled, however it leads to a small performance decrease. @@ -99,6 +103,11 @@ impl SharedParams { &self.log } + /// Should the log color output be disabled? + pub fn disable_log_color(&self) -> bool { + self.disable_log_color + } + /// Is log reloading disabled pub fn is_log_filter_reloading_disabled(&self) -> bool { self.disable_log_reloading diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index fa3574e9dae..f6463c2fc77 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -344,13 +344,15 @@ fn test_add_reset_log_filter() { // Enter log generation / filter reload if std::env::var("TEST_LOG_FILTER").is_ok() { - sc_cli::init_logger("test_before_add=debug", Default::default(), Default::default(), false).unwrap(); + sc_cli::init_logger( + sc_cli::InitLoggerParams { pattern: "test_before_add=debug".into(), ..Default::default() }, + ).unwrap(); for line in std::io::stdin().lock().lines() { let line = line.expect("Failed to read bytes"); if line.contains("add_reload") { - assert!(api(None).system_add_log_filter("test_after_add".to_owned()).is_ok(), "`system_add_log_filter` failed"); + api(None).system_add_log_filter("test_after_add".into()).expect("`system_add_log_filter` failed"); } else if line.contains("reset") { - assert!(api(None).system_reset_log_filter().is_ok(), "`system_reset_log_filter` failed"); + api(None).system_reset_log_filter().expect("`system_reset_log_filter` failed"); } else if line.contains("exit") { return; } -- GitLab From 67c8cadb33313ef317a4266edb334b7fc594629c Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 30 Dec 2020 06:31:29 -0400 Subject: [PATCH 154/163] Use path instead of ident (#7809) --- frame/benchmarking/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 6296c000e28..c963642fabb 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -1072,7 +1072,7 @@ macro_rules! impl_benchmark_test { #[macro_export] macro_rules! add_benchmark { - ( $params:ident, $batches:ident, $name:ident, $( $location:tt )* ) => ( + ( $params:ident, $batches:ident, $name:path, $( $location:tt )* ) => ( let name_string = stringify!($name).as_bytes(); let instance_string = stringify!( $( $location )* ).as_bytes(); let (config, whitelist) = $params; -- GitLab From b44221489f0c491e2b1d797a9c7f65ef6f045ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 30 Dec 2020 14:33:05 +0100 Subject: [PATCH 155/163] Add proper `commit_all` to `TestExternalities` (#7808) * Add proper `commit_all` to `TestExternalities` This pr adds a propoer `commit_all` function to `TestExternalities` to commit all changes from the overlay to the internal backend. Besides that it fixes some bugs with handling empty dbs when calculating a delta storage root. It also changes the way data is added to the in memory backend. * Update primitives/state-machine/src/testing.rs Co-authored-by: cheme * Don't allow self proxies (#7803) * Allow council to slash treasury tip (#7753) * wk2051 | D4 |Allow council to slash treasury tip | p1 * Update frame/tips/src/lib.rs Co-authored-by: Xiliang Chen * wk2051 | D5 |Allow council to slash treasury tip | p2 * wk2051 | D5 |Allow council to slash treasury tip | p3 * wk2051 | D5 |Allow council to slash treasury tip | p4 * wk2051 | D5 |Allow council to slash treasury tip | p5 * random change * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_tips --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/tips/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix typo * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/tips/src/tests.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * wk2052 | D1 | Allow council to slash treasury tip | p6 Co-authored-by: Xiliang Chen Co-authored-by: Shawn Tabrizi Co-authored-by: Parity Benchmarking Bot Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Review feedback * Review feedback * Update docs * More docs * Make it private * Use `None` * Use apply transaction * Update primitives/state-machine/src/testing.rs Co-authored-by: cheme Co-authored-by: Shawn Tabrizi Co-authored-by: RK Co-authored-by: Xiliang Chen Co-authored-by: Parity Benchmarking Bot Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Guillaume Thiolliere --- .../state-machine/src/in_memory_backend.rs | 99 +++++++------------ primitives/state-machine/src/testing.rs | 69 ++++++++++++- primitives/trie/src/lib.rs | 10 +- 3 files changed, 106 insertions(+), 72 deletions(-) diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index f211f602027..ca300aec919 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -17,56 +17,21 @@ //! State machine in memory backend. use crate::{ - StorageKey, StorageValue, StorageCollection, - trie_backend::TrieBackend, + StorageKey, StorageValue, StorageCollection, trie_backend::TrieBackend, backend::Backend, }; -use std::{collections::{BTreeMap, HashMap}}; +use std::collections::{BTreeMap, HashMap}; use hash_db::Hasher; -use sp_trie::{ - MemoryDB, TrieMut, - trie_types::TrieDBMut, -}; +use sp_trie::{MemoryDB, empty_trie_root, Layout}; use codec::Codec; use sp_core::storage::{ChildInfo, Storage}; -/// Insert input pairs into memory db. -fn insert_into_memory_db(mut root: H::Out, mdb: &mut MemoryDB, input: I) -> H::Out -where - H: Hasher, - I: IntoIterator)>, -{ - { - let mut trie = if root == Default::default() { - TrieDBMut::::new(mdb, &mut root) - } else { - TrieDBMut::::from_existing(mdb, &mut root).unwrap() - }; - for (key, value) in input { - if let Err(e) = match value { - Some(value) => { - trie.insert(&key, &value) - }, - None => { - trie.remove(&key) - }, - } { - panic!("Failed to write to trie: {}", e); - } - } - trie.commit(); - } - root -} - /// Create a new empty instance of in-memory backend. pub fn new_in_mem() -> TrieBackend, H> where H::Out: Codec + Ord, { let db = MemoryDB::default(); - let mut backend = TrieBackend::new(db, Default::default()); - backend.insert(std::iter::empty()); - backend + TrieBackend::new(db, empty_trie_root::>()) } impl TrieBackend, H> @@ -92,32 +57,16 @@ where &mut self, changes: T, ) { - let mut new_child_roots = Vec::new(); - let mut root_map = None; - let root = self.root().clone(); - for (child_info, map) in changes { - if let Some(child_info) = child_info.as_ref() { - let prefix_storage_key = child_info.prefixed_storage_key(); - let ch = insert_into_memory_db::(root, self.backend_storage_mut(), map.clone().into_iter()); - new_child_roots.push((prefix_storage_key.into_inner(), Some(ch.as_ref().into()))); - } else { - root_map = Some(map); - } - } + let (top, child) = changes.into_iter().partition::, _>(|v| v.0.is_none()); + let (root, transaction) = self.full_storage_root( + top.iter().map(|(_, v)| v).flatten().map(|(k, v)| (&k[..], v.as_deref())), + child.iter() + .filter_map(|v| + v.0.as_ref().map(|c| (c, v.1.iter().map(|(k, v)| (&k[..], v.as_deref())))) + ), + ); - let root = match root_map { - Some(map) => insert_into_memory_db::( - root, - self.backend_storage_mut(), - map.into_iter().chain(new_child_roots.into_iter()), - ), - None => insert_into_memory_db::( - root, - self.backend_storage_mut(), - new_child_roots.into_iter(), - ), - }; - self.essence.set_root(root); + self.apply_transaction(root, transaction); } /// Merge trie nodes into this backend. @@ -127,6 +76,12 @@ where Self::new(clone, root) } + /// Apply the given transaction to this backend and set the root to the given value. + pub fn apply_transaction(&mut self, root: H::Out, transaction: MemoryDB) { + self.backend_storage_mut().consolidate(transaction); + self.essence.set_root(root); + } + /// Compare with another in-memory backend. pub fn eq(&self, other: &Self) -> bool { self.root() == other.root() @@ -158,7 +113,9 @@ where { fn from(inner: HashMap, BTreeMap>) -> Self { let mut backend = new_in_mem(); - backend.insert(inner.into_iter().map(|(k, m)| (k, m.into_iter().map(|(k, v)| (k, Some(v))).collect()))); + backend.insert( + inner.into_iter().map(|(k, m)| (k, m.into_iter().map(|(k, v)| (k, Some(v))).collect())), + ); backend } } @@ -232,4 +189,16 @@ mod tests { let storage_key = child_info.prefixed_storage_key(); assert!(trie_backend.storage(storage_key.as_slice()).unwrap().is_some()); } + + #[test] + fn insert_multiple_times_child_data_works() { + let mut storage = new_in_mem::(); + let child_info = ChildInfo::new_default(b"1"); + + storage.insert(vec![(Some(child_info.clone()), vec![(b"2".to_vec(), Some(b"3".to_vec()))])]); + storage.insert(vec![(Some(child_info.clone()), vec![(b"1".to_vec(), Some(b"3".to_vec()))])]); + + assert_eq!(storage.child_storage(&child_info, &b"2"[..]), Ok(Some(b"3".to_vec()))); + assert_eq!(storage.child_storage(&child_info, &b"1"[..]), Ok(Some(b"3".to_vec()))); + } } diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 4dcd3082856..23c3abe4910 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -153,8 +153,11 @@ impl TestExternalities &mut self.changes_trie_storage } - /// Return a new backend with all pending value. - pub fn commit_all(&self) -> InMemoryBackend { + /// Return a new backend with all pending changes. + /// + /// In contrast to [`commit_all`](Self::commit_all) this will not panic if there are open + /// transactions. + fn as_backend(&self) -> InMemoryBackend { let top: Vec<_> = self.overlay.changes() .map(|(k, v)| (k.clone(), v.value().cloned())) .collect(); @@ -172,6 +175,23 @@ impl TestExternalities self.backend.update(transaction) } + /// Commit all pending changes to the underlying backend. + /// + /// # Panic + /// + /// This will panic if there are still open transactions. + pub fn commit_all(&mut self) -> Result<(), String> { + let changes = self.overlay.drain_storage_changes::<_, _, N>( + &self.backend, + None, + Default::default(), + &mut Default::default(), + )?; + + self.backend.apply_transaction(changes.transaction_storage_root, changes.transaction); + Ok(()) + } + /// Execute the given closure while `self` is set as externalities. /// /// Returns the result of the given closure. @@ -209,7 +229,7 @@ impl PartialEq for TestExternalities /// This doesn't test if they are in the same state, only if they contains the /// same data at this state fn eq(&self, other: &TestExternalities) -> bool { - self.commit_all().eq(&other.commit_all()) + self.as_backend().eq(&other.as_backend()) } } @@ -258,7 +278,7 @@ impl sp_externalities::ExtensionStore for TestExternalities where #[cfg(test)] mod tests { use super::*; - use sp_core::{H256, traits::Externalities}; + use sp_core::{H256, traits::Externalities, storage::ChildInfo}; use sp_runtime::traits::BlakeTwo256; use hex_literal::hex; @@ -289,4 +309,45 @@ mod tests { fn assert_send() {} assert_send::>(); } + + #[test] + fn commit_all_and_kill_child_storage() { + let mut ext = TestExternalities::::default(); + let child_info = ChildInfo::new_default(&b"test_child"[..]); + + { + let mut ext = ext.ext(); + ext.place_child_storage(&child_info, b"doe".to_vec(), Some(b"reindeer".to_vec())); + ext.place_child_storage(&child_info, b"dog".to_vec(), Some(b"puppy".to_vec())); + ext.place_child_storage(&child_info, b"dog2".to_vec(), Some(b"puppy2".to_vec())); + } + + ext.commit_all().unwrap(); + + { + let mut ext = ext.ext(); + + assert!(!ext.kill_child_storage(&child_info, Some(2)), "Should not delete all keys"); + + assert!(ext.child_storage(&child_info, &b"doe"[..]).is_none()); + assert!(ext.child_storage(&child_info, &b"dog"[..]).is_none()); + assert!(ext.child_storage(&child_info, &b"dog2"[..]).is_some()); + } + } + + #[test] + fn as_backend_generates_same_backend_as_commit_all() { + let mut ext = TestExternalities::::default(); + { + let mut ext = ext.ext(); + ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec()); + ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); + ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); + } + + let backend = ext.as_backend(); + + ext.commit_all().unwrap(); + assert!(ext.backend.eq(&backend), "Both backend should be equal."); + } } diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 2687d8e4227..4914d85f581 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -184,7 +184,7 @@ pub fn delta_trie_root( DB: hash_db::HashDB, { { - let mut trie = TrieDBMut::::from_existing(&mut *db, &mut root)?; + let mut trie = TrieDBMut::::from_existing(db, &mut root)?; let mut delta = delta.into_iter().collect::>(); delta.sort_by(|l, r| l.0.borrow().cmp(r.0.borrow())); @@ -223,9 +223,13 @@ pub fn read_trie_value_with< Ok(TrieDB::::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) } +/// Determine the empty trie root. +pub fn empty_trie_root() -> ::Out { + L::trie_root::<_, Vec, Vec>(core::iter::empty()) +} + /// Determine the empty child trie root. -pub fn empty_child_trie_root( -) -> ::Out { +pub fn empty_child_trie_root() -> ::Out { L::trie_root::<_, Vec, Vec>(core::iter::empty()) } -- GitLab From 0fc832988bef7ab27f6cf2f3040fcb2d3c9b6568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 30 Dec 2020 23:07:37 +0100 Subject: [PATCH 156/163] Define ss58 prefix inside the runtime (#7810) * Add SS58Prefix type to the frame_system config trait * Remove unused chain_id runtime interface --- bin/node-template/pallets/template/src/mock.rs | 2 ++ bin/node-template/runtime/src/lib.rs | 3 +++ bin/node/runtime/src/lib.rs | 2 ++ frame/assets/src/lib.rs | 1 + frame/atomic-swap/src/tests.rs | 1 + frame/aura/src/mock.rs | 1 + frame/authority-discovery/src/lib.rs | 1 + frame/authorship/src/lib.rs | 1 + frame/babe/src/mock.rs | 1 + frame/balances/src/tests_composite.rs | 1 + frame/balances/src/tests_local.rs | 1 + frame/benchmarking/src/tests.rs | 1 + frame/bounties/src/tests.rs | 1 + frame/collective/src/lib.rs | 1 + frame/contracts/src/tests.rs | 1 + frame/democracy/src/tests.rs | 1 + frame/elections-phragmen/src/lib.rs | 1 + frame/elections/src/mock.rs | 1 + frame/example-offchain-worker/src/tests.rs | 1 + frame/example-parallel/src/tests.rs | 1 + frame/example/src/lib.rs | 1 + frame/executive/src/lib.rs | 1 + frame/grandpa/src/mock.rs | 1 + frame/identity/src/tests.rs | 1 + frame/im-online/src/mock.rs | 1 + frame/indices/src/mock.rs | 1 + frame/membership/src/lib.rs | 1 + frame/merkle-mountain-range/src/mock.rs | 1 + frame/multisig/src/tests.rs | 1 + frame/nicks/src/lib.rs | 1 + frame/node-authorization/src/lib.rs | 1 + frame/offences/benchmarking/src/mock.rs | 1 + frame/offences/src/mock.rs | 1 + frame/proxy/src/tests.rs | 1 + frame/randomness-collective-flip/src/lib.rs | 1 + frame/recovery/src/mock.rs | 1 + frame/scheduler/src/lib.rs | 1 + frame/scored-pool/src/mock.rs | 1 + frame/session/benchmarking/src/mock.rs | 1 + frame/session/src/mock.rs | 1 + frame/society/src/mock.rs | 1 + frame/staking/fuzzer/src/mock.rs | 1 + frame/staking/src/mock.rs | 1 + frame/sudo/src/mock.rs | 1 + frame/support/test/tests/pallet.rs | 1 + frame/support/test/tests/pallet_compatibility.rs | 1 + .../test/tests/pallet_compatibility_instance.rs | 1 + frame/support/test/tests/pallet_instance.rs | 1 + frame/support/test/tests/pallet_version.rs | 1 + .../test/tests/pallet_with_name_trait_is_valid.rs | 1 + frame/system/benches/bench.rs | 1 + frame/system/benchmarking/src/mock.rs | 1 + frame/system/src/lib.rs | 14 ++++++++++++++ frame/system/src/mock.rs | 1 + frame/timestamp/src/lib.rs | 1 + frame/tips/src/tests.rs | 15 ++++++++------- frame/transaction-payment/src/lib.rs | 1 + frame/treasury/src/tests.rs | 1 + frame/utility/src/tests.rs | 1 + frame/vesting/src/lib.rs | 1 + primitives/externalities/src/lib.rs | 3 --- primitives/io/src/lib.rs | 5 ----- primitives/state-machine/src/basic.rs | 2 -- primitives/state-machine/src/ext.rs | 4 ---- primitives/state-machine/src/read_only.rs | 2 -- primitives/tasks/src/async_externalities.rs | 2 -- test-utils/runtime/src/lib.rs | 1 + 67 files changed, 85 insertions(+), 25 deletions(-) diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 84af63a1c3b..60d22aad7bc 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -16,6 +16,7 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; } impl system::Config for Test { @@ -40,6 +41,7 @@ impl system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; } impl Config for Test { diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 51df3dd5a3e..08123467796 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -136,6 +136,7 @@ parameter_types! { ::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub const SS58Prefix: u8 = 42; } // Configure FRAME pallets to include in runtime. @@ -185,6 +186,8 @@ impl frame_system::Config for Runtime { type AccountData = pallet_balances::AccountData; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = (); + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; } impl pallet_aura::Config for Runtime { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a86b015dbcf..4eee9d83a58 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -176,6 +176,7 @@ parameter_types! { }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); + pub const SS58Prefix: u8 = 42; } const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); @@ -202,6 +203,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = frame_system::weights::SubstrateWeight; + type SS58Prefix = SS58Prefix; } impl pallet_utility::Config for Runtime { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index df1cb87f75b..137ba81f389 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -952,6 +952,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index 47b5102bc56..19f5fc1dff5 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -42,6 +42,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 1fcb1c2340d..8d5cbcc9b7b 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -66,6 +66,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_timestamp::Config for Test { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 2d275e01bba..59321421755 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -164,6 +164,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl_outer_origin! { diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 693375e3c50..3672174e257 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -438,6 +438,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 77b117db7f3..f8805f7a109 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -86,6 +86,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 81c2b895273..f98194c503e 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -77,6 +77,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index c168e1d8e59..e9d6fe2530a 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -78,6 +78,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = Module; type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index f86abebbb92..e31f5ec0916 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -94,6 +94,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl Config for Test { diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs index 4ebff64b4e4..bcf371eae49 100644 --- a/frame/bounties/src/tests.rs +++ b/frame/bounties/src/tests.rs @@ -82,6 +82,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index efc8626d689..1448bd9bc3a 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -996,6 +996,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl Config for Test { type Origin = Origin; diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 6ac2fb0f976..991a89563eb 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -130,6 +130,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_balances::Config for Test { type MaxLocks = (); diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index dae3a262209..0e369bf3bd5 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -113,6 +113,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index b541303f651..9b7b9064fbf 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1099,6 +1099,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 482c905f89c..8a4111a38c4 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -57,6 +57,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 196d4cac4ad..a94174a33bb 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -76,6 +76,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } type Extrinsic = TestXt, ()>; diff --git a/frame/example-parallel/src/tests.rs b/frame/example-parallel/src/tests.rs index 24e846c3de4..3da41b22185 100644 --- a/frame/example-parallel/src/tests.rs +++ b/frame/example-parallel/src/tests.rs @@ -59,6 +59,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 3ddb2fd4c1d..14c40778bab 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -764,6 +764,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index caba857254d..cb45a49b233 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -618,6 +618,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } type Balance = u64; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index ae13c946597..288ef47a8ef 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -100,6 +100,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index 7f3a95dcd12..04e6bb7df39 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -63,6 +63,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 0a6dc1f79c0..71dc3d52acd 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -130,6 +130,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index 63f0277548f..0e1e9c3d436 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -69,6 +69,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index cfdc38752b5..943071c9a1d 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -321,6 +321,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } ord_parameter_types! { pub const One: u64 = 1; diff --git a/frame/merkle-mountain-range/src/mock.rs b/frame/merkle-mountain-range/src/mock.rs index c311d53446b..4865ea7e572 100644 --- a/frame/merkle-mountain-range/src/mock.rs +++ b/frame/merkle-mountain-range/src/mock.rs @@ -63,6 +63,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl Config for Test { diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index 7a959ec37f2..4101b718bce 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -80,6 +80,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 2b74f323d87..994e6996a14 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -283,6 +283,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 9641bea116a..e48faef128d 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -472,6 +472,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } ord_parameter_types! { diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index e55d7ac8e3a..2a93bfa2c8f 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -63,6 +63,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (Balances,); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 124b0030294..7d23780b12e 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -116,6 +116,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index b1dca43b6a7..b3f9ebc75dd 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -82,6 +82,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 9332262d687..04db12d1df6 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -180,6 +180,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } type System = frame_system::Module; diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 9b991987cee..13033767841 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -78,6 +78,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 9f0f806233d..67b86fad826 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -837,6 +837,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl logger::Config for Test { type Event = (); diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 7d49136cef4..b96daf6ba32 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -68,6 +68,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_balances::Config for Test { diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 9001dee8790..db6c465854b 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -67,6 +67,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = Balances; type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index fa71859feb4..e69eec14b09 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -218,6 +218,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_timestamp::Config for Test { diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 6a718c21850..c7040080671 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -78,6 +78,7 @@ impl frame_system::Config for Test { type OnKilledAccount = (); type AccountData = pallet_balances::AccountData; type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_balances::Config for Test { diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index 6f58d6a669d..ca36bfb4c3b 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -65,6 +65,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (Balances,); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index f3c6d50d4cf..6f7842b6b5a 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -166,6 +166,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_balances::Config for Test { type MaxLocks = MaxLocks; diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index 12707d3e9da..5a0919b8d73 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -139,6 +139,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } // Implement the logger module's `Config` on the Test runtime. diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 5d2785ebf26..e05a0e9bdfe 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -364,6 +364,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 912d68baed1..5711326300c 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -226,6 +226,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index d2f7a6668ca..cdcc6a99cf1 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -218,6 +218,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index 82b058b7bdd..caa9019edf6 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -259,6 +259,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index 25320597ba4..e70d752e40f 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -165,6 +165,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } frame_support::construct_runtime!( diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs index 01b965f3b51..fba19594897 100644 --- a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -141,6 +141,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_test::Trait for Runtime { diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 49093174886..2e5d6292180 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -87,6 +87,7 @@ impl system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl module::Config for Runtime { diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 8cfd70b2f09..686db8fb5a9 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -72,6 +72,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl crate::Config for Test {} diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a89577a478b..a8ffd05bf61 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -257,6 +257,13 @@ pub trait Config: 'static + Eq + Clone { type OnKilledAccount: OnKilledAccount; type SystemWeightInfo: WeightInfo; + + /// The designated SS85 prefix of this chain. + /// + /// This replaces the "ss58Format" property declared in the chain spec. Reason is + /// that the runtime should know about the prefix in order to make use of it as + /// an identifier of the chain. + type SS58Prefix: Get; } pub type DigestOf = generic::Digest<::Hash>; @@ -516,6 +523,13 @@ decl_module! { /// The weight configuration (limits & base values) for each class of extrinsics and block. const BlockWeights: limits::BlockWeights = T::BlockWeights::get(); + /// The designated SS85 prefix of this chain. + /// + /// This replaces the "ss58Format" property declared in the chain spec. Reason is + /// that the runtime should know about the prefix in order to make use of it as + /// an identifier of the chain. + const SS58Prefix: u8 = T::SS58Prefix::get(); + fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index 1558a5ed397..e22f5870eef 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -117,6 +117,7 @@ impl Config for Test { type OnNewAccount = (); type OnKilledAccount = RecordKilled; type SystemWeightInfo = (); + type SS58Prefix = (); } pub type System = Module; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index b62777832ab..423f7f5128e 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -335,6 +335,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index 3bfecafeaf9..15f3481ba25 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -81,6 +81,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -292,28 +293,28 @@ fn slash_tip_works() { System::set_block_number(1); Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_eq!(Treasury::pot(), 100); - + assert_eq!(Balances::reserved_balance(0), 0); assert_eq!(Balances::free_balance(0), 100); - + assert_ok!(TipsModTestInst::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - + assert_eq!(Balances::reserved_balance(0), 12); assert_eq!(Balances::free_balance(0), 88); - + let h = tip_hash(); assert_eq!(last_event(), RawEvent::NewTip(h)); - + // can't remove from any origin assert_noop!( TipsModTestInst::slash_tip(Origin::signed(0), h.clone()), BadOrigin, ); - + // can remove from root. assert_ok!(TipsModTestInst::slash_tip(Origin::root(), h.clone())); assert_eq!(last_event(), RawEvent::TipSlashed(h, 0, 12)); - + // tipper slashed assert_eq!(Balances::reserved_balance(0), 0); assert_eq!(Balances::free_balance(0), 88); diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index e530380dfbb..a787836d24c 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -662,6 +662,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 8db303a426d..4d0bdf32e45 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -80,6 +80,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 95973a8823f..4837be69526 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -118,6 +118,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index a7a8147a062..6a65e58d410 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -433,6 +433,7 @@ mod tests { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } parameter_types! { pub const MaxLocks: u32 = 10; diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 6869969f4ba..a6596a22d10 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -170,9 +170,6 @@ pub trait Externalities: ExtensionStore { value: Option>, ); - /// Get the identity of the chain. - fn chain_id(&self) -> u64; - /// Get the trie root of the current storage map. /// /// This will also update all child storage keys in the top-level storage map. diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 023bf7dcb30..dba984f4333 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -388,11 +388,6 @@ pub trait Trie { /// Interface that provides miscellaneous functions for communicating between the runtime and the node. #[runtime_interface] pub trait Misc { - /// The current relay chain identifier. - fn chain_id(&self) -> u64 { - sp_externalities::Externalities::chain_id(*self) - } - /// Print a number. fn print_num(val: u64) { log::debug!(target: "runtime", "{}", val); diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index 9de75785e45..def0eecf709 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -263,8 +263,6 @@ impl Externalities for BasicExternalities { crate::ext::StorageAppend::new(current).append(value); } - fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> Vec { let mut top = self.inner.top.clone(); let prefixed_keys: Vec<_> = self.inner.children_default.iter().map(|(_k, v)| { diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 3c4d88f3920..c46d0d56be4 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -507,10 +507,6 @@ where StorageAppend::new(current_value).append(value); } - fn chain_id(&self) -> u64 { - 42 - } - fn storage_root(&mut self) -> Vec { let _guard = guard(); if let Some(ref root) = self.storage_transaction_cache.transaction_storage_root { diff --git a/primitives/state-machine/src/read_only.rs b/primitives/state-machine/src/read_only.rs index 2ab92f5fbb6..ba9984a6c7d 100644 --- a/primitives/state-machine/src/read_only.rs +++ b/primitives/state-machine/src/read_only.rs @@ -156,8 +156,6 @@ impl<'a, H: Hasher, B: 'a + Backend> Externalities for ReadOnlyExternalities< unimplemented!("storage_append is not supported in ReadOnlyExternalities") } - fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> Vec { unimplemented!("storage_root is not supported in ReadOnlyExternalities") } diff --git a/primitives/tasks/src/async_externalities.rs b/primitives/tasks/src/async_externalities.rs index efb4c498f75..e2afeee413c 100644 --- a/primitives/tasks/src/async_externalities.rs +++ b/primitives/tasks/src/async_externalities.rs @@ -143,8 +143,6 @@ impl Externalities for AsyncExternalities { panic!("`storage_append`: should not be used in async externalities!") } - fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> Vec { panic!("`storage_root`: should not be used in async externalities!") } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 6bee4b704fc..3e5ab8f6975 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -462,6 +462,7 @@ impl frame_system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type SS58Prefix = (); } impl pallet_timestamp::Config for Runtime { -- GitLab From 2eaeb91bc6d20786aa4ad5f5538c0deac46e14cd Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 1 Jan 2021 17:46:38 +0100 Subject: [PATCH 157/163] remove some unecessary bound (#7813) --- frame/transaction-payment/rpc/src/lib.rs | 2 +- frame/transaction-payment/src/lib.rs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index 5043f0257fc..bf1565f1a40 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -73,7 +73,7 @@ impl TransactionPaymentApi<::Hash, RuntimeDi for TransactionPayment where Block: BlockT, - C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, + C: 'static + ProvideRuntimeApi + HeaderBackend, C::Api: TransactionPaymentRuntimeApi, Balance: Codec + MaybeDisplay + MaybeFromStr, { diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index a787836d24c..a9c595e57ac 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -314,8 +314,6 @@ impl Module where len: u32, ) -> RuntimeDispatchInfo> where - T: Send + Sync, - BalanceOf: Send + Sync, T::Call: Dispatchable, { // NOTE: we can actually make it understand `ChargeTransactionPayment`, but would be some @@ -444,9 +442,9 @@ impl Convert> for Module where /// Require the transactor pay for themselves and maybe include a tip to gain additional priority /// in the queue. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); +pub struct ChargeTransactionPayment(#[codec(compact)] BalanceOf); -impl ChargeTransactionPayment where +impl ChargeTransactionPayment where T::Call: Dispatchable, BalanceOf: Send + Sync + FixedPointOperand, { @@ -494,7 +492,7 @@ impl ChargeTransactionPayment where } } -impl sp_std::fmt::Debug for ChargeTransactionPayment { +impl sp_std::fmt::Debug for ChargeTransactionPayment { #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "ChargeTransactionPayment<{:?}>", self.0) @@ -505,7 +503,7 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment } } -impl SignedExtension for ChargeTransactionPayment where +impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync + From + FixedPointOperand, T::Call: Dispatchable, { -- GitLab From e8a8301c1b3c46926ea58941aed8de36772f2d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 3 Jan 2021 22:17:31 +0100 Subject: [PATCH 158/163] Fix ss58check test when executed with other tests (#7815) There was a bug that could make other ss58 tests fail when being executed with this one in parallel. This test changes the default ss58 version and if other tests are run at the time the default version is changed, they would fail. To fix this problem, we now run the actual test as a new process. --- primitives/core/src/ecdsa.rs | 40 +++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index a836eb0e4c2..8d2ba4a3d1b 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -678,18 +678,34 @@ mod test { #[test] fn ss58check_custom_format_works() { - use crate::crypto::Ss58AddressFormat; - // temp save default format version - let default_format = Ss58AddressFormat::default(); - // set current ss58 version is custom "200" `Ss58AddressFormat::Custom(200)` - set_default_ss58_version(Ss58AddressFormat::Custom(200)); - // custom addr encoded by version 200 - let addr = "2X64kMNEWAW5KLZMSKcGKEc96MyuaRsRUku7vomuYxKgqjVCRj"; - Public::from_ss58check(&addr).unwrap(); - set_default_ss58_version(default_format); - // set current ss58 version to default version - let addr = "KWAfgC2aRG5UVD6CpbPQXCx4YZZUhvWqqAJE6qcYc9Rtr6g5C"; - Public::from_ss58check(&addr).unwrap(); + // We need to run this test in its own process to not interfere with other tests running in + // parallel and also relying on the ss58 version. + if std::env::var("RUN_CUSTOM_FORMAT_TEST") == Ok("1".into()) { + use crate::crypto::Ss58AddressFormat; + // temp save default format version + let default_format = Ss58AddressFormat::default(); + // set current ss58 version is custom "200" `Ss58AddressFormat::Custom(200)` + set_default_ss58_version(Ss58AddressFormat::Custom(200)); + // custom addr encoded by version 200 + let addr = "2X64kMNEWAW5KLZMSKcGKEc96MyuaRsRUku7vomuYxKgqjVCRj"; + Public::from_ss58check(&addr).unwrap(); + set_default_ss58_version(default_format); + // set current ss58 version to default version + let addr = "KWAfgC2aRG5UVD6CpbPQXCx4YZZUhvWqqAJE6qcYc9Rtr6g5C"; + Public::from_ss58check(&addr).unwrap(); + + println!("CUSTOM_FORMAT_SUCCESSFUL"); + } else { + let executable = std::env::current_exe().unwrap(); + let output = std::process::Command::new(executable) + .env("RUN_CUSTOM_FORMAT_TEST", "1") + .args(&["--nocapture", "ss58check_custom_format_works"]) + .output() + .unwrap(); + + let output = String::from_utf8(output.stdout).unwrap(); + assert!(output.contains("CUSTOM_FORMAT_SUCCESSFUL")); + } } #[test] -- GitLab From 5215cd71aed415465e4d25926d426900a0b1f29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Sun, 3 Jan 2021 23:29:46 +0000 Subject: [PATCH 159/163] Cleanup some warnings (#7816) * client: cleanup redundant semicolon warnings * grandpa: remove usage of deprecated compare_and_swap --- client/finality-grandpa/src/communication/mod.rs | 2 +- client/finality-grandpa/src/import.rs | 2 +- client/finality-grandpa/src/tests.rs | 8 ++++---- client/service/src/client/client.rs | 2 +- client/transaction-pool/graph/src/validated_pool.rs | 2 +- utils/fork-tree/src/lib.rs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 29fe8bc7471..04c0a0f6ad0 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -846,7 +846,7 @@ fn check_catch_up( } Ok(()) - }; + } check_weight( voters, diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index 89f9d0c16ad..749d482871e 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -25,7 +25,7 @@ use parking_lot::RwLockWriteGuard; use sp_blockchain::{BlockStatus, well_known_cache_keys}; use sc_client_api::{backend::Backend, utils::is_descendent_of}; use sp_utils::mpsc::TracingUnboundedSender; -use sp_api::{TransactionFor}; +use sp_api::TransactionFor; use sp_consensus::{ BlockImport, Error as ConsensusError, diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 452b30941de..cf1201c6e91 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1068,7 +1068,7 @@ fn voter_persists_its_votes() { drop(_block_import); r }) - }; + } runtime.spawn(alice_voter1); @@ -1110,7 +1110,7 @@ fn voter_persists_its_votes() { let runtime_handle = runtime_handle.clone(); async move { - if state.compare_and_swap(0, 1, Ordering::SeqCst) == 0 { + if state.compare_exchange(0, 1, Ordering::SeqCst, Ordering::SeqCst).unwrap() == 0 { // the first message we receive should be a prevote from alice. let prevote = match signed.message { finality_grandpa::Message::Prevote(prevote) => prevote, @@ -1156,7 +1156,7 @@ fn voter_persists_its_votes() { // we send in a loop including a delay until items are received, this can be // ignored for the sake of reduced complexity. Pin::new(&mut *round_tx.lock()).start_send(finality_grandpa::Message::Prevote(prevote)).unwrap(); - } else if state.compare_and_swap(1, 2, Ordering::SeqCst) == 1 { + } else if state.compare_exchange(1, 2, Ordering::SeqCst, Ordering::SeqCst).unwrap() == 1 { // the next message we receive should be our own prevote let prevote = match signed.message { finality_grandpa::Message::Prevote(prevote) => prevote, @@ -1170,7 +1170,7 @@ fn voter_persists_its_votes() { // therefore we won't ever receive it again since it will be a // known message on the gossip layer - } else if state.compare_and_swap(2, 3, Ordering::SeqCst) == 2 { + } else if state.compare_exchange(2, 3, Ordering::SeqCst, Ordering::SeqCst).unwrap() == 2 { // we then receive a precommit from alice for block 15 // even though we casted a prevote for block 30 let precommit = match signed.message { diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index 84174738b56..26892416b34 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -401,7 +401,7 @@ impl Client where storage: &'a dyn ChangesTrieStorage, NumberFor>, min: NumberFor, required_roots_proofs: Mutex, Block::Hash>>, - }; + } impl<'a, Block: BlockT> ChangesTrieRootsStorage, NumberFor> for AccessedRootsRecorder<'a, Block> diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 86c2e75832f..ad2fdda73b4 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -286,7 +286,7 @@ impl ValidatedPool { /// Transactions that are missing from the pool are not submitted. pub fn resubmit(&self, mut updated_transactions: HashMap, ValidatedTransactionFor>) { #[derive(Debug, Clone, Copy, PartialEq)] - enum Status { Future, Ready, Failed, Dropped }; + enum Status { Future, Ready, Failed, Dropped } let (mut initial_statuses, final_statuses) = { let mut pool = self.pool.write(); diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index d2a0a4f3dd6..2eaced74d31 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -1224,7 +1224,7 @@ mod test { #[test] fn finalize_with_descendent_works() { #[derive(Debug, PartialEq)] - struct Change { effective: u64 }; + struct Change { effective: u64 } let (mut tree, is_descendent_of) = { let mut tree = ForkTree::new(); -- GitLab From 9b08105b8c7106d723c4f470304ad9e2868569d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 4 Jan 2021 10:03:13 +0100 Subject: [PATCH 160/163] Happy new year (#7814) * Happy new year Updates the copyright years and fixes wrong license headers. * Fix the template * Split HEADER into HEADER-APACHE & HEADER-GPL --- .maintain/frame-weight-template.hbs | 2 +- .maintain/update-copyright.sh | 11 +++--- HEADER => HEADER-APACHE | 2 +- docs/license_header.txt => HEADER-GPL | 12 ++++--- bin/node-template/node/src/command.rs | 2 +- bin/node/bench/src/common.rs | 5 ++- bin/node/bench/src/construct.rs | 2 +- bin/node/bench/src/core.rs | 2 +- bin/node/bench/src/generator.rs | 2 +- bin/node/bench/src/import.rs | 2 +- bin/node/bench/src/main.rs | 2 +- bin/node/bench/src/simple_trie.rs | 2 +- bin/node/bench/src/state_sizes.rs | 16 +++++---- bin/node/bench/src/tempdb.rs | 2 +- bin/node/bench/src/trie.rs | 2 +- bin/node/bench/src/txpool.rs | 2 +- bin/node/browser-testing/src/lib.rs | 2 +- bin/node/cli/bin/main.rs | 2 +- bin/node/cli/build.rs | 2 +- bin/node/cli/src/browser.rs | 2 +- bin/node/cli/src/chain_spec.rs | 2 +- bin/node/cli/src/cli.rs | 2 +- bin/node/cli/src/command.rs | 2 +- bin/node/cli/src/lib.rs | 2 +- bin/node/cli/src/service.rs | 2 +- bin/node/cli/tests/build_spec_works.rs | 2 +- bin/node/cli/tests/check_block_works.rs | 2 +- bin/node/cli/tests/common.rs | 2 +- bin/node/cli/tests/export_import_flow.rs | 2 +- bin/node/cli/tests/inspect_works.rs | 2 +- bin/node/cli/tests/purge_chain_works.rs | 2 +- .../tests/running_the_node_and_interrupt.rs | 2 +- bin/node/cli/tests/temp_base_path_works.rs | 2 +- bin/node/cli/tests/version.rs | 2 +- bin/node/executor/benches/bench.rs | 2 +- bin/node/executor/src/lib.rs | 2 +- bin/node/executor/tests/basic.rs | 2 +- bin/node/executor/tests/common.rs | 2 +- bin/node/executor/tests/fees.rs | 2 +- bin/node/executor/tests/submit_transaction.rs | 2 +- bin/node/inspect/src/cli.rs | 2 +- bin/node/inspect/src/command.rs | 2 +- bin/node/inspect/src/lib.rs | 2 +- bin/node/primitives/src/lib.rs | 2 +- bin/node/rpc-client/src/main.rs | 2 +- bin/node/rpc/src/lib.rs | 2 +- bin/node/runtime/build.rs | 2 +- bin/node/runtime/src/constants.rs | 2 +- bin/node/runtime/src/impls.rs | 2 +- bin/node/runtime/src/lib.rs | 2 +- bin/node/testing/src/bench.rs | 2 +- bin/node/testing/src/client.rs | 2 +- bin/node/testing/src/genesis.rs | 2 +- bin/node/testing/src/keyring.rs | 2 +- bin/node/testing/src/lib.rs | 2 +- bin/utils/chain-spec-builder/build.rs | 2 +- bin/utils/chain-spec-builder/src/main.rs | 2 +- bin/utils/subkey/src/lib.rs | 2 +- bin/utils/subkey/src/main.rs | 2 +- client/api/src/backend.rs | 2 +- client/api/src/call_executor.rs | 2 +- client/api/src/cht.rs | 2 +- client/api/src/client.rs | 12 ++++--- client/api/src/execution_extensions.rs | 12 ++++--- client/api/src/in_mem.rs | 2 +- client/api/src/leaves.rs | 2 +- client/api/src/lib.rs | 12 ++++--- client/api/src/light.rs | 12 ++++--- client/api/src/notifications.rs | 2 +- client/api/src/proof_provider.rs | 2 +- client/authority-discovery/src/error.rs | 12 ++++--- client/authority-discovery/src/interval.rs | 12 ++++--- client/authority-discovery/src/lib.rs | 12 ++++--- client/authority-discovery/src/service.rs | 12 ++++--- client/authority-discovery/src/tests.rs | 2 +- client/authority-discovery/src/worker.rs | 12 ++++--- .../src/worker/addr_cache.rs | 12 ++++--- .../authority-discovery/src/worker/tests.rs | 2 +- .../basic-authorship/src/basic_authorship.rs | 2 +- client/basic-authorship/src/lib.rs | 2 +- client/block-builder/src/lib.rs | 2 +- client/chain-spec/derive/src/impls.rs | 12 ++++--- client/chain-spec/derive/src/lib.rs | 12 ++++--- client/chain-spec/src/chain_spec.rs | 2 +- client/chain-spec/src/extension.rs | 12 ++++--- client/chain-spec/src/lib.rs | 12 ++++--- client/cli/proc-macro/src/lib.rs | 2 +- client/cli/src/arg_enums.rs | 2 +- client/cli/src/commands/build_spec_cmd.rs | 2 +- client/cli/src/commands/check_block_cmd.rs | 2 +- client/cli/src/commands/export_blocks_cmd.rs | 2 +- client/cli/src/commands/export_state_cmd.rs | 2 +- client/cli/src/commands/generate.rs | 2 +- client/cli/src/commands/generate_node_key.rs | 2 +- client/cli/src/commands/import_blocks_cmd.rs | 2 +- client/cli/src/commands/insert_key.rs | 2 +- client/cli/src/commands/inspect_key.rs | 2 +- client/cli/src/commands/inspect_node_key.rs | 2 +- client/cli/src/commands/key.rs | 2 +- client/cli/src/commands/mod.rs | 2 +- client/cli/src/commands/purge_chain_cmd.rs | 2 +- client/cli/src/commands/revert_cmd.rs | 2 +- client/cli/src/commands/run_cmd.rs | 2 +- client/cli/src/commands/sign.rs | 2 +- client/cli/src/commands/utils.rs | 2 +- client/cli/src/commands/vanity.rs | 2 +- client/cli/src/commands/verify.rs | 2 +- client/cli/src/config.rs | 2 +- client/cli/src/error.rs | 2 +- client/cli/src/lib.rs | 2 +- client/cli/src/params/database_params.rs | 2 +- client/cli/src/params/import_params.rs | 2 +- client/cli/src/params/keystore_params.rs | 2 +- client/cli/src/params/mod.rs | 2 +- client/cli/src/params/network_params.rs | 2 +- client/cli/src/params/node_key_params.rs | 2 +- .../cli/src/params/offchain_worker_params.rs | 2 +- client/cli/src/params/pruning_params.rs | 2 +- client/cli/src/params/shared_params.rs | 2 +- .../cli/src/params/transaction_pool_params.rs | 2 +- client/cli/src/runner.rs | 2 +- client/consensus/aura/src/digests.rs | 2 +- client/consensus/aura/src/lib.rs | 2 +- client/consensus/babe/rpc/src/lib.rs | 2 +- client/consensus/babe/src/authorship.rs | 12 ++++--- client/consensus/babe/src/aux_schema.rs | 12 ++++--- client/consensus/babe/src/lib.rs | 12 ++++--- client/consensus/babe/src/tests.rs | 12 ++++--- client/consensus/babe/src/verification.rs | 12 ++++--- client/consensus/common/src/lib.rs | 12 ++++--- client/consensus/common/src/longest_chain.rs | 15 ++++---- client/consensus/epochs/src/lib.rs | 12 ++++--- client/consensus/epochs/src/migration.rs | 12 ++++--- client/consensus/manual-seal/src/consensus.rs | 2 +- .../manual-seal/src/consensus/babe.rs | 2 +- client/consensus/manual-seal/src/error.rs | 2 +- .../manual-seal/src/finalize_block.rs | 12 ++++--- client/consensus/manual-seal/src/lib.rs | 2 +- client/consensus/manual-seal/src/rpc.rs | 12 ++++--- .../consensus/manual-seal/src/seal_block.rs | 12 ++++--- client/consensus/pow/src/lib.rs | 2 +- client/consensus/pow/src/worker.rs | 2 +- client/consensus/slots/build.rs | 12 ++++--- client/consensus/slots/src/aux_schema.rs | 12 ++++--- client/consensus/slots/src/lib.rs | 12 ++++--- client/consensus/slots/src/slots.rs | 12 ++++--- client/consensus/uncles/src/lib.rs | 12 ++++--- client/db/src/bench.rs | 2 +- client/db/src/cache/list_cache.rs | 2 +- client/db/src/cache/list_entry.rs | 2 +- client/db/src/cache/list_storage.rs | 2 +- client/db/src/cache/mod.rs | 2 +- client/db/src/changes_tries_storage.rs | 12 ++++--- client/db/src/children.rs | 12 ++++--- client/db/src/lib.rs | 2 +- client/db/src/light.rs | 2 +- client/db/src/offchain.rs | 2 +- client/db/src/parity_db.rs | 2 +- client/db/src/stats.rs | 2 +- client/db/src/storage_cache.rs | 12 ++++--- client/db/src/upgrade.rs | 12 ++++--- client/db/src/utils.rs | 2 +- client/executor/common/src/error.rs | 2 +- client/executor/common/src/lib.rs | 12 ++++--- client/executor/common/src/sandbox.rs | 2 +- client/executor/common/src/util.rs | 2 +- client/executor/common/src/wasm_runtime.rs | 12 ++++--- client/executor/runtime-test/build.rs | 12 ++++--- client/executor/src/integration_tests/mod.rs | 2 +- .../executor/src/integration_tests/sandbox.rs | 2 +- client/executor/src/lib.rs | 2 +- client/executor/src/native_executor.rs | 2 +- client/executor/src/wasm_runtime.rs | 12 ++++--- client/executor/wasmi/src/lib.rs | 12 ++++--- client/executor/wasmtime/src/host.rs | 12 ++++--- client/executor/wasmtime/src/imports.rs | 2 +- .../executor/wasmtime/src/instance_wrapper.rs | 2 +- .../src/instance_wrapper/globals_snapshot.rs | 2 +- client/executor/wasmtime/src/lib.rs | 12 ++++--- client/executor/wasmtime/src/runtime.rs | 12 ++++--- client/executor/wasmtime/src/state_holder.rs | 2 +- client/executor/wasmtime/src/util.rs | 12 ++++--- client/finality-grandpa/rpc/src/error.rs | 2 +- client/finality-grandpa/rpc/src/finality.rs | 2 +- client/finality-grandpa/rpc/src/lib.rs | 2 +- .../finality-grandpa/rpc/src/notification.rs | 2 +- client/finality-grandpa/rpc/src/report.rs | 2 +- client/finality-grandpa/src/authorities.rs | 2 +- client/finality-grandpa/src/aux_schema.rs | 12 ++++--- .../src/communication/gossip.rs | 12 ++++--- .../finality-grandpa/src/communication/mod.rs | 2 +- .../src/communication/periodic.rs | 12 ++++--- .../src/communication/tests.rs | 12 ++++--- client/finality-grandpa/src/environment.rs | 2 +- client/finality-grandpa/src/finality_proof.rs | 2 +- client/finality-grandpa/src/import.rs | 2 +- client/finality-grandpa/src/justification.rs | 2 +- client/finality-grandpa/src/lib.rs | 2 +- client/finality-grandpa/src/notification.rs | 2 +- client/finality-grandpa/src/observer.rs | 2 +- client/finality-grandpa/src/tests.rs | 2 +- client/finality-grandpa/src/until_imported.rs | 2 +- client/finality-grandpa/src/voting_rule.rs | 2 +- client/informant/src/display.rs | 12 ++++--- client/informant/src/lib.rs | 2 +- client/keystore/src/lib.rs | 12 ++++--- client/keystore/src/local.rs | 2 +- client/light/src/backend.rs | 2 +- client/light/src/blockchain.rs | 2 +- client/light/src/call_executor.rs | 2 +- client/light/src/fetcher.rs | 2 +- client/light/src/lib.rs | 2 +- client/network-gossip/src/bridge.rs | 12 ++++--- client/network-gossip/src/lib.rs | 12 ++++--- client/network-gossip/src/state_machine.rs | 2 +- client/network-gossip/src/validator.rs | 2 +- client/network/src/behaviour.rs | 12 ++++--- client/network/src/block_requests.rs | 18 +++++----- client/network/src/chain.rs | 2 +- client/network/src/config.rs | 2 +- client/network/src/discovery.rs | 12 ++++--- client/network/src/error.rs | 2 +- client/network/src/gossip.rs | 2 +- client/network/src/gossip/tests.rs | 2 +- client/network/src/lib.rs | 2 +- client/network/src/light_client_handler.rs | 18 +++++----- client/network/src/network_state.rs | 2 +- client/network/src/on_demand_layer.rs | 2 +- client/network/src/peer_info.rs | 12 ++++--- client/network/src/protocol.rs | 2 +- client/network/src/protocol/event.rs | 12 ++++--- client/network/src/protocol/generic_proto.rs | 12 ++++--- .../src/protocol/generic_proto/behaviour.rs | 12 ++++--- .../src/protocol/generic_proto/handler.rs | 12 ++++--- .../src/protocol/generic_proto/tests.rs | 12 ++++--- .../src/protocol/generic_proto/upgrade.rs | 2 +- .../protocol/generic_proto/upgrade/collec.rs | 36 +++++++++---------- .../protocol/generic_proto/upgrade/legacy.rs | 2 +- .../generic_proto/upgrade/notifications.rs | 12 ++++--- client/network/src/protocol/message.rs | 2 +- client/network/src/protocol/sync.rs | 18 +++++----- client/network/src/protocol/sync/blocks.rs | 2 +- .../src/protocol/sync/extra_requests.rs | 2 +- client/network/src/request_responses.rs | 12 ++++--- client/network/src/schema.rs | 2 +- client/network/src/service.rs | 2 +- client/network/src/service/metrics.rs | 2 +- client/network/src/service/out_events.rs | 2 +- client/network/src/service/tests.rs | 2 +- client/network/src/transport.rs | 2 +- client/network/src/utils.rs | 12 ++++--- client/network/test/src/block_import.rs | 2 +- client/network/test/src/lib.rs | 2 +- client/network/test/src/sync.rs | 2 +- client/offchain/src/api.rs | 12 ++++--- client/offchain/src/api/http.rs | 12 ++++--- client/offchain/src/api/http_dummy.rs | 12 ++++--- client/offchain/src/api/timestamp.rs | 12 ++++--- client/offchain/src/lib.rs | 12 ++++--- client/peerset/src/lib.rs | 2 +- client/peerset/src/peersstate.rs | 12 ++++--- client/peerset/tests/fuzz.rs | 2 +- client/proposer-metrics/src/lib.rs | 12 ++++--- client/rpc-api/src/author/error.rs | 2 +- client/rpc-api/src/author/hash.rs | 12 ++++--- client/rpc-api/src/author/mod.rs | 2 +- client/rpc-api/src/chain/error.rs | 2 +- client/rpc-api/src/chain/mod.rs | 2 +- client/rpc-api/src/child_state/mod.rs | 2 +- client/rpc-api/src/errors.rs | 2 +- client/rpc-api/src/helpers.rs | 2 +- client/rpc-api/src/lib.rs | 12 ++++--- client/rpc-api/src/metadata.rs | 2 +- client/rpc-api/src/offchain/error.rs | 2 +- client/rpc-api/src/offchain/mod.rs | 2 +- client/rpc-api/src/policy.rs | 2 +- client/rpc-api/src/state/error.rs | 2 +- client/rpc-api/src/state/helpers.rs | 2 +- client/rpc-api/src/state/mod.rs | 2 +- client/rpc-api/src/system/error.rs | 2 +- client/rpc-api/src/system/helpers.rs | 2 +- client/rpc-api/src/system/mod.rs | 2 +- client/rpc-servers/src/lib.rs | 2 +- client/rpc-servers/src/middleware.rs | 2 +- client/rpc/src/author/mod.rs | 2 +- client/rpc/src/author/tests.rs | 2 +- client/rpc/src/chain/chain_full.rs | 12 ++++--- client/rpc/src/chain/chain_light.rs | 12 ++++--- client/rpc/src/chain/mod.rs | 2 +- client/rpc/src/chain/tests.rs | 2 +- client/rpc/src/lib.rs | 2 +- client/rpc/src/offchain/mod.rs | 2 +- client/rpc/src/offchain/tests.rs | 2 +- client/rpc/src/state/mod.rs | 2 +- client/rpc/src/state/state_full.rs | 12 ++++--- client/rpc/src/state/state_light.rs | 12 ++++--- client/rpc/src/state/tests.rs | 2 +- client/rpc/src/system/mod.rs | 2 +- client/rpc/src/system/tests.rs | 2 +- client/rpc/src/testing.rs | 2 +- client/service/src/builder.rs | 2 +- client/service/src/chain_ops/check_block.rs | 12 ++++--- client/service/src/chain_ops/export_blocks.rs | 12 ++++--- .../service/src/chain_ops/export_raw_state.rs | 12 ++++--- client/service/src/chain_ops/import_blocks.rs | 2 +- client/service/src/chain_ops/mod.rs | 12 ++++--- client/service/src/chain_ops/revert_chain.rs | 12 ++++--- client/service/src/client/block_rules.rs | 2 +- client/service/src/client/call_executor.rs | 2 +- client/service/src/client/client.rs | 2 +- client/service/src/client/genesis.rs | 2 +- client/service/src/client/light.rs | 2 +- client/service/src/client/mod.rs | 2 +- client/service/src/client/wasm_override.rs | 2 +- client/service/src/config.rs | 2 +- client/service/src/error.rs | 2 +- client/service/src/lib.rs | 2 +- client/service/src/metrics.rs | 2 +- client/service/src/task_manager/mod.rs | 13 ++++--- .../src/task_manager/prometheus_future.rs | 13 ++++--- client/service/src/task_manager/tests.rs | 2 +- client/service/test/src/client/db.rs | 2 +- client/service/test/src/client/light.rs | 2 +- client/service/test/src/client/mod.rs | 2 +- client/service/test/src/lib.rs | 2 +- client/state-db/src/lib.rs | 2 +- client/state-db/src/noncanonical.rs | 2 +- client/state-db/src/pruning.rs | 2 +- client/state-db/src/test.rs | 2 +- client/sync-state-rpc/src/lib.rs | 12 ++++--- client/telemetry/src/lib.rs | 2 +- client/telemetry/src/worker.rs | 2 +- client/telemetry/src/worker/node.rs | 2 +- client/tracing/src/lib.rs | 12 ++++--- client/tracing/src/logging.rs | 2 +- .../transaction-pool/graph/benches/basics.rs | 2 +- .../transaction-pool/graph/src/base_pool.rs | 2 +- client/transaction-pool/graph/src/future.rs | 2 +- client/transaction-pool/graph/src/lib.rs | 2 +- client/transaction-pool/graph/src/listener.rs | 2 +- client/transaction-pool/graph/src/pool.rs | 2 +- client/transaction-pool/graph/src/ready.rs | 2 +- client/transaction-pool/graph/src/rotator.rs | 2 +- .../transaction-pool/graph/src/tracked_map.rs | 2 +- .../graph/src/validated_pool.rs | 2 +- client/transaction-pool/graph/src/watcher.rs | 2 +- client/transaction-pool/src/api.rs | 2 +- client/transaction-pool/src/error.rs | 2 +- client/transaction-pool/src/lib.rs | 2 +- client/transaction-pool/src/metrics.rs | 2 +- client/transaction-pool/src/revalidation.rs | 2 +- client/transaction-pool/src/testing/mod.rs | 2 +- client/transaction-pool/src/testing/pool.rs | 2 +- frame/assets/src/benchmarking.rs | 2 +- frame/assets/src/lib.rs | 2 +- frame/assets/src/weights.rs | 2 +- frame/atomic-swap/src/lib.rs | 2 +- frame/aura/src/lib.rs | 2 +- frame/aura/src/mock.rs | 2 +- frame/aura/src/tests.rs | 2 +- frame/authority-discovery/src/lib.rs | 2 +- frame/authorship/src/lib.rs | 2 +- frame/babe/src/benchmarking.rs | 2 +- frame/babe/src/default_weights.rs | 2 +- frame/babe/src/equivocation.rs | 2 +- frame/babe/src/lib.rs | 2 +- frame/babe/src/mock.rs | 2 +- frame/babe/src/tests.rs | 2 +- frame/balances/src/benchmarking.rs | 2 +- frame/balances/src/lib.rs | 2 +- frame/balances/src/tests.rs | 2 +- frame/balances/src/tests_composite.rs | 2 +- frame/balances/src/tests_local.rs | 2 +- frame/balances/src/weights.rs | 2 +- frame/benchmarking/src/analysis.rs | 2 +- frame/benchmarking/src/lib.rs | 2 +- frame/benchmarking/src/tests.rs | 2 +- frame/benchmarking/src/utils.rs | 2 +- frame/bounties/src/benchmarking.rs | 2 +- frame/bounties/src/lib.rs | 2 +- frame/bounties/src/tests.rs | 2 +- frame/bounties/src/weights.rs | 2 +- frame/collective/src/benchmarking.rs | 2 +- frame/collective/src/lib.rs | 2 +- frame/collective/src/weights.rs | 2 +- frame/contracts/common/src/lib.rs | 27 +++++++------- frame/contracts/proc-macro/src/lib.rs | 2 +- frame/contracts/rpc/runtime-api/src/lib.rs | 2 +- frame/contracts/rpc/src/lib.rs | 2 +- frame/contracts/src/benchmarking/code.rs | 2 +- frame/contracts/src/benchmarking/mod.rs | 2 +- frame/contracts/src/benchmarking/sandbox.rs | 2 +- frame/contracts/src/exec.rs | 27 +++++++------- frame/contracts/src/gas.rs | 27 +++++++------- frame/contracts/src/lib.rs | 27 +++++++------- frame/contracts/src/rent.rs | 27 +++++++------- frame/contracts/src/schedule.rs | 27 +++++++------- frame/contracts/src/storage.rs | 29 +++++++-------- frame/contracts/src/tests.rs | 27 +++++++------- frame/contracts/src/wasm/code_cache.rs | 25 ++++++------- frame/contracts/src/wasm/env_def/macros.rs | 27 +++++++------- frame/contracts/src/wasm/env_def/mod.rs | 25 ++++++------- frame/contracts/src/wasm/mod.rs | 27 +++++++------- frame/contracts/src/wasm/prepare.rs | 27 +++++++------- frame/contracts/src/wasm/runtime.rs | 25 ++++++------- frame/contracts/src/weights.rs | 2 +- frame/democracy/src/benchmarking.rs | 2 +- frame/democracy/src/conviction.rs | 2 +- frame/democracy/src/lib.rs | 2 +- frame/democracy/src/tests.rs | 2 +- frame/democracy/src/tests/cancellation.rs | 2 +- frame/democracy/src/tests/decoders.rs | 25 ++++++------- frame/democracy/src/tests/delegation.rs | 2 +- .../democracy/src/tests/external_proposing.rs | 2 +- frame/democracy/src/tests/fast_tracking.rs | 2 +- frame/democracy/src/tests/lock_voting.rs | 2 +- frame/democracy/src/tests/preimage.rs | 2 +- frame/democracy/src/tests/public_proposals.rs | 2 +- frame/democracy/src/tests/scheduling.rs | 2 +- frame/democracy/src/tests/voting.rs | 2 +- frame/democracy/src/types.rs | 2 +- frame/democracy/src/vote.rs | 2 +- frame/democracy/src/vote_threshold.rs | 2 +- frame/democracy/src/weights.rs | 2 +- frame/elections-phragmen/src/benchmarking.rs | 27 +++++++------- frame/elections-phragmen/src/lib.rs | 2 +- frame/elections-phragmen/src/weights.rs | 2 +- frame/elections/src/lib.rs | 2 +- frame/elections/src/mock.rs | 2 +- frame/elections/src/tests.rs | 2 +- frame/example-offchain-worker/src/lib.rs | 2 +- frame/example-offchain-worker/src/tests.rs | 2 +- frame/example-parallel/src/lib.rs | 2 +- frame/example-parallel/src/tests.rs | 2 +- frame/example/src/lib.rs | 2 +- frame/executive/src/lib.rs | 2 +- frame/grandpa/src/benchmarking.rs | 2 +- frame/grandpa/src/default_weights.rs | 2 +- frame/grandpa/src/equivocation.rs | 2 +- frame/grandpa/src/lib.rs | 2 +- frame/grandpa/src/mock.rs | 2 +- frame/grandpa/src/tests.rs | 2 +- frame/identity/src/benchmarking.rs | 2 +- frame/identity/src/lib.rs | 2 +- frame/identity/src/tests.rs | 2 +- frame/identity/src/weights.rs | 2 +- frame/im-online/src/benchmarking.rs | 2 +- frame/im-online/src/lib.rs | 2 +- frame/im-online/src/mock.rs | 2 +- frame/im-online/src/tests.rs | 2 +- frame/im-online/src/weights.rs | 2 +- frame/indices/src/benchmarking.rs | 2 +- frame/indices/src/lib.rs | 2 +- frame/indices/src/mock.rs | 2 +- frame/indices/src/tests.rs | 2 +- frame/indices/src/weights.rs | 2 +- frame/membership/src/lib.rs | 2 +- .../merkle-mountain-range/src/benchmarking.rs | 2 +- .../src/default_weights.rs | 2 +- frame/merkle-mountain-range/src/lib.rs | 2 +- frame/merkle-mountain-range/src/mmr/mmr.rs | 2 +- frame/merkle-mountain-range/src/mmr/mod.rs | 2 +- .../merkle-mountain-range/src/mmr/storage.rs | 2 +- frame/merkle-mountain-range/src/mmr/utils.rs | 2 +- frame/merkle-mountain-range/src/mock.rs | 2 +- frame/merkle-mountain-range/src/primitives.rs | 2 +- frame/merkle-mountain-range/src/tests.rs | 2 +- frame/metadata/src/lib.rs | 2 +- frame/multisig/src/benchmarking.rs | 2 +- frame/multisig/src/lib.rs | 2 +- frame/multisig/src/tests.rs | 2 +- frame/multisig/src/weights.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/node-authorization/src/lib.rs | 2 +- frame/offences/benchmarking/src/lib.rs | 2 +- frame/offences/benchmarking/src/mock.rs | 2 +- frame/offences/src/lib.rs | 2 +- frame/offences/src/mock.rs | 2 +- frame/offences/src/tests.rs | 2 +- frame/proxy/src/benchmarking.rs | 2 +- frame/proxy/src/lib.rs | 2 +- frame/proxy/src/tests.rs | 2 +- frame/proxy/src/weights.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 2 +- frame/recovery/src/lib.rs | 2 +- frame/recovery/src/mock.rs | 2 +- frame/recovery/src/tests.rs | 2 +- frame/scheduler/src/benchmarking.rs | 2 +- frame/scheduler/src/lib.rs | 2 +- frame/scheduler/src/weights.rs | 2 +- frame/scored-pool/src/lib.rs | 2 +- frame/scored-pool/src/mock.rs | 2 +- frame/scored-pool/src/tests.rs | 2 +- frame/session/benchmarking/src/lib.rs | 2 +- frame/session/benchmarking/src/mock.rs | 2 +- frame/session/src/historical/mod.rs | 2 +- frame/session/src/historical/offchain.rs | 2 +- frame/session/src/historical/onchain.rs | 2 +- frame/session/src/historical/shared.rs | 2 +- frame/session/src/lib.rs | 2 +- frame/session/src/mock.rs | 2 +- frame/session/src/tests.rs | 2 +- frame/session/src/weights.rs | 2 +- frame/society/src/lib.rs | 2 +- frame/society/src/mock.rs | 2 +- frame/society/src/tests.rs | 2 +- frame/staking/fuzzer/src/mock.rs | 2 +- frame/staking/fuzzer/src/submit_solution.rs | 2 +- frame/staking/reward-curve/src/lib.rs | 2 +- frame/staking/reward-curve/tests/test.rs | 2 +- frame/staking/src/benchmarking.rs | 2 +- frame/staking/src/inflation.rs | 2 +- frame/staking/src/lib.rs | 2 +- frame/staking/src/mock.rs | 2 +- frame/staking/src/offchain_election.rs | 2 +- frame/staking/src/slashing.rs | 2 +- frame/staking/src/testing_utils.rs | 2 +- frame/staking/src/tests.rs | 2 +- frame/staking/src/weights.rs | 2 +- frame/sudo/src/lib.rs | 2 +- frame/sudo/src/mock.rs | 2 +- frame/sudo/src/tests.rs | 2 +- .../support/procedural/src/clone_no_bound.rs | 2 +- .../procedural/src/construct_runtime/mod.rs | 2 +- .../procedural/src/construct_runtime/parse.rs | 2 +- .../support/procedural/src/debug_no_bound.rs | 2 +- frame/support/procedural/src/lib.rs | 2 +- .../procedural/src/pallet/expand/call.rs | 2 +- .../procedural/src/pallet/expand/constants.rs | 2 +- .../procedural/src/pallet/expand/error.rs | 2 +- .../procedural/src/pallet/expand/event.rs | 2 +- .../src/pallet/expand/genesis_build.rs | 2 +- .../src/pallet/expand/genesis_config.rs | 2 +- .../procedural/src/pallet/expand/hooks.rs | 2 +- .../procedural/src/pallet/expand/instances.rs | 2 +- .../procedural/src/pallet/expand/mod.rs | 2 +- .../src/pallet/expand/pallet_struct.rs | 2 +- .../procedural/src/pallet/expand/storage.rs | 2 +- .../src/pallet/expand/store_trait.rs | 2 +- .../src/pallet/expand/type_value.rs | 2 +- frame/support/procedural/src/pallet/mod.rs | 2 +- .../procedural/src/pallet/parse/call.rs | 2 +- .../procedural/src/pallet/parse/config.rs | 2 +- .../procedural/src/pallet/parse/error.rs | 2 +- .../procedural/src/pallet/parse/event.rs | 2 +- .../src/pallet/parse/extra_constants.rs | 2 +- .../src/pallet/parse/genesis_build.rs | 2 +- .../src/pallet/parse/genesis_config.rs | 2 +- .../procedural/src/pallet/parse/helper.rs | 2 +- .../procedural/src/pallet/parse/hooks.rs | 2 +- .../procedural/src/pallet/parse/inherent.rs | 2 +- .../procedural/src/pallet/parse/mod.rs | 2 +- .../procedural/src/pallet/parse/origin.rs | 2 +- .../src/pallet/parse/pallet_struct.rs | 2 +- .../procedural/src/pallet/parse/storage.rs | 2 +- .../procedural/src/pallet/parse/type_value.rs | 2 +- .../src/pallet/parse/validate_unsigned.rs | 2 +- .../support/procedural/src/pallet_version.rs | 2 +- .../procedural/src/partial_eq_no_bound.rs | 2 +- .../src/storage/genesis_config/builder_def.rs | 2 +- .../genesis_config/genesis_config_def.rs | 2 +- .../src/storage/genesis_config/mod.rs | 2 +- .../support/procedural/src/storage/getters.rs | 2 +- .../procedural/src/storage/instance_trait.rs | 2 +- .../procedural/src/storage/metadata.rs | 2 +- frame/support/procedural/src/storage/mod.rs | 2 +- frame/support/procedural/src/storage/parse.rs | 2 +- .../procedural/src/storage/storage_struct.rs | 2 +- .../procedural/src/storage/store_trait.rs | 2 +- frame/support/procedural/src/transactional.rs | 2 +- .../procedural/tools/derive/src/lib.rs | 2 +- frame/support/procedural/tools/src/lib.rs | 2 +- frame/support/procedural/tools/src/syn_ext.rs | 2 +- frame/support/src/debug.rs | 2 +- frame/support/src/dispatch.rs | 2 +- frame/support/src/error.rs | 2 +- frame/support/src/event.rs | 24 +++++++------ frame/support/src/genesis_config.rs | 2 +- frame/support/src/hash.rs | 2 +- frame/support/src/inherent.rs | 2 +- frame/support/src/instances.rs | 2 +- frame/support/src/lib.rs | 2 +- frame/support/src/metadata.rs | 2 +- frame/support/src/origin.rs | 2 +- frame/support/src/storage/child.rs | 2 +- .../src/storage/generator/double_map.rs | 2 +- frame/support/src/storage/generator/map.rs | 2 +- frame/support/src/storage/generator/mod.rs | 2 +- frame/support/src/storage/generator/value.rs | 2 +- frame/support/src/storage/hashed.rs | 2 +- frame/support/src/storage/migration.rs | 2 +- frame/support/src/storage/mod.rs | 2 +- frame/support/src/storage/types/double_map.rs | 2 +- frame/support/src/storage/types/map.rs | 2 +- frame/support/src/storage/types/mod.rs | 2 +- frame/support/src/storage/types/value.rs | 2 +- frame/support/src/storage/unhashed.rs | 2 +- frame/support/src/traits.rs | 2 +- frame/support/src/unsigned.rs | 2 +- frame/support/src/weights.rs | 2 +- frame/support/test/src/lib.rs | 2 +- frame/support/test/src/pallet_version.rs | 2 +- frame/support/test/tests/construct_runtime.rs | 2 +- .../test/tests/construct_runtime_ui.rs | 2 +- frame/support/test/tests/decl_module_ui.rs | 2 +- frame/support/test/tests/decl_storage.rs | 2 +- frame/support/test/tests/decl_storage_ui.rs | 2 +- .../tests/decl_storage_ui/config_duplicate.rs | 2 +- .../decl_storage_ui/config_get_duplicate.rs | 2 +- .../tests/decl_storage_ui/get_duplicate.rs | 2 +- frame/support/test/tests/derive_no_bound.rs | 2 +- .../support/test/tests/derive_no_bound_ui.rs | 2 +- frame/support/test/tests/final_keys.rs | 2 +- frame/support/test/tests/genesisconfig.rs | 2 +- frame/support/test/tests/instance.rs | 2 +- frame/support/test/tests/issue2219.rs | 2 +- frame/support/test/tests/pallet.rs | 2 +- .../test/tests/pallet_compatibility.rs | 2 +- .../tests/pallet_compatibility_instance.rs | 2 +- frame/support/test/tests/pallet_instance.rs | 2 +- frame/support/test/tests/pallet_ui.rs | 2 +- frame/support/test/tests/pallet_version.rs | 2 +- .../tests/pallet_with_name_trait_is_valid.rs | 2 +- frame/support/test/tests/reserved_keyword.rs | 2 +- .../support/test/tests/storage_transaction.rs | 2 +- frame/support/test/tests/system.rs | 2 +- frame/system/benches/bench.rs | 2 +- frame/system/benchmarking/src/lib.rs | 2 +- frame/system/benchmarking/src/mock.rs | 2 +- frame/system/rpc/runtime-api/src/lib.rs | 2 +- frame/system/src/extensions/check_genesis.rs | 2 +- .../system/src/extensions/check_mortality.rs | 2 +- frame/system/src/extensions/check_nonce.rs | 2 +- .../src/extensions/check_spec_version.rs | 2 +- .../system/src/extensions/check_tx_version.rs | 2 +- frame/system/src/extensions/check_weight.rs | 2 +- frame/system/src/extensions/mod.rs | 2 +- frame/system/src/lib.rs | 2 +- frame/system/src/limits.rs | 2 +- frame/system/src/mock.rs | 2 +- frame/system/src/offchain.rs | 2 +- frame/system/src/tests.rs | 2 +- frame/system/src/weights.rs | 2 +- frame/timestamp/src/benchmarking.rs | 2 +- frame/timestamp/src/lib.rs | 2 +- frame/timestamp/src/weights.rs | 2 +- frame/tips/src/benchmarking.rs | 2 +- frame/tips/src/lib.rs | 2 +- frame/tips/src/tests.rs | 2 +- frame/tips/src/weights.rs | 2 +- .../rpc/runtime-api/src/lib.rs | 2 +- frame/transaction-payment/rpc/src/lib.rs | 2 +- frame/transaction-payment/src/lib.rs | 2 +- frame/treasury/src/benchmarking.rs | 2 +- frame/treasury/src/lib.rs | 2 +- frame/treasury/src/tests.rs | 2 +- frame/treasury/src/weights.rs | 2 +- frame/utility/src/benchmarking.rs | 2 +- frame/utility/src/lib.rs | 2 +- frame/utility/src/tests.rs | 2 +- frame/utility/src/weights.rs | 2 +- frame/vesting/src/benchmarking.rs | 2 +- frame/vesting/src/lib.rs | 2 +- frame/vesting/src/weights.rs | 2 +- primitives/allocator/src/error.rs | 2 +- primitives/allocator/src/freeing_bump.rs | 2 +- primitives/allocator/src/lib.rs | 2 +- .../api/proc-macro/src/decl_runtime_apis.rs | 2 +- .../api/proc-macro/src/impl_runtime_apis.rs | 2 +- primitives/api/proc-macro/src/lib.rs | 2 +- .../proc-macro/src/mock_impl_runtime_apis.rs | 2 +- primitives/api/proc-macro/src/utils.rs | 2 +- primitives/api/src/lib.rs | 2 +- primitives/api/test/benches/bench.rs | 2 +- primitives/api/test/tests/decl_and_impl.rs | 2 +- primitives/api/test/tests/runtime_calls.rs | 2 +- primitives/api/test/tests/trybuild.rs | 2 +- primitives/application-crypto/src/ecdsa.rs | 27 +++++++------- primitives/application-crypto/src/ed25519.rs | 2 +- primitives/application-crypto/src/lib.rs | 2 +- primitives/application-crypto/src/sr25519.rs | 2 +- primitives/application-crypto/src/traits.rs | 2 +- .../application-crypto/test/src/ecdsa.rs | 25 ++++++------- .../application-crypto/test/src/ed25519.rs | 2 +- primitives/application-crypto/test/src/lib.rs | 2 +- .../application-crypto/test/src/sr25519.rs | 2 +- primitives/arithmetic/benches/bench.rs | 2 +- primitives/arithmetic/fuzzer/src/biguint.rs | 2 +- .../arithmetic/fuzzer/src/fixed_point.rs | 2 +- .../fuzzer/src/multiply_by_rational.rs | 2 +- primitives/arithmetic/fuzzer/src/normalize.rs | 2 +- .../fuzzer/src/per_thing_rational.rs | 2 +- primitives/arithmetic/src/biguint.rs | 2 +- primitives/arithmetic/src/fixed_point.rs | 27 +++++++------- primitives/arithmetic/src/helpers_128bit.rs | 2 +- primitives/arithmetic/src/lib.rs | 2 +- primitives/arithmetic/src/per_things.rs | 2 +- primitives/arithmetic/src/rational.rs | 2 +- primitives/arithmetic/src/traits.rs | 2 +- primitives/authority-discovery/src/lib.rs | 2 +- primitives/authorship/src/lib.rs | 2 +- primitives/block-builder/src/lib.rs | 2 +- primitives/blockchain/src/backend.rs | 2 +- primitives/blockchain/src/error.rs | 2 +- primitives/blockchain/src/header_metadata.rs | 2 +- primitives/blockchain/src/lib.rs | 2 +- primitives/chain-spec/src/lib.rs | 2 +- primitives/consensus/aura/src/inherents.rs | 2 +- primitives/consensus/aura/src/lib.rs | 2 +- primitives/consensus/babe/src/digests.rs | 2 +- primitives/consensus/babe/src/inherents.rs | 2 +- primitives/consensus/babe/src/lib.rs | 2 +- .../consensus/common/src/block_import.rs | 2 +- .../consensus/common/src/block_validation.rs | 25 ++++++------- primitives/consensus/common/src/error.rs | 2 +- primitives/consensus/common/src/evaluation.rs | 2 +- .../consensus/common/src/import_queue.rs | 2 +- .../common/src/import_queue/basic_queue.rs | 2 +- .../common/src/import_queue/buffered_link.rs | 2 +- primitives/consensus/common/src/lib.rs | 31 ++++++++-------- primitives/consensus/common/src/metrics.rs | 25 ++++++------- .../consensus/common/src/offline_tracker.rs | 2 +- .../consensus/common/src/select_chain.rs | 31 ++++++++-------- primitives/consensus/pow/src/lib.rs | 2 +- primitives/consensus/slots/src/lib.rs | 2 +- primitives/consensus/vrf/src/lib.rs | 2 +- primitives/consensus/vrf/src/schnorrkel.rs | 2 +- primitives/core/src/changes_trie.rs | 2 +- primitives/core/src/crypto.rs | 2 +- primitives/core/src/ecdsa.rs | 2 +- primitives/core/src/ed25519.rs | 2 +- primitives/core/src/hash.rs | 2 +- primitives/core/src/hasher.rs | 2 +- primitives/core/src/hashing.rs | 2 +- primitives/core/src/hexdisplay.rs | 2 +- primitives/core/src/lib.rs | 2 +- primitives/core/src/offchain/mod.rs | 2 +- primitives/core/src/offchain/storage.rs | 2 +- primitives/core/src/offchain/testing.rs | 2 +- primitives/core/src/sandbox.rs | 2 +- primitives/core/src/sr25519.rs | 2 +- primitives/core/src/testing.rs | 2 +- primitives/core/src/traits.rs | 2 +- primitives/core/src/u32_trait.rs | 2 +- primitives/core/src/uint.rs | 2 +- primitives/database/src/error.rs | 2 +- primitives/database/src/kvdb.rs | 2 +- primitives/database/src/lib.rs | 2 +- primitives/database/src/mem.rs | 2 +- primitives/debug-derive/src/impls.rs | 2 +- primitives/debug-derive/src/lib.rs | 2 +- primitives/debug-derive/tests/tests.rs | 2 +- primitives/externalities/src/extensions.rs | 2 +- primitives/externalities/src/lib.rs | 2 +- primitives/externalities/src/scope_limited.rs | 2 +- primitives/finality-grandpa/src/lib.rs | 2 +- primitives/inherents/src/lib.rs | 2 +- primitives/io/src/batch_verifier.rs | 2 +- primitives/io/src/lib.rs | 2 +- primitives/keyring/src/ed25519.rs | 2 +- primitives/keyring/src/lib.rs | 2 +- primitives/keyring/src/sr25519.rs | 2 +- primitives/keystore/src/lib.rs | 2 +- primitives/keystore/src/testing.rs | 2 +- primitives/keystore/src/vrf.rs | 2 +- .../npos-elections/compact/src/assignment.rs | 2 +- .../npos-elections/compact/src/codec.rs | 2 +- primitives/npos-elections/compact/src/lib.rs | 2 +- .../npos-elections/fuzzer/src/common.rs | 2 +- .../fuzzer/src/phragmen_balancing.rs | 2 +- .../fuzzer/src/phragmms_balancing.rs | 2 +- .../npos-elections/fuzzer/src/reduce.rs | 2 +- primitives/npos-elections/src/balancing.rs | 2 +- primitives/npos-elections/src/helpers.rs | 2 +- primitives/npos-elections/src/lib.rs | 2 +- primitives/npos-elections/src/mock.rs | 2 +- primitives/npos-elections/src/node.rs | 2 +- primitives/npos-elections/src/phragmen.rs | 2 +- primitives/npos-elections/src/phragmms.rs | 2 +- primitives/npos-elections/src/reduce.rs | 2 +- primitives/npos-elections/src/tests.rs | 2 +- primitives/offchain/src/lib.rs | 2 +- primitives/panic-handler/src/lib.rs | 2 +- primitives/rpc/src/lib.rs | 2 +- primitives/rpc/src/list.rs | 2 +- primitives/rpc/src/number.rs | 2 +- .../runtime-interface/proc-macro/src/lib.rs | 2 +- .../proc-macro/src/pass_by/codec.rs | 2 +- .../proc-macro/src/pass_by/enum_.rs | 2 +- .../proc-macro/src/pass_by/inner.rs | 2 +- .../proc-macro/src/pass_by/mod.rs | 2 +- .../bare_function_interface.rs | 2 +- .../host_function_interface.rs | 2 +- .../proc-macro/src/runtime_interface/mod.rs | 2 +- .../src/runtime_interface/trait_decl_impl.rs | 2 +- .../runtime-interface/proc-macro/src/utils.rs | 29 +++++++-------- primitives/runtime-interface/src/host.rs | 2 +- primitives/runtime-interface/src/impls.rs | 2 +- primitives/runtime-interface/src/lib.rs | 2 +- primitives/runtime-interface/src/pass_by.rs | 2 +- primitives/runtime-interface/src/util.rs | 2 +- primitives/runtime-interface/src/wasm.rs | 2 +- .../test-wasm-deprecated/build.rs | 2 +- .../test-wasm-deprecated/src/lib.rs | 2 +- .../runtime-interface/test-wasm/build.rs | 2 +- .../runtime-interface/test-wasm/src/lib.rs | 2 +- primitives/runtime-interface/test/src/lib.rs | 2 +- primitives/runtime-interface/tests/ui.rs | 2 +- primitives/runtime/src/curve.rs | 2 +- primitives/runtime/src/generic/block.rs | 2 +- .../runtime/src/generic/checked_extrinsic.rs | 2 +- primitives/runtime/src/generic/digest.rs | 2 +- primitives/runtime/src/generic/era.rs | 2 +- primitives/runtime/src/generic/header.rs | 2 +- primitives/runtime/src/generic/mod.rs | 2 +- primitives/runtime/src/generic/tests.rs | 2 +- .../src/generic/unchecked_extrinsic.rs | 2 +- primitives/runtime/src/lib.rs | 2 +- primitives/runtime/src/multiaddress.rs | 2 +- primitives/runtime/src/offchain/http.rs | 2 +- primitives/runtime/src/offchain/mod.rs | 2 +- primitives/runtime/src/offchain/storage.rs | 2 +- .../runtime/src/offchain/storage_lock.rs | 27 +++++++------- .../runtime/src/random_number_generator.rs | 2 +- primitives/runtime/src/runtime_string.rs | 2 +- primitives/runtime/src/testing.rs | 2 +- primitives/runtime/src/traits.rs | 2 +- .../runtime/src/transaction_validity.rs | 2 +- primitives/sandbox/src/lib.rs | 2 +- primitives/sandbox/with_std.rs | 2 +- primitives/sandbox/without_std.rs | 2 +- primitives/serializer/src/lib.rs | 2 +- primitives/session/src/lib.rs | 2 +- primitives/sr-api/proc-macro/src/lib.rs | 25 ++++++------- primitives/staking/src/lib.rs | 23 ++++++------ primitives/staking/src/offence.rs | 2 +- primitives/state-machine/src/backend.rs | 2 +- primitives/state-machine/src/basic.rs | 2 +- .../state-machine/src/changes_trie/build.rs | 2 +- .../src/changes_trie/build_cache.rs | 2 +- .../src/changes_trie/build_iterator.rs | 2 +- .../src/changes_trie/changes_iterator.rs | 2 +- .../state-machine/src/changes_trie/input.rs | 2 +- .../state-machine/src/changes_trie/mod.rs | 2 +- .../state-machine/src/changes_trie/prune.rs | 2 +- .../state-machine/src/changes_trie/storage.rs | 2 +- .../src/changes_trie/surface_iterator.rs | 2 +- primitives/state-machine/src/error.rs | 2 +- primitives/state-machine/src/ext.rs | 2 +- .../state-machine/src/in_memory_backend.rs | 27 +++++++------- primitives/state-machine/src/lib.rs | 2 +- .../src/overlayed_changes/changeset.rs | 2 +- .../src/overlayed_changes/mod.rs | 2 +- .../state-machine/src/proving_backend.rs | 2 +- primitives/state-machine/src/read_only.rs | 2 +- primitives/state-machine/src/stats.rs | 2 +- primitives/state-machine/src/testing.rs | 2 +- primitives/state-machine/src/trie_backend.rs | 2 +- .../state-machine/src/trie_backend_essence.rs | 2 +- primitives/std/src/lib.rs | 2 +- primitives/std/with_std.rs | 2 +- primitives/std/without_std.rs | 2 +- primitives/storage/src/lib.rs | 2 +- primitives/tasks/src/async_externalities.rs | 2 +- primitives/tasks/src/lib.rs | 2 +- primitives/test-primitives/src/lib.rs | 2 +- primitives/timestamp/src/lib.rs | 2 +- primitives/tracing/src/lib.rs | 2 +- primitives/tracing/src/types.rs | 2 +- primitives/transaction-pool/src/error.rs | 2 +- primitives/transaction-pool/src/lib.rs | 2 +- primitives/transaction-pool/src/pool.rs | 2 +- .../transaction-pool/src/runtime_api.rs | 2 +- primitives/trie/benches/bench.rs | 25 ++++++------- primitives/trie/src/error.rs | 21 +++++++---- primitives/trie/src/lib.rs | 27 +++++++------- primitives/trie/src/node_codec.rs | 27 +++++++------- primitives/trie/src/node_header.rs | 25 ++++++------- primitives/trie/src/storage_proof.rs | 27 +++++++------- primitives/trie/src/trie_stream.rs | 27 +++++++------- primitives/utils/src/lib.rs | 2 +- primitives/utils/src/metrics.rs | 2 +- primitives/utils/src/mpsc.rs | 2 +- primitives/utils/src/status_sinks.rs | 27 +++++++------- primitives/version/src/lib.rs | 2 +- primitives/wasm-interface/src/lib.rs | 2 +- primitives/wasm-interface/src/wasmi_impl.rs | 2 +- test-utils/client/src/client_ext.rs | 2 +- test-utils/client/src/lib.rs | 2 +- test-utils/derive/src/lib.rs | 2 +- test-utils/runtime/build.rs | 2 +- .../runtime/client/src/block_builder_ext.rs | 2 +- test-utils/runtime/client/src/lib.rs | 2 +- test-utils/runtime/client/src/trait_tests.rs | 2 +- test-utils/runtime/src/genesismap.rs | 2 +- test-utils/runtime/src/lib.rs | 2 +- test-utils/runtime/src/system.rs | 2 +- .../runtime/transaction-pool/src/lib.rs | 2 +- test-utils/src/lib.rs | 2 +- test-utils/test-crate/src/main.rs | 2 +- test-utils/tests/basic.rs | 2 +- test-utils/tests/ui.rs | 2 +- test-utils/tests/ui/missing-func-parameter.rs | 2 +- .../tests/ui/too-many-func-parameters.rs | 2 +- utils/browser/src/lib.rs | 2 +- utils/build-script-utils/src/git.rs | 2 +- utils/build-script-utils/src/lib.rs | 2 +- utils/build-script-utils/src/version.rs | 2 +- utils/fork-tree/src/lib.rs | 2 +- utils/frame/benchmarking-cli/src/command.rs | 2 +- utils/frame/benchmarking-cli/src/lib.rs | 2 +- utils/frame/benchmarking-cli/src/writer.rs | 2 +- utils/frame/frame-utilities-cli/src/lib.rs | 2 +- .../frame-utilities-cli/src/module_id.rs | 2 +- utils/frame/rpc/support/src/lib.rs | 2 +- utils/frame/rpc/system/src/lib.rs | 2 +- utils/prometheus/src/lib.rs | 27 +++++++------- utils/prometheus/src/networking.rs | 2 +- utils/prometheus/src/sourced.rs | 27 +++++++------- utils/wasm-builder/src/builder.rs | 2 +- utils/wasm-builder/src/lib.rs | 2 +- utils/wasm-builder/src/prerequisites.rs | 2 +- utils/wasm-builder/src/wasm_project.rs | 2 +- 923 files changed, 2004 insertions(+), 1769 deletions(-) rename HEADER => HEADER-APACHE (92%) rename docs/license_header.txt => HEADER-GPL (50%) diff --git a/.maintain/frame-weight-template.hbs b/.maintain/frame-weight-template.hbs index 76f89eafbae..2253452e203 100644 --- a/.maintain/frame-weight-template.hbs +++ b/.maintain/frame-weight-template.hbs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/.maintain/update-copyright.sh b/.maintain/update-copyright.sh index d48fc3cc979..d67cab7c1e1 100755 --- a/.maintain/update-copyright.sh +++ b/.maintain/update-copyright.sh @@ -1,15 +1,14 @@ #!/usr/bin/env bash -SINGLE_DATES=$(grep -lr "// Copyright [0-9]* Parity Technologies (UK) Ltd.") -RANGE_DATES=$(grep -lr "// Copyright [0-9]*-[0-9]* Parity Technologies (UK) Ltd.") +SINGLE_DATES=$(grep -lr "// Copyright (C) [0-9]* Parity Technologies (UK) Ltd.") YEAR=$(date +%Y) for file in $SINGLE_DATES; do - FILE_YEAR=$(cat $file | sed -n "s|// Copyright \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\) Parity Technologies (UK) Ltd.|\1|p") + FILE_YEAR=$(cat $file | sed -n "s|// Copyright (C) \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\) Parity Technologies (UK) Ltd.|\1|p") if [ $YEAR -ne $FILE_YEAR ]; then - sed -i -e "s|// Copyright \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\) Parity Technologies (UK) Ltd.|// Copyright \1-$YEAR Parity Technologies (UK) Ltd.|g" $file + sed -i -e "s|// Copyright (C) \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\) Parity Technologies (UK) Ltd.|// Copyright (C) \1-$YEAR Parity Technologies (UK) Ltd.|g" $file fi done -grep -lr "// Copyright [0-9]*-[0-9]* Parity Technologies (UK) Ltd." | - xargs sed -i -e "s|// Copyright \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\)-[[:digit:]][[:digit:]][[:digit:]][[:digit:]] Parity Technologies (UK) Ltd.|// Copyright \1-$YEAR Parity Technologies (UK) Ltd.|g" +grep -lr "// Copyright (C) [0-9]*-[0-9]* Parity Technologies (UK) Ltd." | + xargs sed -i -e "s|// Copyright (C) \([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\)-[[:digit:]][[:digit:]][[:digit:]][[:digit:]] Parity Technologies (UK) Ltd.|// Copyright (C) \1-$YEAR Parity Technologies (UK) Ltd.|g" diff --git a/HEADER b/HEADER-APACHE similarity index 92% rename from HEADER rename to HEADER-APACHE index c9b28a07b0f..f364f4bdf84 100644 --- a/HEADER +++ b/HEADER-APACHE @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/docs/license_header.txt b/HEADER-GPL similarity index 50% rename from docs/license_header.txt rename to HEADER-GPL index f9c1daa1ad1..0dd7e4f7602 100644 --- a/docs/license_header.txt +++ b/HEADER-GPL @@ -1,15 +1,17 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index acf29bd591e..1c22b388af7 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/bench/src/common.rs b/bin/node/bench/src/common.rs index 2637d6e9bd0..d04d79e9907 100644 --- a/bin/node/bench/src/common.rs +++ b/bin/node/bench/src/common.rs @@ -1,7 +1,6 @@ - // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 @@ -45,4 +44,4 @@ impl SizeType { SizeType::Custom(val) => Some(*val), } } -} \ No newline at end of file +} diff --git a/bin/node/bench/src/construct.rs b/bin/node/bench/src/construct.rs index 5506dc426de..a8a02f19c30 100644 --- a/bin/node/bench/src/construct.rs +++ b/bin/node/bench/src/construct.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/core.rs b/bin/node/bench/src/core.rs index 6faa7b72721..26b7f92b144 100644 --- a/bin/node/bench/src/core.rs +++ b/bin/node/bench/src/core.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/generator.rs b/bin/node/bench/src/generator.rs index 759a4299c72..c540ae147c9 100644 --- a/bin/node/bench/src/generator.rs +++ b/bin/node/bench/src/generator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/import.rs b/bin/node/bench/src/import.rs index ae28a20089e..b4fee58dac0 100644 --- a/bin/node/bench/src/import.rs +++ b/bin/node/bench/src/import.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/main.rs b/bin/node/bench/src/main.rs index 46b659dd883..40e9e157777 100644 --- a/bin/node/bench/src/main.rs +++ b/bin/node/bench/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/simple_trie.rs b/bin/node/bench/src/simple_trie.rs index 3cfd7ddb300..a29b51a38af 100644 --- a/bin/node/bench/src/simple_trie.rs +++ b/bin/node/bench/src/simple_trie.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/state_sizes.rs b/bin/node/bench/src/state_sizes.rs index d35989f61be..f9288c10548 100644 --- a/bin/node/bench/src/state_sizes.rs +++ b/bin/node/bench/src/state_sizes.rs @@ -1,18 +1,20 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity. +// This file is part of Substrate. -// Parity is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Parity is distributed in the hope that it will be useful, +// 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 +// 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 Parity. If not, see . +// along with this program. If not, see . /// Kusama value size distribution pub const KUSAMA_STATE_DISTRIBUTION: &'static[(u32, u32)] = &[ @@ -4753,4 +4755,4 @@ pub const KUSAMA_STATE_DISTRIBUTION: &'static[(u32, u32)] = &[ (1516670, 1), (1605731, 1), (1605821, 1), -]; \ No newline at end of file +]; diff --git a/bin/node/bench/src/tempdb.rs b/bin/node/bench/src/tempdb.rs index abce7daa518..31ef71fba7b 100644 --- a/bin/node/bench/src/tempdb.rs +++ b/bin/node/bench/src/tempdb.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/trie.rs b/bin/node/bench/src/trie.rs index eb6c574e271..a3e7620473d 100644 --- a/bin/node/bench/src/trie.rs +++ b/bin/node/bench/src/trie.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/bench/src/txpool.rs b/bin/node/bench/src/txpool.rs index 7ea13fc15ec..ecac3827adf 100644 --- a/bin/node/bench/src/txpool.rs +++ b/bin/node/bench/src/txpool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/browser-testing/src/lib.rs b/bin/node/browser-testing/src/lib.rs index f4dc0908567..ad18de87b3d 100644 --- a/bin/node/browser-testing/src/lib.rs +++ b/bin/node/browser-testing/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/cli/bin/main.rs b/bin/node/cli/bin/main.rs index 299b760c82e..cf32a7cf288 100644 --- a/bin/node/cli/bin/main.rs +++ b/bin/node/cli/bin/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/cli/build.rs b/bin/node/cli/build.rs index a36f0d01a0a..befcdaea6d9 100644 --- a/bin/node/cli/build.rs +++ b/bin/node/cli/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 41770f5fcde..42886a668d3 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 83dc95e3b64..7bee74d6c67 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index 2130ff1e4b1..63a07e00e21 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index bb1bf0169e6..ed3aff88c75 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/bin/node/cli/src/lib.rs b/bin/node/cli/src/lib.rs index bd2298514a7..d29836c7499 100644 --- a/bin/node/cli/src/lib.rs +++ b/bin/node/cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 5eb8e35e69e..0b4e24f2ce6 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/cli/tests/build_spec_works.rs b/bin/node/cli/tests/build_spec_works.rs index 800a4a8c51e..6d863ea7f94 100644 --- a/bin/node/cli/tests/build_spec_works.rs +++ b/bin/node/cli/tests/build_spec_works.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/check_block_works.rs b/bin/node/cli/tests/check_block_works.rs index 34078b08cf0..39963fb0028 100644 --- a/bin/node/cli/tests/check_block_works.rs +++ b/bin/node/cli/tests/check_block_works.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/common.rs b/bin/node/cli/tests/common.rs index 61a07dd1ca8..c3bb96555da 100644 --- a/bin/node/cli/tests/common.rs +++ b/bin/node/cli/tests/common.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/export_import_flow.rs b/bin/node/cli/tests/export_import_flow.rs index 557e722ddb7..02fba49e834 100644 --- a/bin/node/cli/tests/export_import_flow.rs +++ b/bin/node/cli/tests/export_import_flow.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/inspect_works.rs b/bin/node/cli/tests/inspect_works.rs index aa9653acadb..67dbc97056c 100644 --- a/bin/node/cli/tests/inspect_works.rs +++ b/bin/node/cli/tests/inspect_works.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/purge_chain_works.rs b/bin/node/cli/tests/purge_chain_works.rs index 001bed8b136..4c0727d26cb 100644 --- a/bin/node/cli/tests/purge_chain_works.rs +++ b/bin/node/cli/tests/purge_chain_works.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs index bd79dcd77a4..05eb9a7027b 100644 --- a/bin/node/cli/tests/running_the_node_and_interrupt.rs +++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/temp_base_path_works.rs b/bin/node/cli/tests/temp_base_path_works.rs index 9351568d879..0152ddb464d 100644 --- a/bin/node/cli/tests/temp_base_path_works.rs +++ b/bin/node/cli/tests/temp_base_path_works.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/cli/tests/version.rs b/bin/node/cli/tests/version.rs index bbc9139d4f0..38e4b1fbda7 100644 --- a/bin/node/cli/tests/version.rs +++ b/bin/node/cli/tests/version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/executor/benches/bench.rs b/bin/node/executor/benches/bench.rs index 168cff0ff45..554e6c4af42 100644 --- a/bin/node/executor/benches/bench.rs +++ b/bin/node/executor/benches/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/executor/src/lib.rs b/bin/node/executor/src/lib.rs index 4c3b82bc7d3..e7fb09a19c5 100644 --- a/bin/node/executor/src/lib.rs +++ b/bin/node/executor/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 09438bfacd4..2b644fad291 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/executor/tests/common.rs b/bin/node/executor/tests/common.rs index efc54ebebf1..b376ebc35ba 100644 --- a/bin/node/executor/tests/common.rs +++ b/bin/node/executor/tests/common.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index d04af1d8270..07460e54680 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 5bac6b5e374..f3cb90cbecd 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/inspect/src/cli.rs b/bin/node/inspect/src/cli.rs index d66644bab52..abdbedc296d 100644 --- a/bin/node/inspect/src/cli.rs +++ b/bin/node/inspect/src/cli.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/inspect/src/command.rs b/bin/node/inspect/src/command.rs index fae6c10c7fe..a1a9c947a56 100644 --- a/bin/node/inspect/src/command.rs +++ b/bin/node/inspect/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/inspect/src/lib.rs b/bin/node/inspect/src/lib.rs index 02f5614b81a..2a55fdcda62 100644 --- a/bin/node/inspect/src/lib.rs +++ b/bin/node/inspect/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. // -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/bin/node/primitives/src/lib.rs b/bin/node/primitives/src/lib.rs index 137fb1d94c7..9470adc399f 100644 --- a/bin/node/primitives/src/lib.rs +++ b/bin/node/primitives/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/rpc-client/src/main.rs b/bin/node/rpc-client/src/main.rs index 31f1efa28cc..ddd8a50ad36 100644 --- a/bin/node/rpc-client/src/main.rs +++ b/bin/node/rpc-client/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 1ced3d60ab3..e68ca6843bc 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/runtime/build.rs b/bin/node/runtime/build.rs index 8a0b4d7a0c1..a1c4b2d892c 100644 --- a/bin/node/runtime/build.rs +++ b/bin/node/runtime/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/runtime/src/constants.rs b/bin/node/runtime/src/constants.rs index 0301c30d5b6..f447486c7ff 100644 --- a/bin/node/runtime/src/constants.rs +++ b/bin/node/runtime/src/constants.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index d7910c2c63b..c6a56e5ac0d 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 4eee9d83a58..20600862434 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 35af52a2f36..3bc31c6e414 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index f44747b26b7..c4ace4ced9b 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 6fa178ba4bc..75d0d18e6ef 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index f0b8ff70729..da61040206e 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/node/testing/src/lib.rs b/bin/node/testing/src/lib.rs index d682347e400..c5792bccee8 100644 --- a/bin/node/testing/src/lib.rs +++ b/bin/node/testing/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/utils/chain-spec-builder/build.rs b/bin/utils/chain-spec-builder/build.rs index 8d5aac1a087..57424f016f3 100644 --- a/bin/utils/chain-spec-builder/build.rs +++ b/bin/utils/chain-spec-builder/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index c2db944050e..f3336b1d53a 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/bin/utils/subkey/src/lib.rs b/bin/utils/subkey/src/lib.rs index 0fe6f417d1a..5f7787f0224 100644 --- a/bin/utils/subkey/src/lib.rs +++ b/bin/utils/subkey/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index dd14425130b..39f2f9e2e5b 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/api/src/backend.rs b/client/api/src/backend.rs index 47fec977f5e..c2b42d1b344 100644 --- a/client/api/src/backend.rs +++ b/client/api/src/backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/api/src/call_executor.rs b/client/api/src/call_executor.rs index 86e3440f19c..9c0ea87ea71 100644 --- a/client/api/src/call_executor.rs +++ b/client/api/src/call_executor.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/api/src/cht.rs b/client/api/src/cht.rs index 7fd7aa0dbcb..b4c4ce70cb3 100644 --- a/client/api/src/cht.rs +++ b/client/api/src/cht.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/api/src/client.rs b/client/api/src/client.rs index f97daa48763..4dc2b6bb524 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A set of APIs supported by the client along with their primitives. diff --git a/client/api/src/execution_extensions.rs b/client/api/src/execution_extensions.rs index c187e758002..68b412a0d77 100644 --- a/client/api/src/execution_extensions.rs +++ b/client/api/src/execution_extensions.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Execution extensions for runtime calls. //! diff --git a/client/api/src/in_mem.rs b/client/api/src/in_mem.rs index ded030fb804..cef52982f16 100644 --- a/client/api/src/in_mem.rs +++ b/client/api/src/in_mem.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/api/src/leaves.rs b/client/api/src/leaves.rs index d10fa7ac0e5..1971012c6aa 100644 --- a/client/api/src/leaves.rs +++ b/client/api/src/leaves.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/api/src/lib.rs b/client/api/src/lib.rs index 67706693633..0f860b95e78 100644 --- a/client/api/src/lib.rs +++ b/client/api/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate client interfaces. #![warn(missing_docs)] diff --git a/client/api/src/light.rs b/client/api/src/light.rs index f9ba64544a8..a068e2d4a34 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate light client interfaces diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index ec63c372c7e..bfd419ec9a5 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/api/src/proof_provider.rs b/client/api/src/proof_provider.rs index 5749ae0576f..a0dbcf1d1e8 100644 --- a/client/api/src/proof_provider.rs +++ b/client/api/src/proof_provider.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index 82e4a6dd6f3..f482d192483 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Authority discovery errors. diff --git a/client/authority-discovery/src/interval.rs b/client/authority-discovery/src/interval.rs index b3aa5b1c0f6..0710487203d 100644 --- a/client/authority-discovery/src/interval.rs +++ b/client/authority-discovery/src/interval.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use futures::stream::Stream; use futures::future::FutureExt; diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 41aa01e56bd..26d4396ca88 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![warn(missing_docs)] #![recursion_limit = "1024"] diff --git a/client/authority-discovery/src/service.rs b/client/authority-discovery/src/service.rs index d23d2f3a480..1da97cbb03b 100644 --- a/client/authority-discovery/src/service.rs +++ b/client/authority-discovery/src/service.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::ServicetoWorkerMsg; diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index 414ffc1e3f3..78e978e07a1 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/authority-discovery/src/worker.rs b/client/authority-discovery/src/worker.rs index d886f24542d..0f4986a4a14 100644 --- a/client/authority-discovery/src/worker.rs +++ b/client/authority-discovery/src/worker.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{error::{Error, Result}, interval::ExpIncInterval, ServicetoWorkerMsg}; diff --git a/client/authority-discovery/src/worker/addr_cache.rs b/client/authority-discovery/src/worker/addr_cache.rs index 75fcaa84017..4ae6ae0cdeb 100644 --- a/client/authority-discovery/src/worker/addr_cache.rs +++ b/client/authority-discovery/src/worker/addr_cache.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use libp2p::core::multiaddr::{Multiaddr, Protocol}; use rand::seq::SliceRandom; diff --git a/client/authority-discovery/src/worker/tests.rs b/client/authority-discovery/src/worker/tests.rs index fee861dfeb0..2bc9c1ba6aa 100644 --- a/client/authority-discovery/src/worker/tests.rs +++ b/client/authority-discovery/src/worker/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 065acbde2cc..8a7750c69fe 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 2cb66d4ccc4..3bb0a0b7e5c 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index cc1431ea349..5a7e0277d9e 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/chain-spec/derive/src/impls.rs b/client/chain-spec/derive/src/impls.rs index ded961a6da8..bb72270ed55 100644 --- a/client/chain-spec/derive/src/impls.rs +++ b/client/chain-spec/derive/src/impls.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use proc_macro2::{Span, TokenStream}; use quote::quote; diff --git a/client/chain-spec/derive/src/lib.rs b/client/chain-spec/derive/src/lib.rs index 0dc053f7e30..53f0c69491e 100644 --- a/client/chain-spec/derive/src/lib.rs +++ b/client/chain-spec/derive/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Macros to derive chain spec extension traits implementation. diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 39c47e32908..2faf9556829 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/chain-spec/src/extension.rs b/client/chain-spec/src/extension.rs index c0338203eb1..c0352529f86 100644 --- a/client/chain-spec/src/extension.rs +++ b/client/chain-spec/src/extension.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Chain Spec extensions helpers. diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index 27657ccb7f8..ee4f757f8cf 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate chain configurations. //! diff --git a/client/cli/proc-macro/src/lib.rs b/client/cli/proc-macro/src/lib.rs index 775d1eb96ea..0e2466ec3ae 100644 --- a/client/cli/proc-macro/src/lib.rs +++ b/client/cli/proc-macro/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/arg_enums.rs b/client/cli/src/arg_enums.rs index 85400f2a277..2ebfa38925e 100644 --- a/client/cli/src/arg_enums.rs +++ b/client/cli/src/arg_enums.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/build_spec_cmd.rs b/client/cli/src/commands/build_spec_cmd.rs index 616c5139f64..3d66e752b81 100644 --- a/client/cli/src/commands/build_spec_cmd.rs +++ b/client/cli/src/commands/build_spec_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/check_block_cmd.rs b/client/cli/src/commands/check_block_cmd.rs index b536d4f26bb..74e2d34f975 100644 --- a/client/cli/src/commands/check_block_cmd.rs +++ b/client/cli/src/commands/check_block_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs index 497531ad393..55f05d9d7f3 100644 --- a/client/cli/src/commands/export_blocks_cmd.rs +++ b/client/cli/src/commands/export_blocks_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/export_state_cmd.rs b/client/cli/src/commands/export_state_cmd.rs index c078db0d8ae..2211b3131a0 100644 --- a/client/cli/src/commands/export_state_cmd.rs +++ b/client/cli/src/commands/export_state_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/commands/generate.rs b/client/cli/src/commands/generate.rs index 86b039ce6a4..08b5f207723 100644 --- a/client/cli/src/commands/generate.rs +++ b/client/cli/src/commands/generate.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/generate_node_key.rs b/client/cli/src/commands/generate_node_key.rs index ad292e4712d..ec22c6298ad 100644 --- a/client/cli/src/commands/generate_node_key.rs +++ b/client/cli/src/commands/generate_node_key.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/import_blocks_cmd.rs b/client/cli/src/commands/import_blocks_cmd.rs index 00f8ec43b02..89f70d06813 100644 --- a/client/cli/src/commands/import_blocks_cmd.rs +++ b/client/cli/src/commands/import_blocks_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/insert_key.rs b/client/cli/src/commands/insert_key.rs index 3338b708a4f..90588f96d20 100644 --- a/client/cli/src/commands/insert_key.rs +++ b/client/cli/src/commands/insert_key.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/inspect_key.rs b/client/cli/src/commands/inspect_key.rs index fb3a7ef4f3b..2642eee88ad 100644 --- a/client/cli/src/commands/inspect_key.rs +++ b/client/cli/src/commands/inspect_key.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/inspect_node_key.rs b/client/cli/src/commands/inspect_node_key.rs index be0b88589d5..4db32aefb5f 100644 --- a/client/cli/src/commands/inspect_node_key.rs +++ b/client/cli/src/commands/inspect_node_key.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/key.rs b/client/cli/src/commands/key.rs index d01e273f0ef..54645415971 100644 --- a/client/cli/src/commands/key.rs +++ b/client/cli/src/commands/key.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index 395d3fa9c5e..8c0d6acd6a5 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/purge_chain_cmd.rs b/client/cli/src/commands/purge_chain_cmd.rs index 9c9c6e91fb2..1902d92e634 100644 --- a/client/cli/src/commands/purge_chain_cmd.rs +++ b/client/cli/src/commands/purge_chain_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/revert_cmd.rs b/client/cli/src/commands/revert_cmd.rs index b2e3c1bf8e2..2745ce2c652 100644 --- a/client/cli/src/commands/revert_cmd.rs +++ b/client/cli/src/commands/revert_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs index 48bad16afb6..bbb8d6f68d7 100644 --- a/client/cli/src/commands/run_cmd.rs +++ b/client/cli/src/commands/run_cmd.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/sign.rs b/client/cli/src/commands/sign.rs index 605fd5b1231..a39e14697b9 100644 --- a/client/cli/src/commands/sign.rs +++ b/client/cli/src/commands/sign.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/utils.rs b/client/cli/src/commands/utils.rs index 25c7294fd1e..1bbff392eca 100644 --- a/client/cli/src/commands/utils.rs +++ b/client/cli/src/commands/utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/client/cli/src/commands/vanity.rs b/client/cli/src/commands/vanity.rs index 33b9025c13f..da47e8bb26c 100644 --- a/client/cli/src/commands/vanity.rs +++ b/client/cli/src/commands/vanity.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/commands/verify.rs b/client/cli/src/commands/verify.rs index 15abc04002f..f5bd5a06060 100644 --- a/client/cli/src/commands/verify.rs +++ b/client/cli/src/commands/verify.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 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 diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index f0eb84f853b..017d2b42168 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index 6290f071c98..75867e2f76b 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 0ab26e60647..1402e5e7ae4 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/cli/src/params/database_params.rs b/client/cli/src/params/database_params.rs index 24b23f6076a..21529f65a56 100644 --- a/client/cli/src/params/database_params.rs +++ b/client/cli/src/params/database_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index 376a72b8421..7409dbf79dc 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs index 751c2bb0700..d75cdebc5a5 100644 --- a/client/cli/src/params/keystore_params.rs +++ b/client/cli/src/params/keystore_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/params/mod.rs b/client/cli/src/params/mod.rs index 93467bc8ec6..8308b123f71 100644 --- a/client/cli/src/params/mod.rs +++ b/client/cli/src/params/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index a973d61272c..2040bd9bc78 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index 875411fbfb6..d43c87804dd 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/cli/src/params/offchain_worker_params.rs b/client/cli/src/params/offchain_worker_params.rs index f8d48edc472..ef39a1ed41b 100644 --- a/client/cli/src/params/offchain_worker_params.rs +++ b/client/cli/src/params/offchain_worker_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/params/pruning_params.rs b/client/cli/src/params/pruning_params.rs index 7db808e6d8f..80118cafd87 100644 --- a/client/cli/src/params/pruning_params.rs +++ b/client/cli/src/params/pruning_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index 13e24938482..45ce41846bf 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/params/transaction_pool_params.rs b/client/cli/src/params/transaction_pool_params.rs index 3ad27842692..bf0ed53e531 100644 --- a/client/cli/src/params/transaction_pool_params.rs +++ b/client/cli/src/params/transaction_pool_params.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index e6d35282ada..9836471fb9f 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/aura/src/digests.rs b/client/consensus/aura/src/digests.rs index 3332e4c6a6d..fec412b62d1 100644 --- a/client/consensus/aura/src/digests.rs +++ b/client/consensus/aura/src/digests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 246b3977127..60aad59e8f9 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/consensus/babe/rpc/src/lib.rs b/client/consensus/babe/rpc/src/lib.rs index a90964cdf73..4d5c091e0cb 100644 --- a/client/consensus/babe/rpc/src/lib.rs +++ b/client/consensus/babe/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 28a3692958e..90ad12c4558 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! BABE authority selection and slot claiming. diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 287121566a4..d399a12ea8a 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Schema for BABE epoch changes in the aux-db. diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index bf929992db0..ea3ca29dad0 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! # BABE (Blind Assignment for Blockchain Extension) //! diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 6e0536c85ce..82d8f9de5af 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! BABE testsuite diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index fd3c27be4f3..47c4da0834d 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Verification for BABE headers. use sp_runtime::{traits::Header, traits::DigestItemFor}; diff --git a/client/consensus/common/src/lib.rs b/client/consensus/common/src/lib.rs index 1d9b072cfe9..a53517c5c35 100644 --- a/client/consensus/common/src/lib.rs +++ b/client/consensus/common/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Collection of common consensus specific implementations mod longest_chain; diff --git a/client/consensus/common/src/longest_chain.rs b/client/consensus/common/src/longest_chain.rs index 981dbad0f60..8cf32a1dbd3 100644 --- a/client/consensus/common/src/longest_chain.rs +++ b/client/consensus/common/src/longest_chain.rs @@ -1,18 +1,21 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . + //! Longest chain implementation use std::sync::Arc; @@ -98,4 +101,4 @@ impl SelectChain for LongestChain self.backend.blockchain().best_containing(target_hash, maybe_max_number, import_lock) .map_err(|e| ConsensusError::ChainLookup(e.to_string()).into()) } -} \ No newline at end of file +} diff --git a/client/consensus/epochs/src/lib.rs b/client/consensus/epochs/src/lib.rs index acb07dd668a..76e8c8ed541 100644 --- a/client/consensus/epochs/src/lib.rs +++ b/client/consensus/epochs/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Generic utilities for epoch-based consensus engines. diff --git a/client/consensus/epochs/src/migration.rs b/client/consensus/epochs/src/migration.rs index e4717b5584e..6e7baba8053 100644 --- a/client/consensus/epochs/src/migration.rs +++ b/client/consensus/epochs/src/migration.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Migration types for epoch changes. diff --git a/client/consensus/manual-seal/src/consensus.rs b/client/consensus/manual-seal/src/consensus.rs index 7bafeb50207..0cfd99cab5c 100644 --- a/client/consensus/manual-seal/src/consensus.rs +++ b/client/consensus/manual-seal/src/consensus.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/manual-seal/src/consensus/babe.rs b/client/consensus/manual-seal/src/consensus/babe.rs index c2fdf6243c3..1566b647f2c 100644 --- a/client/consensus/manual-seal/src/consensus/babe.rs +++ b/client/consensus/manual-seal/src/consensus/babe.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/manual-seal/src/error.rs b/client/consensus/manual-seal/src/error.rs index e2628008c24..77140c835a3 100644 --- a/client/consensus/manual-seal/src/error.rs +++ b/client/consensus/manual-seal/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/manual-seal/src/finalize_block.rs b/client/consensus/manual-seal/src/finalize_block.rs index 5780a25f972..76ae6eeeae5 100644 --- a/client/consensus/manual-seal/src/finalize_block.rs +++ b/client/consensus/manual-seal/src/finalize_block.rs @@ -1,18 +1,20 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Block finalization utilities diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 9c4465f82fd..5bf08571195 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/manual-seal/src/rpc.rs b/client/consensus/manual-seal/src/rpc.rs index 690b6c1eb99..293d4487a5d 100644 --- a/client/consensus/manual-seal/src/rpc.rs +++ b/client/consensus/manual-seal/src/rpc.rs @@ -1,18 +1,20 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RPC interface for the `ManualSeal` Engine. diff --git a/client/consensus/manual-seal/src/seal_block.rs b/client/consensus/manual-seal/src/seal_block.rs index a4afaa343e9..59b99349bf9 100644 --- a/client/consensus/manual-seal/src/seal_block.rs +++ b/client/consensus/manual-seal/src/seal_block.rs @@ -1,18 +1,20 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Block sealing utilities diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index e353ed6358a..975a6f17e79 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/consensus/pow/src/worker.rs b/client/consensus/pow/src/worker.rs index 4ed863dcd9e..c19c5524d97 100644 --- a/client/consensus/pow/src/worker.rs +++ b/client/consensus/pow/src/worker.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/consensus/slots/build.rs b/client/consensus/slots/build.rs index 513cc234d43..57424f016f3 100644 --- a/client/consensus/slots/build.rs +++ b/client/consensus/slots/build.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::env; diff --git a/client/consensus/slots/src/aux_schema.rs b/client/consensus/slots/src/aux_schema.rs index 1f1fe37068f..c8095f238ec 100644 --- a/client/consensus/slots/src/aux_schema.rs +++ b/client/consensus/slots/src/aux_schema.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Schema for slots in the aux-db. diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 571766bc44b..93d3614584f 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Slots functionality for Substrate. //! diff --git a/client/consensus/slots/src/slots.rs b/client/consensus/slots/src/slots.rs index e7c84a2c1fd..0c93e16461c 100644 --- a/client/consensus/slots/src/slots.rs +++ b/client/consensus/slots/src/slots.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Utility stream for yielding slots in a loop. //! diff --git a/client/consensus/uncles/src/lib.rs b/client/consensus/uncles/src/lib.rs index 2a129b20006..f38849300d0 100644 --- a/client/consensus/uncles/src/lib.rs +++ b/client/consensus/uncles/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Uncles functionality for Substrate. #![forbid(unsafe_code, missing_docs)] diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index 5696922b4fb..f0c187bd379 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/db/src/cache/list_cache.rs b/client/db/src/cache/list_cache.rs index 15ad339b1f2..341105b16a5 100644 --- a/client/db/src/cache/list_cache.rs +++ b/client/db/src/cache/list_cache.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/cache/list_entry.rs b/client/db/src/cache/list_entry.rs index d14fab9274c..94d4eb9f49b 100644 --- a/client/db/src/cache/list_entry.rs +++ b/client/db/src/cache/list_entry.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/cache/list_storage.rs b/client/db/src/cache/list_storage.rs index 377d744effa..e4b3677b4ab 100644 --- a/client/db/src/cache/list_storage.rs +++ b/client/db/src/cache/list_storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/cache/mod.rs b/client/db/src/cache/mod.rs index 5501f0f1864..005d25b90f9 100644 --- a/client/db/src/cache/mod.rs +++ b/client/db/src/cache/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index a2299a82337..6233eab3ea3 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -1,18 +1,20 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! DB-backed changes tries storage. diff --git a/client/db/src/children.rs b/client/db/src/children.rs index bfba797cd46..62352e6d061 100644 --- a/client/db/src/children.rs +++ b/client/db/src/children.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Functionality for reading and storing children hashes from db. diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index e32e45a2f31..e3b94b03c87 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/light.rs b/client/db/src/light.rs index acfb6217ce9..91f37dd374d 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/offchain.rs b/client/db/src/offchain.rs index c4f0ce115ca..aead4397343 100644 --- a/client/db/src/offchain.rs +++ b/client/db/src/offchain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs index 313069706f3..e56ca4de6cb 100644 --- a/client/db/src/parity_db.rs +++ b/client/db/src/parity_db.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/stats.rs b/client/db/src/stats.rs index 8d208024b4b..3fd93db931d 100644 --- a/client/db/src/stats.rs +++ b/client/db/src/stats.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 292d3c51626..bbbc8413be7 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Global cache state. diff --git a/client/db/src/upgrade.rs b/client/db/src/upgrade.rs index 95592d071f7..e87b11b6966 100644 --- a/client/db/src/upgrade.rs +++ b/client/db/src/upgrade.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Database upgrade logic. diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index e999469c18f..dfc1e945b3a 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index df0eaf8cc26..0af148fd958 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/executor/common/src/lib.rs b/client/executor/common/src/lib.rs index df839d4ab65..050bad27d6c 100644 --- a/client/executor/common/src/lib.rs +++ b/client/executor/common/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A set of common definitions that are needed for defining execution engines. diff --git a/client/executor/common/src/sandbox.rs b/client/executor/common/src/sandbox.rs index b2c35b75827..8ed294bb839 100644 --- a/client/executor/common/src/sandbox.rs +++ b/client/executor/common/src/sandbox.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/executor/common/src/util.rs b/client/executor/common/src/util.rs index 564f9dadcbe..5947be4469c 100644 --- a/client/executor/common/src/util.rs +++ b/client/executor/common/src/util.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/executor/common/src/wasm_runtime.rs b/client/executor/common/src/wasm_runtime.rs index c407d9967cb..cca0d99c4b9 100644 --- a/client/executor/common/src/wasm_runtime.rs +++ b/client/executor/common/src/wasm_runtime.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Definitions for a wasm runtime. diff --git a/client/executor/runtime-test/build.rs b/client/executor/runtime-test/build.rs index a83de21db7f..9456d6bc90f 100644 --- a/client/executor/runtime-test/build.rs +++ b/client/executor/runtime-test/build.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use substrate_wasm_builder::WasmBuilder; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 0a00375145f..5920d269c86 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/executor/src/integration_tests/sandbox.rs b/client/executor/src/integration_tests/sandbox.rs index 447e395c2fb..3c964c62804 100644 --- a/client/executor/src/integration_tests/sandbox.rs +++ b/client/executor/src/integration_tests/sandbox.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/executor/src/lib.rs b/client/executor/src/lib.rs index 56a81b24b40..ccb7aa1b445 100644 --- a/client/executor/src/lib.rs +++ b/client/executor/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/executor/src/native_executor.rs b/client/executor/src/native_executor.rs index b5d67b9e73f..766dada331c 100644 --- a/client/executor/src/native_executor.rs +++ b/client/executor/src/native_executor.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index 7288df35f31..a7d8b0ce238 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Traits and accessor functions for calling into the Substrate Wasm runtime. //! diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index 17b92e04950..e6a6ef3a610 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! This crate provides an implementation of `WasmModule` that is baked by wasmi. diff --git a/client/executor/wasmtime/src/host.rs b/client/executor/wasmtime/src/host.rs index 8d20c9a566d..c1eb77ff81f 100644 --- a/client/executor/wasmtime/src/host.rs +++ b/client/executor/wasmtime/src/host.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! This module defines `HostState` and `HostContext` structs which provide logic and state //! required for execution of host. diff --git a/client/executor/wasmtime/src/imports.rs b/client/executor/wasmtime/src/imports.rs index add62df5cef..b5eaeae5e66 100644 --- a/client/executor/wasmtime/src/imports.rs +++ b/client/executor/wasmtime/src/imports.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs index 089d8cb237b..2103ab9b7b9 100644 --- a/client/executor/wasmtime/src/instance_wrapper.rs +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs index 42935d851d9..a6b1ed39415 100644 --- a/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs +++ b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/executor/wasmtime/src/lib.rs b/client/executor/wasmtime/src/lib.rs index 66e4e085235..db7776d4c58 100644 --- a/client/executor/wasmtime/src/lib.rs +++ b/client/executor/wasmtime/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . ///! Defines a `WasmRuntime` that uses the Wasmtime JIT to execute. diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 965b0675357..a17a034918d 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Defines the compiled Wasm runtime that uses Wasmtime internally. diff --git a/client/executor/wasmtime/src/state_holder.rs b/client/executor/wasmtime/src/state_holder.rs index 711d3bb735d..0e2684cd251 100644 --- a/client/executor/wasmtime/src/state_holder.rs +++ b/client/executor/wasmtime/src/state_holder.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/executor/wasmtime/src/util.rs b/client/executor/wasmtime/src/util.rs index d2de95d4cc7..1437c6f8509 100644 --- a/client/executor/wasmtime/src/util.rs +++ b/client/executor/wasmtime/src/util.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::ops::Range; diff --git a/client/finality-grandpa/rpc/src/error.rs b/client/finality-grandpa/rpc/src/error.rs index 6464acbe10e..6122db03f88 100644 --- a/client/finality-grandpa/rpc/src/error.rs +++ b/client/finality-grandpa/rpc/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/rpc/src/finality.rs b/client/finality-grandpa/rpc/src/finality.rs index 1f288b86a0e..9272edb39b6 100644 --- a/client/finality-grandpa/rpc/src/finality.rs +++ b/client/finality-grandpa/rpc/src/finality.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/rpc/src/lib.rs b/client/finality-grandpa/rpc/src/lib.rs index 172473ad651..c6e4613c4f5 100644 --- a/client/finality-grandpa/rpc/src/lib.rs +++ b/client/finality-grandpa/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/rpc/src/notification.rs b/client/finality-grandpa/rpc/src/notification.rs index fd03a622b21..4c9141be363 100644 --- a/client/finality-grandpa/rpc/src/notification.rs +++ b/client/finality-grandpa/rpc/src/notification.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/rpc/src/report.rs b/client/finality-grandpa/rpc/src/report.rs index a635728cb93..0482d90f58f 100644 --- a/client/finality-grandpa/rpc/src/report.rs +++ b/client/finality-grandpa/rpc/src/report.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index de14c7b3ba3..62a23a7ceab 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index 97041f4081a..0146269c8f7 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Schema for stuff in the aux-db. diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 276529d555f..c217218aecc 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Gossip and politeness for polite-grandpa. //! diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 04c0a0f6ad0..77d2d15e5d0 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index dadd7deb57f..377882ed5dd 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Periodic rebroadcast of neighbor packets. diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index 27a394a062b..d7db68d0652 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Tests for the communication portion of the GRANDPA crate. diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 790be2a2217..5e4203b2a40 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index bf367ab3f4a..bd29b18bae1 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index 749d482871e..d9630e272ef 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/justification.rs b/client/finality-grandpa/src/justification.rs index d5ca92d50e9..9429acff06d 100644 --- a/client/finality-grandpa/src/justification.rs +++ b/client/finality-grandpa/src/justification.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 0757a484afb..0c38d796197 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/notification.rs b/client/finality-grandpa/src/notification.rs index 84155830519..b545f0d8a63 100644 --- a/client/finality-grandpa/src/notification.rs +++ b/client/finality-grandpa/src/notification.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index c61998225e3..c9db917e169 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index cf1201c6e91..1ee71dddc4d 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index 3ac94f3b062..c27eab53515 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/finality-grandpa/src/voting_rule.rs b/client/finality-grandpa/src/voting_rule.rs index 700b0aeb551..a861e792755 100644 --- a/client/finality-grandpa/src/voting_rule.rs +++ b/client/finality-grandpa/src/voting_rule.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/informant/src/display.rs b/client/informant/src/display.rs index 5c8f5f8ef84..0caef4e5fba 100644 --- a/client/informant/src/display.rs +++ b/client/informant/src/display.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::OutputFormat; use ansi_term::Colour; diff --git a/client/informant/src/lib.rs b/client/informant/src/lib.rs index d4f34cb488a..c955834c0f1 100644 --- a/client/informant/src/lib.rs +++ b/client/informant/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index 0b6d654bc62..9cad56efacf 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Keystore (and session key management) for ed25519 based chains like Polkadot. diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 98f8bf6d001..866a50ae4c9 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/client/light/src/backend.rs b/client/light/src/backend.rs index 74e1d613bcf..27e0754eb55 100644 --- a/client/light/src/backend.rs +++ b/client/light/src/backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/light/src/blockchain.rs b/client/light/src/blockchain.rs index 3b5753f2849..f682e6e35b3 100644 --- a/client/light/src/blockchain.rs +++ b/client/light/src/blockchain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/light/src/call_executor.rs b/client/light/src/call_executor.rs index 458ea2bd6b8..7115f24a77d 100644 --- a/client/light/src/call_executor.rs +++ b/client/light/src/call_executor.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/light/src/fetcher.rs b/client/light/src/fetcher.rs index 60fce87b8d0..b71c4871803 100644 --- a/client/light/src/fetcher.rs +++ b/client/light/src/fetcher.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/light/src/lib.rs b/client/light/src/lib.rs index 899d1ae31a3..e647b8743cc 100644 --- a/client/light/src/lib.rs +++ b/client/light/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 4deaad6d748..9f1813f2224 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{Network, Validator}; use crate::state_machine::{ConsensusGossip, TopicNotification, PERIODIC_MAINTENANCE_INTERVAL}; diff --git a/client/network-gossip/src/lib.rs b/client/network-gossip/src/lib.rs index 2b333610223..81575bdc774 100644 --- a/client/network-gossip/src/lib.rs +++ b/client/network-gossip/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Polite gossiping. //! diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 88f9d48375d..7ae630a9723 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network-gossip/src/validator.rs b/client/network-gossip/src/validator.rs index fd29aaddafe..4b5440c1a06 100644 --- a/client/network-gossip/src/validator.rs +++ b/client/network-gossip/src/validator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 8b9e321ca59..e0ca241ede2 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{ config::{ProtocolId, Role}, block_requests, light_client_handler, diff --git a/client/network/src/block_requests.rs b/client/network/src/block_requests.rs index ace63e6e1cd..ff107e37ef3 100644 --- a/client/network/src/block_requests.rs +++ b/client/network/src/block_requests.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// -// Substrate is free software: you can redistribute it and/or modify + +// Copyright (C) 2020-2021 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. -// -// Substrate is distributed in the hope that it will be useful, + +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! `NetworkBehaviour` implementation which handles incoming block requests. //! diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 61d19c10dae..081d4b0d3ac 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/config.rs b/client/network/src/config.rs index b7b113dc146..7c85da8bbaa 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index b2517efb660..d9d28569ad3 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Discovery mechanisms of Substrate. //! diff --git a/client/network/src/error.rs b/client/network/src/error.rs index 7d7603ce92a..2a226b58b46 100644 --- a/client/network/src/error.rs +++ b/client/network/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/gossip.rs b/client/network/src/gossip.rs index 8a46d0701e9..4e6845e3412 100644 --- a/client/network/src/gossip.rs +++ b/client/network/src/gossip.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/gossip/tests.rs b/client/network/src/gossip/tests.rs index 93b69f7b64c..d284616ce94 100644 --- a/client/network/src/gossip/tests.rs +++ b/client/network/src/gossip/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index fb65c754d79..533a69dd4d5 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index 007cdcbf7a6..83c1160a336 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// -// Substrate is free software: you can redistribute it and/or modify + +// Copyright (C) 2020-2021 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. -// -// Substrate is distributed in the hope that it will be useful, + +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! [`NetworkBehaviour`] implementation which handles light client requests. //! diff --git a/client/network/src/network_state.rs b/client/network/src/network_state.rs index db2b6429304..ba3e7cbff45 100644 --- a/client/network/src/network_state.rs +++ b/client/network/src/network_state.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index 6e0add18adb..9ec1fb7508c 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/peer_info.rs b/client/network/src/peer_info.rs index 0bf2fe59fa2..28b913ea401 100644 --- a/client/network/src/peer_info.rs +++ b/client/network/src/peer_info.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use fnv::FnvHashMap; use futures::prelude::*; diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 1a67aec57ab..3bbfdb2cb65 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index 86cb93bef26..3fb383040dd 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! 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. diff --git a/client/network/src/protocol/generic_proto.rs b/client/network/src/protocol/generic_proto.rs index 4d6e607a146..a305fc1f5ea 100644 --- a/client/network/src/protocol/generic_proto.rs +++ b/client/network/src/protocol/generic_proto.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Implementation of libp2p's `NetworkBehaviour` trait that opens a single substream with the //! remote and then allows any communication with them. diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index b8b4cce0a72..c7bd7ce8cb0 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::config::ProtocolId; use crate::protocol::generic_proto::{ diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index e479a34d14f..97417000c20 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for both incoming //! and outgoing substreams for all gossiping protocols together. diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 9c45c62f8bb..fb28bd40d3d 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![cfg(test)] diff --git a/client/network/src/protocol/generic_proto/upgrade.rs b/client/network/src/protocol/generic_proto/upgrade.rs index 6322a10b572..6917742d8ab 100644 --- a/client/network/src/protocol/generic_proto/upgrade.rs +++ b/client/network/src/protocol/generic_proto/upgrade.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/network/src/protocol/generic_proto/upgrade/collec.rs b/client/network/src/protocol/generic_proto/upgrade/collec.rs index f8d19997494..8531fb8bdfd 100644 --- a/client/network/src/protocol/generic_proto/upgrade/collec.rs +++ b/client/network/src/protocol/generic_proto/upgrade/collec.rs @@ -1,22 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +// This file is part of Substrate. + +// Copyright (C) 2018-2021 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 . use futures::prelude::*; use libp2p::core::upgrade::{InboundUpgrade, ProtocolName, UpgradeInfo}; diff --git a/client/network/src/protocol/generic_proto/upgrade/legacy.rs b/client/network/src/protocol/generic_proto/upgrade/legacy.rs index 91282d0cf57..307bfd7ad63 100644 --- a/client/network/src/protocol/generic_proto/upgrade/legacy.rs +++ b/client/network/src/protocol/generic_proto/upgrade/legacy.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index 64b4b980da0..ae9839f4f04 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . /// Notifications protocol. /// diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index 4213d56bbf0..c0a92629d90 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 7e50f586917..70f860bdcb3 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// -// Substrate is free software: you can redistribute it and/or modify + +// Copyright (C) 2017-2021 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. -// -// Substrate is distributed in the hope that it will be useful, + +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Contains the state of the chain synchronization process //! diff --git a/client/network/src/protocol/sync/blocks.rs b/client/network/src/protocol/sync/blocks.rs index b64c9e053e9..60492f24ed8 100644 --- a/client/network/src/protocol/sync/blocks.rs +++ b/client/network/src/protocol/sync/blocks.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 84ad308c61e..d0fcfb777b8 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/request_responses.rs b/client/network/src/request_responses.rs index a410ae0dff5..4cd6bc3c5c4 100644 --- a/client/network/src/request_responses.rs +++ b/client/network/src/request_responses.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Collection of request-response protocols. //! diff --git a/client/network/src/schema.rs b/client/network/src/schema.rs index 423d3ef5b41..5b9a70b0cd5 100644 --- a/client/network/src/schema.rs +++ b/client/network/src/schema.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 3a368088e53..c2d3dcc55b8 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/service/metrics.rs b/client/network/src/service/metrics.rs index 614c24b522d..3dd0d48888e 100644 --- a/client/network/src/service/metrics.rs +++ b/client/network/src/service/metrics.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index 976548f6ed4..eb811d56ab8 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 225a3ae98ab..3372fd9f929 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index 4bf252d5797..4d9d4fbde23 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/network/src/utils.rs b/client/network/src/utils.rs index 490e2ced382..02673ef49fb 100644 --- a/client/network/src/utils.rs +++ b/client/network/src/utils.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use futures::{stream::unfold, FutureExt, Stream, StreamExt}; use futures_timer::Delay; diff --git a/client/network/test/src/block_import.rs b/client/network/test/src/block_import.rs index 5f9064d410e..4000e53420b 100644 --- a/client/network/test/src/block_import.rs +++ b/client/network/test/src/block_import.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 428d8390b36..68e2bd1594d 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index e04ef060f08..999f9fe1ee3 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index 6fb1da19bf0..6bef7187e45 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ str::FromStr, diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 1f542b7c11e..dbe8e55b364 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! This module is composed of two structs: [`HttpApi`] and [`HttpWorker`]. Calling the [`http`] //! function returns a pair of [`HttpApi`] and [`HttpWorker`] that share some state. diff --git a/client/offchain/src/api/http_dummy.rs b/client/offchain/src/api/http_dummy.rs index 1c83325c93b..ff9c2fb2aa0 100644 --- a/client/offchain/src/api/http_dummy.rs +++ b/client/offchain/src/api/http_dummy.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Contains the same API as the `http` module, except that everything returns an error. diff --git a/client/offchain/src/api/timestamp.rs b/client/offchain/src/api/timestamp.rs index 222d3273cb3..31370d4f733 100644 --- a/client/offchain/src/api/timestamp.rs +++ b/client/offchain/src/api/timestamp.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Helper methods dedicated to timestamps. diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 885294449fb..767d2ac5a12 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate offchain workers. //! diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index bb08bdc18e6..141cafc0d12 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/peerset/src/peersstate.rs b/client/peerset/src/peersstate.rs index 19b2489eff4..d635f51781c 100644 --- a/client/peerset/src/peersstate.rs +++ b/client/peerset/src/peersstate.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Reputation and slots allocation system behind the peerset. //! diff --git a/client/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs index e02742fc40a..6f1bcb653de 100644 --- a/client/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/proposer-metrics/src/lib.rs b/client/proposer-metrics/src/lib.rs index 50498d40b62..8fec9779de4 100644 --- a/client/proposer-metrics/src/lib.rs +++ b/client/proposer-metrics/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Prometheus basic proposer metrics. diff --git a/client/rpc-api/src/author/error.rs b/client/rpc-api/src/author/error.rs index 69c036be95f..4d3a256a1a4 100644 --- a/client/rpc-api/src/author/error.rs +++ b/client/rpc-api/src/author/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/author/hash.rs b/client/rpc-api/src/author/hash.rs index 4287af8ede5..618159a8ad4 100644 --- a/client/rpc-api/src/author/hash.rs +++ b/client/rpc-api/src/author/hash.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Extrinsic helpers for author RPC module. diff --git a/client/rpc-api/src/author/mod.rs b/client/rpc-api/src/author/mod.rs index 29f5b1d26e8..6ccf1ebab37 100644 --- a/client/rpc-api/src/author/mod.rs +++ b/client/rpc-api/src/author/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/chain/error.rs b/client/rpc-api/src/chain/error.rs index fd7bd0a43d7..59a0c0a2f84 100644 --- a/client/rpc-api/src/chain/error.rs +++ b/client/rpc-api/src/chain/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/chain/mod.rs b/client/rpc-api/src/chain/mod.rs index 9bb75216c01..5e2d4844130 100644 --- a/client/rpc-api/src/chain/mod.rs +++ b/client/rpc-api/src/chain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index d956a7554f8..7efff742259 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/errors.rs b/client/rpc-api/src/errors.rs index 4e1a5b10fc5..8e4883a4cc2 100644 --- a/client/rpc-api/src/errors.rs +++ b/client/rpc-api/src/errors.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/rpc-api/src/helpers.rs b/client/rpc-api/src/helpers.rs index 025fef1102c..e85c26062b5 100644 --- a/client/rpc-api/src/helpers.rs +++ b/client/rpc-api/src/helpers.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/rpc-api/src/lib.rs b/client/rpc-api/src/lib.rs index 7bae7518105..814319add2a 100644 --- a/client/rpc-api/src/lib.rs +++ b/client/rpc-api/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate RPC interfaces. //! diff --git a/client/rpc-api/src/metadata.rs b/client/rpc-api/src/metadata.rs index cffcbf61f54..efe090acc62 100644 --- a/client/rpc-api/src/metadata.rs +++ b/client/rpc-api/src/metadata.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/offchain/error.rs b/client/rpc-api/src/offchain/error.rs index ea5223f1ce7..f74d419e544 100644 --- a/client/rpc-api/src/offchain/error.rs +++ b/client/rpc-api/src/offchain/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc-api/src/offchain/mod.rs b/client/rpc-api/src/offchain/mod.rs index 427b6a1cc01..7a1f6db9e80 100644 --- a/client/rpc-api/src/offchain/mod.rs +++ b/client/rpc-api/src/offchain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc-api/src/policy.rs b/client/rpc-api/src/policy.rs index 141dcfbc415..5d56c62bfec 100644 --- a/client/rpc-api/src/policy.rs +++ b/client/rpc-api/src/policy.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc-api/src/state/error.rs b/client/rpc-api/src/state/error.rs index 1c22788062c..4f2a2c854ae 100644 --- a/client/rpc-api/src/state/error.rs +++ b/client/rpc-api/src/state/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/state/helpers.rs b/client/rpc-api/src/state/helpers.rs index 0d176ea67f3..cb7bd380afa 100644 --- a/client/rpc-api/src/state/helpers.rs +++ b/client/rpc-api/src/state/helpers.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index 874fc862a39..aae2dcb5ae7 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/system/error.rs b/client/rpc-api/src/system/error.rs index 4897aa485cb..a0dfd863ce3 100644 --- a/client/rpc-api/src/system/error.rs +++ b/client/rpc-api/src/system/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/system/helpers.rs b/client/rpc-api/src/system/helpers.rs index c5dddedef95..b2b793a8ee4 100644 --- a/client/rpc-api/src/system/helpers.rs +++ b/client/rpc-api/src/system/helpers.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index f05f1fada90..2cf22b98029 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-servers/src/lib.rs b/client/rpc-servers/src/lib.rs index 1f99e8bb0d2..26d3cb1b781 100644 --- a/client/rpc-servers/src/lib.rs +++ b/client/rpc-servers/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc-servers/src/middleware.rs b/client/rpc-servers/src/middleware.rs index 233ceab3cf8..2cbc61716c3 100644 --- a/client/rpc-servers/src/middleware.rs +++ b/client/rpc-servers/src/middleware.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 1a2d84e4e57..7cd98054450 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index dc553e60dbf..9dd4f1b143f 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/chain/chain_full.rs b/client/rpc/src/chain/chain_full.rs index 816dbba8664..9687b13d50f 100644 --- a/client/rpc/src/chain/chain_full.rs +++ b/client/rpc/src/chain/chain_full.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Blockchain API backend for full nodes. diff --git a/client/rpc/src/chain/chain_light.rs b/client/rpc/src/chain/chain_light.rs index 8a4afbed71c..41d4d02e33c 100644 --- a/client/rpc/src/chain/chain_light.rs +++ b/client/rpc/src/chain/chain_light.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Blockchain API backend for light nodes. diff --git a/client/rpc/src/chain/mod.rs b/client/rpc/src/chain/mod.rs index cb67d9ba231..d3a28d53433 100644 --- a/client/rpc/src/chain/mod.rs +++ b/client/rpc/src/chain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/chain/tests.rs b/client/rpc/src/chain/tests.rs index b36fc4eab1d..80b990a9fbf 100644 --- a/client/rpc/src/chain/tests.rs +++ b/client/rpc/src/chain/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index 434859a39c2..7b3af8cb2f3 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/offchain/mod.rs b/client/rpc/src/offchain/mod.rs index f8d2bb6a50f..dbb48a9e519 100644 --- a/client/rpc/src/offchain/mod.rs +++ b/client/rpc/src/offchain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc/src/offchain/tests.rs b/client/rpc/src/offchain/tests.rs index f65971a7ffe..b8054d81632 100644 --- a/client/rpc/src/offchain/tests.rs +++ b/client/rpc/src/offchain/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 8573b3cf825..52a4ed1d753 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index a1b9fbc4eeb..8d93d445b08 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! State API backend for full nodes. diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 8f4dce08b3f..c1294dd27b0 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! State API backend for light nodes. diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index d145ac5e551..87b0fae1d6b 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index f1ebf5f702a..60a410b8056 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index f6463c2fc77..c24c7a3faa6 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/rpc/src/testing.rs b/client/rpc/src/testing.rs index 9530ff00206..b69cc7d4b19 100644 --- a/client/rpc/src/testing.rs +++ b/client/rpc/src/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 5e511d3d7c7..5426169a833 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/chain_ops/check_block.rs b/client/service/src/chain_ops/check_block.rs index 34baeb55445..94f6d25c9eb 100644 --- a/client/service/src/chain_ops/check_block.rs +++ b/client/service/src/chain_ops/check_block.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error::Error; use futures::{future, prelude::*}; diff --git a/client/service/src/chain_ops/export_blocks.rs b/client/service/src/chain_ops/export_blocks.rs index 3d2dbcbb9d0..1d9325d1d74 100644 --- a/client/service/src/chain_ops/export_blocks.rs +++ b/client/service/src/chain_ops/export_blocks.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error::Error; use log::info; diff --git a/client/service/src/chain_ops/export_raw_state.rs b/client/service/src/chain_ops/export_raw_state.rs index 3fe44dbdb14..71822cf6275 100644 --- a/client/service/src/chain_ops/export_raw_state.rs +++ b/client/service/src/chain_ops/export_raw_state.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error::Error; use sp_runtime::traits::Block as BlockT; diff --git a/client/service/src/chain_ops/import_blocks.rs b/client/service/src/chain_ops/import_blocks.rs index 74a33c6557c..3f918e05120 100644 --- a/client/service/src/chain_ops/import_blocks.rs +++ b/client/service/src/chain_ops/import_blocks.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/chain_ops/mod.rs b/client/service/src/chain_ops/mod.rs index af6e6f632fc..c213e745a5d 100644 --- a/client/service/src/chain_ops/mod.rs +++ b/client/service/src/chain_ops/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Chain utilities. diff --git a/client/service/src/chain_ops/revert_chain.rs b/client/service/src/chain_ops/revert_chain.rs index eaee2c03f9b..e3301eb2627 100644 --- a/client/service/src/chain_ops/revert_chain.rs +++ b/client/service/src/chain_ops/revert_chain.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error::Error; use log::info; diff --git a/client/service/src/client/block_rules.rs b/client/service/src/client/block_rules.rs index be84614c2a5..1af06666339 100644 --- a/client/service/src/client/block_rules.rs +++ b/client/service/src/client/block_rules.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/service/src/client/call_executor.rs b/client/service/src/client/call_executor.rs index cd01a587775..d6f04d70270 100644 --- a/client/service/src/client/call_executor.rs +++ b/client/service/src/client/call_executor.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index 26892416b34..d8884f235f9 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/client/genesis.rs b/client/service/src/client/genesis.rs index 4df08025e38..08235f7efb6 100644 --- a/client/service/src/client/genesis.rs +++ b/client/service/src/client/genesis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/client/light.rs b/client/service/src/client/light.rs index 6d4f9aa1c9d..5b5c0cb0eb3 100644 --- a/client/service/src/client/light.rs +++ b/client/service/src/client/light.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/client/mod.rs b/client/service/src/client/mod.rs index e4d1dc8bd85..06f48048f8f 100644 --- a/client/service/src/client/mod.rs +++ b/client/service/src/client/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/client/wasm_override.rs b/client/service/src/client/wasm_override.rs index ba76f7a0fcf..aca29694fca 100644 --- a/client/service/src/client/wasm_override.rs +++ b/client/service/src/client/wasm_override.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 2b3eff1371c..e253ed97ff3 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/error.rs b/client/service/src/error.rs index 3515df78be8..31c3cea4ef4 100644 --- a/client/service/src/error.rs +++ b/client/service/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index cd129de3260..8b26b1a75dd 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/service/src/metrics.rs b/client/service/src/metrics.rs index d3ad780b5be..446cce95274 100644 --- a/client/service/src/metrics.rs +++ b/client/service/src/metrics.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/service/src/task_manager/mod.rs b/client/service/src/task_manager/mod.rs index a0aeba3009d..d1ab8c9c2a7 100644 --- a/client/service/src/task_manager/mod.rs +++ b/client/service/src/task_manager/mod.rs @@ -1,16 +1,21 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 . + //! Substrate service tasks management module. use std::{panic, result::Result, pin::Pin}; diff --git a/client/service/src/task_manager/prometheus_future.rs b/client/service/src/task_manager/prometheus_future.rs index 53bd59aa7a5..6d2a52354d6 100644 --- a/client/service/src/task_manager/prometheus_future.rs +++ b/client/service/src/task_manager/prometheus_future.rs @@ -1,16 +1,21 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 . + //! Wrapper around a `Future` that reports statistics about when the `Future` is polled. use futures::prelude::*; diff --git a/client/service/src/task_manager/tests.rs b/client/service/src/task_manager/tests.rs index 27d9b0b9e9a..0509392ce38 100644 --- a/client/service/src/task_manager/tests.rs +++ b/client/service/src/task_manager/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/service/test/src/client/db.rs b/client/service/test/src/client/db.rs index 36d49732246..a86e8f2de46 100644 --- a/client/service/test/src/client/db.rs +++ b/client/service/test/src/client/db.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/service/test/src/client/light.rs b/client/service/test/src/client/light.rs index f38aef008e1..201b24a6efa 100644 --- a/client/service/test/src/client/light.rs +++ b/client/service/test/src/client/light.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/service/test/src/client/mod.rs b/client/service/test/src/client/mod.rs index 23d6a342973..6bb09981107 100644 --- a/client/service/test/src/client/mod.rs +++ b/client/service/test/src/client/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 1f200b4cbee..c30246e91ca 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index 61470894e48..8fd02ee17b9 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/state-db/src/noncanonical.rs b/client/state-db/src/noncanonical.rs index d77f20c50d0..551bf5fb860 100644 --- a/client/state-db/src/noncanonical.rs +++ b/client/state-db/src/noncanonical.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/state-db/src/pruning.rs b/client/state-db/src/pruning.rs index 69b07c285fa..0c682d8954b 100644 --- a/client/state-db/src/pruning.rs +++ b/client/state-db/src/pruning.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/state-db/src/test.rs b/client/state-db/src/test.rs index 11ce4ad8226..e1bb6d01c37 100644 --- a/client/state-db/src/test.rs +++ b/client/state-db/src/test.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/sync-state-rpc/src/lib.rs b/client/sync-state-rpc/src/lib.rs index 573610fb2f6..84665231164 100644 --- a/client/sync-state-rpc/src/lib.rs +++ b/client/sync-state-rpc/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A RPC handler to create sync states for light clients. //! Currently only usable with BABE + GRANDPA. diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index 6a5ac0e0cb3..58c9fe73b28 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/telemetry/src/worker.rs b/client/telemetry/src/worker.rs index a01ab89e7dd..158781f0433 100644 --- a/client/telemetry/src/worker.rs +++ b/client/telemetry/src/worker.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/telemetry/src/worker/node.rs b/client/telemetry/src/worker/node.rs index eef7ca7e815..5fbafde8c94 100644 --- a/client/telemetry/src/worker/node.rs +++ b/client/telemetry/src/worker/node.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 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 diff --git a/client/tracing/src/lib.rs b/client/tracing/src/lib.rs index f4017023eff..639ba56b12e 100644 --- a/client/tracing/src/lib.rs +++ b/client/tracing/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2021 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Instrumentation implementation for substrate. //! diff --git a/client/tracing/src/logging.rs b/client/tracing/src/logging.rs index 370b09f781b..248c91feb80 100644 --- a/client/tracing/src/logging.rs +++ b/client/tracing/src/logging.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index bb10086bd4a..f7096b02144 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 81d8e802c2c..445ef0adaf7 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index 80e6825d4ff..98d49817e32 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/lib.rs b/client/transaction-pool/graph/src/lib.rs index bf220ce2297..b8d36d0399b 100644 --- a/client/transaction-pool/graph/src/lib.rs +++ b/client/transaction-pool/graph/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/listener.rs b/client/transaction-pool/graph/src/listener.rs index 1bc3720fa6b..d707c0a0f80 100644 --- a/client/transaction-pool/graph/src/listener.rs +++ b/client/transaction-pool/graph/src/listener.rs @@ -1,7 +1,7 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 56ff550d775..8255370df55 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index cbdb2507893..c2af4f9cb91 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/rotator.rs b/client/transaction-pool/graph/src/rotator.rs index 65e21d0d4b5..3d9b359fd36 100644 --- a/client/transaction-pool/graph/src/rotator.rs +++ b/client/transaction-pool/graph/src/rotator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/tracked_map.rs b/client/transaction-pool/graph/src/tracked_map.rs index c799eb0b96e..9cd6ad84b48 100644 --- a/client/transaction-pool/graph/src/tracked_map.rs +++ b/client/transaction-pool/graph/src/tracked_map.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index ad2fdda73b4..ef689436275 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/graph/src/watcher.rs b/client/transaction-pool/graph/src/watcher.rs index 9d9a91bb23f..6f8eb7c6e56 100644 --- a/client/transaction-pool/graph/src/watcher.rs +++ b/client/transaction-pool/graph/src/watcher.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index 853b66f6e74..fc14a5a0cba 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/src/error.rs b/client/transaction-pool/src/error.rs index 49fc433e320..62c812d1470 100644 --- a/client/transaction-pool/src/error.rs +++ b/client/transaction-pool/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index e03c01bd1d8..e9a1c3906f4 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/src/metrics.rs b/client/transaction-pool/src/metrics.rs index 376e6dfe944..e0b70183a86 100644 --- a/client/transaction-pool/src/metrics.rs +++ b/client/transaction-pool/src/metrics.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index 7be8688eaea..69b601484c7 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 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 diff --git a/client/transaction-pool/src/testing/mod.rs b/client/transaction-pool/src/testing/mod.rs index 350c4137c37..9c7f1dfd7f3 100644 --- a/client/transaction-pool/src/testing/mod.rs +++ b/client/transaction-pool/src/testing/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 8fa742cd419..6e00af47602 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs index cecb2ccae58..db98164023d 100644 --- a/frame/assets/src/benchmarking.rs +++ b/frame/assets/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 137ba81f389..0455f35e245 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/assets/src/weights.rs b/frame/assets/src/weights.rs index f6408e527f5..a8e17615d28 100644 --- a/frame/assets/src/weights.rs +++ b/frame/assets/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/atomic-swap/src/lib.rs b/frame/atomic-swap/src/lib.rs index ac9b82b0df0..e6d44d73c40 100644 --- a/frame/atomic-swap/src/lib.rs +++ b/frame/atomic-swap/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 34f216850c6..2e32fc61585 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 8d5cbcc9b7b..69e914a23a1 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/aura/src/tests.rs b/frame/aura/src/tests.rs index ca0fc3de376..b198308282c 100644 --- a/frame/aura/src/tests.rs +++ b/frame/aura/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 59321421755..fdc13cd7470 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 3672174e257..d31d6866254 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/benchmarking.rs b/frame/babe/src/benchmarking.rs index 8ee4a5913c8..4d75c36669e 100644 --- a/frame/babe/src/benchmarking.rs +++ b/frame/babe/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/default_weights.rs b/frame/babe/src/default_weights.rs index a0e13781961..c7c87b58374 100644 --- a/frame/babe/src/default_weights.rs +++ b/frame/babe/src/default_weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/equivocation.rs b/frame/babe/src/equivocation.rs index 55aaedfe082..e7053f5ac0f 100644 --- a/frame/babe/src/equivocation.rs +++ b/frame/babe/src/equivocation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index fa7954b9512..d7da96a3ddd 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index f8805f7a109..d29e467b791 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 1e522bd83cd..0d0536359f6 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index 078d74006ba..249934a61b4 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index b7d2488bfdd..4fcda02c4fd 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index f47776e0ee6..728bf036bb3 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index f98194c503e..7cb9b9d502b 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index e9d6fe2530a..887b280945f 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/balances/src/weights.rs b/frame/balances/src/weights.rs index 189947003b1..1f7e1bec080 100644 --- a/frame/balances/src/weights.rs +++ b/frame/balances/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/benchmarking/src/analysis.rs b/frame/benchmarking/src/analysis.rs index dafe42de92e..bdfa1cf65c4 100644 --- a/frame/benchmarking/src/analysis.rs +++ b/frame/benchmarking/src/analysis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index c963642fabb..308e5285d3f 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index e31f5ec0916..7ea6bfd9afa 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index 2c2aee910e3..945141345ce 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/bounties/src/benchmarking.rs b/frame/bounties/src/benchmarking.rs index 21f68b07819..0fe479bda7b 100644 --- a/frame/bounties/src/benchmarking.rs +++ b/frame/bounties/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/bounties/src/lib.rs b/frame/bounties/src/lib.rs index 32a37747262..a8b97d9e33b 100644 --- a/frame/bounties/src/lib.rs +++ b/frame/bounties/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs index bcf371eae49..2f503f39b94 100644 --- a/frame/bounties/src/tests.rs +++ b/frame/bounties/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/bounties/src/weights.rs b/frame/bounties/src/weights.rs index 6ba1b9d32b1..fcbee727abe 100644 --- a/frame/bounties/src/weights.rs +++ b/frame/bounties/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index 551d6c7856c..50fab1b3e47 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 1448bd9bc3a..7c41b97996a 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/collective/src/weights.rs b/frame/collective/src/weights.rs index 8a76ff516ca..f8558c833f0 100644 --- a/frame/collective/src/weights.rs +++ b/frame/collective/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/common/src/lib.rs b/frame/contracts/common/src/lib.rs index 9da105cf2d8..2b325d63d62 100644 --- a/frame/contracts/common/src/lib.rs +++ b/frame/contracts/common/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! A crate that hosts a common definitions that are relevant for the pallet-contracts. diff --git a/frame/contracts/proc-macro/src/lib.rs b/frame/contracts/proc-macro/src/lib.rs index 4e38508297d..6fc2fbe82e0 100644 --- a/frame/contracts/proc-macro/src/lib.rs +++ b/frame/contracts/proc-macro/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/rpc/runtime-api/src/lib.rs b/frame/contracts/rpc/runtime-api/src/lib.rs index 94b9fe7967c..6f0399586fa 100644 --- a/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/frame/contracts/rpc/runtime-api/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index a44ba769e96..e0a056906f7 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/src/benchmarking/code.rs b/frame/contracts/src/benchmarking/code.rs index 847be9b434c..88e8b265a57 100644 --- a/frame/contracts/src/benchmarking/code.rs +++ b/frame/contracts/src/benchmarking/code.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index 4bdd279eb8b..d6092f40a67 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/src/benchmarking/sandbox.rs b/frame/contracts/src/benchmarking/sandbox.rs index 61277ebce67..a97fcc2b113 100644 --- a/frame/contracts/src/benchmarking/sandbox.rs +++ b/frame/contracts/src/benchmarking/sandbox.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 8577d04452f..b5f4034b5bf 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use crate::{ CodeHash, ConfigCache, Event, RawEvent, Config, Module as Contracts, diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 18a200fd312..949f970f03b 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use crate::Config; use sp_std::marker::PhantomData; diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index a3c2c914cb8..1be5b8f4484 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! # Contract Module //! diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 4b10a0408c1..d31efd5f552 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! A module responsible for computing the right amount of weight and charging it. diff --git a/frame/contracts/src/schedule.rs b/frame/contracts/src/schedule.rs index df1ea240630..e6902c53b9c 100644 --- a/frame/contracts/src/schedule.rs +++ b/frame/contracts/src/schedule.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! This module contains the cost schedule and supporting code that constructs a //! sane default schedule from a `WeightInfo` implementation. diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index ba09adb285b..180ec7237ff 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -1,18 +1,19 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! This module contains routines for accessing and altering a contract related state. @@ -225,4 +226,4 @@ where .and_then(|i| i.as_alive().map(|i| i.code_hash)) .ok_or(ContractAbsentError) } -} \ No newline at end of file +} diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 991a89563eb..e9307e14b63 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use crate::{ BalanceOf, ContractInfo, ContractInfoOf, GenesisConfig, Module, diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index d90c7502b85..3150ee4b7bd 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! A module that implements instrumented code cache. //! diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index e49014ed950..dbb6705e972 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Definition of macros that hides boilerplate of defining external environment //! for a wasm module. diff --git a/frame/contracts/src/wasm/env_def/mod.rs b/frame/contracts/src/wasm/env_def/mod.rs index 7b67f74ec95..0d9ceeee023 100644 --- a/frame/contracts/src/wasm/env_def/mod.rs +++ b/frame/contracts/src/wasm/env_def/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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 super::Runtime; use crate::exec::Ext; diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index a10e087cde8..e150e84d349 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! This module provides a means for executing contracts //! represented in wasm. diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 070e68bc475..b30feb72ede 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! This module takes care of loading, checking and preprocessing of a //! wasm module before execution. It also extracts some essential information diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index c4365e2cb0f..c8e142d12cc 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Environment definition of the wasm smart-contract runtime. diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index 24c1273a44f..b9d7bc6e1fc 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 542bfaa79db..7460249b6c3 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/conviction.rs b/frame/democracy/src/conviction.rs index bb563e4b748..c2dff741a9c 100644 --- a/frame/democracy/src/conviction.rs +++ b/frame/democracy/src/conviction.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 70383beaa06..a7dd2d5bd92 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 0e369bf3bd5..5927f1dcdd8 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/cancellation.rs b/frame/democracy/src/tests/cancellation.rs index 4221865a3e5..d48173a39d8 100644 --- a/frame/democracy/src/tests/cancellation.rs +++ b/frame/democracy/src/tests/cancellation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/decoders.rs b/frame/democracy/src/tests/decoders.rs index 6b8e661ca9f..52b61d8d9e7 100644 --- a/frame/democracy/src/tests/decoders.rs +++ b/frame/democracy/src/tests/decoders.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The for various partial storage decoders diff --git a/frame/democracy/src/tests/delegation.rs b/frame/democracy/src/tests/delegation.rs index 34dec6d0b49..d3afa1c13f9 100644 --- a/frame/democracy/src/tests/delegation.rs +++ b/frame/democracy/src/tests/delegation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/external_proposing.rs b/frame/democracy/src/tests/external_proposing.rs index 3f9be213790..ff1a7a87da8 100644 --- a/frame/democracy/src/tests/external_proposing.rs +++ b/frame/democracy/src/tests/external_proposing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/fast_tracking.rs b/frame/democracy/src/tests/fast_tracking.rs index 8df34001cde..d01dafaa762 100644 --- a/frame/democracy/src/tests/fast_tracking.rs +++ b/frame/democracy/src/tests/fast_tracking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/lock_voting.rs b/frame/democracy/src/tests/lock_voting.rs index 93867030588..29cd24e1de6 100644 --- a/frame/democracy/src/tests/lock_voting.rs +++ b/frame/democracy/src/tests/lock_voting.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/preimage.rs b/frame/democracy/src/tests/preimage.rs index 8a2cbaf5340..135b167520b 100644 --- a/frame/democracy/src/tests/preimage.rs +++ b/frame/democracy/src/tests/preimage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs index d862aa98e78..4785ef0a894 100644 --- a/frame/democracy/src/tests/public_proposals.rs +++ b/frame/democracy/src/tests/public_proposals.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/scheduling.rs b/frame/democracy/src/tests/scheduling.rs index 5bcfbae9946..e178ff0fc1a 100644 --- a/frame/democracy/src/tests/scheduling.rs +++ b/frame/democracy/src/tests/scheduling.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index 9ae57797d15..207085ceb57 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/types.rs b/frame/democracy/src/types.rs index 8ee0838f8a3..22341ba31ee 100644 --- a/frame/democracy/src/types.rs +++ b/frame/democracy/src/types.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/vote.rs b/frame/democracy/src/vote.rs index 09ff0d71e48..fdf13b944d6 100644 --- a/frame/democracy/src/vote.rs +++ b/frame/democracy/src/vote.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/vote_threshold.rs b/frame/democracy/src/vote_threshold.rs index 2268a55936c..3114b22499d 100644 --- a/frame/democracy/src/vote_threshold.rs +++ b/frame/democracy/src/vote_threshold.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/democracy/src/weights.rs b/frame/democracy/src/weights.rs index 06899b47dea..7c169cc813e 100644 --- a/frame/democracy/src/weights.rs +++ b/frame/democracy/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/elections-phragmen/src/benchmarking.rs b/frame/elections-phragmen/src/benchmarking.rs index eaa5bbe9ed4..db3a8c96023 100644 --- a/frame/elections-phragmen/src/benchmarking.rs +++ b/frame/elections-phragmen/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Elections-Phragmen pallet benchmarking. diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 9b7b9064fbf..5027840aef3 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/elections-phragmen/src/weights.rs b/frame/elections-phragmen/src/weights.rs index 48fd40e782e..baecda61800 100644 --- a/frame/elections-phragmen/src/weights.rs +++ b/frame/elections-phragmen/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index 1490b6d86ae..6eaa2dfad37 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 8a4111a38c4..bf3d355b6de 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index 38a16953572..62e28eb6da0 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index 29e545ae2d9..dbcf7b10f4a 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index a94174a33bb..882c2d6057c 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/example-parallel/src/lib.rs b/frame/example-parallel/src/lib.rs index b616e3d4927..c83a722be12 100644 --- a/frame/example-parallel/src/lib.rs +++ b/frame/example-parallel/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/example-parallel/src/tests.rs b/frame/example-parallel/src/tests.rs index 3da41b22185..4623de196df 100644 --- a/frame/example-parallel/src/tests.rs +++ b/frame/example-parallel/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 14c40778bab..382d67263d1 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index cb45a49b233..fdde914b07e 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/benchmarking.rs b/frame/grandpa/src/benchmarking.rs index bac2c245844..d91bd223a57 100644 --- a/frame/grandpa/src/benchmarking.rs +++ b/frame/grandpa/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/default_weights.rs b/frame/grandpa/src/default_weights.rs index 4893fc2cf18..63122fcf4b5 100644 --- a/frame/grandpa/src/default_weights.rs +++ b/frame/grandpa/src/default_weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/equivocation.rs b/frame/grandpa/src/equivocation.rs index 72f1434b24a..593ebf6ba65 100644 --- a/frame/grandpa/src/equivocation.rs +++ b/frame/grandpa/src/equivocation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 15099672d0d..078acbaa575 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 288ef47a8ef..bf4ce5a519e 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 4963d7e6b6d..0e2a458a3df 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 0176986c822..dccef494a0e 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 959107e527a..fed32afa2e6 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index 04e6bb7df39..0ac3c93a75b 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/identity/src/weights.rs b/frame/identity/src/weights.rs index 431a26cc096..1026e8f73f8 100644 --- a/frame/identity/src/weights.rs +++ b/frame/identity/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index 452a9f26ed7..8493f2b4c64 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 09cb2afa22b..71ee25d779b 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 71dc3d52acd..624014cd55f 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index 22c6b4464c3..dc6fc4f3733 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/im-online/src/weights.rs b/frame/im-online/src/weights.rs index c0f11c69c4b..8f4140fc793 100644 --- a/frame/im-online/src/weights.rs +++ b/frame/im-online/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/indices/src/benchmarking.rs b/frame/indices/src/benchmarking.rs index 382bf07f113..51182b10477 100644 --- a/frame/indices/src/benchmarking.rs +++ b/frame/indices/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 18eb5449848..c925d3a0533 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index 0e1e9c3d436..77797213cb5 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/indices/src/tests.rs b/frame/indices/src/tests.rs index e288871d553..96b8c4acfcd 100644 --- a/frame/indices/src/tests.rs +++ b/frame/indices/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/indices/src/weights.rs b/frame/indices/src/weights.rs index 96470625329..6cc9593d20b 100644 --- a/frame/indices/src/weights.rs +++ b/frame/indices/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 943071c9a1d..a43a5b4089f 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/benchmarking.rs b/frame/merkle-mountain-range/src/benchmarking.rs index af634e18821..4a5ff4b7296 100644 --- a/frame/merkle-mountain-range/src/benchmarking.rs +++ b/frame/merkle-mountain-range/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/default_weights.rs b/frame/merkle-mountain-range/src/default_weights.rs index 0b31698545a..98bb404e3f3 100644 --- a/frame/merkle-mountain-range/src/default_weights.rs +++ b/frame/merkle-mountain-range/src/default_weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/lib.rs b/frame/merkle-mountain-range/src/lib.rs index 81833a20538..85e448fd3a1 100644 --- a/frame/merkle-mountain-range/src/lib.rs +++ b/frame/merkle-mountain-range/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/mmr/mmr.rs b/frame/merkle-mountain-range/src/mmr/mmr.rs index ee27163ae43..10762d98d7e 100644 --- a/frame/merkle-mountain-range/src/mmr/mmr.rs +++ b/frame/merkle-mountain-range/src/mmr/mmr.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/mmr/mod.rs b/frame/merkle-mountain-range/src/mmr/mod.rs index 7fd8f5ae1bf..38833af6f2f 100644 --- a/frame/merkle-mountain-range/src/mmr/mod.rs +++ b/frame/merkle-mountain-range/src/mmr/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/mmr/storage.rs b/frame/merkle-mountain-range/src/mmr/storage.rs index a1aa57087a2..c8390e27047 100644 --- a/frame/merkle-mountain-range/src/mmr/storage.rs +++ b/frame/merkle-mountain-range/src/mmr/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/mmr/utils.rs b/frame/merkle-mountain-range/src/mmr/utils.rs index 7a55605a64c..e966367b71f 100644 --- a/frame/merkle-mountain-range/src/mmr/utils.rs +++ b/frame/merkle-mountain-range/src/mmr/utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/mock.rs b/frame/merkle-mountain-range/src/mock.rs index 4865ea7e572..153aecdbd31 100644 --- a/frame/merkle-mountain-range/src/mock.rs +++ b/frame/merkle-mountain-range/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/primitives.rs b/frame/merkle-mountain-range/src/primitives.rs index cab4b6a0dc8..4d13a32c89f 100644 --- a/frame/merkle-mountain-range/src/primitives.rs +++ b/frame/merkle-mountain-range/src/primitives.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/merkle-mountain-range/src/tests.rs b/frame/merkle-mountain-range/src/tests.rs index 34ce96eaba7..c279e42a8c2 100644 --- a/frame/merkle-mountain-range/src/tests.rs +++ b/frame/merkle-mountain-range/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/metadata/src/lib.rs b/frame/metadata/src/lib.rs index 109f33f4201..8e6b8b6bd79 100644 --- a/frame/metadata/src/lib.rs +++ b/frame/metadata/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/multisig/src/benchmarking.rs b/frame/multisig/src/benchmarking.rs index 0b549b3d947..a257a96caca 100644 --- a/frame/multisig/src/benchmarking.rs +++ b/frame/multisig/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index b39b979f999..f58fe549fe5 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index 4101b718bce..d16b0ad4955 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/multisig/src/weights.rs b/frame/multisig/src/weights.rs index c0f6399e764..f67e0c8868a 100644 --- a/frame/multisig/src/weights.rs +++ b/frame/multisig/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 994e6996a14..983be4056d0 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index e48faef128d..79b1d6e74c3 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index 1d133c1b613..09ac820cf5c 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 2a93bfa2c8f..8e0bb361e15 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index e3f01823c18..5c1247853da 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 7d23780b12e..042c0501094 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 18582ec042c..a33ba96447a 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/proxy/src/benchmarking.rs b/frame/proxy/src/benchmarking.rs index ac0fa52c970..b08b47123d9 100644 --- a/frame/proxy/src/benchmarking.rs +++ b/frame/proxy/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 93f1d8e80d5..1e5aaadcc62 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index b3f9ebc75dd..6867dd510dd 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/proxy/src/weights.rs b/frame/proxy/src/weights.rs index 8f5a608aa58..92cf66120df 100644 --- a/frame/proxy/src/weights.rs +++ b/frame/proxy/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 04db12d1df6..b3eb64db9a0 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 023a805a719..7cd1eb4b028 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 13033767841..38b5d58ddda 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index 8e9484f0fb0..4c7c6ef108d 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scheduler/src/benchmarking.rs b/frame/scheduler/src/benchmarking.rs index 6a67efc9d2d..e45551269bc 100644 --- a/frame/scheduler/src/benchmarking.rs +++ b/frame/scheduler/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 67b86fad826..9ea6c760371 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scheduler/src/weights.rs b/frame/scheduler/src/weights.rs index 3c8be54c9ae..0508930f4ef 100644 --- a/frame/scheduler/src/weights.rs +++ b/frame/scheduler/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index afcac229367..ce2279b1500 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index b96daf6ba32..e3707806e81 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/scored-pool/src/tests.rs b/frame/scored-pool/src/tests.rs index 44b71bc00ba..8f33f30f6ed 100644 --- a/frame/scored-pool/src/tests.rs +++ b/frame/scored-pool/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index bd85b97c0d3..89afc73b6b4 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index db6c465854b..31593b3da54 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/historical/mod.rs b/frame/session/src/historical/mod.rs index 53f4dd7639b..85d7c3f3f34 100644 --- a/frame/session/src/historical/mod.rs +++ b/frame/session/src/historical/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/historical/offchain.rs b/frame/session/src/historical/offchain.rs index 9bb20ababb3..7a636c6e14c 100644 --- a/frame/session/src/historical/offchain.rs +++ b/frame/session/src/historical/offchain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs index 1ee7ce4419d..3b933bf262a 100644 --- a/frame/session/src/historical/onchain.rs +++ b/frame/session/src/historical/onchain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/historical/shared.rs b/frame/session/src/historical/shared.rs index fda0361b059..b054854d88f 100644 --- a/frame/session/src/historical/shared.rs +++ b/frame/session/src/historical/shared.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index cd02ddaac49..90eba3815a7 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index e69eec14b09..3201500ee64 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 3da5d16caad..4ef3bb9f980 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/session/src/weights.rs b/frame/session/src/weights.rs index 243ddc04b08..05d9f7d7873 100644 --- a/frame/session/src/weights.rs +++ b/frame/session/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 6fe8a2673b2..f8f8fa61a00 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index c7040080671..b7735994ec9 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/society/src/tests.rs b/frame/society/src/tests.rs index 0374c7bcd7a..7c834483957 100644 --- a/frame/society/src/tests.rs +++ b/frame/society/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index ca36bfb4c3b..b3c9dd9f57b 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/fuzzer/src/submit_solution.rs b/frame/staking/fuzzer/src/submit_solution.rs index 4f85066f7f6..d94ee49b96d 100644 --- a/frame/staking/fuzzer/src/submit_solution.rs +++ b/frame/staking/fuzzer/src/submit_solution.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/reward-curve/src/lib.rs b/frame/staking/reward-curve/src/lib.rs index 275669fe26b..3a8d625e835 100644 --- a/frame/staking/reward-curve/src/lib.rs +++ b/frame/staking/reward-curve/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/reward-curve/tests/test.rs b/frame/staking/reward-curve/tests/test.rs index 45ad59e00ad..fda7df145d0 100644 --- a/frame/staking/reward-curve/tests/test.rs +++ b/frame/staking/reward-curve/tests/test.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index d336bfd1ddd..0ebe1eab788 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index 2161fe20af8..bd9d1f8bbdb 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index f70a76cb1ac..795f222158e 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 6f7842b6b5a..048806b0623 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index 35d9fa7c1f8..433e02261cc 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index e59f2e84e43..2b2ac61356c 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index 2f198166d7e..d3139b53e6f 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index d4534834d20..bf0b2bf0da4 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/staking/src/weights.rs b/frame/staking/src/weights.rs index 2e715c53356..c0099f63785 100644 --- a/frame/staking/src/weights.rs +++ b/frame/staking/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index e8a13c8b00f..1d20fd2bb77 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index 5a0919b8d73..6cb418de132 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/sudo/src/tests.rs b/frame/sudo/src/tests.rs index 03ce100c3a4..1aeb9b57b61 100644 --- a/frame/sudo/src/tests.rs +++ b/frame/sudo/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/clone_no_bound.rs b/frame/support/procedural/src/clone_no_bound.rs index 35854d23f4d..1911fdfd9fb 100644 --- a/frame/support/procedural/src/clone_no_bound.rs +++ b/frame/support/procedural/src/clone_no_bound.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 15f0935f382..31fc71faf44 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 4a45044d67f..b6c9ce8375f 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/debug_no_bound.rs b/frame/support/procedural/src/debug_no_bound.rs index 2a818fb205f..7a5509cf986 100644 --- a/frame/support/procedural/src/debug_no_bound.rs +++ b/frame/support/procedural/src/debug_no_bound.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 7adc646c339..3f6afd3ff53 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs index 56b8ecf9941..2709995bf88 100644 --- a/frame/support/procedural/src/pallet/expand/call.rs +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/constants.rs b/frame/support/procedural/src/pallet/expand/constants.rs index 25cceb7449e..5740d606a33 100644 --- a/frame/support/procedural/src/pallet/expand/constants.rs +++ b/frame/support/procedural/src/pallet/expand/constants.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/error.rs b/frame/support/procedural/src/pallet/expand/error.rs index e60d717ff7d..a88f626fdc5 100644 --- a/frame/support/procedural/src/pallet/expand/error.rs +++ b/frame/support/procedural/src/pallet/expand/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/event.rs b/frame/support/procedural/src/pallet/expand/event.rs index 1dc3431f9ba..76eda4448ba 100644 --- a/frame/support/procedural/src/pallet/expand/event.rs +++ b/frame/support/procedural/src/pallet/expand/event.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/genesis_build.rs b/frame/support/procedural/src/pallet/expand/genesis_build.rs index 678e89eddf2..8f42bfadc20 100644 --- a/frame/support/procedural/src/pallet/expand/genesis_build.rs +++ b/frame/support/procedural/src/pallet/expand/genesis_build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/genesis_config.rs b/frame/support/procedural/src/pallet/expand/genesis_config.rs index db67eaeaee7..1dade8f0144 100644 --- a/frame/support/procedural/src/pallet/expand/genesis_config.rs +++ b/frame/support/procedural/src/pallet/expand/genesis_config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/hooks.rs b/frame/support/procedural/src/pallet/expand/hooks.rs index 8ae7738bcc1..a20dac09166 100644 --- a/frame/support/procedural/src/pallet/expand/hooks.rs +++ b/frame/support/procedural/src/pallet/expand/hooks.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/instances.rs b/frame/support/procedural/src/pallet/expand/instances.rs index 1b05be4f61f..c60cd5ebe8d 100644 --- a/frame/support/procedural/src/pallet/expand/instances.rs +++ b/frame/support/procedural/src/pallet/expand/instances.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/mod.rs b/frame/support/procedural/src/pallet/expand/mod.rs index 6bfc1f9a9ee..c2a81e9bbcd 100644 --- a/frame/support/procedural/src/pallet/expand/mod.rs +++ b/frame/support/procedural/src/pallet/expand/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/frame/support/procedural/src/pallet/expand/pallet_struct.rs index 133e49a85d8..6c89c0217ce 100644 --- a/frame/support/procedural/src/pallet/expand/pallet_struct.rs +++ b/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs index a8b6b2f0d7b..a77f9cf6084 100644 --- a/frame/support/procedural/src/pallet/expand/storage.rs +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/store_trait.rs b/frame/support/procedural/src/pallet/expand/store_trait.rs index ceea270bb9f..1fa95addb18 100644 --- a/frame/support/procedural/src/pallet/expand/store_trait.rs +++ b/frame/support/procedural/src/pallet/expand/store_trait.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/expand/type_value.rs b/frame/support/procedural/src/pallet/expand/type_value.rs index 3de3be8fcf2..cb5d8307d89 100644 --- a/frame/support/procedural/src/pallet/expand/type_value.rs +++ b/frame/support/procedural/src/pallet/expand/type_value.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index 7ae5a573d01..560d57d50e0 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index 239329639e5..92613fa981b 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index 46355b0fdb1..7684009bcb3 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/error.rs b/frame/support/procedural/src/pallet/parse/error.rs index 0bdf8e73b37..7df88ce7b82 100644 --- a/frame/support/procedural/src/pallet/parse/error.rs +++ b/frame/support/procedural/src/pallet/parse/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index 6b83ca4bf04..ef0c3e2e928 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/extra_constants.rs b/frame/support/procedural/src/pallet/parse/extra_constants.rs index f37c7135de8..4b03fd99f1f 100644 --- a/frame/support/procedural/src/pallet/parse/extra_constants.rs +++ b/frame/support/procedural/src/pallet/parse/extra_constants.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/genesis_build.rs b/frame/support/procedural/src/pallet/parse/genesis_build.rs index 79c64b8a1a9..f9aa26d173a 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_build.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs index f42fcc6dac3..729d1241390 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_config.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs index cbf09ee2317..9d4298cc005 100644 --- a/frame/support/procedural/src/pallet/parse/helper.rs +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/hooks.rs b/frame/support/procedural/src/pallet/parse/hooks.rs index 93061069f8c..f7fec5696d4 100644 --- a/frame/support/procedural/src/pallet/parse/hooks.rs +++ b/frame/support/procedural/src/pallet/parse/hooks.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/inherent.rs b/frame/support/procedural/src/pallet/parse/inherent.rs index b4dfd71d8a5..a3f12b15749 100644 --- a/frame/support/procedural/src/pallet/parse/inherent.rs +++ b/frame/support/procedural/src/pallet/parse/inherent.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 085467bdaa2..d7bb605a954 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/origin.rs b/frame/support/procedural/src/pallet/parse/origin.rs index 00b64c20bc4..6cb8520dbf1 100644 --- a/frame/support/procedural/src/pallet/parse/origin.rs +++ b/frame/support/procedural/src/pallet/parse/origin.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/frame/support/procedural/src/pallet/parse/pallet_struct.rs index 140355070df..8e7ddf27c4e 100644 --- a/frame/support/procedural/src/pallet/parse/pallet_struct.rs +++ b/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs index b7ffe3da751..c744ad3b52e 100644 --- a/frame/support/procedural/src/pallet/parse/storage.rs +++ b/frame/support/procedural/src/pallet/parse/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/type_value.rs b/frame/support/procedural/src/pallet/parse/type_value.rs index 0313c76c3ec..7d675b82e7e 100644 --- a/frame/support/procedural/src/pallet/parse/type_value.rs +++ b/frame/support/procedural/src/pallet/parse/type_value.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs index 3c460249811..0a406413f39 100644 --- a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs +++ b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/pallet_version.rs b/frame/support/procedural/src/pallet_version.rs index f0437d4cb6b..d7227b47bae 100644 --- a/frame/support/procedural/src/pallet_version.rs +++ b/frame/support/procedural/src/pallet_version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/partial_eq_no_bound.rs b/frame/support/procedural/src/partial_eq_no_bound.rs index df8d661a2b2..1c37be8021c 100644 --- a/frame/support/procedural/src/partial_eq_no_bound.rs +++ b/frame/support/procedural/src/partial_eq_no_bound.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/genesis_config/builder_def.rs b/frame/support/procedural/src/storage/genesis_config/builder_def.rs index a045794529c..0cbfa04787f 100644 --- a/frame/support/procedural/src/storage/genesis_config/builder_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/builder_def.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs index 93543075a3d..300e47bc850 100644 --- a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index ebc4c7a7f79..87dfabcefba 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/getters.rs b/frame/support/procedural/src/storage/getters.rs index 5507db46305..65a3519033a 100644 --- a/frame/support/procedural/src/storage/getters.rs +++ b/frame/support/procedural/src/storage/getters.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/instance_trait.rs b/frame/support/procedural/src/storage/instance_trait.rs index a28c3ae6220..5468c3d3441 100644 --- a/frame/support/procedural/src/storage/instance_trait.rs +++ b/frame/support/procedural/src/storage/instance_trait.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/metadata.rs b/frame/support/procedural/src/storage/metadata.rs index 065320cd018..c321386ae1d 100644 --- a/frame/support/procedural/src/storage/metadata.rs +++ b/frame/support/procedural/src/storage/metadata.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 265c4b4cd10..2f9625d2c94 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/parse.rs b/frame/support/procedural/src/storage/parse.rs index 504af6d0ffc..c9602344c59 100644 --- a/frame/support/procedural/src/storage/parse.rs +++ b/frame/support/procedural/src/storage/parse.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/storage_struct.rs b/frame/support/procedural/src/storage/storage_struct.rs index e89b06770a6..9c049789f9b 100644 --- a/frame/support/procedural/src/storage/storage_struct.rs +++ b/frame/support/procedural/src/storage/storage_struct.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/storage/store_trait.rs b/frame/support/procedural/src/storage/store_trait.rs index 7efe65b5f31..18adadbc610 100644 --- a/frame/support/procedural/src/storage/store_trait.rs +++ b/frame/support/procedural/src/storage/store_trait.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/src/transactional.rs b/frame/support/procedural/src/transactional.rs index 8c49a8deec1..6ef26834cf0 100644 --- a/frame/support/procedural/src/transactional.rs +++ b/frame/support/procedural/src/transactional.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/tools/derive/src/lib.rs b/frame/support/procedural/tools/derive/src/lib.rs index 6e5d6c896cb..15394e0c559 100644 --- a/frame/support/procedural/tools/derive/src/lib.rs +++ b/frame/support/procedural/tools/derive/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/tools/src/lib.rs b/frame/support/procedural/tools/src/lib.rs index 2cf559eab9b..ce84f698199 100644 --- a/frame/support/procedural/tools/src/lib.rs +++ b/frame/support/procedural/tools/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/procedural/tools/src/syn_ext.rs b/frame/support/procedural/tools/src/syn_ext.rs index 2ba4cf3f28a..36bd03fed1b 100644 --- a/frame/support/procedural/tools/src/syn_ext.rs +++ b/frame/support/procedural/tools/src/syn_ext.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index 54a1e9c3a03..43efd3d9162 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 2477f9421ff..03cda0e4d40 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 0e3f66f9f3c..508de49e949 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index 3cb91e4a3e3..b55f5d7e0b2 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -1,15 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Macros that define an Event types. Events can be used to easily report changes or conditions //! in your runtime to external entities like users, chain explorers, or dApps. diff --git a/frame/support/src/genesis_config.rs b/frame/support/src/genesis_config.rs index 99f8ad886dd..2b7cae898ff 100644 --- a/frame/support/src/genesis_config.rs +++ b/frame/support/src/genesis_config.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index 147a6301380..0a8be8aec03 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/inherent.rs b/frame/support/src/inherent.rs index 83a1872ab4f..feb200dae5b 100644 --- a/frame/support/src/inherent.rs +++ b/frame/support/src/inherent.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/instances.rs b/frame/support/src/instances.rs index ee38a6a403e..086ed9a6cc1 100644 --- a/frame/support/src/instances.rs +++ b/frame/support/src/instances.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index c8279dff9ee..da4bfbb5d86 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index f72365985da..a6048193370 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/origin.rs b/frame/support/src/origin.rs index 980ab902a38..c17c617b86b 100644 --- a/frame/support/src/origin.rs +++ b/frame/support/src/origin.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index d9861554472..ede7b98e5ee 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index d8891a5ee67..e5ee7ec45b1 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 11d895577f6..198fad08dc7 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 4b444ce074f..a9e5665c544 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/generator/value.rs b/frame/support/src/storage/generator/value.rs index 2da3d917184..093dcb305e6 100644 --- a/frame/support/src/storage/generator/value.rs +++ b/frame/support/src/storage/generator/value.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/hashed.rs b/frame/support/src/storage/hashed.rs index 96a487111a2..a0c9ab6708e 100644 --- a/frame/support/src/storage/hashed.rs +++ b/frame/support/src/storage/hashed.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index 75f90ba7b06..69b9920194f 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 61ba147b091..dbb1062c246 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/types/double_map.rs b/frame/support/src/storage/types/double_map.rs index 1133dbd84d9..93f40b660f7 100644 --- a/frame/support/src/storage/types/double_map.rs +++ b/frame/support/src/storage/types/double_map.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/types/map.rs b/frame/support/src/storage/types/map.rs index 8fe11488b11..5c236e7f6b5 100644 --- a/frame/support/src/storage/types/map.rs +++ b/frame/support/src/storage/types/map.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/types/mod.rs b/frame/support/src/storage/types/mod.rs index 73b032b39e7..5bb6684b792 100644 --- a/frame/support/src/storage/types/mod.rs +++ b/frame/support/src/storage/types/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/types/value.rs b/frame/support/src/storage/types/value.rs index 649b7b9fd27..39f718956eb 100644 --- a/frame/support/src/storage/types/value.rs +++ b/frame/support/src/storage/types/value.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/storage/unhashed.rs b/frame/support/src/storage/unhashed.rs index 42f21cab499..8ac4240a9f0 100644 --- a/frame/support/src/storage/unhashed.rs +++ b/frame/support/src/storage/unhashed.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 1802c302466..0b2d3bceea5 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/unsigned.rs b/frame/support/src/unsigned.rs index 16c434fe638..71ae31d95d1 100644 --- a/frame/support/src/unsigned.rs +++ b/frame/support/src/unsigned.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index fc0d7854a7d..7fde8b342c4 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index 2baf698f1e5..d837056fe6a 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/src/pallet_version.rs b/frame/support/test/src/pallet_version.rs index 5912bd5b8e4..aaa46c3ef2c 100644 --- a/frame/support/test/src/pallet_version.rs +++ b/frame/support/test/src/pallet_version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 33bb4a9cc87..2b9f026487b 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/construct_runtime_ui.rs b/frame/support/test/tests/construct_runtime_ui.rs index 83a90c96dd6..a55e8006285 100644 --- a/frame/support/test/tests/construct_runtime_ui.rs +++ b/frame/support/test/tests/construct_runtime_ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_module_ui.rs b/frame/support/test/tests/decl_module_ui.rs index 22237d904ae..2c097bb6e13 100644 --- a/frame/support/test/tests/decl_module_ui.rs +++ b/frame/support/test/tests/decl_module_ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 97cf68c799b..99697393785 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_storage_ui.rs b/frame/support/test/tests/decl_storage_ui.rs index 4b082cb8172..99d2da87aca 100644 --- a/frame/support/test/tests/decl_storage_ui.rs +++ b/frame/support/test/tests/decl_storage_ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs index c7de52dd893..17f80c8c847 100644 --- a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs index 60bfa7f89c3..fec6aeb64ce 100644 --- a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs index 921dfa6b774..13c57a638bb 100644 --- a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/derive_no_bound.rs b/frame/support/test/tests/derive_no_bound.rs index 48f2f3ec3f6..b96fbcfba93 100644 --- a/frame/support/test/tests/derive_no_bound.rs +++ b/frame/support/test/tests/derive_no_bound.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/derive_no_bound_ui.rs b/frame/support/test/tests/derive_no_bound_ui.rs index ba8fff1f3a5..434671e19b1 100644 --- a/frame/support/test/tests/derive_no_bound_ui.rs +++ b/frame/support/test/tests/derive_no_bound_ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index e7c95c6b432..9839a3d3b2d 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index 4a875bb6889..dd98fca8c95 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index b5bb6dd671b..a734363b018 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index 70a84dfee59..59410c6db22 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index e05a0e9bdfe..1e4bfa7474e 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 5711326300c..7cc3392ef04 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index cdcc6a99cf1..05ad44e7a7f 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index caa9019edf6..2317fb05a2b 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_ui.rs b/frame/support/test/tests/pallet_ui.rs index d323526622a..1836b06cabf 100644 --- a/frame/support/test/tests/pallet_ui.rs +++ b/frame/support/test/tests/pallet_ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index e70d752e40f..ca36ee7fc46 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs index fba19594897..42b0ebc6e93 100644 --- a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/reserved_keyword.rs b/frame/support/test/tests/reserved_keyword.rs index 8136d11824a..d29b0477c38 100644 --- a/frame/support/test/tests/reserved_keyword.rs +++ b/frame/support/test/tests/reserved_keyword.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/storage_transaction.rs b/frame/support/test/tests/storage_transaction.rs index 93b531a678d..0c3fa2ff364 100644 --- a/frame/support/test/tests/storage_transaction.rs +++ b/frame/support/test/tests/storage_transaction.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index 2021aa43f51..19858731b3a 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 2e5d6292180..c5e95e3c44f 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index 080b1cd80f2..f60cd94a0f6 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 686db8fb5a9..87f9113a493 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/rpc/runtime-api/src/lib.rs b/frame/system/rpc/runtime-api/src/lib.rs index 0ead94aabe0..319883c36d7 100644 --- a/frame/system/rpc/runtime-api/src/lib.rs +++ b/frame/system/rpc/runtime-api/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs index f60437887b1..de635b4fb91 100644 --- a/frame/system/src/extensions/check_genesis.rs +++ b/frame/system/src/extensions/check_genesis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_mortality.rs b/frame/system/src/extensions/check_mortality.rs index fbc37f527d8..8e5fd36e621 100644 --- a/frame/system/src/extensions/check_mortality.rs +++ b/frame/system/src/extensions/check_mortality.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_nonce.rs b/frame/system/src/extensions/check_nonce.rs index a1a310833cd..0c610506d66 100644 --- a/frame/system/src/extensions/check_nonce.rs +++ b/frame/system/src/extensions/check_nonce.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs index f4838ab3547..1fd8376d342 100644 --- a/frame/system/src/extensions/check_spec_version.rs +++ b/frame/system/src/extensions/check_spec_version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs index 5a1c8cc7386..fa11a0a5727 100644 --- a/frame/system/src/extensions/check_tx_version.rs +++ b/frame/system/src/extensions/check_tx_version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index fc74b03a61c..c84c2951859 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/extensions/mod.rs b/frame/system/src/extensions/mod.rs index ff61353e2d1..8b6c9b49e4d 100644 --- a/frame/system/src/extensions/mod.rs +++ b/frame/system/src/extensions/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a8ffd05bf61..463712ba68d 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/limits.rs b/frame/system/src/limits.rs index aac347b8e65..3d59bd2b7fa 100644 --- a/frame/system/src/limits.rs +++ b/frame/system/src/limits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index e22f5870eef..d67f00917fd 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index f5186234b60..db417c02867 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/tests.rs b/frame/system/src/tests.rs index 58cb0b95e5e..ca916301103 100644 --- a/frame/system/src/tests.rs +++ b/frame/system/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/system/src/weights.rs b/frame/system/src/weights.rs index 99ea4a033ca..f28e90b34c3 100644 --- a/frame/system/src/weights.rs +++ b/frame/system/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/timestamp/src/benchmarking.rs b/frame/timestamp/src/benchmarking.rs index a0700179a93..27294a91c52 100644 --- a/frame/timestamp/src/benchmarking.rs +++ b/frame/timestamp/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 423f7f5128e..44f88347c08 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/timestamp/src/weights.rs b/frame/timestamp/src/weights.rs index d3f2dcc7ba6..8cc40faecc9 100644 --- a/frame/timestamp/src/weights.rs +++ b/frame/timestamp/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/tips/src/benchmarking.rs b/frame/tips/src/benchmarking.rs index 4f0338b9c5d..6e54247cdb6 100644 --- a/frame/tips/src/benchmarking.rs +++ b/frame/tips/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs index eaa785a5638..442df89428f 100644 --- a/frame/tips/src/lib.rs +++ b/frame/tips/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index 15f3481ba25..ae16117d6b1 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/tips/src/weights.rs b/frame/tips/src/weights.rs index c1d99829100..94c12f740c0 100644 --- a/frame/tips/src/weights.rs +++ b/frame/tips/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/transaction-payment/rpc/runtime-api/src/lib.rs b/frame/transaction-payment/rpc/runtime-api/src/lib.rs index 5575f8f7d09..f2c1b2c1414 100644 --- a/frame/transaction-payment/rpc/runtime-api/src/lib.rs +++ b/frame/transaction-payment/rpc/runtime-api/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index bf1565f1a40..ec06fad08d1 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index a9c595e57ac..932aaf43dc9 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 39b398ab891..ee462cd372f 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 835cf11d721..b5e2c7881bb 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 4d0bdf32e45..177c39eec24 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/treasury/src/weights.rs b/frame/treasury/src/weights.rs index 3bc1fcd2308..ea939396c5f 100644 --- a/frame/treasury/src/weights.rs +++ b/frame/treasury/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs index 501e1b293bc..068d40c399b 100644 --- a/frame/utility/src/benchmarking.rs +++ b/frame/utility/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 3aee32b250d..2286c64fcf3 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 4837be69526..9d03ead0eb1 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/utility/src/weights.rs b/frame/utility/src/weights.rs index c03ef0d064b..5e2eb39f6ef 100644 --- a/frame/utility/src/weights.rs +++ b/frame/utility/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 0cb030668d0..6a61a6479b1 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 6a65e58d410..5e20c863c51 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/frame/vesting/src/weights.rs b/frame/vesting/src/weights.rs index 3d2d6dd9670..f4a1ee36691 100644 --- a/frame/vesting/src/weights.rs +++ b/frame/vesting/src/weights.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/allocator/src/error.rs b/primitives/allocator/src/error.rs index 77c911cef9d..8464cd225d0 100644 --- a/primitives/allocator/src/error.rs +++ b/primitives/allocator/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/allocator/src/freeing_bump.rs b/primitives/allocator/src/freeing_bump.rs index 19d7866e1b5..14746c8784f 100644 --- a/primitives/allocator/src/freeing_bump.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/allocator/src/lib.rs b/primitives/allocator/src/lib.rs index b7cfce80483..7d45fb5f368 100644 --- a/primitives/allocator/src/lib.rs +++ b/primitives/allocator/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs index aebefe7ea03..7c6f95c926d 100644 --- a/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 85f5a1797b1..d44792ef773 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/proc-macro/src/lib.rs b/primitives/api/proc-macro/src/lib.rs index 4dd48094683..30767efd41c 100644 --- a/primitives/api/proc-macro/src/lib.rs +++ b/primitives/api/proc-macro/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index 14cf47fc64b..c6ff98c0f1d 100644 --- a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/proc-macro/src/utils.rs b/primitives/api/proc-macro/src/utils.rs index 534ddcfddd9..dbe7c723af0 100644 --- a/primitives/api/proc-macro/src/utils.rs +++ b/primitives/api/proc-macro/src/utils.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index 96da63cf2e2..265439bf37a 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/test/benches/bench.rs b/primitives/api/test/benches/bench.rs index 280b7079028..20ddbbe7116 100644 --- a/primitives/api/test/benches/bench.rs +++ b/primitives/api/test/benches/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/test/tests/decl_and_impl.rs b/primitives/api/test/tests/decl_and_impl.rs index be549d7b7f4..134ee508565 100644 --- a/primitives/api/test/tests/decl_and_impl.rs +++ b/primitives/api/test/tests/decl_and_impl.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/test/tests/runtime_calls.rs b/primitives/api/test/tests/runtime_calls.rs index d72872959ce..ec1a86d8379 100644 --- a/primitives/api/test/tests/runtime_calls.rs +++ b/primitives/api/test/tests/runtime_calls.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/api/test/tests/trybuild.rs b/primitives/api/test/tests/trybuild.rs index f23c7291e8e..5a6025f463a 100644 --- a/primitives/api/test/tests/trybuild.rs +++ b/primitives/api/test/tests/trybuild.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/src/ecdsa.rs b/primitives/application-crypto/src/ecdsa.rs index 287ac8f3afc..fe54dab39ee 100644 --- a/primitives/application-crypto/src/ecdsa.rs +++ b/primitives/application-crypto/src/ecdsa.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Ecdsa crypto types. diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index e761745cf54..98eb4727df6 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index 12e11d69054..d085d961a10 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index 4700e0f7567..f3ce8678583 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/src/traits.rs b/primitives/application-crypto/src/traits.rs index f06e194aefd..8daa866af63 100644 --- a/primitives/application-crypto/src/traits.rs +++ b/primitives/application-crypto/src/traits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/test/src/ecdsa.rs b/primitives/application-crypto/test/src/ecdsa.rs index 89def7cd687..5ad10e79ef9 100644 --- a/primitives/application-crypto/test/src/ecdsa.rs +++ b/primitives/application-crypto/test/src/ecdsa.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Integration tests for ecdsa use std::sync::Arc; diff --git a/primitives/application-crypto/test/src/ed25519.rs b/primitives/application-crypto/test/src/ed25519.rs index 9df198dc4f9..06b962f1902 100644 --- a/primitives/application-crypto/test/src/ed25519.rs +++ b/primitives/application-crypto/test/src/ed25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/test/src/lib.rs b/primitives/application-crypto/test/src/lib.rs index b7853923969..bee926f8dd8 100644 --- a/primitives/application-crypto/test/src/lib.rs +++ b/primitives/application-crypto/test/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/application-crypto/test/src/sr25519.rs b/primitives/application-crypto/test/src/sr25519.rs index f96d7b7ef00..889f662b681 100644 --- a/primitives/application-crypto/test/src/sr25519.rs +++ b/primitives/application-crypto/test/src/sr25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/benches/bench.rs b/primitives/arithmetic/benches/bench.rs index 7a576c8af14..fd535c1d2d0 100644 --- a/primitives/arithmetic/benches/bench.rs +++ b/primitives/arithmetic/benches/bench.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/fuzzer/src/biguint.rs b/primitives/arithmetic/fuzzer/src/biguint.rs index 481ac5561dd..57be7f53420 100644 --- a/primitives/arithmetic/fuzzer/src/biguint.rs +++ b/primitives/arithmetic/fuzzer/src/biguint.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/fuzzer/src/fixed_point.rs b/primitives/arithmetic/fuzzer/src/fixed_point.rs index 9a88197ac32..db415ecb84c 100644 --- a/primitives/arithmetic/fuzzer/src/fixed_point.rs +++ b/primitives/arithmetic/fuzzer/src/fixed_point.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/fuzzer/src/multiply_by_rational.rs b/primitives/arithmetic/fuzzer/src/multiply_by_rational.rs index 5d06df3f1f8..40f315ce755 100644 --- a/primitives/arithmetic/fuzzer/src/multiply_by_rational.rs +++ b/primitives/arithmetic/fuzzer/src/multiply_by_rational.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/fuzzer/src/normalize.rs b/primitives/arithmetic/fuzzer/src/normalize.rs index 3c1759d5685..48d52ba71ba 100644 --- a/primitives/arithmetic/fuzzer/src/normalize.rs +++ b/primitives/arithmetic/fuzzer/src/normalize.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs index 8ddbd0c6d59..ff172b8bd27 100644 --- a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs +++ b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/biguint.rs b/primitives/arithmetic/src/biguint.rs index 64418956fcd..210cba8e2b1 100644 --- a/primitives/arithmetic/src/biguint.rs +++ b/primitives/arithmetic/src/biguint.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/fixed_point.rs b/primitives/arithmetic/src/fixed_point.rs index 8b882666946..44a86956107 100644 --- a/primitives/arithmetic/src/fixed_point.rs +++ b/primitives/arithmetic/src/fixed_point.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Decimal Fixed Point implementations for Substrate runtime. diff --git a/primitives/arithmetic/src/helpers_128bit.rs b/primitives/arithmetic/src/helpers_128bit.rs index 1e332f54d3b..a979b6a48aa 100644 --- a/primitives/arithmetic/src/helpers_128bit.rs +++ b/primitives/arithmetic/src/helpers_128bit.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs index f6521988c91..ca02df0d1d4 100644 --- a/primitives/arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 59d98eea2b7..c6a31a0ffe8 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/rational.rs b/primitives/arithmetic/src/rational.rs index 07556bc0e2d..88eaca1efb6 100644 --- a/primitives/arithmetic/src/rational.rs +++ b/primitives/arithmetic/src/rational.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index ce645cfe65d..ea297077e35 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/authority-discovery/src/lib.rs b/primitives/authority-discovery/src/lib.rs index 0ae47c9758e..b04ce43a2c7 100644 --- a/primitives/authority-discovery/src/lib.rs +++ b/primitives/authority-discovery/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/authorship/src/lib.rs b/primitives/authorship/src/lib.rs index a760c546a25..7bf6769951b 100644 --- a/primitives/authorship/src/lib.rs +++ b/primitives/authorship/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/block-builder/src/lib.rs b/primitives/block-builder/src/lib.rs index 6367a18afa6..f51d041c9f1 100644 --- a/primitives/block-builder/src/lib.rs +++ b/primitives/block-builder/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 01a7a59d6f9..b50545b1a20 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/blockchain/src/error.rs b/primitives/blockchain/src/error.rs index c7180a61b00..6ed5fe1b335 100644 --- a/primitives/blockchain/src/error.rs +++ b/primitives/blockchain/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/blockchain/src/header_metadata.rs b/primitives/blockchain/src/header_metadata.rs index b8d9c5c9345..87d0057f32c 100644 --- a/primitives/blockchain/src/header_metadata.rs +++ b/primitives/blockchain/src/header_metadata.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/blockchain/src/lib.rs b/primitives/blockchain/src/lib.rs index 27b9c3585e9..696050f57ac 100644 --- a/primitives/blockchain/src/lib.rs +++ b/primitives/blockchain/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/chain-spec/src/lib.rs b/primitives/chain-spec/src/lib.rs index 869fae8236b..5456718e351 100644 --- a/primitives/chain-spec/src/lib.rs +++ b/primitives/chain-spec/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/aura/src/inherents.rs b/primitives/consensus/aura/src/inherents.rs index a18bd337030..e92775c501a 100644 --- a/primitives/consensus/aura/src/inherents.rs +++ b/primitives/consensus/aura/src/inherents.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/aura/src/lib.rs b/primitives/consensus/aura/src/lib.rs index cf0bcf2218a..f3de26da90d 100644 --- a/primitives/consensus/aura/src/lib.rs +++ b/primitives/consensus/aura/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/babe/src/digests.rs b/primitives/consensus/babe/src/digests.rs index f7ae560afff..eeea747179a 100644 --- a/primitives/consensus/babe/src/digests.rs +++ b/primitives/consensus/babe/src/digests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/babe/src/inherents.rs b/primitives/consensus/babe/src/inherents.rs index 5384183f9e6..98104385c70 100644 --- a/primitives/consensus/babe/src/inherents.rs +++ b/primitives/consensus/babe/src/inherents.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index ac75f26a3de..84915c3e71e 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 0100041fc0a..41b5f391f65 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/block_validation.rs b/primitives/consensus/common/src/block_validation.rs index b9261441595..8ae832ad27c 100644 --- a/primitives/consensus/common/src/block_validation.rs +++ b/primitives/consensus/common/src/block_validation.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. + +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at // -// Substrate 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. -// -// Substrate 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. +// http://www.apache.org/licenses/LICENSE-2.0 // -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . +// 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. //! Block announcement validation. diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index 11b24d273d5..d7461fe9203 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/evaluation.rs b/primitives/consensus/common/src/evaluation.rs index fc9ab24d15d..be930fa4a00 100644 --- a/primitives/consensus/common/src/evaluation.rs +++ b/primitives/consensus/common/src/evaluation.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index 713c59b07a5..83f6271941f 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index b426c39100e..03c0661f92c 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index db9bcc8f0ad..0295f704c4e 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/lib.rs b/primitives/consensus/common/src/lib.rs index 10fe8a2b315..43edf4f7776 100644 --- a/primitives/consensus/common/src/lib.rs +++ b/primitives/consensus/common/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate Consensus Common. - -// Substrate Demo 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. - -// Substrate Consensus Common 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 Substrate Consensus Common. If not, see . +// This file is part of Substrate. + +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Common utilities for building and using consensus engines in substrate. //! diff --git a/primitives/consensus/common/src/metrics.rs b/primitives/consensus/common/src/metrics.rs index 6e6b582e125..29d39436cbe 100644 --- a/primitives/consensus/common/src/metrics.rs +++ b/primitives/consensus/common/src/metrics.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Metering tools for consensus diff --git a/primitives/consensus/common/src/offline_tracker.rs b/primitives/consensus/common/src/offline_tracker.rs index b96498041f2..8e33a2c449e 100644 --- a/primitives/consensus/common/src/offline_tracker.rs +++ b/primitives/consensus/common/src/offline_tracker.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/common/src/select_chain.rs b/primitives/consensus/common/src/select_chain.rs index fe0d3972043..11f6fbeb54d 100644 --- a/primitives/consensus/common/src/select_chain.rs +++ b/primitives/consensus/common/src/select_chain.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate Consensus Common. - -// Substrate Demo 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. - -// Substrate Consensus Common 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 Substrate Consensus Common. If not, see . +// This file is part of Substrate. + +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use crate::error::Error; use sp_runtime::traits::{Block as BlockT, NumberFor}; diff --git a/primitives/consensus/pow/src/lib.rs b/primitives/consensus/pow/src/lib.rs index 79c9b6f16c3..12d3440ea9d 100644 --- a/primitives/consensus/pow/src/lib.rs +++ b/primitives/consensus/pow/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/slots/src/lib.rs b/primitives/consensus/slots/src/lib.rs index f898cf9da6e..52df467c291 100644 --- a/primitives/consensus/slots/src/lib.rs +++ b/primitives/consensus/slots/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/vrf/src/lib.rs b/primitives/consensus/vrf/src/lib.rs index 430e11974bc..19391c6c1c8 100644 --- a/primitives/consensus/vrf/src/lib.rs +++ b/primitives/consensus/vrf/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/consensus/vrf/src/schnorrkel.rs b/primitives/consensus/vrf/src/schnorrkel.rs index 65e68375865..400bdb2f580 100644 --- a/primitives/consensus/vrf/src/schnorrkel.rs +++ b/primitives/consensus/vrf/src/schnorrkel.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/changes_trie.rs b/primitives/core/src/changes_trie.rs index 1d88242e43d..32991ce44a5 100644 --- a/primitives/core/src/changes_trie.rs +++ b/primitives/core/src/changes_trie.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 12746a07868..7943ac1beed 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 8d2ba4a3d1b..0f654f816c4 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index ad08f9ab8ba..65893109312 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/hash.rs b/primitives/core/src/hash.rs index 20a6788c320..dcaafd2906d 100644 --- a/primitives/core/src/hash.rs +++ b/primitives/core/src/hash.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/hasher.rs b/primitives/core/src/hasher.rs index 8ccaa4d90a7..13a168c70f9 100644 --- a/primitives/core/src/hasher.rs +++ b/primitives/core/src/hasher.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/hashing.rs b/primitives/core/src/hashing.rs index 6807da02feb..8a4c5191dd3 100644 --- a/primitives/core/src/hashing.rs +++ b/primitives/core/src/hashing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/hexdisplay.rs b/primitives/core/src/hexdisplay.rs index 9d2b7a12d03..304b665a72c 100644 --- a/primitives/core/src/hexdisplay.rs +++ b/primitives/core/src/hexdisplay.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 7857937aebf..7fc9fa09196 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/offchain/mod.rs b/primitives/core/src/offchain/mod.rs index 4768496c4a5..002e3540048 100644 --- a/primitives/core/src/offchain/mod.rs +++ b/primitives/core/src/offchain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/offchain/storage.rs b/primitives/core/src/offchain/storage.rs index 7d7c711ed95..ec6f91e6a5a 100644 --- a/primitives/core/src/offchain/storage.rs +++ b/primitives/core/src/offchain/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/offchain/testing.rs b/primitives/core/src/offchain/testing.rs index 5256f417711..773f74b7379 100644 --- a/primitives/core/src/offchain/testing.rs +++ b/primitives/core/src/offchain/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/sandbox.rs b/primitives/core/src/sandbox.rs index 4cb5bd41d58..330ea7eb92e 100644 --- a/primitives/core/src/sandbox.rs +++ b/primitives/core/src/sandbox.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 9a757c89005..37926d8f801 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index cee8bec22aa..1506abb77f9 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/traits.rs b/primitives/core/src/traits.rs index 97100ea58f8..8488a1873ca 100644 --- a/primitives/core/src/traits.rs +++ b/primitives/core/src/traits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/u32_trait.rs b/primitives/core/src/u32_trait.rs index 6f73e1f6ba7..07f9bb00328 100644 --- a/primitives/core/src/u32_trait.rs +++ b/primitives/core/src/u32_trait.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/core/src/uint.rs b/primitives/core/src/uint.rs index ef1adc4a0e0..f917f472d78 100644 --- a/primitives/core/src/uint.rs +++ b/primitives/core/src/uint.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/database/src/error.rs b/primitives/database/src/error.rs index 3253839bbef..4bf5a20aff4 100644 --- a/primitives/database/src/error.rs +++ b/primitives/database/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/database/src/kvdb.rs b/primitives/database/src/kvdb.rs index c48bd9c610f..b50ca53786f 100644 --- a/primitives/database/src/kvdb.rs +++ b/primitives/database/src/kvdb.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index 1908eb49bb6..94fe16ce01d 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index 51cb854334d..41af2e2f235 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/debug-derive/src/impls.rs b/primitives/debug-derive/src/impls.rs index 1757b294d9d..898e4eef5d0 100644 --- a/primitives/debug-derive/src/impls.rs +++ b/primitives/debug-derive/src/impls.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/debug-derive/src/lib.rs b/primitives/debug-derive/src/lib.rs index db370f89081..74907b13874 100644 --- a/primitives/debug-derive/src/lib.rs +++ b/primitives/debug-derive/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/debug-derive/tests/tests.rs b/primitives/debug-derive/tests/tests.rs index 6a03762b1c6..d51d6a05bf2 100644 --- a/primitives/debug-derive/tests/tests.rs +++ b/primitives/debug-derive/tests/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/externalities/src/extensions.rs b/primitives/externalities/src/extensions.rs index a7f5ee8bc73..611951dd1a5 100644 --- a/primitives/externalities/src/extensions.rs +++ b/primitives/externalities/src/extensions.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index a6596a22d10..a10ce32bdc8 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/externalities/src/scope_limited.rs b/primitives/externalities/src/scope_limited.rs index 1f70276f02d..3b5013ba8e7 100644 --- a/primitives/externalities/src/scope_limited.rs +++ b/primitives/externalities/src/scope_limited.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index 0426dad9468..5a5468aff56 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/inherents/src/lib.rs b/primitives/inherents/src/lib.rs index e91fb06e3f3..8adf44cbc41 100644 --- a/primitives/inherents/src/lib.rs +++ b/primitives/inherents/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/io/src/batch_verifier.rs b/primitives/io/src/batch_verifier.rs index 39229b1200b..341df36c556 100644 --- a/primitives/io/src/batch_verifier.rs +++ b/primitives/io/src/batch_verifier.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index dba984f4333..397dd3c2171 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keyring/src/ed25519.rs b/primitives/keyring/src/ed25519.rs index 17882027387..c9dd70d63d5 100644 --- a/primitives/keyring/src/ed25519.rs +++ b/primitives/keyring/src/ed25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keyring/src/lib.rs b/primitives/keyring/src/lib.rs index 55ed14d294f..d7fb7c4fd2f 100644 --- a/primitives/keyring/src/lib.rs +++ b/primitives/keyring/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index 80397f0de9f..a4f43be07f0 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keystore/src/lib.rs b/primitives/keystore/src/lib.rs index 068c174aecd..25f8cb49654 100644 --- a/primitives/keystore/src/lib.rs +++ b/primitives/keystore/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keystore/src/testing.rs b/primitives/keystore/src/testing.rs index a5e46095149..702e2bbc857 100644 --- a/primitives/keystore/src/testing.rs +++ b/primitives/keystore/src/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/keystore/src/vrf.rs b/primitives/keystore/src/vrf.rs index 9c1ac92738d..759c8263ceb 100644 --- a/primitives/keystore/src/vrf.rs +++ b/primitives/keystore/src/vrf.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/compact/src/assignment.rs b/primitives/npos-elections/compact/src/assignment.rs index 8b61076521d..4f527aa40a7 100644 --- a/primitives/npos-elections/compact/src/assignment.rs +++ b/primitives/npos-elections/compact/src/assignment.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/compact/src/codec.rs b/primitives/npos-elections/compact/src/codec.rs index 6c5a3bc2134..6e8d4d9277d 100644 --- a/primitives/npos-elections/compact/src/codec.rs +++ b/primitives/npos-elections/compact/src/codec.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/compact/src/lib.rs b/primitives/npos-elections/compact/src/lib.rs index 22997e4f616..32397652f9b 100644 --- a/primitives/npos-elections/compact/src/lib.rs +++ b/primitives/npos-elections/compact/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/fuzzer/src/common.rs b/primitives/npos-elections/fuzzer/src/common.rs index a5099098f5a..29f0247f84f 100644 --- a/primitives/npos-elections/fuzzer/src/common.rs +++ b/primitives/npos-elections/fuzzer/src/common.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs b/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs index 67cc7ba3c9a..024b721b222 100644 --- a/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs +++ b/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs b/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs index 0aada6a5624..868aa67236f 100644 --- a/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs +++ b/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/fuzzer/src/reduce.rs b/primitives/npos-elections/fuzzer/src/reduce.rs index 0f0d9893e04..074c1546d49 100644 --- a/primitives/npos-elections/fuzzer/src/reduce.rs +++ b/primitives/npos-elections/fuzzer/src/reduce.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/balancing.rs b/primitives/npos-elections/src/balancing.rs index 517ac5c03f1..48cb980d78c 100644 --- a/primitives/npos-elections/src/balancing.rs +++ b/primitives/npos-elections/src/balancing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/helpers.rs b/primitives/npos-elections/src/helpers.rs index bfde63676c6..6f4400b6748 100644 --- a/primitives/npos-elections/src/helpers.rs +++ b/primitives/npos-elections/src/helpers.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/lib.rs b/primitives/npos-elections/src/lib.rs index 2c7d133529c..1e3c2707497 100644 --- a/primitives/npos-elections/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. SPDX-License-Identifier: Apache-2.0 +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at diff --git a/primitives/npos-elections/src/mock.rs b/primitives/npos-elections/src/mock.rs index 75ff292450d..410adcc3779 100644 --- a/primitives/npos-elections/src/mock.rs +++ b/primitives/npos-elections/src/mock.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/node.rs b/primitives/npos-elections/src/node.rs index d18c0e9016b..ae65318ff04 100644 --- a/primitives/npos-elections/src/node.rs +++ b/primitives/npos-elections/src/node.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/phragmen.rs b/primitives/npos-elections/src/phragmen.rs index 135f992aba7..8f88c45ae6d 100644 --- a/primitives/npos-elections/src/phragmen.rs +++ b/primitives/npos-elections/src/phragmen.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/phragmms.rs b/primitives/npos-elections/src/phragmms.rs index 9b59e22c249..b0f841e57f2 100644 --- a/primitives/npos-elections/src/phragmms.rs +++ b/primitives/npos-elections/src/phragmms.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index a96a2ed8457..a34f1612ca1 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/npos-elections/src/tests.rs b/primitives/npos-elections/src/tests.rs index 79f95a469ad..1d26909911f 100644 --- a/primitives/npos-elections/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/offchain/src/lib.rs b/primitives/offchain/src/lib.rs index fa5ab808df8..fbbcdcd9b83 100644 --- a/primitives/offchain/src/lib.rs +++ b/primitives/offchain/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/panic-handler/src/lib.rs b/primitives/panic-handler/src/lib.rs index 2ac30dd6369..150ce529768 100644 --- a/primitives/panic-handler/src/lib.rs +++ b/primitives/panic-handler/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/rpc/src/lib.rs b/primitives/rpc/src/lib.rs index c479f0df8b6..822aba4ba19 100644 --- a/primitives/rpc/src/lib.rs +++ b/primitives/rpc/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/rpc/src/list.rs b/primitives/rpc/src/list.rs index a80d5a22272..1f4c6ff098c 100644 --- a/primitives/rpc/src/list.rs +++ b/primitives/rpc/src/list.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/rpc/src/number.rs b/primitives/rpc/src/number.rs index 0a81a34db8f..93d64aa2c37 100644 --- a/primitives/rpc/src/number.rs +++ b/primitives/rpc/src/number.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/lib.rs b/primitives/runtime-interface/proc-macro/src/lib.rs index df43551398a..53df4e084d2 100644 --- a/primitives/runtime-interface/proc-macro/src/lib.rs +++ b/primitives/runtime-interface/proc-macro/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs b/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs index 5e514409384..1e6b72f8823 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs index 35ed9c0cb80..cc0428fc9b5 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs b/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs index cf3bb965d07..7fe0d1734c3 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs b/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs index ff5ea4849af..80ac3396759 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs index 2725bd2c89c..c5d0073e3fb 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs index 7a4dbc5773a..fb127b19415 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs index 02c29197573..78feda66385 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs index 70015d02426..0e392b1a02f 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/proc-macro/src/utils.rs b/primitives/runtime-interface/proc-macro/src/utils.rs index 45f66e3bf65..f4cef852076 100644 --- a/primitives/runtime-interface/proc-macro/src/utils.rs +++ b/primitives/runtime-interface/proc-macro/src/utils.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Util function used by this crate. @@ -297,4 +298,4 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait) } Ok(RuntimeInterface { items: functions }) -} \ No newline at end of file +} diff --git a/primitives/runtime-interface/src/host.rs b/primitives/runtime-interface/src/host.rs index 4a01291e684..a6ea96af900 100644 --- a/primitives/runtime-interface/src/host.rs +++ b/primitives/runtime-interface/src/host.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index 7d84085a9e4..4dd79aeccb3 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index 7a7b78bc45b..93b4a8db87e 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/src/pass_by.rs b/primitives/runtime-interface/src/pass_by.rs index 5ccb3a5e96e..e2a9b4ed427 100644 --- a/primitives/runtime-interface/src/pass_by.rs +++ b/primitives/runtime-interface/src/pass_by.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/src/util.rs b/primitives/runtime-interface/src/util.rs index 604e37e8be3..5b3aa07e60d 100644 --- a/primitives/runtime-interface/src/util.rs +++ b/primitives/runtime-interface/src/util.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/src/wasm.rs b/primitives/runtime-interface/src/wasm.rs index 5511f60e30d..387d6901e2f 100644 --- a/primitives/runtime-interface/src/wasm.rs +++ b/primitives/runtime-interface/src/wasm.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/test-wasm-deprecated/build.rs b/primitives/runtime-interface/test-wasm-deprecated/build.rs index 8a0b4d7a0c1..a1c4b2d892c 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/build.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs index ae0697b2938..0a7e2b49bbb 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/test-wasm/build.rs b/primitives/runtime-interface/test-wasm/build.rs index 8a0b4d7a0c1..a1c4b2d892c 100644 --- a/primitives/runtime-interface/test-wasm/build.rs +++ b/primitives/runtime-interface/test-wasm/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 852be609fef..4cdf59349dd 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index 1f079e86ff3..75aebf1caef 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime-interface/tests/ui.rs b/primitives/runtime-interface/tests/ui.rs index f23c7291e8e..5a6025f463a 100644 --- a/primitives/runtime-interface/tests/ui.rs +++ b/primitives/runtime-interface/tests/ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/curve.rs b/primitives/runtime/src/curve.rs index 27eb89a7694..09ca9a9c46a 100644 --- a/primitives/runtime/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/block.rs b/primitives/runtime/src/generic/block.rs index 4a758b7416d..7b2a10297f9 100644 --- a/primitives/runtime/src/generic/block.rs +++ b/primitives/runtime/src/generic/block.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index f355308a59f..2c3392a1337 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs index ec0963e5ba0..16bd887f047 100644 --- a/primitives/runtime/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/era.rs b/primitives/runtime/src/generic/era.rs index 9bfab517a92..381c34ef419 100644 --- a/primitives/runtime/src/generic/era.rs +++ b/primitives/runtime/src/generic/era.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/header.rs b/primitives/runtime/src/generic/header.rs index e6c800e5787..09f473e7d81 100644 --- a/primitives/runtime/src/generic/header.rs +++ b/primitives/runtime/src/generic/header.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/mod.rs b/primitives/runtime/src/generic/mod.rs index 2a25c063ead..f5087eccab0 100644 --- a/primitives/runtime/src/generic/mod.rs +++ b/primitives/runtime/src/generic/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/tests.rs b/primitives/runtime/src/generic/tests.rs index 56138094fa0..ec31e7de485 100644 --- a/primitives/runtime/src/generic/tests.rs +++ b/primitives/runtime/src/generic/tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index ab9afdb28b6..5c87d271550 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index ccd50334af6..563e0965d83 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs index bb352f7eb5f..d09cd7acaf4 100644 --- a/primitives/runtime/src/multiaddress.rs +++ b/primitives/runtime/src/multiaddress.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/offchain/http.rs b/primitives/runtime/src/offchain/http.rs index 12a0fcf1e5b..31eec32f6a3 100644 --- a/primitives/runtime/src/offchain/http.rs +++ b/primitives/runtime/src/offchain/http.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/offchain/mod.rs b/primitives/runtime/src/offchain/mod.rs index fe5844ce300..c9d1eda0f87 100644 --- a/primitives/runtime/src/offchain/mod.rs +++ b/primitives/runtime/src/offchain/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/offchain/storage.rs b/primitives/runtime/src/offchain/storage.rs index e39514686e1..56bebf956c1 100644 --- a/primitives/runtime/src/offchain/storage.rs +++ b/primitives/runtime/src/offchain/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/offchain/storage_lock.rs b/primitives/runtime/src/offchain/storage_lock.rs index 0d9cf835c15..416689cadfb 100644 --- a/primitives/runtime/src/offchain/storage_lock.rs +++ b/primitives/runtime/src/offchain/storage_lock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! # Off-chain Storage Lock //! diff --git a/primitives/runtime/src/random_number_generator.rs b/primitives/runtime/src/random_number_generator.rs index 23d0421742b..a4d1a66370c 100644 --- a/primitives/runtime/src/random_number_generator.rs +++ b/primitives/runtime/src/random_number_generator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/runtime_string.rs b/primitives/runtime/src/runtime_string.rs index 7fd38f48df6..df57def219e 100644 --- a/primitives/runtime/src/runtime_string.rs +++ b/primitives/runtime/src/runtime_string.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 97e128f363c..3e72c25af9e 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index d475be3579b..b0567b7ae0d 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/runtime/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs index 74709d9ae9c..b0c3e4dd031 100644 --- a/primitives/runtime/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs index a1348370dfe..22e68439958 100755 --- a/primitives/sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/sandbox/with_std.rs b/primitives/sandbox/with_std.rs index 0f46f49503c..d5f87f16513 100755 --- a/primitives/sandbox/with_std.rs +++ b/primitives/sandbox/with_std.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/sandbox/without_std.rs b/primitives/sandbox/without_std.rs index dfd3742c6e9..5897462629c 100755 --- a/primitives/sandbox/without_std.rs +++ b/primitives/sandbox/without_std.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/serializer/src/lib.rs b/primitives/serializer/src/lib.rs index c1e03e58a7a..3aef9ef5a38 100644 --- a/primitives/serializer/src/lib.rs +++ b/primitives/serializer/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/session/src/lib.rs b/primitives/session/src/lib.rs index 38a852dafd1..8000c23dd43 100644 --- a/primitives/session/src/lib.rs +++ b/primitives/session/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/sr-api/proc-macro/src/lib.rs b/primitives/sr-api/proc-macro/src/lib.rs index 0c506a1455d..4c4aa0d7cb9 100644 --- a/primitives/sr-api/proc-macro/src/lib.rs +++ b/primitives/sr-api/proc-macro/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Macros for declaring and implementing runtime apis. diff --git a/primitives/staking/src/lib.rs b/primitives/staking/src/lib.rs index 3f6c1873ff0..4bb8ed93f88 100644 --- a/primitives/staking/src/lib.rs +++ b/primitives/staking/src/lib.rs @@ -1,16 +1,19 @@ - -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. #![cfg_attr(not(feature = "std"), no_std)] diff --git a/primitives/staking/src/offence.rs b/primitives/staking/src/offence.rs index 650a17e7898..0212d1bd8f2 100644 --- a/primitives/staking/src/offence.rs +++ b/primitives/staking/src/offence.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 02151c2480e..eb1c566c6dd 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index def0eecf709..3b265208136 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index b23481411ae..1e0fc5c4d6c 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/build_cache.rs b/primitives/state-machine/src/changes_trie/build_cache.rs index ef83966795f..901ea86835a 100644 --- a/primitives/state-machine/src/changes_trie/build_cache.rs +++ b/primitives/state-machine/src/changes_trie/build_cache.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/build_iterator.rs b/primitives/state-machine/src/changes_trie/build_iterator.rs index 3bafd608efa..43089d819b6 100644 --- a/primitives/state-machine/src/changes_trie/build_iterator.rs +++ b/primitives/state-machine/src/changes_trie/build_iterator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/changes_iterator.rs b/primitives/state-machine/src/changes_trie/changes_iterator.rs index f9398b3ce5d..be35581e751 100644 --- a/primitives/state-machine/src/changes_trie/changes_iterator.rs +++ b/primitives/state-machine/src/changes_trie/changes_iterator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/input.rs b/primitives/state-machine/src/changes_trie/input.rs index 56971f70897..3702eefb996 100644 --- a/primitives/state-machine/src/changes_trie/input.rs +++ b/primitives/state-machine/src/changes_trie/input.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index fd7b38c052f..105f3d7de6d 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/prune.rs b/primitives/state-machine/src/changes_trie/prune.rs index 54456f97add..a741b814a5c 100644 --- a/primitives/state-machine/src/changes_trie/prune.rs +++ b/primitives/state-machine/src/changes_trie/prune.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/storage.rs b/primitives/state-machine/src/changes_trie/storage.rs index 51b7ff6f50f..e08fe36126c 100644 --- a/primitives/state-machine/src/changes_trie/storage.rs +++ b/primitives/state-machine/src/changes_trie/storage.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/changes_trie/surface_iterator.rs b/primitives/state-machine/src/changes_trie/surface_iterator.rs index b9c9d09f0f7..13da8511f3f 100644 --- a/primitives/state-machine/src/changes_trie/surface_iterator.rs +++ b/primitives/state-machine/src/changes_trie/surface_iterator.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/error.rs b/primitives/state-machine/src/error.rs index f20f9e530dc..2705e4623a7 100644 --- a/primitives/state-machine/src/error.rs +++ b/primitives/state-machine/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index c46d0d56be4..e080192d49b 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/in_memory_backend.rs b/primitives/state-machine/src/in_memory_backend.rs index ca300aec919..4ee16dfd2f8 100644 --- a/primitives/state-machine/src/in_memory_backend.rs +++ b/primitives/state-machine/src/in_memory_backend.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! State machine in memory backend. diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index c83dce4bedf..6d85b56f8aa 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/overlayed_changes/changeset.rs b/primitives/state-machine/src/overlayed_changes/changeset.rs index 5e4fd77c685..311af042177 100644 --- a/primitives/state-machine/src/overlayed_changes/changeset.rs +++ b/primitives/state-machine/src/overlayed_changes/changeset.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/overlayed_changes/mod.rs b/primitives/state-machine/src/overlayed_changes/mod.rs index 6ef09fc8150..edf4c2e88e8 100644 --- a/primitives/state-machine/src/overlayed_changes/mod.rs +++ b/primitives/state-machine/src/overlayed_changes/mod.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 63a027cfba0..6b87aa12eb1 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/read_only.rs b/primitives/state-machine/src/read_only.rs index ba9984a6c7d..dee7c9e337c 100644 --- a/primitives/state-machine/src/read_only.rs +++ b/primitives/state-machine/src/read_only.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/stats.rs b/primitives/state-machine/src/stats.rs index f84de6a5bad..9d4ac27e5e9 100644 --- a/primitives/state-machine/src/stats.rs +++ b/primitives/state-machine/src/stats.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 23c3abe4910..40e37f2116c 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index ffae1a02c03..3e74f2d3df4 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 8485cb27e70..c085099da77 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/std/src/lib.rs b/primitives/std/src/lib.rs index b323c43720d..6acf4b75967 100644 --- a/primitives/std/src/lib.rs +++ b/primitives/std/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/std/with_std.rs b/primitives/std/with_std.rs index 92e804b27e1..b044eb29122 100644 --- a/primitives/std/with_std.rs +++ b/primitives/std/with_std.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/std/without_std.rs b/primitives/std/without_std.rs index 3c130d547a1..697a0787e53 100755 --- a/primitives/std/without_std.rs +++ b/primitives/std/without_std.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index b253733e7b2..268448ae125 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/tasks/src/async_externalities.rs b/primitives/tasks/src/async_externalities.rs index e2afeee413c..249222ec71c 100644 --- a/primitives/tasks/src/async_externalities.rs +++ b/primitives/tasks/src/async_externalities.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/primitives/tasks/src/lib.rs b/primitives/tasks/src/lib.rs index 030e178109d..96aca0e1cef 100644 --- a/primitives/tasks/src/lib.rs +++ b/primitives/tasks/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/test-primitives/src/lib.rs b/primitives/test-primitives/src/lib.rs index 27c7ec5e10e..ed408f338e4 100644 --- a/primitives/test-primitives/src/lib.rs +++ b/primitives/test-primitives/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/timestamp/src/lib.rs b/primitives/timestamp/src/lib.rs index 89bfcc20e0e..59f792678c4 100644 --- a/primitives/timestamp/src/lib.rs +++ b/primitives/timestamp/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/tracing/src/lib.rs b/primitives/tracing/src/lib.rs index 9130c08744d..227e1ee994e 100644 --- a/primitives/tracing/src/lib.rs +++ b/primitives/tracing/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/tracing/src/types.rs b/primitives/tracing/src/types.rs index 050ac4c3141..725565c3718 100644 --- a/primitives/tracing/src/types.rs +++ b/primitives/tracing/src/types.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/transaction-pool/src/error.rs b/primitives/transaction-pool/src/error.rs index e356df75908..62d4a5281c9 100644 --- a/primitives/transaction-pool/src/error.rs +++ b/primitives/transaction-pool/src/error.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/transaction-pool/src/lib.rs b/primitives/transaction-pool/src/lib.rs index b991c541521..276c53443eb 100644 --- a/primitives/transaction-pool/src/lib.rs +++ b/primitives/transaction-pool/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 6235ca7cdfc..b0964cab2d1 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/transaction-pool/src/runtime_api.rs b/primitives/transaction-pool/src/runtime_api.rs index 9080c023f58..e1c3280ca2a 100644 --- a/primitives/transaction-pool/src/runtime_api.rs +++ b/primitives/transaction-pool/src/runtime_api.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/trie/benches/bench.rs b/primitives/trie/benches/bench.rs index d385b4bacd4..c2ccb31328a 100644 --- a/primitives/trie/benches/bench.rs +++ b/primitives/trie/benches/bench.rs @@ -1,18 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Parity 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 Parity. If not, see . +// 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 criterion::{Criterion, criterion_group, criterion_main}; criterion_group!(benches, benchmark); diff --git a/primitives/trie/src/error.rs b/primitives/trie/src/error.rs index 2d3a1b79287..453f74afeb8 100644 --- a/primitives/trie/src/error.rs +++ b/primitives/trie/src/error.rs @@ -1,10 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. +// 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. #[cfg(feature="std")] use std::fmt; diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 4914d85f581..572283f1c02 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. - -// Parity 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 Parity. If not, see . +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie"). diff --git a/primitives/trie/src/node_codec.rs b/primitives/trie/src/node_codec.rs index 8a61f372cf2..0c923ff024c 100644 --- a/primitives/trie/src/node_codec.rs +++ b/primitives/trie/src/node_codec.rs @@ -1,18 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. - -// Parity 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 Parity. If not, see . +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! `NodeCodec` implementation for Substrate's trie format. diff --git a/primitives/trie/src/node_header.rs b/primitives/trie/src/node_header.rs index 7aa16292549..14a998903d6 100644 --- a/primitives/trie/src/node_header.rs +++ b/primitives/trie/src/node_header.rs @@ -1,18 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Parity 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 Parity. If not, see . +// 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. //! The node header. diff --git a/primitives/trie/src/storage_proof.rs b/primitives/trie/src/storage_proof.rs index 254adc2fcb4..f0b2bfd4bc3 100644 --- a/primitives/trie/src/storage_proof.rs +++ b/primitives/trie/src/storage_proof.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. - -// Parity 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 Parity. If not, see . +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use sp_std::vec::Vec; use codec::{Encode, Decode}; diff --git a/primitives/trie/src/trie_stream.rs b/primitives/trie/src/trie_stream.rs index 0c92e673aae..3a65c5a9190 100644 --- a/primitives/trie/src/trie_stream.rs +++ b/primitives/trie/src/trie_stream.rs @@ -1,18 +1,19 @@ -// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Parity 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. - -// Parity 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 Parity. If not, see . +// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! `TrieStream` implementation for Substrate's trie format. diff --git a/primitives/utils/src/lib.rs b/primitives/utils/src/lib.rs index 77bcd096561..430ec1ecb6f 100644 --- a/primitives/utils/src/lib.rs +++ b/primitives/utils/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/utils/src/metrics.rs b/primitives/utils/src/metrics.rs index a66589b5927..45d68ae4e6f 100644 --- a/primitives/utils/src/metrics.rs +++ b/primitives/utils/src/metrics.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/utils/src/mpsc.rs b/primitives/utils/src/mpsc.rs index 321ab72f0d2..b033a5527d8 100644 --- a/primitives/utils/src/mpsc.rs +++ b/primitives/utils/src/mpsc.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/utils/src/status_sinks.rs b/primitives/utils/src/status_sinks.rs index 6ca9452893f..dc8115670de 100644 --- a/primitives/utils/src/status_sinks.rs +++ b/primitives/utils/src/status_sinks.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use crate::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use futures::{prelude::*, lock::Mutex}; diff --git a/primitives/version/src/lib.rs b/primitives/version/src/lib.rs index 133d0497a25..24a1b85ed0c 100644 --- a/primitives/version/src/lib.rs +++ b/primitives/version/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/wasm-interface/src/lib.rs b/primitives/wasm-interface/src/lib.rs index c432a966056..fd200268473 100644 --- a/primitives/wasm-interface/src/lib.rs +++ b/primitives/wasm-interface/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/primitives/wasm-interface/src/wasmi_impl.rs b/primitives/wasm-interface/src/wasmi_impl.rs index 5931671c97e..79110487ffc 100644 --- a/primitives/wasm-interface/src/wasmi_impl.rs +++ b/primitives/wasm-interface/src/wasmi_impl.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/client/src/client_ext.rs b/test-utils/client/src/client_ext.rs index 43e89c8f10b..db3e42f7e01 100644 --- a/test-utils/client/src/client_ext.rs +++ b/test-utils/client/src/client_ext.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index bde2156e0cc..487be14a789 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/derive/src/lib.rs b/test-utils/derive/src/lib.rs index f5d62706896..7a9954d21d8 100644 --- a/test-utils/derive/src/lib.rs +++ b/test-utils/derive/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/test-utils/runtime/build.rs b/test-utils/runtime/build.rs index 5c9af20528a..1de18d32b08 100644 --- a/test-utils/runtime/build.rs +++ b/test-utils/runtime/build.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/client/src/block_builder_ext.rs b/test-utils/runtime/client/src/block_builder_ext.rs index cc0bbc69e8f..9dc27c64143 100644 --- a/test-utils/runtime/client/src/block_builder_ext.rs +++ b/test-utils/runtime/client/src/block_builder_ext.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs index 9089be3ad4f..5800203cf7e 100644 --- a/test-utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/client/src/trait_tests.rs b/test-utils/runtime/client/src/trait_tests.rs index b240a42a785..5a8083065ec 100644 --- a/test-utils/runtime/client/src/trait_tests.rs +++ b/test-utils/runtime/client/src/trait_tests.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/src/genesismap.rs b/test-utils/runtime/src/genesismap.rs index 126447d4818..63c4bab55ec 100644 --- a/test-utils/runtime/src/genesismap.rs +++ b/test-utils/runtime/src/genesismap.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 3e5ab8f6975..f7bff693021 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index db22a6092c7..9fcb81b7b09 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index f772ba9b02d..bcba2fb6e67 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 224eacd5129..a2e83fe7b0b 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test-utils/test-crate/src/main.rs b/test-utils/test-crate/src/main.rs index 209f29f7613..2f04568591a 100644 --- a/test-utils/test-crate/src/main.rs +++ b/test-utils/test-crate/src/main.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/test-utils/tests/basic.rs b/test-utils/tests/basic.rs index 3e96bfe83d3..3273d0386e8 100644 --- a/test-utils/tests/basic.rs +++ b/test-utils/tests/basic.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/test-utils/tests/ui.rs b/test-utils/tests/ui.rs index 1f3b466c7dd..13602f25572 100644 --- a/test-utils/tests/ui.rs +++ b/test-utils/tests/ui.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/test-utils/tests/ui/missing-func-parameter.rs b/test-utils/tests/ui/missing-func-parameter.rs index bd34a76902e..e08d8ae1310 100644 --- a/test-utils/tests/ui/missing-func-parameter.rs +++ b/test-utils/tests/ui/missing-func-parameter.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/test-utils/tests/ui/too-many-func-parameters.rs b/test-utils/tests/ui/too-many-func-parameters.rs index 9aeadc2a884..3b742fac7a6 100644 --- a/test-utils/tests/ui/too-many-func-parameters.rs +++ b/test-utils/tests/ui/too-many-func-parameters.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 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 diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 071ed332fcd..07404f04412 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/build-script-utils/src/git.rs b/utils/build-script-utils/src/git.rs index 29c6a325fe7..d01343634bc 100644 --- a/utils/build-script-utils/src/git.rs +++ b/utils/build-script-utils/src/git.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/build-script-utils/src/lib.rs b/utils/build-script-utils/src/lib.rs index 512e6dcaefd..8eb17a7de61 100644 --- a/utils/build-script-utils/src/lib.rs +++ b/utils/build-script-utils/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/build-script-utils/src/version.rs b/utils/build-script-utils/src/version.rs index 103fd5b1d24..f92c637c78c 100644 --- a/utils/build-script-utils/src/version.rs +++ b/utils/build-script-utils/src/version.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index 2eaced74d31..d1ec67d37b9 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/benchmarking-cli/src/command.rs b/utils/frame/benchmarking-cli/src/command.rs index 00a2e7bd7f9..8a6a39f045c 100644 --- a/utils/frame/benchmarking-cli/src/command.rs +++ b/utils/frame/benchmarking-cli/src/command.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index b89bceeb953..ba1a52aa364 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs index 4afc8107306..bde0be25d03 100644 --- a/utils/frame/benchmarking-cli/src/writer.rs +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/frame-utilities-cli/src/lib.rs b/utils/frame/frame-utilities-cli/src/lib.rs index 872cfc99a63..2d6bf4ab9d8 100644 --- a/utils/frame/frame-utilities-cli/src/lib.rs +++ b/utils/frame/frame-utilities-cli/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/frame-utilities-cli/src/module_id.rs b/utils/frame/frame-utilities-cli/src/module_id.rs index ae26f31ad24..187c2de1dd6 100644 --- a/utils/frame/frame-utilities-cli/src/module_id.rs +++ b/utils/frame/frame-utilities-cli/src/module_id.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/rpc/support/src/lib.rs b/utils/frame/rpc/support/src/lib.rs index 85cb433cb2b..417f2bfc22a 100644 --- a/utils/frame/rpc/support/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index cefe39534a1..db19652507b 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 097073239c4..d7cdfcd0443 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. use futures_util::{FutureExt, future::Future}; pub use prometheus::{ diff --git a/utils/prometheus/src/networking.rs b/utils/prometheus/src/networking.rs index 92b9fedf6c7..48ae8a23297 100644 --- a/utils/prometheus/src/networking.rs +++ b/utils/prometheus/src/networking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/prometheus/src/sourced.rs b/utils/prometheus/src/sourced.rs index 58f60e4969b..014bdb30f8a 100644 --- a/utils/prometheus/src/sourced.rs +++ b/utils/prometheus/src/sourced.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. //! Metrics that are collected from existing sources. diff --git a/utils/wasm-builder/src/builder.rs b/utils/wasm-builder/src/builder.rs index 75e1d805720..8ef6c95324c 100644 --- a/utils/wasm-builder/src/builder.rs +++ b/utils/wasm-builder/src/builder.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 573afbfcb6d..0a3c856344d 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/wasm-builder/src/prerequisites.rs b/utils/wasm-builder/src/prerequisites.rs index 3df2707d1d4..5dedcc4641a 100644 --- a/utils/wasm-builder/src/prerequisites.rs +++ b/utils/wasm-builder/src/prerequisites.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index 4c4c80e5a86..73dc2e13af3 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); -- GitLab From d972eb143317001415747f50921ae7a1af29b8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 4 Jan 2021 12:15:17 +0100 Subject: [PATCH 161/163] contracts: Allow runtime authors to define a chain extension (#7548) * Make host functions return TrapReason This avoids the need to manually store any trap reasons to the `Runtime` from the host function. This adds the following benefits: * It properly composes with the upcoming chain extensions * Missing to set a trap value is now a compile error * Add chain extension The chain extension is a way for the contract author to add new host functions for contracts to call. * Add tests for chain extensions * Fix regression in set_rent.wat fixture Not all offsets where properly updated when changing the fixtures for the new salt on instantiate. * Pre-charge a weight amount based off the specified length * Improve fn write docs * Renamed state to phantom * Fix typo --- bin/node/runtime/src/lib.rs | 1 + frame/contracts/fixtures/chain_extension.wat | 46 +++ frame/contracts/fixtures/set_rent.wat | 6 +- frame/contracts/src/chain_extension.rs | 393 +++++++++++++++++++ frame/contracts/src/gas.rs | 28 +- frame/contracts/src/lib.rs | 9 + frame/contracts/src/tests.rs | 201 ++++++++++ frame/contracts/src/wasm/mod.rs | 3 +- frame/contracts/src/wasm/prepare.rs | 15 +- frame/contracts/src/wasm/runtime.rs | 103 ++++- 10 files changed, 768 insertions(+), 37 deletions(-) create mode 100644 frame/contracts/fixtures/chain_extension.wat create mode 100644 frame/contracts/src/chain_extension.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 20600862434..45f47f904e7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -734,6 +734,7 @@ impl pallet_contracts::Config for Runtime { type MaxValueSize = MaxValueSize; type WeightPrice = pallet_transaction_payment::Module; type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = (); } impl pallet_sudo::Config for Runtime { diff --git a/frame/contracts/fixtures/chain_extension.wat b/frame/contracts/fixtures/chain_extension.wat new file mode 100644 index 00000000000..db7e83fd96b --- /dev/null +++ b/frame/contracts/fixtures/chain_extension.wat @@ -0,0 +1,46 @@ +;; Call chain extension by passing through input and output of this contract +(module + (import "seal0" "seal_call_chain_extension" + (func $seal_call_chain_extension (param i32 i32 i32 i32 i32) (result i32)) + ) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 16 16)) + + (func $assert (param i32) + (block $ok + (br_if $ok (get_local 0)) + (unreachable) + ) + ) + + ;; [0, 4) len of input output + (data (i32.const 0) "\02") + + ;; [4, 12) buffer for input + + ;; [12, 16) len of output buffer + (data (i32.const 12) "\02") + + ;; [16, inf) buffer for output + + (func (export "deploy")) + + (func (export "call") + (call $seal_input (i32.const 4) (i32.const 0)) + + ;; the chain extension passes through the input and returns it as output + (call $seal_call_chain_extension + (i32.load8_u (i32.const 4)) ;; func_id + (i32.const 4) ;; input_ptr + (i32.load (i32.const 0)) ;; input_len + (i32.const 16) ;; output_ptr + (i32.const 12) ;; output_len_ptr + ) + + ;; the chain extension passes through the func_id + (call $assert (i32.eq (i32.load8_u (i32.const 4)))) + + (call $seal_return (i32.const 0) (i32.const 16) (i32.load (i32.const 12))) + ) +) diff --git a/frame/contracts/fixtures/set_rent.wat b/frame/contracts/fixtures/set_rent.wat index 1c6b512cc77..4abb7ffe9db 100644 --- a/frame/contracts/fixtures/set_rent.wat +++ b/frame/contracts/fixtures/set_rent.wat @@ -84,11 +84,11 @@ ) (i32.store (i32.const 128) (i32.const 64)) (call $seal_input - (i32.const 104) - (i32.const 100) + (i32.const 132) + (i32.const 128) ) (call $seal_set_rent_allowance - (i32.const 104) + (i32.const 132) (i32.load (i32.const 128)) ) ) diff --git a/frame/contracts/src/chain_extension.rs b/frame/contracts/src/chain_extension.rs new file mode 100644 index 00000000000..662cfb2053e --- /dev/null +++ b/frame/contracts/src/chain_extension.rs @@ -0,0 +1,393 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! A mechanism for runtime authors to augment the functionality of contracts. +//! +//! The runtime is able to call into any contract and retrieve the result using +//! [`bare_call`](crate::Module::bare_call). This already allows customization of runtime +//! behaviour by user generated code (contracts). However, often it is more straightforward +//! to allow the reverse behaviour: The contract calls into the runtime. We call the latter +//! one a "chain extension" because it allows the chain to extend the set of functions that are +//! callable by a contract. +//! +//! In order to create a chain extension the runtime author implements the [`ChainExtension`] +//! trait and declares it in this pallet's [configuration Trait](crate::Config). All types +//! required for this endeavour are defined or re-exported in this module. There is an +//! implementation on `()` which can be used to signal that no chain extension is available. +//! +//! # Security +//! +//! The chain author alone is responsible for the security of the chain extension. +//! This includes avoiding the exposure of exploitable functions and charging the +//! appropriate amount of weight. In order to do so benchmarks must be written and the +//! [`charge_weight`](Environment::charge_weight) function must be called **before** +//! carrying out any action that causes the consumption of the chargeable weight. +//! It cannot be overstated how delicate of a process the creation of a chain extension +//! is. Check whether using [`bare_call`](crate::Module::bare_call) suffices for the +//! use case at hand. +//! +//! # Benchmarking +//! +//! The builtin contract callable functions that pallet-contracts provides all have +//! benchmarks that determine the correct weight that an invocation of these functions +//! induces. In order to be able to charge the correct weight for the functions defined +//! by a chain extension benchmarks must be written, too. In the near future this crate +//! will provide the means for easier creation of those specialized benchmarks. + +use crate::{ + Error, + wasm::{Runtime, RuntimeToken}, +}; +use codec::Decode; +use frame_support::weights::Weight; +use sp_runtime::DispatchError; +use sp_std::{ + marker::PhantomData, + vec::Vec, +}; + +pub use frame_system::Config as SysConfig; +pub use pallet_contracts_primitives::ReturnFlags; +pub use sp_core::crypto::UncheckedFrom; +pub use crate::exec::Ext; +pub use state::Init as InitState; + +/// Result that returns a [`DispatchError`] on error. +pub type Result = sp_std::result::Result; + +/// A trait used to extend the set of contract callable functions. +/// +/// In order to create a custom chain extension this trait must be implemented and supplied +/// to the pallet contracts configuration trait as the associated type of the same name. +/// Consult the [module documentation](self) for a general explanation of chain extensions. +pub trait ChainExtension { + /// Call the chain extension logic. + /// + /// This is the only function that needs to be implemented in order to write a + /// chain extensions. It is called whenever a contract calls the `seal_call_chain_extension` + /// imported wasm function. + /// + /// # Parameters + /// - `func_id`: The first argument to `seal_call_chain_extension`. Usually used to + /// determine which function to realize. + /// - `env`: Access to the remaining arguments and the execution environment. + /// + /// # Return + /// + /// In case of `Err` the contract execution is immediatly suspended and the passed error + /// is returned to the caller. Otherwise the value of [`RetVal`] determines the exit + /// behaviour. + fn call(func_id: u32, env: Environment) -> Result + where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>; + + /// Determines whether chain extensions are enabled for this chain. + /// + /// The default implementation returns `true`. Therefore it is not necessary to overwrite + /// this function when implementing a chain extension. In case of `false` the deployment of + /// a contract that references `seal_call_chain_extension` will be denied and calling this + /// function will return [`NoChainExtension`](Error::NoChainExtension) without first calling + /// into [`call`](Self::call). + fn enabled() -> bool { + true + } +} + +/// Implementation that indicates that no chain extension is available. +impl ChainExtension for () { + fn call(_func_id: u32, mut _env: Environment) -> Result + where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, + { + // Never called since [`Self::enabled()`] is set to `false`. Because we want to + // avoid panics at all costs we supply a sensible error value here instead + // of an `unimplemented!`. + Err(Error::::NoChainExtension.into()) + } + + fn enabled() -> bool { + false + } +} + +/// Determines the exit behaviour and return value of a chain extension. +pub enum RetVal { + /// The chain extensions returns the supplied value to its calling contract. + Converging(u32), + /// The control does **not** return to the calling contract. + /// + /// Use this to stop the execution of the contract when the chain extension returns. + /// The semantic is the same as for calling `seal_return`: The control returns to + /// the caller of the currently executing contract yielding the supplied buffer and + /// flags. + Diverging{flags: ReturnFlags, data: Vec}, +} + +/// Grants the chain extension access to its parameters and execution environment. +/// +/// It uses the typestate pattern to enforce the correct usage of the parameters passed +/// to the chain extension. +pub struct Environment<'a, 'b, E: Ext, S: state::State> { + /// The actual data of this type. + inner: Inner<'a, 'b, E>, + /// `S` is only used in the type system but never as value. + phantom: PhantomData, +} + +/// Functions that are available in every state of this type. +impl<'a, 'b, E: Ext, S: state::State> Environment<'a, 'b, E, S> +where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, +{ + /// Charge the passed `amount` of weight from the overall limit. + /// + /// It returns `Ok` when there the remaining weight budget is larger than the passed + /// `weight`. It returns `Err` otherwise. In this case the chain extension should + /// abort the execution and pass through the error. + /// + /// # Note + /// + /// Weight is synonymous with gas in substrate. + pub fn charge_weight(&mut self, amount: Weight) -> Result<()> { + self.inner.runtime.charge_gas(RuntimeToken::ChainExtension(amount)).map(|_| ()) + } + + /// Grants access to the execution environment of the current contract call. + /// + /// Consult the functions on the returned type before re-implementing those functions. + pub fn ext(&mut self) -> &mut E { + self.inner.runtime.ext() + } +} + +/// Functions that are only available in the initial state of this type. +/// +/// Those are the functions that determine how the arguments to the chain extensions +/// should be consumed. +impl<'a, 'b, E: Ext> Environment<'a, 'b, E, state::Init> { + /// Creates a new environment for consumption by a chain extension. + /// + /// It is only available to this crate because only the wasm runtime module needs to + /// ever create this type. Chain extensions merely consume it. + pub(crate) fn new( + runtime: &'a mut Runtime::<'b, E>, + input_ptr: u32, + input_len: u32, + output_ptr: u32, + output_len_ptr: u32, + ) -> Self { + Environment { + inner: Inner { + runtime, + input_ptr, + input_len, + output_ptr, + output_len_ptr, + }, + phantom: PhantomData, + } + } + + /// Use all arguments as integer values. + pub fn only_in(self) -> Environment<'a, 'b, E, state::OnlyIn> { + Environment { + inner: self.inner, + phantom: PhantomData, + } + } + + /// Use input arguments as integer and output arguments as pointer to a buffer. + pub fn prim_in_buf_out(self) -> Environment<'a, 'b, E, state::PrimInBufOut> { + Environment { + inner: self.inner, + phantom: PhantomData, + } + } + + /// Use input and output arguments as pointers to a buffer. + pub fn buf_in_buf_out(self) -> Environment<'a, 'b, E, state::BufInBufOut> { + Environment { + inner: self.inner, + phantom: PhantomData, + } + } +} + +/// Functions to use the input arguments as integers. +impl<'a, 'b, E: Ext, S: state::PrimIn> Environment<'a, 'b, E, S> { + /// The `input_ptr` argument. + pub fn val0(&self) -> u32 { + self.inner.input_ptr + } + + /// The `input_len` argument. + pub fn val1(&self) -> u32 { + self.inner.input_len + } +} + +/// Functions to use the output arguments as integers. +impl<'a, 'b, E: Ext, S: state::PrimOut> Environment<'a, 'b, E, S> { + /// The `output_ptr` argument. + pub fn val2(&self) -> u32 { + self.inner.output_ptr + } + + /// The `output_len_ptr` argument. + pub fn val3(&self) -> u32 { + self.inner.output_len_ptr + } +} + +/// Functions to use the input arguments as pointer to a buffer. +impl<'a, 'b, E: Ext, S: state::BufIn> Environment<'a, 'b, E, S> +where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, +{ + /// Reads `min(max_len, in_len)` from contract memory. + /// + /// This does **not** charge any weight. The caller must make sure that the an + /// appropriate amount of weight is charged **before** reading from contract memory. + /// The reason for that is that usually the costs for reading data and processing + /// said data cannot be separated in a benchmark. Therefore a chain extension would + /// charge the overall costs either using `max_len` (worst case approximation) or using + /// [`in_len()`](Self::in_len). + pub fn read(&self, max_len: u32) -> Result> { + self.inner.runtime.read_sandbox_memory( + self.inner.input_ptr, + self.inner.input_len.min(max_len), + ) + } + + /// Reads `min(buffer.len(), in_len) from contract memory. + /// + /// This takes a mutable pointer to a buffer fills it with data and shrinks it to + /// the size of the actual data. Apart from supporting pre-allocated buffers it is + /// equivalent to to [`read()`](Self::read). + pub fn read_into(&self, buffer: &mut &mut [u8]) -> Result<()> { + let len = buffer.len(); + let sliced = { + let buffer = core::mem::take(buffer); + &mut buffer[..len.min(self.inner.input_len as usize)] + }; + self.inner.runtime.read_sandbox_memory_into_buf( + self.inner.input_ptr, + sliced, + )?; + *buffer = sliced; + Ok(()) + } + + /// Reads `in_len` from contract memory and scale decodes it. + /// + /// This function is secure and recommended for all input types of fixed size + /// as long as the cost of reading the memory is included in the overall already charged + /// weight of the chain extension. This should usually be the case when fixed input types + /// are used. Non fixed size types (like everything using `Vec`) usually need to use + /// [`in_len()`](Self::in_len) in order to properly charge the necessary weight. + pub fn read_as(&mut self) -> Result { + self.inner.runtime.read_sandbox_memory_as( + self.inner.input_ptr, + self.inner.input_len, + ) + } + + /// The length of the input as passed in as `input_len`. + /// + /// A chain extension would use this value to calculate the dynamic part of its + /// weight. For example a chain extension that calculates the hash of some passed in + /// bytes would use `in_len` to charge the costs of hashing that amount of bytes. + /// This also subsumes the act of copying those bytes as a benchmarks measures both. + pub fn in_len(&self) -> u32 { + self.inner.input_len + } +} + +/// Functions to use the output arguments as pointer to a buffer. +impl<'a, 'b, E: Ext, S: state::BufOut> Environment<'a, 'b, E, S> +where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, +{ + /// Write the supplied buffer to contract memory. + /// + /// If the contract supplied buffer is smaller than the passed `buffer` an `Err` is returned. + /// If `allow_skip` is set to true the contract is allowed to skip the copying of the buffer + /// by supplying the guard value of [`u32::max_value()`] as `out_ptr`. The + /// `weight_per_byte` is only charged when the write actually happens and is not skipped or + /// failed due to a too small output buffer. + pub fn write( + &mut self, + buffer: &[u8], + allow_skip: bool, + weight_per_byte: Option, + ) -> Result<()> { + self.inner.runtime.write_sandbox_output( + self.inner.output_ptr, + self.inner.output_len_ptr, + buffer, + allow_skip, + |len| { + weight_per_byte.map(|w| RuntimeToken::ChainExtension(w.saturating_mul(len.into()))) + }, + ) + } +} + +/// The actual data of an `Environment`. +/// +/// All data is put into this struct to easily pass it around as part of the typestate +/// pattern. Also it creates the opportunity to box this struct in the future in case it +/// gets too large. +struct Inner<'a, 'b, E: Ext> { + /// The runtime contains all necessary functions to interact with the running contract. + runtime: &'a mut Runtime::<'b, E>, + /// Verbatim argument passed to `seal_call_chain_extension`. + input_ptr: u32, + /// Verbatim argument passed to `seal_call_chain_extension`. + input_len: u32, + /// Verbatim argument passed to `seal_call_chain_extension`. + output_ptr: u32, + /// Verbatim argument passed to `seal_call_chain_extension`. + output_len_ptr: u32, +} + +/// Private submodule with public types to prevent other modules from naming them. +mod state { + pub trait State {} + + pub trait PrimIn: State {} + pub trait PrimOut: State {} + pub trait BufIn: State {} + pub trait BufOut: State {} + + pub enum Init {} + pub enum OnlyIn {} + pub enum PrimInBufOut {} + pub enum BufInBufOut {} + + impl State for Init {} + impl State for OnlyIn {} + impl State for PrimInBufOut {} + impl State for BufInBufOut {} + + impl PrimIn for OnlyIn {} + impl PrimOut for OnlyIn {} + impl PrimIn for PrimInBufOut {} + impl BufOut for PrimInBufOut {} + impl BufIn for BufInBufOut {} + impl BufOut for BufInBufOut {} +} diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 949f970f03b..9bb6185e558 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -32,7 +32,7 @@ pub type Gas = frame_support::weights::Weight; #[must_use] #[derive(Debug, PartialEq, Eq)] pub enum GasMeterResult { - Proceed, + Proceed(ChargedAmount), OutOfGas, } @@ -40,11 +40,20 @@ impl GasMeterResult { pub fn is_out_of_gas(&self) -> bool { match *self { GasMeterResult::OutOfGas => true, - GasMeterResult::Proceed => false, + GasMeterResult::Proceed(_) => false, } } } +#[derive(Debug, PartialEq, Eq)] +pub struct ChargedAmount(Gas); + +impl ChargedAmount { + pub fn amount(&self) -> Gas { + self.0 + } +} + #[cfg(not(test))] pub trait TestAuxiliaries {} #[cfg(not(test))] @@ -139,17 +148,18 @@ impl GasMeter { self.gas_left = new_value.unwrap_or_else(Zero::zero); match new_value { - Some(_) => GasMeterResult::Proceed, + Some(_) => GasMeterResult::Proceed(ChargedAmount(amount)), None => GasMeterResult::OutOfGas, } } - // Account for not fully used gas. - // - // This can be used after dispatching a runtime call to refund gas that was not - // used by the dispatchable. - pub fn refund(&mut self, gas: Gas) { - self.gas_left = self.gas_left.saturating_add(gas).max(self.gas_limit); + /// Refund previously charged gas back to the gas meter. + /// + /// This can be used if a gas worst case estimation must be charged before + /// performing a certain action. This way the difference can be refundend when + /// the worst case did not happen. + pub fn refund(&mut self, amount: ChargedAmount) { + self.gas_left = self.gas_left.saturating_add(amount.0).min(self.gas_limit) } /// Allocate some amount of gas and perform some work with diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 1be5b8f4484..ad694b0c877 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -89,6 +89,8 @@ mod wasm; mod rent; mod benchmarking; mod schedule; + +pub mod chain_extension; pub mod weights; #[cfg(test)] @@ -320,6 +322,9 @@ pub trait Config: frame_system::Config { /// Describes the weights of the dispatchables of this module and is also used to /// construct a default cost schedule. type WeightInfo: WeightInfo; + + /// Type that allows the runtime authors to add new host functions for a contract to call. + type ChainExtension: chain_extension::ChainExtension; } decl_error! { @@ -387,6 +392,10 @@ decl_error! { TooManyTopics, /// The topics passed to `seal_deposit_events` contains at least one duplicate. DuplicateTopics, + /// The chain does not provide a chain extension. Calling the chain extension results + /// in this error. Note that this usually shouldn't happen as deploying such contracts + /// is rejected. + NoChainExtension, } } diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index e9307e14b63..1f069a9b465 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -19,6 +19,10 @@ use crate::{ BalanceOf, ContractInfo, ContractInfoOf, GenesisConfig, Module, RawAliveContractInfo, RawEvent, Config, Schedule, gas::Gas, Error, ConfigCache, RuntimeReturnCode, storage::Storage, + chain_extension::{ + Result as ExtensionResult, Environment, ChainExtension, Ext, SysConfig, RetVal, + UncheckedFrom, InitState, ReturnFlags, + }, exec::AccountIdOf, }; use assert_matches::assert_matches; @@ -101,6 +105,85 @@ pub mod test_utils { } } +thread_local! { + static TEST_EXTENSION: sp_std::cell::RefCell = Default::default(); +} + +pub struct TestExtension { + enabled: bool, + last_seen_buffer: Vec, + last_seen_inputs: (u32, u32, u32, u32), +} + +impl TestExtension { + fn disable() { + TEST_EXTENSION.with(|e| e.borrow_mut().enabled = false) + } + + fn last_seen_buffer() -> Vec { + TEST_EXTENSION.with(|e| e.borrow().last_seen_buffer.clone()) + } + + fn last_seen_inputs() -> (u32, u32, u32, u32) { + TEST_EXTENSION.with(|e| e.borrow().last_seen_inputs.clone()) + } +} + +impl Default for TestExtension { + fn default() -> Self { + Self { + enabled: true, + last_seen_buffer: vec![], + last_seen_inputs: (0, 0, 0, 0), + } + } +} + +impl ChainExtension for TestExtension { + fn call(func_id: u32, env: Environment) -> ExtensionResult + where + ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, + { + match func_id { + 0 => { + let mut env = env.buf_in_buf_out(); + let input = env.read(2)?; + env.write(&input, false, None)?; + TEST_EXTENSION.with(|e| e.borrow_mut().last_seen_buffer = input); + Ok(RetVal::Converging(func_id)) + }, + 1 => { + let env = env.only_in(); + TEST_EXTENSION.with(|e| + e.borrow_mut().last_seen_inputs = ( + env.val0(), env.val1(), env.val2(), env.val3() + ) + ); + Ok(RetVal::Converging(func_id)) + }, + 2 => { + let mut env = env.buf_in_buf_out(); + let weight = env.read(2)?[1].into(); + env.charge_weight(weight)?; + Ok(RetVal::Converging(func_id)) + }, + 3 => { + Ok(RetVal::Diverging{ + flags: ReturnFlags::REVERT, + data: vec![42, 99], + }) + }, + _ => { + panic!("Passed unknown func_id to test chain extension: {}", func_id); + } + } + } + + fn enabled() -> bool { + TEST_EXTENSION.with(|e| e.borrow().enabled) + } +} + #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; parameter_types! { @@ -188,6 +271,7 @@ impl Config for Test { type MaxValueSize = MaxValueSize; type WeightPrice = Self; type WeightInfo = (); + type ChainExtension = TestExtension; } type Balances = pallet_balances::Module; @@ -1933,3 +2017,120 @@ fn instantiate_return_code() { }); } + +#[test] +fn disabled_chain_extension_wont_deploy() { + let (code, _hash) = compile_module::("chain_extension").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + TestExtension::disable(); + assert_eq!( + Contracts::put_code(Origin::signed(ALICE), code), + Err("module uses chain extensions but chain extensions are disabled".into()), + ); + }); +} + +#[test] +fn disabled_chain_extension_errors_on_call() { + let (code, hash) = compile_module::("chain_extension").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + TestExtension::disable(); + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + assert_err_ignore_postinfo!( + Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + ), + Error::::NoChainExtension, + ); + }); +} + +#[test] +fn chain_extension_works() { + let (code, hash) = compile_module::("chain_extension").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + + // The contract takes a up to 2 byte buffer where the first byte passed is used as + // as func_id to the chain extension which behaves differently based on the + // func_id. + + // 0 = read input buffer and pass it through as output + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + vec![0, 99], + ); + let gas_consumed = result.gas_consumed; + assert_eq!(TestExtension::last_seen_buffer(), vec![0, 99]); + assert_eq!(result.exec_result.unwrap().data, vec![0, 99]); + + // 1 = treat inputs as integer primitives and store the supplied integers + Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + vec![1], + ).exec_result.unwrap(); + // those values passed in the fixture + assert_eq!(TestExtension::last_seen_inputs(), (4, 1, 16, 12)); + + // 2 = charge some extra weight (amount supplied in second byte) + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + vec![2, 42], + ); + assert_ok!(result.exec_result); + assert_eq!(result.gas_consumed, gas_consumed + 42); + + // 3 = diverging chain extension call that sets flags to 0x1 and returns a fixed buffer + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + vec![3], + ).exec_result.unwrap(); + assert_eq!(result.flags, ReturnFlags::REVERT); + assert_eq!(result.data, vec![42, 99]); + }); +} + diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index e150e84d349..e295febb514 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -34,14 +34,13 @@ mod code_cache; mod prepare; mod runtime; -use self::runtime::Runtime; use self::code_cache::load as load_code; use pallet_contracts_primitives::ExecResult; pub use self::code_cache::save as save_code; #[cfg(feature = "runtime-benchmarks")] pub use self::code_cache::save_raw as save_code_raw; -pub use self::runtime::ReturnCode; +pub use self::runtime::{ReturnCode, Runtime, RuntimeToken}; /// A prepared wasm module ready for execution. #[derive(Clone, Encode, Decode)] diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index b30feb72ede..e03eb3d39bc 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -19,10 +19,11 @@ //! wasm module before execution. It also extracts some essential information //! from a module. -use crate::wasm::env_def::ImportSatisfyCheck; -use crate::wasm::PrefabWasmModule; -use crate::{Schedule, Config}; - +use crate::{ + Schedule, Config, + chain_extension::ChainExtension, + wasm::{PrefabWasmModule, env_def::ImportSatisfyCheck}, +}; use parity_wasm::elements::{self, Internal, External, MemoryType, Type, ValueType}; use pwasm_utils; use sp_std::prelude::*; @@ -355,6 +356,12 @@ impl<'a, T: Config> ContractModule<'a, T> { return Err("module imports `seal_println` but debug features disabled"); } + if !T::ChainExtension::enabled() && + import.field().as_bytes() == b"seal_call_chain_extension" + { + return Err("module uses chain extensions but chain extensions are disabled"); + } + if import_fn_banlist.iter().any(|f| import.field().as_bytes() == *f) || !C::can_satisfy(import.field().as_bytes(), func_ty) { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index c8e142d12cc..41ab3e390ae 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -20,7 +20,7 @@ use crate::{ HostFnWeights, Schedule, Config, CodeHash, BalanceOf, Error, exec::{Ext, StorageKey, TopicOf}, - gas::{Gas, GasMeter, Token, GasMeterResult}, + gas::{Gas, GasMeter, Token, GasMeterResult, ChargedAmount}, wasm::env_def::ConvertibleToWasm, }; use sp_sandbox; @@ -28,7 +28,7 @@ use parity_wasm::elements::ValueType; use frame_system; use frame_support::dispatch::DispatchError; use sp_std::prelude::*; -use codec::{Decode, Encode}; +use codec::{Decode, DecodeAll, Encode}; use sp_runtime::traits::SaturatedConversion; use sp_core::crypto::UncheckedFrom; use sp_io::hashing::{ @@ -126,7 +126,7 @@ impl> From for TrapReason { #[cfg_attr(test, derive(Debug, PartialEq, Eq))] #[derive(Copy, Clone)] -enum RuntimeToken { +pub enum RuntimeToken { /// Charge the gas meter with the cost of a metering block. The charged costs are /// the supplied cost of the block plus the overhead of the metering itself. MeteringBlock(u32), @@ -198,6 +198,10 @@ enum RuntimeToken { HashBlake256(u32), /// Weight of calling `seal_hash_blake2_128` for the given input size. HashBlake128(u32), + /// Weight charged by a chain extension through `seal_call_chain_extension`. + ChainExtension(u64), + /// Weight charged for copying data from the sandbox. + CopyIn(u32), } impl Token for RuntimeToken @@ -256,6 +260,8 @@ where .saturating_add(s.hash_blake2_256_per_byte.saturating_mul(len.into())), HashBlake128(len) => s.hash_blake2_128 .saturating_add(s.hash_blake2_128_per_byte.saturating_mul(len.into())), + ChainExtension(amount) => amount, + CopyIn(len) => s.return_per_byte.saturating_mul(len.into()), } } } @@ -376,6 +382,14 @@ where } } + /// Get a mutable reference to the inner `Ext`. + /// + /// This is mainly for the chain extension to have access to the environment the + /// contract is executing in. + pub fn ext(&mut self) -> &mut E { + self.ext + } + /// Store the reason for a host function triggered trap. /// /// This is called by the `define_env` macro in order to store any error returned by @@ -388,12 +402,12 @@ where /// Charge the gas meter with the specified token. /// /// Returns `Err(HostError)` if there is not enough gas. - fn charge_gas(&mut self, token: Tok) -> Result<(), DispatchError> + pub fn charge_gas(&mut self, token: Tok) -> Result where Tok: Token>, { match self.gas_meter.charge(&self.schedule.host_fn_weights, token) { - GasMeterResult::Proceed => Ok(()), + GasMeterResult::Proceed(amount) => Ok(amount), GasMeterResult::OutOfGas => Err(Error::::OutOfGas.into()) } } @@ -403,7 +417,7 @@ where /// Returns `Err` if one of the following conditions occurs: /// /// - requested buffer is not within the bounds of the sandbox memory. - fn read_sandbox_memory(&self, ptr: u32, len: u32) + pub fn read_sandbox_memory(&self, ptr: u32, len: u32) -> Result, DispatchError> { let mut buf = vec![0u8; len as usize]; @@ -417,7 +431,7 @@ where /// Returns `Err` if one of the following conditions occurs: /// /// - requested buffer is not within the bounds of the sandbox memory. - fn read_sandbox_memory_into_buf(&self, ptr: u32, buf: &mut [u8]) + pub fn read_sandbox_memory_into_buf(&self, ptr: u32, buf: &mut [u8]) -> Result<(), DispatchError> { self.memory.get(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) @@ -429,20 +443,29 @@ where /// /// - requested buffer is not within the bounds of the sandbox memory. /// - the buffer contents cannot be decoded as the required type. - fn read_sandbox_memory_as(&self, ptr: u32, len: u32) + /// + /// # Note + /// + /// It is safe to forgo benchmarking and charging weight relative to `len` for fixed + /// size types (basically everything not containing a heap collection): + /// Despite the fact that we are usually about to read the encoding of a fixed size + /// type, we cannot know the encoded size of that type. We therefore are required to + /// use the length provided by the contract. This length is untrusted and therefore + /// we charge weight relative to the provided size upfront that covers the copy costs. + /// On success this cost is refunded as the copying was already covered in the + /// overall cost of the host function. This is different from `read_sandbox_memory` + /// where the size is dynamic and the costs resulting from that dynamic size must + /// be charged relative to this dynamic size anyways (before reading) by constructing + /// the benchmark for that. + pub fn read_sandbox_memory_as(&mut self, ptr: u32, len: u32) -> Result { + let amount = self.charge_gas(RuntimeToken::CopyIn(len))?; let buf = self.read_sandbox_memory(ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| Error::::DecodingFailed.into()) - } - - /// Write the given buffer to the designated location in the sandbox memory. - /// - /// Returns `Err` if one of the following conditions occurs: - /// - /// - designated area is not within the bounds of the sandbox memory. - fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<(), DispatchError> { - self.memory.set(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) + let decoded = D::decode_all(&mut &buf[..]) + .map_err(|_| DispatchError::from(Error::::DecodingFailed))?; + self.gas_meter.refund(amount); + Ok(decoded) } /// Write the given buffer and its length to the designated locations in sandbox memory and @@ -464,7 +487,7 @@ where /// /// In addition to the error conditions of `write_sandbox_memory` this functions returns /// `Err` if the size of the buffer located at `out_ptr` is too small to fit `buf`. - fn write_sandbox_output( + pub fn write_sandbox_output( &mut self, out_ptr: u32, out_len_ptr: u32, @@ -496,6 +519,15 @@ where Ok(()) } + /// Write the given buffer to the designated location in the sandbox memory. + /// + /// Returns `Err` if one of the following conditions occurs: + /// + /// - designated area is not within the bounds of the sandbox memory. + fn write_sandbox_memory(&mut self, ptr: u32, buf: &[u8]) -> Result<(), DispatchError> { + self.memory.set(ptr, buf).map_err(|_| Error::::OutOfBounds.into()) + } + /// Computes the given hash function on the supplied input. /// /// Reads from the sandboxed input buffer into an intermediate buffer. @@ -1362,4 +1394,37 @@ define_env!(Env, , ctx.charge_gas(RuntimeToken::HashBlake128(input_len))?; Ok(ctx.compute_hash_on_intermediate_buffer(blake2_128, input_ptr, input_len, output_ptr)?) }, + + // Call into the chain extension provided by the chain if any. + // + // Handling of the input values is up to the specific chain extension and so is the + // return value. The extension can decide to use the inputs as primitive inputs or as + // in/out arguments by interpreting them as pointers. Any caller of this function + // must therefore coordinate with the chain that it targets. + // + // # Note + // + // If no chain extension exists the contract will trap with the `NoChainExtension` + // module error. + seal_call_chain_extension( + ctx, + func_id: u32, + input_ptr: u32, + input_len: u32, + output_ptr: u32, + output_len_ptr: u32 + ) -> u32 => { + use crate::chain_extension::{ChainExtension, Environment, RetVal}; + if ::ChainExtension::enabled() == false { + Err(Error::::NoChainExtension)?; + } + let env = Environment::new(ctx, input_ptr, input_len, output_ptr, output_len_ptr); + match ::ChainExtension::call(func_id, env)? { + RetVal::Converging(val) => Ok(val), + RetVal::Diverging{flags, data} => Err(TrapReason::Return(ReturnData { + flags: flags.bits(), + data, + })), + } + }, ); -- GitLab From 28ffe375838bc918efd348cc18cc4a46b364e949 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 4 Jan 2021 12:54:51 +0100 Subject: [PATCH 162/163] *: Update to libp2p v0.33.0 (#7759) * *: Update to libp2p v0.33.0 * client/network: Consistently track request arrival time With https://github.com/libp2p/rust-libp2p/pull/1886/ one is guaranteed to receive either a `ResponseSent` or a `InboundFailure` event for each received inbound request via `RequestResponseEvent::Message`. Given this guarantee there is no need to track arrival times in a best-effort manner and thus there is no need to use a LRU cache for arrival times. * client/offchain: Adjust to PeerId API changes --- Cargo.lock | 103 +++++++++++++----------- bin/node/browser-testing/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 5 +- client/network/src/behaviour.rs | 4 +- client/network/src/request_responses.rs | 34 +++----- client/network/src/service.rs | 7 +- client/network/test/Cargo.toml | 2 +- client/offchain/src/api.rs | 8 +- client/peerset/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 15 files changed, 88 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff6f679ed78..c99c439eee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -716,6 +716,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "cipher" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +dependencies = [ + "generic-array 0.14.4", +] + [[package]] name = "ckb-merkle-mountain-range" version = "0.3.1" @@ -2819,9 +2828,9 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.32.2" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022cdac4ab124be12de581e591796d4dfb7d1f1eef94669d2c1eaa0e98dd2f0e" +checksum = "2e17c636b5fe5ff900ccc2840b643074bfac321551d821243a781d0d46f06588" dependencies = [ "atomic", "bytes 0.5.6", @@ -2857,13 +2866,12 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c96d3a606a696a3a6c0ad3c3352c57bda2082ec9090930f1bd9daf787039f" +checksum = "e1cb706da14c064dce54d8864ade6836b3486b51689300da74eeb7053aa4551e" dependencies = [ "asn1_der", "bs58", - "bytes 0.5.6", "ed25519-dalek", "either", "fnv", @@ -2902,9 +2910,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a579d7dd506d0620ba88ccc1754436b7de35ed6c884234f9a226bbfce382640" +checksum = "e3257a41f376aa23f237231971fee7e350e4d8353cfcf233aef34d6d6b638f0c" dependencies = [ "flate2", "futures 0.3.8", @@ -2913,9 +2921,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15dea5933f570844d7b5222b12b58f7bd52e9ca38cd65a1bd4f35341f053f012" +checksum = "2e09bab25af01326b4ed9486d31325911437448edda30bc57681502542d49f20" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -2924,9 +2932,9 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23070a0838bd9a8adb27e6eba477eeb650c498f9d139383dd0135d20a8170253" +checksum = "6fd8cdd5ef1dd0b7346975477216d752de976b92e43051bc8bd808c372ea6cec" dependencies = [ "cuckoofilter", "fnv", @@ -2942,9 +2950,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e8f3aa0906fbad435dac23c177eef3cdfaaf62609791bd7f54f8553edcfdf9" +checksum = "d489531aa9d4ba8726a08b3b74e21c2e10a518ad266ebca98d79040123ab0036" dependencies = [ "base64 0.13.0", "byteorder", @@ -2968,9 +2976,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "802fb973a7e0dde3fb9a2113a62bad90338ebe01983b706e1d576d0c2af93cda" +checksum = "c43bc51a9bc3780288c526615ba0f5f8216820ea6dcc02b89e8daee526c5fccb" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -2984,9 +2992,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6506b7b7982f7626fc96a91bc61be4b1fe7ae9ac23824f0ecefcce21cb39238c" +checksum = "a226956b49438a10f3206480b8faf5e61fc445c349ea9d9cc37766a83745fa9a" dependencies = [ "arrayvec 0.5.2", "bytes 0.5.6", @@ -3010,9 +3018,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b934ee03a361f317df7d75defa4177b285534c58f49d5e6e240278e13ef3f65" +checksum = "8a9e12688e8f14008c950c1efde587cb44dbf316fa805f419cd4e524991236f5" dependencies = [ "async-io", "data-encoding", @@ -3031,9 +3039,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae2132b14045009b0f8e577a06e1459592ef0a89dedc58f3d4baf4eac956837b" +checksum = "ce3200fbe6608e623bd9efa459cc8bafa0e4efbb0a2dfcdd0e1387ff4181264b" dependencies = [ "bytes 0.5.6", "futures 0.3.8", @@ -3049,9 +3057,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9610a524bef4db383cd96b4ec3ec4722eafa72c7242fa89990b74166760583d" +checksum = "0580e0d18019d254c9c349c03ff7b22e564b6f2ada70c045fc39738e144f2139" dependencies = [ "bytes 0.5.6", "curve25519-dalek 3.0.0", @@ -3071,9 +3079,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659adf89356e04f65398bb74ee791b269e63da9e41b37f8dc19eaacd12487bfe" +checksum = "50b2ec86a18cbf09d7df440e7786a2409640c774e476e9a3b4d031382c3d7588" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -3086,9 +3094,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96dfe26270c91d4ff095030d1fcadd602f3fd84968ebd592829916d0715798a6" +checksum = "6a7b1bdcbe46a3a2159c231601ed29645282653c0a96ce3a2ad8352c9fbe6800" dependencies = [ "bytes 0.5.6", "futures 0.3.8", @@ -3103,13 +3111,13 @@ dependencies = [ [[package]] name = "libp2p-pnet" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b3c2d5d26a9500e959a0e19743897239a6c4be78dadf99b70414301a70c006" +checksum = "6ce3374f3b28162db9d3442c9347c4f14cb01e8290052615c7d341d40eae0599" dependencies = [ "futures 0.3.8", "log", - "pin-project 0.4.27", + "pin-project 1.0.2", "rand 0.7.3", "salsa20", "sha3", @@ -3117,9 +3125,9 @@ dependencies = [ [[package]] name = "libp2p-request-response" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd96c3580fe59a9379ac7906c2f61c7f5ad3b7515362af0e72153a7cc9a45550" +checksum = "620e2950decbf77554b5aed3824f7d0e2c04923f28c70f9bff1a402c47ef6b1e" dependencies = [ "async-trait", "bytes 0.5.6", @@ -3137,9 +3145,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de333c483f27d02ecf7b6cef814a36f5e1876f15139eefb00225c405350e1c22" +checksum = "fdf5894ee1ee63a38aa58d58a16e3dcf7ede6b59ea7b22302c00c1a41d7aec41" dependencies = [ "either", "futures 0.3.8", @@ -3153,9 +3161,9 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.25.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc28c9ad6dc43f4c3950411cf808639d90307a076330e7996e5e94e70279bde0" +checksum = "1d2113a7dab2b502c55fe290910cd7399a2aa04fe70a2f5a415a87a1db600c0e" dependencies = [ "async-std", "futures 0.3.8", @@ -3169,9 +3177,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d821208d4b9af4b293a56dde470edd9f9fac8bb94a51f4f5327cc29a471b3f3" +checksum = "af05fe92c2a3aa320bc82a308ddb7b33bef3b060154c5a4b9fb0b01f15385fc0" dependencies = [ "async-std", "futures 0.3.8", @@ -3181,9 +3189,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6ef400b231ba78e866b860445480ca21ee447e03034138c6d57cf2969d6bf4" +checksum = "37cd44ea05a4523f40183f60ab6e6a80e400a5ddfc98b0df1c55edeb85576cd9" dependencies = [ "futures 0.3.8", "js-sys", @@ -3195,9 +3203,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.26.3" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522a877ce42ededf1f5dd011dbc40ea116f1776818f09dacb3d7a206f3ad6305" +checksum = "270c80528e21089ea25b41dd1ab8fd834bdf093ebee422fed3b68699a857a083" dependencies = [ "async-tls", "either", @@ -3215,9 +3223,9 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be7ac000fa3e42ac09a6e658e48de34ac8ef9fff64a4e6e6b08dcc8f4b0e5f6" +checksum = "36799de9092c35782f080032eddbc8de870f94a0def87cf9f8883efccd5cacf0" dependencies = [ "futures 0.3.8", "libp2p-core", @@ -6372,11 +6380,11 @@ dependencies = [ [[package]] name = "salsa20" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f47b10fa80f6969bbbd9c8e7cc998f082979d402a9e10579e2303a87955395" +checksum = "399f290ffc409596022fce5ea5d4138184be4784f2b28c62c59f0d8389059a15" dependencies = [ - "stream-cipher", + "cipher", ] [[package]] @@ -7101,7 +7109,6 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log", - "lru", "nohash-hasher", "parity-scale-codec", "parking_lot 0.11.1", diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index f297e624ca0..e29f104f87e 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } jsonrpc-core = "15.0.0" serde = "1.0.106" serde_json = "1.0.48" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 8878becd7e0..5c1d0b9d91f 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -23,7 +23,7 @@ derive_more = "0.99.2" either = "1.5.3" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.32.2", default-features = false, features = ["kad"] } +libp2p = { version = "0.33.0", default-features = false, features = ["kad"] } log = "0.4.8" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0"} prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 02d14d0d194..cd8afb1cce1 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -19,7 +19,7 @@ regex = "1.4.2" tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.2.1" -libp2p = "0.32.2" +libp2p = "0.33.0" parity-scale-codec = "1.3.0" hex = "0.4.2" rand = "0.7.3" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 5b82bd679c0..5c3990d320b 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } log = "0.4.8" lru = "0.6.1" sc-network = { version = "0.8.0", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index b7cb1512dd4..a300dac19bf 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -36,7 +36,6 @@ ip_network = "0.3.4" linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" -lru = "0.6.1" nohash-hasher = "0.2.0" parking_lot = "0.11.1" pin-project = "0.4.6" @@ -64,13 +63,13 @@ wasm-timer = "0.2" zeroize = "1.2.0" [dependencies.libp2p] -version = "0.32.2" +version = "0.33.0" default-features = false features = ["identify", "kad", "mdns", "mplex", "noise", "ping", "request-response", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] assert_matches = "1.3" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index e0ca241ede2..a7366d00e7c 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -90,7 +90,7 @@ pub enum BehaviourOut { protocol: Cow<'static, str>, /// If `Ok`, contains the time elapsed between when we received the request and when we /// sent back the response. If `Err`, the error that happened. - result: Result, ResponseFailure>, + result: Result, }, /// A request initiated using [`Behaviour::send_request`] has succeeded or failed. @@ -419,7 +419,7 @@ impl NetworkBehaviourEventProcess { diff --git a/client/network/src/request_responses.rs b/client/network/src/request_responses.rs index 4cd6bc3c5c4..806c04e5f30 100644 --- a/client/network/src/request_responses.rs +++ b/client/network/src/request_responses.rs @@ -50,7 +50,6 @@ use libp2p::{ PollParameters, ProtocolsHandler, }, }; -use lru::LruCache; use std::{ borrow::Cow, collections::{hash_map::Entry, HashMap}, convert::TryFrom as _, io, iter, pin::Pin, task::{Context, Poll}, time::{Duration, Instant}, @@ -129,12 +128,11 @@ pub enum Event { peer: PeerId, /// Name of the protocol in question. protocol: Cow<'static, str>, - /// If `Ok`, contains the time elapsed between when we received the request and when we - /// sent back the response. If `Err`, the error that happened. + /// Whether handling the request was successful or unsuccessful. /// - /// Note: Given that response time is tracked on a best-effort basis only, `Ok(time)` can be - /// `None`. - result: Result, ResponseFailure>, + /// When successful contains the time elapsed between when we received the request and when + /// we sent back the response. When unsuccessful contains the failure reason. + result: Result, }, /// A request initiated using [`RequestResponsesBehaviour::send_request`] has succeeded or @@ -164,7 +162,7 @@ pub struct RequestResponsesBehaviour { >, /// Whenever an incoming request arrives, the arrival [`Instant`] is recorded here. - pending_responses_arrival_time: LruCache, + pending_responses_arrival_time: HashMap, } /// Generated by the response builder and waiting to be processed. @@ -206,7 +204,7 @@ impl RequestResponsesBehaviour { Ok(Self { protocols, pending_responses: Default::default(), - pending_responses_arrival_time: LruCache::new(1_000), + pending_responses_arrival_time: Default::default(), }) } @@ -367,9 +365,8 @@ impl NetworkBehaviour for RequestResponsesBehaviour { if let Some((protocol, _)) = self.protocols.get_mut(&*protocol_name) { if let Err(_) = protocol.send_response(inner_channel, Ok(response)) { - // Note: In case this happened due to a timeout, the corresponding - // `RequestResponse` behaviour will emit an `InboundFailure::Timeout` event. - self.pending_responses_arrival_time.pop(&request_id); + // Note: Failure is handled further below when receiving `InboundFailure` + // event from `RequestResponse` behaviour. log::debug!( target: "sub-libp2p", "Failed to send response for {:?} on protocol {:?} due to a \ @@ -425,7 +422,7 @@ impl NetworkBehaviour for RequestResponsesBehaviour { peer, message: RequestResponseMessage::Request { request_id, request, channel, .. }, } => { - self.pending_responses_arrival_time.put( + self.pending_responses_arrival_time.insert( request_id.clone(), Instant::now(), ); @@ -495,7 +492,7 @@ impl NetworkBehaviour for RequestResponsesBehaviour { // An inbound request failed, either while reading the request or due to failing // to send a response. RequestResponseEvent::InboundFailure { request_id, peer, error, .. } => { - self.pending_responses_arrival_time.pop(&request_id); + self.pending_responses_arrival_time.remove(&request_id); let out = Event::InboundRequest { peer, protocol: protocol.clone(), @@ -504,14 +501,9 @@ impl NetworkBehaviour for RequestResponsesBehaviour { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(out)); } RequestResponseEvent::ResponseSent { request_id, peer } => { - let arrival_time = self.pending_responses_arrival_time.pop(&request_id) - .map(|t| t.elapsed()); - if arrival_time.is_none() { - log::debug!( - "Expected to find arrival time for sent response. Is the LRU \ - cache size set too small?", - ); - } + let arrival_time = self.pending_responses_arrival_time.remove(&request_id) + .map(|t| t.elapsed()) + .expect("To find request arrival time for answered request."); let out = Event::InboundRequest { peer, diff --git a/client/network/src/service.rs b/client/network/src/service.rs index c2d3dcc55b8..816f80106b8 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1373,14 +1373,11 @@ impl Future for NetworkWorker { Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::InboundRequest { protocol, result, .. })) => { if let Some(metrics) = this.metrics.as_ref() { match result { - Ok(Some(serve_time)) => { + Ok(serve_time) => { metrics.requests_in_success_total .with_label_values(&[&protocol]) .observe(serve_time.as_secs_f64()); } - // Response time tracking is happening on a best-effort basis. Ignore - // the event in case response time could not be provided. - Ok(None) => {}, Err(err) => { let reason = match err { ResponseFailure::Network(InboundFailure::Timeout) => "timeout", @@ -1388,6 +1385,8 @@ impl Future for NetworkWorker { "unsupported", ResponseFailure::Network(InboundFailure::ResponseOmission) => "busy-omitted", + ResponseFailure::Network(InboundFailure::ConnectionClosed) => + "connection-closed", }; metrics.requests_in_failure_total diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index d3036742f17..4bc46e35832 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" } sc-consensus = { version = "0.8.0", path = "../../consensus/common" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index 6bef7187e45..64c5060fb0c 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -187,9 +187,9 @@ impl OffchainExt for Api { fn set_authorized_nodes(&mut self, nodes: Vec, authorized_only: bool) { let peer_ids: HashSet = nodes.into_iter() - .filter_map(|node| PeerId::from_bytes(node.0).ok()) + .filter_map(|node| PeerId::from_bytes(&node.0).ok()) .collect(); - + self.network_provider.set_authorized_peers(peer_ids); self.network_provider.set_authorized_only(authorized_only); } @@ -213,7 +213,7 @@ impl NetworkState { impl From for OpaqueNetworkState { fn from(state: NetworkState) -> OpaqueNetworkState { - let enc = Encode::encode(&state.peer_id.into_bytes()); + let enc = Encode::encode(&state.peer_id.to_bytes()); let peer_id = OpaquePeerId::new(enc); let external_addresses: Vec = state @@ -239,7 +239,7 @@ impl TryFrom for NetworkState { let inner_vec = state.peer_id.0; let bytes: Vec = Decode::decode(&mut &inner_vec[..]).map_err(|_| ())?; - let peer_id = PeerId::from_bytes(bytes).map_err(|_| ())?; + let peer_id = PeerId::from_bytes(&bytes).map_err(|_| ())?; let external_addresses: Result, Self::Error> = state.external_addresses .iter() diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 41e2033bccf..92a4cf27753 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } sp-utils = { version = "2.0.0", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 98ed6388661..de8eea442ef 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -19,7 +19,7 @@ parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.5" -libp2p = { version = "0.32.2", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } +libp2p = { version = "0.33.0", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 642e047223b..f53e80aab79 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] thiserror = "1.0.21" -libp2p = { version = "0.32.2", default-features = false } +libp2p = { version = "0.33.0", default-features = false } log = "0.4.8" sp-core = { path= "../../core", version = "2.0.0"} sp-inherents = { version = "2.0.0", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 31fc1e37f3d..96fdf5ce191 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] futures = { version = "0.3", features = ["compat"] } futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.25", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.26", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.2.0" js-sys = "0.3.34" -- GitLab From fcdba68bc7b6bbc960bdfb326e2a706d580aa8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Mon, 4 Jan 2021 13:35:57 +0100 Subject: [PATCH 163/163] contracts: Lazy storage removal (#7740) * Do not evict a contract from within a call stack We don't want to trigger contract eviction automatically when a contract is called. This is because those changes can be reverted due to how storage transactions are used at the moment. More Information: https://github.com/paritytech/substrate/issues/6439#issuecomment-648754324 It can be re-introduced once the linked issue is resolved. In the meantime `claim_surcharge` must be called to evict a contract. * Lazily delete storage in on_initialize instead of when removing the contract * Add missing documentation of new error * Make Module::claim_surcharge public It being the only dispatchable that is private is an oversight. * review: Add final newline * review: Simplify assert statement * Add test that checks that partial remove of a contract works * Premote warning to error * Added missing docs for seal_terminate * Lazy deletion should only take AVERAGE_ON_INITIALIZE_RATIO of the block * Added informational about the lazy deletion throughput * Avoid lazy deletion in case the block is already full * Prevent queue decoding in case of an already full block * Add test that checks that on_initialize honors block limits --- bin/node/runtime/src/lib.rs | 12 + frame/contracts/src/benchmarking/mod.rs | 92 +- frame/contracts/src/exec.rs | 29 +- frame/contracts/src/lib.rs | 56 +- frame/contracts/src/rent.rs | 99 +-- frame/contracts/src/storage.rs | 131 ++- frame/contracts/src/tests.rs | 414 ++++++++- frame/contracts/src/wasm/runtime.rs | 2 + frame/contracts/src/weights.rs | 1038 ++++++++++++++--------- 9 files changed, 1348 insertions(+), 525 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 45f47f904e7..a36448c4708 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -71,6 +71,7 @@ pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, Currency use pallet_session::{historical as pallet_session_historical}; use sp_inherents::{InherentData, CheckInherentsResult}; use static_assertions::const_assert; +use pallet_contracts::WeightInfo; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -716,6 +717,15 @@ parameter_types! { pub const MaxDepth: u32 = 32; pub const StorageSizeOffset: u32 = 8; pub const MaxValueSize: u32 = 16 * 1024; + // The lazy deletion runs inside on_initialize. + pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * + RuntimeBlockWeights::get().max_block; + // The weight needed for decoding the queue should be less or equal than a fifth + // of the overall weight dedicated to the lazy deletion. + pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / ( + ::WeightInfo::on_initialize_per_queue_item(1) - + ::WeightInfo::on_initialize_per_queue_item(0) + )) / 5) as u32; } impl pallet_contracts::Config for Runtime { @@ -735,6 +745,8 @@ impl pallet_contracts::Config for Runtime { type WeightPrice = pallet_transaction_payment::Module; type WeightInfo = pallet_contracts::weights::SubstrateWeight; type ChainExtension = (); + type DeletionQueueDepth = DeletionQueueDepth; + type DeletionWeightLimit = DeletionWeightLimit; } impl pallet_sudo::Config for Runtime { diff --git a/frame/contracts/src/benchmarking/mod.rs b/frame/contracts/src/benchmarking/mod.rs index d6092f40a67..d08f0ab5e65 100644 --- a/frame/contracts/src/benchmarking/mod.rs +++ b/frame/contracts/src/benchmarking/mod.rs @@ -39,7 +39,7 @@ use self::{ use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use frame_system::{Module as System, RawOrigin}; use parity_wasm::elements::{Instruction, ValueType, BlockType}; -use sp_runtime::traits::{Hash, Bounded}; +use sp_runtime::traits::{Hash, Bounded, Zero}; use sp_std::{default::Default, convert::{TryInto}, vec::Vec, vec}; use pallet_contracts_primitives::RentProjection; @@ -209,37 +209,52 @@ where } } -/// A `Contract` that was evicted after accumulating some storage. +/// A `Contract` that contains some storage items. /// -/// This is used to benchmark contract resurrection. -struct Tombstone { +/// This is used to benchmark contract destruction and resurection. Those operations' +/// weight depend on the amount of storage accumulated. +struct ContractWithStorage { /// The contract that was evicted. contract: Contract, /// The storage the contract held when it was avicted. storage: Vec<(StorageKey, Vec)>, } -impl Tombstone +impl ContractWithStorage where T: Config, T::AccountId: UncheckedFrom + AsRef<[u8]>, { - /// Create and evict a new contract with the supplied storage item count and size each. + /// Same as [`Self::with_code`] but with dummy contract code. fn new(stor_num: u32, stor_size: u32) -> Result { - let contract = Contract::::new(WasmModule::dummy(), vec![], Endow::CollectRent)?; + Self::with_code(WasmModule::dummy(), stor_num, stor_size) + } + + /// Create and evict a new contract with the supplied storage item count and size each. + fn with_code(code: WasmModule, stor_num: u32, stor_size: u32) -> Result { + let contract = Contract::::new(code, vec![], Endow::CollectRent)?; let storage_items = create_storage::(stor_num, stor_size)?; contract.store(&storage_items)?; - System::::set_block_number( - contract.eviction_at()? + T::SignedClaimHandicap::get() + 5u32.into() - ); - Rent::::collect(&contract.account_id); - contract.ensure_tombstone()?; - - Ok(Tombstone { + Ok(Self { contract, storage: storage_items, }) } + + /// Increase the system block number so that this contract is eligible for eviction. + fn set_block_num_for_eviction(&self) -> Result<(), &'static str> { + System::::set_block_number( + self.contract.eviction_at()? + T::SignedClaimHandicap::get() + 5u32.into() + ); + Ok(()) + } + + /// Evict this contract. + fn evict(&mut self) -> Result<(), &'static str> { + self.set_block_num_for_eviction()?; + Rent::::snitch_contract_should_be_evicted(&self.contract.account_id, Zero::zero())?; + self.contract.ensure_tombstone() + } } /// Generate `stor_num` storage items. Each has the size `stor_size`. @@ -270,6 +285,30 @@ benchmarks! { _ { } + // The base weight without any actual work performed apart from the setup costs. + on_initialize {}: { + Storage::::process_deletion_queue_batch(Weight::max_value()) + } + + on_initialize_per_trie_key { + let k in 0..1024; + let instance = ContractWithStorage::::new(k, T::MaxValueSize::get())?; + Storage::::queue_trie_for_deletion(&instance.contract.alive_info()?)?; + }: { + Storage::::process_deletion_queue_batch(Weight::max_value()) + } + + on_initialize_per_queue_item { + let q in 0..1024.min(T::DeletionQueueDepth::get()); + for i in 0 .. q { + let instance = Contract::::with_index(i, WasmModule::dummy(), vec![], Endow::Max)?; + Storage::::queue_trie_for_deletion(&instance.alive_info()?)?; + ContractInfoOf::::remove(instance.account_id); + } + }: { + Storage::::process_deletion_queue_batch(Weight::max_value()) + } + // This extrinsic is pretty much constant as it is only a simple setter. update_schedule { let schedule = Schedule { @@ -650,7 +689,8 @@ benchmarks! { // Restore just moves the trie id from origin to destination and therefore // does not depend on the size of the destination contract. However, to not // trigger any edge case we won't use an empty contract as destination. - let tombstone = Tombstone::::new(10, T::MaxValueSize::get())?; + let mut tombstone = ContractWithStorage::::new(10, T::MaxValueSize::get())?; + tombstone.evict()?; let dest = tombstone.contract.account_id.encode(); let dest_len = dest.len(); @@ -723,7 +763,8 @@ benchmarks! { seal_restore_to_per_delta { let d in 0 .. API_BENCHMARK_BATCHES; - let tombstone = Tombstone::::new(0, 0)?; + let mut tombstone = ContractWithStorage::::new(0, 0)?; + tombstone.evict()?; let delta = create_storage::(d * API_BENCHMARK_BATCH_SIZE, T::MaxValueSize::get())?; let dest = tombstone.contract.account_id.encode(); @@ -2368,7 +2409,20 @@ benchmarks! { #[extra] print_schedule { #[cfg(feature = "std")] - println!("{:#?}", Schedule::::default()); + { + let weight_per_key = T::WeightInfo::on_initialize_per_trie_key(1) - + T::WeightInfo::on_initialize_per_trie_key(0); + let weight_per_queue_item = T::WeightInfo::on_initialize_per_queue_item(1) - + T::WeightInfo::on_initialize_per_queue_item(0); + let weight_limit = T::DeletionWeightLimit::get(); + let queue_depth: u64 = T::DeletionQueueDepth::get().into(); + println!("{:#?}", Schedule::::default()); + println!("###############################################"); + println!("Lazy deletion throughput per block (empty queue, full queue): {}, {}", + weight_limit / weight_per_key, + (weight_limit - weight_per_queue_item * queue_depth) / weight_per_key, + ); + } #[cfg(not(feature = "std"))] return Err("Run this bench with a native runtime in order to see the schedule."); }: {} @@ -2394,6 +2448,10 @@ mod tests { } } + create_test!(on_initialize); + create_test!(on_initialize_per_trie_key); + create_test!(on_initialize_per_queue_item); + create_test!(update_schedule); create_test!(put_code); create_test!(instantiate); diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index b5f4034b5bf..47ff216cd23 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -268,12 +268,12 @@ where Err(Error::::MaxCallDepthReached)? } - // Assumption: `collect` doesn't collide with overlay because - // `collect` will be done on first call and destination contract and balance - // cannot be changed before the first call - // We do not allow 'calling' plain accounts. For transfering value - // `seal_transfer` must be used. - let contract = if let Some(ContractInfo::Alive(info)) = Rent::::collect(&dest) { + // This charges the rent and denies access to a contract that is in need of + // eviction by returning `None`. We cannot evict eagerly here because those + // changes would be rolled back in case this contract is called by another + // contract. + // See: https://github.com/paritytech/substrate/issues/6439#issuecomment-648754324 + let contract = if let Ok(Some(ContractInfo::Alive(info))) = Rent::::charge(&dest) { info } else { Err(Error::::NotCallable)? @@ -575,13 +575,16 @@ where value, self.ctx, )?; - let self_trie_id = self.ctx.self_trie_id.as_ref().expect( - "this function is only invoked by in the context of a contract;\ - a contract has a trie id;\ - this can't be None; qed", - ); - Storage::::destroy_contract(&self_id, self_trie_id); - Ok(()) + if let Some(ContractInfo::Alive(info)) = ContractInfoOf::::take(&self_id) { + Storage::::queue_trie_for_deletion(&info)?; + Ok(()) + } else { + panic!( + "this function is only invoked by in the context of a contract;\ + this contract is therefore alive;\ + qed" + ); + } } fn call( diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index ad694b0c877..7b919fe2172 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -123,7 +123,7 @@ use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, traits::{OnUnbalanced, Currency, Get, Time, Randomness}, }; -use frame_system::{ensure_signed, ensure_root}; +use frame_system::{ensure_signed, ensure_root, Module as System}; use pallet_contracts_primitives::{ RentProjectionResult, GetStorageResult, ContractAccessError, ContractExecResult, ExecResult, }; @@ -325,6 +325,12 @@ pub trait Config: frame_system::Config { /// Type that allows the runtime authors to add new host functions for a contract to call. type ChainExtension: chain_extension::ChainExtension; + + /// The maximum number of tries that can be queued for deletion. + type DeletionQueueDepth: Get; + + /// The maximum amount of weight that can be consumed per block for lazy trie removal. + type DeletionWeightLimit: Get; } decl_error! { @@ -396,6 +402,17 @@ decl_error! { /// 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 either calling [`Module::claim_surcharge`] or `seal_terminate`. + /// The queue is filled by deleting contracts and emptied by a fixed amount each block. + /// Trying again during another block is the only way to resolve this issue. + DeletionQueueFull, + /// A contract could not be evicted because it has enough balance to pay rent. + /// + /// This can be returned from [`Module::claim_surcharge`] because the target + /// contract has enough balance to pay for its rent. + ContractNotEvictable, } } @@ -449,8 +466,24 @@ decl_module! { /// The maximum size of a storage value in bytes. A reasonable default is 16 KiB. const MaxValueSize: u32 = T::MaxValueSize::get(); + /// The maximum number of tries that can be queued for deletion. + const DeletionQueueDepth: u32 = T::DeletionQueueDepth::get(); + + /// The maximum amount of weight that can be consumed per block for lazy trie removal. + const DeletionWeightLimit: Weight = T::DeletionWeightLimit::get(); + fn deposit_event() = default; + fn on_initialize() -> Weight { + // 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()); + Storage::::process_deletion_queue_batch(weight_limit) + .saturating_add(T::WeightInfo::on_initialize()) + } + /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. @@ -549,10 +582,14 @@ decl_module! { /// Allows block producers to claim a small reward for evicting a contract. If a block producer /// fails to do so, a regular users will be allowed to claim the reward. /// - /// If contract is not evicted as a result of this call, no actions are taken and - /// the sender is not eligible for the reward. + /// If contract is not evicted as a result of this call, [`Error::ContractNotEvictable`] + /// is returned and the sender is not eligible for the reward. #[weight = T::WeightInfo::claim_surcharge()] - fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { + pub fn claim_surcharge( + origin, + dest: T::AccountId, + aux_sender: Option + ) -> DispatchResult { let origin = origin.into(); let (signed, rewarded) = match (origin, aux_sender) { (Ok(frame_system::RawOrigin::Signed(account)), None) => { @@ -574,8 +611,10 @@ decl_module! { }; // If poking the contract has lead to eviction of the contract, give out the rewards. - if Rent::::snitch_contract_should_be_evicted(&dest, handicap) { - T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; + if Rent::::snitch_contract_should_be_evicted(&dest, handicap)? { + T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get()).map(|_| ()) + } else { + Err(Error::::ContractNotEvictable.into()) } } } @@ -733,6 +772,11 @@ decl_storage! { /// /// TWOX-NOTE: SAFE since `AccountId` is a secure hash. pub ContractInfoOf: map hasher(twox_64_concat) T::AccountId => Option>; + /// 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`. + pub DeletionQueue: Vec; } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index d31efd5f552..f30b25b447a 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -20,13 +20,16 @@ use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, TombstoneContractInfo, Config, CodeHash, ConfigCache, Error, + storage::Storage, }; use sp_std::prelude::*; use sp_io::hashing::blake2_256; use sp_core::crypto::UncheckedFrom; -use frame_support::storage::child; -use frame_support::traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReasons}; -use frame_support::StorageMap; +use frame_support::{ + debug, StorageMap, + storage::child, + traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReasons}, +}; use pallet_contracts_primitives::{ContractAccessError, RentProjection, RentProjectionResult}; use sp_runtime::{ DispatchError, @@ -74,10 +77,6 @@ enum Verdict { /// For example, it already paid its rent in the current block, or it has enough deposit for not /// paying rent at all. Exempt, - /// Funds dropped below the subsistence deposit. - /// - /// Remove the contract along with it's storage. - Kill, /// The contract cannot afford payment within its rent budget so it gets evicted. However, /// because its balance is greater than the subsistence threshold it leaves a tombstone. Evict { @@ -181,11 +180,17 @@ where let rent_budget = match Self::rent_budget(&total_balance, &free_balance, contract) { Some(rent_budget) => rent_budget, None => { - // The contract's total balance is already below subsistence threshold. That - // indicates that the contract cannot afford to leave a tombstone. - // - // So cleanly wipe the contract. - return Verdict::Kill; + // All functions that allow a contract to transfer balance enforce + // that the contract always stays above the subsistence threshold. + // We want the rent system to always leave a tombstone to prevent the + // accidental loss of a contract. Ony `seal_terminate` can remove a + // contract without a tombstone. Therefore this case should be never + // hit. + debug::error!( + "Tombstoned a contract that is below the subsistence threshold: {:?}", + account + ); + 0u32.into() } }; @@ -234,19 +239,19 @@ where alive_contract_info: AliveContractInfo, current_block_number: T::BlockNumber, verdict: Verdict, - ) -> Option> { + allow_eviction: bool, + ) -> Result>, DispatchError> { match verdict { - Verdict::Exempt => return Some(ContractInfo::Alive(alive_contract_info)), - Verdict::Kill => { - >::remove(account); - child::kill_storage( - &alive_contract_info.child_trie_info(), - None, - ); - >::deposit_event(RawEvent::Evicted(account.clone(), false)); - None + Verdict::Exempt => return Ok(Some(ContractInfo::Alive(alive_contract_info))), + Verdict::Evict { amount: _ } if !allow_eviction => { + Ok(None) } Verdict::Evict { amount } => { + // We need to remove the trie first because it is the only operation + // that can fail and this function is called without a storage + // transaction when called through `claim_surcharge`. + Storage::::queue_trie_for_deletion(&alive_contract_info)?; + if let Some(amount) = amount { amount.withdraw(account); } @@ -262,14 +267,8 @@ where ); let tombstone_info = ContractInfo::Tombstone(tombstone); >::insert(account, &tombstone_info); - - child::kill_storage( - &alive_contract_info.child_trie_info(), - None, - ); - >::deposit_event(RawEvent::Evicted(account.clone(), true)); - Some(tombstone_info) + Ok(Some(tombstone_info)) } Verdict::Charge { amount } => { let contract_info = ContractInfo::Alive(AliveContractInfo:: { @@ -278,21 +277,21 @@ where ..alive_contract_info }); >::insert(account, &contract_info); - amount.withdraw(account); - Some(contract_info) + Ok(Some(contract_info)) } } } /// Make account paying the rent for the current block number /// - /// NOTE this function performs eviction eagerly. All changes are read and written directly to - /// storage. - pub fn collect(account: &T::AccountId) -> Option> { + /// This functions does **not** evict the contract. It returns `None` in case the + /// contract is in need of eviction. [`snitch_contract_should_be_evicted`] must + /// be called to perform the eviction. + pub fn charge(account: &T::AccountId) -> Result>, DispatchError> { let contract_info = >::get(account); let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return contract_info, + None | Some(ContractInfo::Tombstone(_)) => return Ok(contract_info), Some(ContractInfo::Alive(contract)) => contract, }; @@ -303,7 +302,7 @@ where Zero::zero(), &alive_contract_info, ); - Self::enact_verdict(account, alive_contract_info, current_block_number, verdict) + Self::enact_verdict(account, alive_contract_info, current_block_number, verdict, false) } /// Process a report that a contract under the given address should be evicted. @@ -321,10 +320,10 @@ where pub fn snitch_contract_should_be_evicted( account: &T::AccountId, handicap: T::BlockNumber, - ) -> bool { - let contract_info = >::get(account); - let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return false, + ) -> Result { + let contract = >::get(account); + let contract = match contract { + None | Some(ContractInfo::Tombstone(_)) => return Ok(false), Some(ContractInfo::Alive(contract)) => contract, }; let current_block_number = >::block_number(); @@ -332,16 +331,16 @@ where account, current_block_number, handicap, - &alive_contract_info, + &contract, ); // Enact the verdict only if the contract gets removed. match verdict { - Verdict::Kill | Verdict::Evict { .. } => { - Self::enact_verdict(account, alive_contract_info, current_block_number, verdict); - true + Verdict::Evict { .. } => { + Self::enact_verdict(account, contract, current_block_number, verdict, true)?; + Ok(true) } - _ => false, + _ => Ok(false), } } @@ -359,9 +358,11 @@ where pub fn compute_projection( account: &T::AccountId, ) -> RentProjectionResult { + use ContractAccessError::IsTombstone; + let contract_info = >::get(account); let alive_contract_info = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + None | Some(ContractInfo::Tombstone(_)) => return Err(IsTombstone), Some(ContractInfo::Alive(contract)) => contract, }; let current_block_number = >::block_number(); @@ -372,11 +373,11 @@ where &alive_contract_info, ); let new_contract_info = - Self::enact_verdict(account, alive_contract_info, current_block_number, verdict); + Self::enact_verdict(account, alive_contract_info, current_block_number, verdict, false); // Check what happened after enaction of the verdict. - let alive_contract_info = match new_contract_info { - None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + let alive_contract_info = match new_contract_info.map_err(|_| IsTombstone)? { + None | Some(ContractInfo::Tombstone(_)) => return Err(IsTombstone), Some(ContractInfo::Alive(contract)) => contract, }; diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs index 180ec7237ff..520a114986f 100644 --- a/frame/contracts/src/storage.rs +++ b/frame/contracts/src/storage.rs @@ -20,20 +20,37 @@ use crate::{ exec::{AccountIdOf, StorageKey}, AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Config, TrieId, - AccountCounter, + AccountCounter, DeletionQueue, Error, + weights::WeightInfo, }; +use codec::{Encode, Decode}; use sp_std::prelude::*; use sp_std::marker::PhantomData; use sp_io::hashing::blake2_256; use sp_runtime::traits::Bounded; use sp_core::crypto::UncheckedFrom; -use frame_support::{storage::child, StorageMap}; +use frame_support::{ + dispatch::DispatchResult, + StorageMap, + debug, + storage::{child::{self, KillOutcome}, StorageValue}, + traits::Get, + weights::Weight, +}; /// An error that means that the account requested either doesn't exist or represents a tombstone /// account. #[cfg_attr(test, derive(PartialEq, Eq, Debug))] pub struct ContractAbsentError; +#[derive(Encode, Decode)] +pub struct DeletedContract { + pair_count: u32, + trie_id: TrieId, +} + + + pub struct Storage(PhantomData); impl Storage @@ -191,18 +208,105 @@ where }) } - /// Removes the contract and all the storage associated with it. + /// Push a contract's trie to the deletion queue for lazy removal. /// - /// This function doesn't affect the account. - pub fn destroy_contract(address: &AccountIdOf, trie_id: &TrieId) { - >::remove(address); - child::kill_storage(&crate::child_trie_info(&trie_id), None); + /// You must make sure that the contract is also removed or converted into a tombstone + /// when queuing the trie for deletion. + pub fn queue_trie_for_deletion(contract: &AliveContractInfo) -> DispatchResult { + if DeletionQueue::decode_len().unwrap_or(0) >= T::DeletionQueueDepth::get() as usize { + Err(Error::::DeletionQueueFull.into()) + } else { + DeletionQueue::append(DeletedContract { + pair_count: contract.total_pair_count, + trie_id: contract.trie_id.clone(), + }); + Ok(()) + } + } + + /// 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) -> (u64, u32) { + let base_weight = T::WeightInfo::on_initialize(); + 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 Weight); + + // `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(weight_per_key) + .unwrap_or(0) as u32; + + (weight_per_key, key_budget) + } + + /// Delete as many items from the deletion queue possible within the supplied weight limit. + /// + /// It returns the amount of weight used for that task or `None` when no weight was used + /// apart from the base weight. + pub fn process_deletion_queue_batch(weight_limit: Weight) -> Weight { + let queue_len = DeletionQueue::decode_len().unwrap_or(0); + if queue_len == 0 { + return weight_limit; + } + + let (weight_per_key, mut remaining_key_budget) = Self::deletion_budget( + queue_len, + 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 + // which consume the whole block before the other `on_initialize` blocks are called. + if remaining_key_budget == 0 { + return weight_limit; + } + + let mut queue = DeletionQueue::get(); + + while !queue.is_empty() && remaining_key_budget > 0 { + // Cannot panic due to loop condition + let trie = &mut queue[0]; + let pair_count = trie.pair_count; + let outcome = child::kill_storage( + &crate::child_trie_info(&trie.trie_id), + Some(remaining_key_budget), + ); + if pair_count > remaining_key_budget { + // Cannot underflow because of the if condition + trie.pair_count -= remaining_key_budget; + } else { + // We do not care to preserve order. The contract is deleted already and + // noone waits for the trie to be deleted. + let removed = queue.swap_remove(0); + match outcome { + // This should not happen as our budget was large enough to remove all keys. + KillOutcome::SomeRemaining => { + debug::error!( + "After deletion keys are remaining in this child trie: {:?}", + removed.trie_id, + ); + }, + KillOutcome::AllRemoved => (), + } + } + remaining_key_budget = remaining_key_budget + .saturating_sub(remaining_key_budget.min(pair_count)); + } + + DeletionQueue::put(queue); + weight_limit.saturating_sub(weight_per_key.saturating_mul(remaining_key_budget as Weight)) } /// This generator uses inner counter for account id and applies the hash over `AccountId + /// accountid_counter`. pub fn generate_trie_id(account_id: &AccountIdOf) -> TrieId { - use frame_support::StorageValue; use sp_runtime::traits::Hash; // Note that skipping a value due to error is not an issue here. // We only need uniqueness, not sequence. @@ -226,4 +330,15 @@ where .and_then(|i| i.as_alive().map(|i| i.code_hash)) .ok_or(ContractAbsentError) } + + /// Fill up the queue in order to exercise the limits during testing. + #[cfg(test)] + pub fn fill_queue_with_dummies() { + let queue: Vec<_> = (0..T::DeletionQueueDepth::get()).map(|_| DeletedContract { + pair_count: 0, + trie_id: vec![], + }) + .collect(); + DeletionQueue::put(queue); + } } diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 1f069a9b465..d1a9521924f 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -32,12 +32,14 @@ use sp_runtime::{ testing::{Header, H256}, AccountId32, }; +use sp_io::hashing::blake2_256; use frame_support::{ - assert_ok, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, + assert_ok, assert_err, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, StorageMap, - traits::{Currency, ReservableCurrency}, - weights::{Weight, PostDispatchInfo}, + traits::{Currency, ReservableCurrency, OnInitialize}, + weights::{Weight, PostDispatchInfo, DispatchClass, constants::WEIGHT_PER_SECOND}, dispatch::DispatchErrorWithPostInfo, + storage::child, }; use frame_system::{self as system, EventRecord, Phase}; @@ -189,12 +191,12 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); + frame_system::limits::BlockWeights::simple_max(2 * WEIGHT_PER_SECOND); pub static ExistentialDeposit: u64 = 0; } impl frame_system::Config for Test { type BaseCallFilter = (); - type BlockWeights = (); + type BlockWeights = BlockWeights; type BlockLength = (); type DbWeight = (); type Origin = Origin; @@ -243,6 +245,8 @@ parameter_types! { pub const SurchargeReward: u64 = 150; pub const MaxDepth: u32 = 100; pub const MaxValueSize: u32 = 16_384; + pub const DeletionQueueDepth: u32 = 1024; + pub const DeletionWeightLimit: Weight = 500_000_000_000; } parameter_types! { @@ -272,6 +276,8 @@ impl Config for Test { type WeightPrice = Self; type WeightInfo = (); type ChainExtension = TestExtension; + type DeletionQueueDepth = DeletionQueueDepth; + type DeletionWeightLimit = DeletionWeightLimit; } type Balances = pallet_balances::Module; @@ -859,15 +865,6 @@ fn deduct_blocks() { }); } -#[test] -fn call_contract_removals() { - removals(|addr| { - // Call on already-removed account might fail, and this is fine. - let _ = Contracts::call(Origin::signed(ALICE), addr, 0, GAS_LIMIT, call::null()); - true - }); -} - #[test] fn inherent_claim_surcharge_contract_removals() { removals(|addr| Contracts::claim_surcharge(Origin::none(), addr, Some(ALICE)).is_ok()); @@ -918,7 +915,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn(AccountIdOf) -> bool initialize_block(blocks); // Trigger rent through call - assert!(trigger_call(addr.clone())); + assert_eq!(trigger_call(addr.clone()), removes); if removes { assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); @@ -956,7 +953,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert_eq!(ContractInfoOf::::get(&addr).unwrap().get_alive().unwrap().rent_allowance, 1_000); assert_eq!(Balances::free_balance(&addr), 100); @@ -972,7 +969,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); assert_eq!(Balances::free_balance(&addr), subsistence_threshold); }); @@ -996,7 +993,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert_eq!( ContractInfoOf::::get(&addr) .unwrap() @@ -1023,7 +1020,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert!(ContractInfoOf::::get(&addr) .unwrap() .get_tombstone() @@ -1052,7 +1049,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { let addr = Contracts::contract_address(&ALICE, &code_hash, &[]); // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert_eq!( ContractInfoOf::::get(&addr) .unwrap() @@ -1096,7 +1093,7 @@ fn removals(trigger_call: impl Fn(AccountIdOf) -> bool) { initialize_block(20); // Trigger rent must have no effect - assert!(trigger_call(addr.clone())); + assert!(!trigger_call(addr.clone())); assert_matches!(ContractInfoOf::::get(&addr), Some(ContractInfo::Tombstone(_))); assert_eq!(Balances::free_balance(&addr), subsistence_threshold); }); @@ -1131,25 +1128,23 @@ fn call_removed_contract() { // Advance blocks initialize_block(10); - // Calling contract should remove contract and fail. + // Calling contract should deny access because rent cannot be paid. assert_err_ignore_postinfo!( Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()), Error::::NotCallable ); - // Calling a contract that is about to evict shall emit an event. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(addr.clone(), true)), - topics: vec![], - }, - ]); + // No event is generated because the contract is not actually removed. + assert_eq!(System::events(), vec![]); // Subsequent contract calls should also fail. assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), addr, 0, GAS_LIMIT, call::null()), + Contracts::call(Origin::signed(ALICE), addr.clone(), 0, GAS_LIMIT, call::null()), Error::::NotCallable ); + + // A snitch can now remove the contract + assert_ok!(Contracts::claim_surcharge(Origin::none(), addr.clone(), Some(ALICE))); + assert!(ContractInfoOf::::get(&addr).unwrap().get_tombstone().is_some()); }) } @@ -1278,13 +1273,17 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: initialize_block(5); // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 - // we expect that it will get removed leaving tombstone. + // we expect that it is no longer callable but keeps existing until someone + // calls `claim_surcharge`. assert_err_ignore_postinfo!( Contracts::call( Origin::signed(ALICE), addr_bob.clone(), 0, GAS_LIMIT, call::null() ), Error::::NotCallable ); + assert!(System::events().is_empty()); + assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_alive().is_some()); + assert_ok!(Contracts::claim_surcharge(Origin::none(), addr_bob.clone(), Some(ALICE))); assert!(ContractInfoOf::::get(&addr_bob).unwrap().get_tombstone().is_some()); assert_eq!(System::events(), vec![ EventRecord { @@ -2134,3 +2133,354 @@ fn chain_extension_works() { }); } +#[test] +fn lazy_removal_works() { + let (code, hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + let info = >::get(&addr).unwrap().get_alive().unwrap(); + let trie = &info.child_trie_info(); + + // Put value into the contracts child trie + child::put(trie, &[99], &42); + + // Terminate the contract + assert_ok!(Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + )); + + // Contract info should be gone + assert!(!>::contains_key(&addr)); + + // But value should be still there as the lazy removal did not run, yet. + assert_matches!(child::get(trie, &[99]), Some(42)); + + // Run the lazy removal + Contracts::on_initialize(Weight::max_value()); + + // Value should be gone now + assert_matches!(child::get::(trie, &[99]), None); + }); +} + +#[test] +fn lazy_removal_partial_remove_works() { + let (code, hash) = compile_module::("self_destruct").unwrap(); + + // We create a contract with some extra keys above the weight limit + let extra_keys = 7u32; + let weight_limit = 5_000_000_000; + let (_, max_keys) = Storage::::deletion_budget(1, weight_limit); + let vals: Vec<_> = (0..max_keys + extra_keys).map(|i| { + (blake2_256(&i.encode()), (i as u32), (i as u32).encode()) + }) + .collect(); + + let mut ext = ExtBuilder::default().existential_deposit(50).build(); + + let trie = ext.execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + let info = >::get(&addr).unwrap().get_alive().unwrap(); + let trie = &info.child_trie_info(); + + // Put value into the contracts child trie + for val in &vals { + Storage::::write( + &addr, + &info.trie_id, + &val.0, + Some(val.2.clone()), + ).unwrap(); + } + + // Terminate the contract + assert_ok!(Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + )); + + // Contract info should be gone + assert!(!>::contains_key(&addr)); + + // But value should be still there as the lazy removal did not run, yet. + for val in &vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), Some(val.1)); + } + + trie.clone() + }); + + // The lazy removal limit only applies to the backend but not to the overlay. + // This commits all keys from the overlay to the backend. + ext.commit_all().unwrap(); + + ext.execute_with(|| { + // Run the lazy removal + let weight_used = Storage::::process_deletion_queue_batch(weight_limit); + + // Weight should be exhausted because we could not even delete all keys + assert_eq!(weight_used, weight_limit); + + let mut num_deleted = 0u32; + let mut num_remaining = 0u32; + + for val in &vals { + match child::get::(&trie, &blake2_256(&val.0)) { + None => num_deleted += 1, + Some(x) if x == val.1 => num_remaining += 1, + Some(_) => panic!("Unexpected value in contract storage"), + } + } + + // All but one key is removed + assert_eq!(num_deleted + num_remaining, vals.len() as u32); + assert_eq!(num_deleted, max_keys); + assert_eq!(num_remaining, extra_keys); + }); +} + +#[test] +fn lazy_removal_does_no_run_on_full_block() { + let (code, hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + let info = >::get(&addr).unwrap().get_alive().unwrap(); + let trie = &info.child_trie_info(); + let max_keys = 30; + + // Create some storage items for the contract. + let vals: Vec<_> = (0..max_keys).map(|i| { + (blake2_256(&i.encode()), (i as u32), (i as u32).encode()) + }) + .collect(); + + // Put value into the contracts child trie + for val in &vals { + Storage::::write( + &addr, + &info.trie_id, + &val.0, + Some(val.2.clone()), + ).unwrap(); + } + + // Terminate the contract + assert_ok!(Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + )); + + // Contract info should be gone + assert!(!>::contains_key(&addr)); + + // But value should be still there as the lazy removal did not run, yet. + for val in &vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), Some(val.1)); + } + + // Fill up the block which should prevent the lazy storage removal from running. + System::register_extra_weight_unchecked( + ::BlockWeights::get().max_block, + DispatchClass::Mandatory, + ); + + // Run the lazy removal without any limit so that all keys would be removed if there + // had been some weight left in the block. + let weight_used = Contracts::on_initialize(Weight::max_value()); + let base = <::WeightInfo as crate::WeightInfo>::on_initialize(); + assert_eq!(weight_used, base); + + // All the keys are still in place + for val in &vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), Some(val.1)); + } + + // Run the lazy removal directly which disregards the block limits + Storage::::process_deletion_queue_batch(Weight::max_value()); + + // Now the keys should be gone + for val in &vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), None); + } + }); +} + + +#[test] +fn lazy_removal_does_not_use_all_weight() { + let (code, hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + let info = >::get(&addr).unwrap().get_alive().unwrap(); + let trie = &info.child_trie_info(); + let weight_limit = 5_000_000_000; + let (weight_per_key, max_keys) = Storage::::deletion_budget(1, weight_limit); + + // We create a contract with one less storage item than we can remove within the limit + let vals: Vec<_> = (0..max_keys - 1).map(|i| { + (blake2_256(&i.encode()), (i as u32), (i as u32).encode()) + }) + .collect(); + + // Put value into the contracts child trie + for val in &vals { + Storage::::write( + &addr, + &info.trie_id, + &val.0, + Some(val.2.clone()), + ).unwrap(); + } + + // Terminate the contract + assert_ok!(Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + )); + + // Contract info should be gone + assert!(!>::contains_key(&addr)); + + // But value should be still there as the lazy removal did not run, yet. + for val in &vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), Some(val.1)); + } + + // Run the lazy removal + let weight_used = Storage::::process_deletion_queue_batch(weight_limit); + + // We have one less key in our trie than our weight limit suffices for + assert_eq!(weight_used, weight_limit - weight_per_key); + + // All the keys are removed + for val in vals { + assert_eq!(child::get::(trie, &blake2_256(&val.0)), None); + } + }); +} + +#[test] +fn deletion_queue_full() { + let (code, hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default().existential_deposit(50).build().execute_with(|| { + let subsistence = ConfigCache::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), code)); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + hash.into(), + vec![], + vec![], + ), + ); + + let addr = Contracts::contract_address(&ALICE, &hash, &[]); + + // fill the deletion queue up until its limit + Storage::::fill_queue_with_dummies(); + + // Terminate the contract should fail + assert_err_ignore_postinfo!( + Contracts::call( + Origin::signed(ALICE), + addr.clone(), + 0, + GAS_LIMIT, + vec![], + ), + Error::::DeletionQueueFull, + ); + + // Contract should be alive because removal failed + >::get(&addr).unwrap().get_alive().unwrap(); + + // make the contract ripe for eviction + initialize_block(5); + + // eviction should fail for the same reason as termination + assert_err!( + Contracts::claim_surcharge(Origin::none(), addr.clone(), Some(ALICE)), + Error::::DeletionQueueFull, + ); + + // Contract should be alive because removal failed + >::get(&addr).unwrap().get_alive().unwrap(); + }); +} diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 41ab3e390ae..dd4e37b8e8f 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -923,6 +923,8 @@ define_env!(Env, , // # Traps // // - The contract is live i.e is already on the call stack. + // - Failed to send the balance to the beneficiary. + // - The deletion queue is full. seal_terminate( ctx, beneficiary_ptr: u32, diff --git a/frame/contracts/src/weights.rs b/frame/contracts/src/weights.rs index b9d7bc6e1fc..8b1b7732766 100644 --- a/frame/contracts/src/weights.rs +++ b/frame/contracts/src/weights.rs @@ -15,9 +15,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Weights for pallet_contracts +//! Autogenerated weights for pallet_contracts +//! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-11-10, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2020-12-12, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -43,6 +44,9 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_contracts. pub trait WeightInfo { + fn on_initialize() -> Weight; + fn on_initialize_per_trie_key(k: u32, ) -> Weight; + fn on_initialize_per_queue_item(q: u32, ) -> Weight; fn update_schedule() -> Weight; fn put_code(n: u32, ) -> Weight; fn instantiate(n: u32, s: u32, ) -> Weight; @@ -145,948 +149,1182 @@ pub trait WeightInfo { /// Weights for pallet_contracts using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + fn on_initialize() -> Weight { + (7_239_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + fn on_initialize_per_trie_key(k: u32, ) -> Weight { + (40_584_000 as Weight) + // Standard Error: 4_000 + .saturating_add((2_314_000 as Weight).saturating_mul(k as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) + } + fn on_initialize_per_queue_item(q: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 175_000 + .saturating_add((135_919_000 as Weight).saturating_mul(q as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } fn update_schedule() -> Weight { - (35_214_000 as Weight) + (36_262_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn put_code(n: u32, ) -> Weight { - (0 as Weight) - .saturating_add((109_242_000 as Weight).saturating_mul(n as Weight)) + (22_510_000 as Weight) + // Standard Error: 209_000 + .saturating_add((113_251_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn instantiate(n: u32, s: u32, ) -> Weight { - (195_276_000 as Weight) - .saturating_add((35_000 as Weight).saturating_mul(n as Weight)) - .saturating_add((2_244_000 as Weight).saturating_mul(s as Weight)) + (216_181_000 as Weight) + // Standard Error: 1_000 + .saturating_add((6_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 1_000 + .saturating_add((2_240_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn call() -> Weight { - (207_142_000 as Weight) + (209_785_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn claim_surcharge() -> Weight { - (489_633_000 as Weight) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) + (302_124_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (136_550_000 as Weight) - .saturating_add((373_182_000 as Weight).saturating_mul(r as Weight)) + (138_697_000 as Weight) + // Standard Error: 412_000 + .saturating_add((390_370_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (136_329_000 as Weight) - .saturating_add((373_392_000 as Weight).saturating_mul(r as Weight)) + (141_999_000 as Weight) + // Standard Error: 218_000 + .saturating_add((389_261_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (111_577_000 as Weight) - .saturating_add((373_536_000 as Weight).saturating_mul(r as Weight)) + (134_956_000 as Weight) + // Standard Error: 205_000 + .saturating_add((384_439_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (157_531_000 as Weight) - .saturating_add((810_382_000 as Weight).saturating_mul(r as Weight)) + (130_585_000 as Weight) + // Standard Error: 784_000 + .saturating_add((860_797_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (143_801_000 as Weight) - .saturating_add((369_769_000 as Weight).saturating_mul(r as Weight)) + (138_382_000 as Weight) + // Standard Error: 163_000 + .saturating_add((384_676_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (133_546_000 as Weight) - .saturating_add((370_036_000 as Weight).saturating_mul(r as Weight)) + (137_766_000 as Weight) + // Standard Error: 218_000 + .saturating_add((386_002_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (138_568_000 as Weight) - .saturating_add((370_322_000 as Weight).saturating_mul(r as Weight)) + (144_552_000 as Weight) + // Standard Error: 187_000 + .saturating_add((384_754_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (144_431_000 as Weight) - .saturating_add((851_810_000 as Weight).saturating_mul(r as Weight)) + (150_812_000 as Weight) + // Standard Error: 276_000 + .saturating_add((903_965_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (133_237_000 as Weight) - .saturating_add((369_156_000 as Weight).saturating_mul(r as Weight)) + (145_168_000 as Weight) + // Standard Error: 191_000 + .saturating_add((382_798_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (139_700_000 as Weight) - .saturating_add((368_961_000 as Weight).saturating_mul(r as Weight)) + (145_806_000 as Weight) + // Standard Error: 195_000 + .saturating_add((382_888_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (149_395_000 as Weight) - .saturating_add((625_812_000 as Weight).saturating_mul(r as Weight)) + (154_081_000 as Weight) + // Standard Error: 248_000 + .saturating_add((716_294_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (125_777_000 as Weight) - .saturating_add((187_585_000 as Weight).saturating_mul(r as Weight)) + (149_684_000 as Weight) + // Standard Error: 460_000 + .saturating_add((196_251_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (132_584_000 as Weight) - .saturating_add((7_661_000 as Weight).saturating_mul(r as Weight)) + (135_447_000 as Weight) + // Standard Error: 75_000 + .saturating_add((8_362_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (143_408_000 as Weight) - .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) + (146_099_000 as Weight) + // Standard Error: 0 + .saturating_add((270_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (126_257_000 as Weight) - .saturating_add((5_455_000 as Weight).saturating_mul(r as Weight)) + (125_358_000 as Weight) + // Standard Error: 52_000 + .saturating_add((5_454_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (133_286_000 as Weight) - .saturating_add((698_000 as Weight).saturating_mul(n as Weight)) + (135_523_000 as Weight) + // Standard Error: 0 + .saturating_add((785_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (130_607_000 as Weight) - .saturating_add((358_370_000 as Weight).saturating_mul(r as Weight)) + (135_321_000 as Weight) + // Standard Error: 100_000 + .saturating_add((110_300_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) - .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to(r: u32, ) -> Weight { - (233_645_000 as Weight) - .saturating_add((135_355_000 as Weight).saturating_mul(r as Weight)) + (242_790_000 as Weight) + // Standard Error: 823_000 + .saturating_add((135_544_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (74_573_000 as Weight) - .saturating_add((3_768_682_000 as Weight).saturating_mul(d as Weight)) + (34_052_000 as Weight) + // Standard Error: 2_395_000 + .saturating_add((3_970_866_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(T::DbWeight::get().writes(5 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (140_286_000 as Weight) - .saturating_add((950_890_000 as Weight).saturating_mul(r as Weight)) + (154_549_000 as Weight) + // Standard Error: 692_000 + .saturating_add((989_540_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (167_735_000 as Weight) - .saturating_add((1_375_429_000 as Weight).saturating_mul(r as Weight)) + (125_367_000 as Weight) + // Standard Error: 977_000 + .saturating_add((1_424_216_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_715_857_000 as Weight) - .saturating_add((760_777_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((241_853_000 as Weight).saturating_mul(n as Weight)) + (1_843_333_000 as Weight) + // Standard Error: 3_040_000 + .saturating_add((771_663_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 599_000 + .saturating_add((251_555_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (156_911_000 as Weight) - .saturating_add((1_006_139_000 as Weight).saturating_mul(r as Weight)) + (136_437_000 as Weight) + // Standard Error: 299_000 + .saturating_add((1_072_778_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((14_938_793_000 as Weight).saturating_mul(r as Weight)) + (182_452_000 as Weight) + // Standard Error: 26_839_000 + .saturating_add((15_911_876_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (2_300_169_000 as Weight) - .saturating_add((204_543_000 as Weight).saturating_mul(n as Weight)) + (2_385_415_000 as Weight) + // Standard Error: 751_000 + .saturating_add((223_264_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((5_140_241_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_154_000 + .saturating_add((5_341_117_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (45_212_000 as Weight) - .saturating_add((1_131_504_000 as Weight).saturating_mul(r as Weight)) + (62_353_000 as Weight) + // Standard Error: 1_183_000 + .saturating_add((1_141_653_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (885_531_000 as Weight) - .saturating_add((148_986_000 as Weight).saturating_mul(n as Weight)) + (905_905_000 as Weight) + // Standard Error: 363_000 + .saturating_add((155_161_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (92_276_000 as Weight) - .saturating_add((6_216_852_000 as Weight).saturating_mul(r as Weight)) + (60_519_000 as Weight) + // Standard Error: 1_942_000 + .saturating_add((6_453_551_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) .saturating_add(T::DbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((10_734_719_000 as Weight).saturating_mul(r as Weight)) + (192_122_000 as Weight) + // Standard Error: 7_851_000 + .saturating_add((10_736_771_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (12_735_614_000 as Weight) - .saturating_add((2_870_730_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((52_569_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((73_956_000 as Weight).saturating_mul(o as Weight)) + (10_599_501_000 as Weight) + // Standard Error: 133_182_000 + .saturating_add((5_423_848_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 47_000 + .saturating_add((60_108_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 50_000 + .saturating_add((82_691_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(105 as Weight)) .saturating_add(T::DbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(T::DbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((22_365_908_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 39_807_000 + .saturating_add((22_562_812_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) } fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (18_899_296_000 as Weight) - .saturating_add((53_289_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((76_026_000 as Weight).saturating_mul(o as Weight)) - .saturating_add((281_097_000 as Weight).saturating_mul(s as Weight)) + (19_823_256_000 as Weight) + // Standard Error: 153_000 + .saturating_add((60_707_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 153_000 + .saturating_add((83_770_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 153_000 + .saturating_add((284_423_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(207 as Weight)) .saturating_add(T::DbWeight::get().writes(202 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (136_601_000 as Weight) - .saturating_add((323_373_000 as Weight).saturating_mul(r as Weight)) + (142_838_000 as Weight) + // Standard Error: 243_000 + .saturating_add((332_354_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (777_563_000 as Weight) - .saturating_add((423_353_000 as Weight).saturating_mul(n as Weight)) + (877_119_000 as Weight) + // Standard Error: 73_000 + .saturating_add((434_752_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (136_771_000 as Weight) - .saturating_add((337_881_000 as Weight).saturating_mul(r as Weight)) + (139_913_000 as Weight) + // Standard Error: 160_000 + .saturating_add((345_830_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (337_906_000 as Weight) - .saturating_add((336_778_000 as Weight).saturating_mul(n as Weight)) + (723_122_000 as Weight) + // Standard Error: 29_000 + .saturating_add((343_949_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (131_040_000 as Weight) - .saturating_add((312_992_000 as Weight).saturating_mul(r as Weight)) + (137_249_000 as Weight) + // Standard Error: 168_000 + .saturating_add((320_295_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (693_415_000 as Weight) - .saturating_add((152_745_000 as Weight).saturating_mul(n as Weight)) + (736_756_000 as Weight) + // Standard Error: 39_000 + .saturating_add((159_952_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (135_654_000 as Weight) - .saturating_add((311_271_000 as Weight).saturating_mul(r as Weight)) + (124_530_000 as Weight) + // Standard Error: 203_000 + .saturating_add((321_292_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (839_521_000 as Weight) - .saturating_add((153_146_000 as Weight).saturating_mul(n as Weight)) + (782_032_000 as Weight) + // Standard Error: 36_000 + .saturating_add((159_878_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (26_679_000 as Weight) - .saturating_add((3_155_000 as Weight).saturating_mul(r as Weight)) + (24_624_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_280_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (28_920_000 as Weight) - .saturating_add((159_343_000 as Weight).saturating_mul(r as Weight)) + (27_171_000 as Weight) + // Standard Error: 62_000 + .saturating_add((161_737_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (28_928_000 as Weight) - .saturating_add((227_286_000 as Weight).saturating_mul(r as Weight)) + (27_106_000 as Weight) + // Standard Error: 94_000 + .saturating_add((229_960_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (26_591_000 as Weight) - .saturating_add((12_591_000 as Weight).saturating_mul(r as Weight)) + (24_566_000 as Weight) + // Standard Error: 18_000 + .saturating_add((12_157_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (26_597_000 as Weight) - .saturating_add((12_258_000 as Weight).saturating_mul(r as Weight)) + (24_531_000 as Weight) + // Standard Error: 17_000 + .saturating_add((12_007_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (26_586_000 as Weight) - .saturating_add((5_811_000 as Weight).saturating_mul(r as Weight)) + (24_567_000 as Weight) + // Standard Error: 20_000 + .saturating_add((6_132_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (26_581_000 as Weight) - .saturating_add((14_058_000 as Weight).saturating_mul(r as Weight)) + (24_628_000 as Weight) + // Standard Error: 21_000 + .saturating_add((13_480_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (26_615_000 as Weight) - .saturating_add((15_687_000 as Weight).saturating_mul(r as Weight)) + (24_653_000 as Weight) + // Standard Error: 21_000 + .saturating_add((15_005_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (40_963_000 as Weight) - .saturating_add((92_000 as Weight).saturating_mul(e as Weight)) + (38_573_000 as Weight) + // Standard Error: 0 + .saturating_add((118_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (26_880_000 as Weight) - .saturating_add((97_523_000 as Weight).saturating_mul(r as Weight)) + (24_952_000 as Weight) + // Standard Error: 61_000 + .saturating_add((99_409_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (34_628_000 as Weight) - .saturating_add((201_913_000 as Weight).saturating_mul(r as Weight)) + (32_478_000 as Weight) + // Standard Error: 242_000 + .saturating_add((193_797_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (255_763_000 as Weight) - .saturating_add((3_612_000 as Weight).saturating_mul(p as Weight)) + (238_200_000 as Weight) + // Standard Error: 4_000 + .saturating_add((3_467_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (45_954_000 as Weight) - .saturating_add((3_439_000 as Weight).saturating_mul(r as Weight)) + (41_994_000 as Weight) + // Standard Error: 22_000 + .saturating_add((3_230_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (45_952_000 as Weight) - .saturating_add((3_601_000 as Weight).saturating_mul(r as Weight)) + (41_994_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_558_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (45_883_000 as Weight) - .saturating_add((5_203_000 as Weight).saturating_mul(r as Weight)) + (41_965_000 as Weight) + // Standard Error: 33_000 + .saturating_add((4_806_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (29_895_000 as Weight) - .saturating_add((8_221_000 as Weight).saturating_mul(r as Weight)) + (27_997_000 as Weight) + // Standard Error: 26_000 + .saturating_add((7_859_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (29_916_000 as Weight) - .saturating_add((12_036_000 as Weight).saturating_mul(r as Weight)) + (28_118_000 as Weight) + // Standard Error: 33_000 + .saturating_add((11_825_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (28_878_000 as Weight) - .saturating_add((3_794_000 as Weight).saturating_mul(r as Weight)) + (27_172_000 as Weight) + // Standard Error: 19_000 + .saturating_add((3_466_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (27_351_000 as Weight) - .saturating_add((2_302_301_000 as Weight).saturating_mul(r as Weight)) + (25_582_000 as Weight) + // Standard Error: 4_756_000 + .saturating_add((2_290_170_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (26_535_000 as Weight) - .saturating_add((5_450_000 as Weight).saturating_mul(r as Weight)) + (24_712_000 as Weight) + // Standard Error: 24_000 + .saturating_add((5_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (26_489_000 as Weight) - .saturating_add((5_410_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 23_000 + .saturating_add((5_282_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (26_576_000 as Weight) - .saturating_add((5_976_000 as Weight).saturating_mul(r as Weight)) + (24_640_000 as Weight) + // Standard Error: 17_000 + .saturating_add((5_964_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (26_521_000 as Weight) - .saturating_add((5_465_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 11_000 + .saturating_add((5_128_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (26_534_000 as Weight) - .saturating_add((5_375_000 as Weight).saturating_mul(r as Weight)) + (24_540_000 as Weight) + // Standard Error: 11_000 + .saturating_add((5_224_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (26_560_000 as Weight) - .saturating_add((5_284_000 as Weight).saturating_mul(r as Weight)) + (24_623_000 as Weight) + // Standard Error: 16_000 + .saturating_add((5_138_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (26_554_000 as Weight) - .saturating_add((5_358_000 as Weight).saturating_mul(r as Weight)) + (24_623_000 as Weight) + // Standard Error: 15_000 + .saturating_add((5_242_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (26_549_000 as Weight) - .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) + (24_575_000 as Weight) + // Standard Error: 9_000 + .saturating_add((7_328_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (26_582_000 as Weight) - .saturating_add((7_266_000 as Weight).saturating_mul(r as Weight)) + (24_674_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_147_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (26_558_000 as Weight) - .saturating_add((7_293_000 as Weight).saturating_mul(r as Weight)) + (24_645_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_158_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (26_569_000 as Weight) - .saturating_add((7_278_000 as Weight).saturating_mul(r as Weight)) + (24_688_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (26_516_000 as Weight) - .saturating_add((7_334_000 as Weight).saturating_mul(r as Weight)) + (24_579_000 as Weight) + // Standard Error: 13_000 + .saturating_add((7_187_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (26_561_000 as Weight) - .saturating_add((7_283_000 as Weight).saturating_mul(r as Weight)) + (24_578_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_235_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (26_589_000 as Weight) - .saturating_add((7_244_000 as Weight).saturating_mul(r as Weight)) + (24_625_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_089_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (26_593_000 as Weight) - .saturating_add((7_318_000 as Weight).saturating_mul(r as Weight)) + (24_589_000 as Weight) + // Standard Error: 9_000 + .saturating_add((7_078_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (26_626_000 as Weight) - .saturating_add((7_348_000 as Weight).saturating_mul(r as Weight)) + (24_572_000 as Weight) + // Standard Error: 13_000 + .saturating_add((7_286_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (26_595_000 as Weight) - .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) + (24_566_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (26_568_000 as Weight) - .saturating_add((8_657_000 as Weight).saturating_mul(r as Weight)) + (24_581_000 as Weight) + // Standard Error: 18_000 + .saturating_add((7_190_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (27_393_000 as Weight) - .saturating_add((6_743_000 as Weight).saturating_mul(r as Weight)) + (24_565_000 as Weight) + // Standard Error: 10_000 + .saturating_add((7_242_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (26_571_000 as Weight) - .saturating_add((7_329_000 as Weight).saturating_mul(r as Weight)) + (24_542_000 as Weight) + // Standard Error: 11_000 + .saturating_add((7_216_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (26_585_000 as Weight) - .saturating_add((12_977_000 as Weight).saturating_mul(r as Weight)) + (24_608_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_966_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (26_554_000 as Weight) - .saturating_add((11_955_000 as Weight).saturating_mul(r as Weight)) + (24_564_000 as Weight) + // Standard Error: 1_424_000 + .saturating_add((13_665_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (26_570_000 as Weight) - .saturating_add((12_903_000 as Weight).saturating_mul(r as Weight)) + (24_611_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_932_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (26_561_000 as Weight) - .saturating_add((12_112_000 as Weight).saturating_mul(r as Weight)) + (24_590_000 as Weight) + // Standard Error: 10_000 + .saturating_add((12_207_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (26_587_000 as Weight) - .saturating_add((7_411_000 as Weight).saturating_mul(r as Weight)) + (24_622_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_172_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (26_588_000 as Weight) - .saturating_add((7_479_000 as Weight).saturating_mul(r as Weight)) + (24_585_000 as Weight) + // Standard Error: 18_000 + .saturating_add((7_202_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (26_541_000 as Weight) - .saturating_add((7_386_000 as Weight).saturating_mul(r as Weight)) + (24_600_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_182_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (26_562_000 as Weight) - .saturating_add((7_263_000 as Weight).saturating_mul(r as Weight)) + (24_621_000 as Weight) + // Standard Error: 11_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (26_569_000 as Weight) - .saturating_add((7_353_000 as Weight).saturating_mul(r as Weight)) + (24_643_000 as Weight) + // Standard Error: 22_000 + .saturating_add((7_254_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (26_533_000 as Weight) - .saturating_add((7_342_000 as Weight).saturating_mul(r as Weight)) + (24_586_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_246_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (26_545_000 as Weight) - .saturating_add((7_362_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 22_000 + .saturating_add((7_306_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (26_535_000 as Weight) - .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) + (24_643_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_183_000 as Weight).saturating_mul(r as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { + fn on_initialize() -> Weight { + (7_239_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } + fn on_initialize_per_trie_key(k: u32, ) -> Weight { + (40_584_000 as Weight) + // Standard Error: 4_000 + .saturating_add((2_314_000 as Weight).saturating_mul(k as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) + } + fn on_initialize_per_queue_item(q: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 175_000 + .saturating_add((135_919_000 as Weight).saturating_mul(q as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } fn update_schedule() -> Weight { - (35_214_000 as Weight) + (36_262_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn put_code(n: u32, ) -> Weight { - (0 as Weight) - .saturating_add((109_242_000 as Weight).saturating_mul(n as Weight)) + (22_510_000 as Weight) + // Standard Error: 209_000 + .saturating_add((113_251_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn instantiate(n: u32, s: u32, ) -> Weight { - (195_276_000 as Weight) - .saturating_add((35_000 as Weight).saturating_mul(n as Weight)) - .saturating_add((2_244_000 as Weight).saturating_mul(s as Weight)) + (216_181_000 as Weight) + // Standard Error: 1_000 + .saturating_add((6_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 1_000 + .saturating_add((2_240_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn call() -> Weight { - (207_142_000 as Weight) + (209_785_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn claim_surcharge() -> Weight { - (489_633_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(3 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + (302_124_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } fn seal_caller(r: u32, ) -> Weight { - (136_550_000 as Weight) - .saturating_add((373_182_000 as Weight).saturating_mul(r as Weight)) + (138_697_000 as Weight) + // Standard Error: 412_000 + .saturating_add((390_370_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_address(r: u32, ) -> Weight { - (136_329_000 as Weight) - .saturating_add((373_392_000 as Weight).saturating_mul(r as Weight)) + (141_999_000 as Weight) + // Standard Error: 218_000 + .saturating_add((389_261_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_gas_left(r: u32, ) -> Weight { - (111_577_000 as Weight) - .saturating_add((373_536_000 as Weight).saturating_mul(r as Weight)) + (134_956_000 as Weight) + // Standard Error: 205_000 + .saturating_add((384_439_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_balance(r: u32, ) -> Weight { - (157_531_000 as Weight) - .saturating_add((810_382_000 as Weight).saturating_mul(r as Weight)) + (130_585_000 as Weight) + // Standard Error: 784_000 + .saturating_add((860_797_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_value_transferred(r: u32, ) -> Weight { - (143_801_000 as Weight) - .saturating_add((369_769_000 as Weight).saturating_mul(r as Weight)) + (138_382_000 as Weight) + // Standard Error: 163_000 + .saturating_add((384_676_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_minimum_balance(r: u32, ) -> Weight { - (133_546_000 as Weight) - .saturating_add((370_036_000 as Weight).saturating_mul(r as Weight)) + (137_766_000 as Weight) + // Standard Error: 218_000 + .saturating_add((386_002_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_tombstone_deposit(r: u32, ) -> Weight { - (138_568_000 as Weight) - .saturating_add((370_322_000 as Weight).saturating_mul(r as Weight)) + (144_552_000 as Weight) + // Standard Error: 187_000 + .saturating_add((384_754_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_rent_allowance(r: u32, ) -> Weight { - (144_431_000 as Weight) - .saturating_add((851_810_000 as Weight).saturating_mul(r as Weight)) + (150_812_000 as Weight) + // Standard Error: 276_000 + .saturating_add((903_965_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_block_number(r: u32, ) -> Weight { - (133_237_000 as Weight) - .saturating_add((369_156_000 as Weight).saturating_mul(r as Weight)) + (145_168_000 as Weight) + // Standard Error: 191_000 + .saturating_add((382_798_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_now(r: u32, ) -> Weight { - (139_700_000 as Weight) - .saturating_add((368_961_000 as Weight).saturating_mul(r as Weight)) + (145_806_000 as Weight) + // Standard Error: 195_000 + .saturating_add((382_888_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_weight_to_fee(r: u32, ) -> Weight { - (149_395_000 as Weight) - .saturating_add((625_812_000 as Weight).saturating_mul(r as Weight)) + (154_081_000 as Weight) + // Standard Error: 248_000 + .saturating_add((716_294_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_gas(r: u32, ) -> Weight { - (125_777_000 as Weight) - .saturating_add((187_585_000 as Weight).saturating_mul(r as Weight)) + (149_684_000 as Weight) + // Standard Error: 460_000 + .saturating_add((196_251_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_input(r: u32, ) -> Weight { - (132_584_000 as Weight) - .saturating_add((7_661_000 as Weight).saturating_mul(r as Weight)) + (135_447_000 as Weight) + // Standard Error: 75_000 + .saturating_add((8_362_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_input_per_kb(n: u32, ) -> Weight { - (143_408_000 as Weight) - .saturating_add((274_000 as Weight).saturating_mul(n as Weight)) + (146_099_000 as Weight) + // Standard Error: 0 + .saturating_add((270_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_return(r: u32, ) -> Weight { - (126_257_000 as Weight) - .saturating_add((5_455_000 as Weight).saturating_mul(r as Weight)) + (125_358_000 as Weight) + // Standard Error: 52_000 + .saturating_add((5_454_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_return_per_kb(n: u32, ) -> Weight { - (133_286_000 as Weight) - .saturating_add((698_000 as Weight).saturating_mul(n as Weight)) + (135_523_000 as Weight) + // Standard Error: 0 + .saturating_add((785_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_terminate(r: u32, ) -> Weight { - (130_607_000 as Weight) - .saturating_add((358_370_000 as Weight).saturating_mul(r as Weight)) + (135_321_000 as Weight) + // Standard Error: 100_000 + .saturating_add((110_300_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) - .saturating_add(RocksDbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) - .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) + .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to(r: u32, ) -> Weight { - (233_645_000 as Weight) - .saturating_add((135_355_000 as Weight).saturating_mul(r as Weight)) + (242_790_000 as Weight) + // Standard Error: 823_000 + .saturating_add((135_544_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(r as Weight))) } fn seal_restore_to_per_delta(d: u32, ) -> Weight { - (74_573_000 as Weight) - .saturating_add((3_768_682_000 as Weight).saturating_mul(d as Weight)) + (34_052_000 as Weight) + // Standard Error: 2_395_000 + .saturating_add((3_970_866_000 as Weight).saturating_mul(d as Weight)) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(d as Weight))) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(d as Weight))) } fn seal_random(r: u32, ) -> Weight { - (140_286_000 as Weight) - .saturating_add((950_890_000 as Weight).saturating_mul(r as Weight)) + (154_549_000 as Weight) + // Standard Error: 692_000 + .saturating_add((989_540_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_deposit_event(r: u32, ) -> Weight { - (167_735_000 as Weight) - .saturating_add((1_375_429_000 as Weight).saturating_mul(r as Weight)) + (125_367_000 as Weight) + // Standard Error: 977_000 + .saturating_add((1_424_216_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_deposit_event_per_topic_and_kb(t: u32, n: u32, ) -> Weight { - (1_715_857_000 as Weight) - .saturating_add((760_777_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((241_853_000 as Weight).saturating_mul(n as Weight)) + (1_843_333_000 as Weight) + // Standard Error: 3_040_000 + .saturating_add((771_663_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 599_000 + .saturating_add((251_555_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(t as Weight))) } fn seal_set_rent_allowance(r: u32, ) -> Weight { - (156_911_000 as Weight) - .saturating_add((1_006_139_000 as Weight).saturating_mul(r as Weight)) + (136_437_000 as Weight) + // Standard Error: 299_000 + .saturating_add((1_072_778_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } fn seal_set_storage(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((14_938_793_000 as Weight).saturating_mul(r as Weight)) + (182_452_000 as Weight) + // Standard Error: 26_839_000 + .saturating_add((15_911_876_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_set_storage_per_kb(n: u32, ) -> Weight { - (2_300_169_000 as Weight) - .saturating_add((204_543_000 as Weight).saturating_mul(n as Weight)) + (2_385_415_000 as Weight) + // Standard Error: 751_000 + .saturating_add((223_264_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } fn seal_clear_storage(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((5_140_241_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_154_000 + .saturating_add((5_341_117_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage(r: u32, ) -> Weight { - (45_212_000 as Weight) - .saturating_add((1_131_504_000 as Weight).saturating_mul(r as Weight)) + (62_353_000 as Weight) + // Standard Error: 1_183_000 + .saturating_add((1_141_653_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_get_storage_per_kb(n: u32, ) -> Weight { - (885_531_000 as Weight) - .saturating_add((148_986_000 as Weight).saturating_mul(n as Weight)) + (905_905_000 as Weight) + // Standard Error: 363_000 + .saturating_add((155_161_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) } fn seal_transfer(r: u32, ) -> Weight { - (92_276_000 as Weight) - .saturating_add((6_216_852_000 as Weight).saturating_mul(r as Weight)) + (60_519_000 as Weight) + // Standard Error: 1_942_000 + .saturating_add((6_453_551_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) .saturating_add(RocksDbWeight::get().writes((100 as Weight).saturating_mul(r as Weight))) } fn seal_call(r: u32, ) -> Weight { - (0 as Weight) - .saturating_add((10_734_719_000 as Weight).saturating_mul(r as Weight)) + (192_122_000 as Weight) + // Standard Error: 7_851_000 + .saturating_add((10_736_771_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().reads((100 as Weight).saturating_mul(r as Weight))) } fn seal_call_per_transfer_input_output_kb(t: u32, i: u32, o: u32, ) -> Weight { - (12_735_614_000 as Weight) - .saturating_add((2_870_730_000 as Weight).saturating_mul(t as Weight)) - .saturating_add((52_569_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((73_956_000 as Weight).saturating_mul(o as Weight)) + (10_599_501_000 as Weight) + // Standard Error: 133_182_000 + .saturating_add((5_423_848_000 as Weight).saturating_mul(t as Weight)) + // Standard Error: 47_000 + .saturating_add((60_108_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 50_000 + .saturating_add((82_691_000 as Weight).saturating_mul(o as Weight)) .saturating_add(RocksDbWeight::get().reads(105 as Weight)) .saturating_add(RocksDbWeight::get().reads((101 as Weight).saturating_mul(t as Weight))) .saturating_add(RocksDbWeight::get().writes((101 as Weight).saturating_mul(t as Weight))) } fn seal_instantiate(r: u32, ) -> Weight { (0 as Weight) - .saturating_add((22_365_908_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 39_807_000 + .saturating_add((22_562_812_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().reads((300 as Weight).saturating_mul(r as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) .saturating_add(RocksDbWeight::get().writes((200 as Weight).saturating_mul(r as Weight))) } fn seal_instantiate_per_input_output_salt_kb(i: u32, o: u32, s: u32, ) -> Weight { - (18_899_296_000 as Weight) - .saturating_add((53_289_000 as Weight).saturating_mul(i as Weight)) - .saturating_add((76_026_000 as Weight).saturating_mul(o as Weight)) - .saturating_add((281_097_000 as Weight).saturating_mul(s as Weight)) + (19_823_256_000 as Weight) + // Standard Error: 153_000 + .saturating_add((60_707_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 153_000 + .saturating_add((83_770_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 153_000 + .saturating_add((284_423_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(207 as Weight)) .saturating_add(RocksDbWeight::get().writes(202 as Weight)) } fn seal_hash_sha2_256(r: u32, ) -> Weight { - (136_601_000 as Weight) - .saturating_add((323_373_000 as Weight).saturating_mul(r as Weight)) + (142_838_000 as Weight) + // Standard Error: 243_000 + .saturating_add((332_354_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_sha2_256_per_kb(n: u32, ) -> Weight { - (777_563_000 as Weight) - .saturating_add((423_353_000 as Weight).saturating_mul(n as Weight)) + (877_119_000 as Weight) + // Standard Error: 73_000 + .saturating_add((434_752_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_keccak_256(r: u32, ) -> Weight { - (136_771_000 as Weight) - .saturating_add((337_881_000 as Weight).saturating_mul(r as Weight)) + (139_913_000 as Weight) + // Standard Error: 160_000 + .saturating_add((345_830_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_keccak_256_per_kb(n: u32, ) -> Weight { - (337_906_000 as Weight) - .saturating_add((336_778_000 as Weight).saturating_mul(n as Weight)) + (723_122_000 as Weight) + // Standard Error: 29_000 + .saturating_add((343_949_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_256(r: u32, ) -> Weight { - (131_040_000 as Weight) - .saturating_add((312_992_000 as Weight).saturating_mul(r as Weight)) + (137_249_000 as Weight) + // Standard Error: 168_000 + .saturating_add((320_295_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_256_per_kb(n: u32, ) -> Weight { - (693_415_000 as Weight) - .saturating_add((152_745_000 as Weight).saturating_mul(n as Weight)) + (736_756_000 as Weight) + // Standard Error: 39_000 + .saturating_add((159_952_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_128(r: u32, ) -> Weight { - (135_654_000 as Weight) - .saturating_add((311_271_000 as Weight).saturating_mul(r as Weight)) + (124_530_000 as Weight) + // Standard Error: 203_000 + .saturating_add((321_292_000 as Weight).saturating_mul(r as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn seal_hash_blake2_128_per_kb(n: u32, ) -> Weight { - (839_521_000 as Weight) - .saturating_add((153_146_000 as Weight).saturating_mul(n as Weight)) + (782_032_000 as Weight) + // Standard Error: 36_000 + .saturating_add((159_878_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) } fn instr_i64const(r: u32, ) -> Weight { - (26_679_000 as Weight) - .saturating_add((3_155_000 as Weight).saturating_mul(r as Weight)) + (24_624_000 as Weight) + // Standard Error: 18_000 + .saturating_add((3_280_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64load(r: u32, ) -> Weight { - (28_920_000 as Weight) - .saturating_add((159_343_000 as Weight).saturating_mul(r as Weight)) + (27_171_000 as Weight) + // Standard Error: 62_000 + .saturating_add((161_737_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64store(r: u32, ) -> Weight { - (28_928_000 as Weight) - .saturating_add((227_286_000 as Weight).saturating_mul(r as Weight)) + (27_106_000 as Weight) + // Standard Error: 94_000 + .saturating_add((229_960_000 as Weight).saturating_mul(r as Weight)) } fn instr_select(r: u32, ) -> Weight { - (26_591_000 as Weight) - .saturating_add((12_591_000 as Weight).saturating_mul(r as Weight)) + (24_566_000 as Weight) + // Standard Error: 18_000 + .saturating_add((12_157_000 as Weight).saturating_mul(r as Weight)) } fn instr_if(r: u32, ) -> Weight { - (26_597_000 as Weight) - .saturating_add((12_258_000 as Weight).saturating_mul(r as Weight)) + (24_531_000 as Weight) + // Standard Error: 17_000 + .saturating_add((12_007_000 as Weight).saturating_mul(r as Weight)) } fn instr_br(r: u32, ) -> Weight { - (26_586_000 as Weight) - .saturating_add((5_811_000 as Weight).saturating_mul(r as Weight)) + (24_567_000 as Weight) + // Standard Error: 20_000 + .saturating_add((6_132_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_if(r: u32, ) -> Weight { - (26_581_000 as Weight) - .saturating_add((14_058_000 as Weight).saturating_mul(r as Weight)) + (24_628_000 as Weight) + // Standard Error: 21_000 + .saturating_add((13_480_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table(r: u32, ) -> Weight { - (26_615_000 as Weight) - .saturating_add((15_687_000 as Weight).saturating_mul(r as Weight)) + (24_653_000 as Weight) + // Standard Error: 21_000 + .saturating_add((15_005_000 as Weight).saturating_mul(r as Weight)) } fn instr_br_table_per_entry(e: u32, ) -> Weight { - (40_963_000 as Weight) - .saturating_add((92_000 as Weight).saturating_mul(e as Weight)) + (38_573_000 as Weight) + // Standard Error: 0 + .saturating_add((118_000 as Weight).saturating_mul(e as Weight)) } fn instr_call(r: u32, ) -> Weight { - (26_880_000 as Weight) - .saturating_add((97_523_000 as Weight).saturating_mul(r as Weight)) + (24_952_000 as Weight) + // Standard Error: 61_000 + .saturating_add((99_409_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect(r: u32, ) -> Weight { - (34_628_000 as Weight) - .saturating_add((201_913_000 as Weight).saturating_mul(r as Weight)) + (32_478_000 as Weight) + // Standard Error: 242_000 + .saturating_add((193_797_000 as Weight).saturating_mul(r as Weight)) } fn instr_call_indirect_per_param(p: u32, ) -> Weight { - (255_763_000 as Weight) - .saturating_add((3_612_000 as Weight).saturating_mul(p as Weight)) + (238_200_000 as Weight) + // Standard Error: 4_000 + .saturating_add((3_467_000 as Weight).saturating_mul(p as Weight)) } fn instr_local_get(r: u32, ) -> Weight { - (45_954_000 as Weight) - .saturating_add((3_439_000 as Weight).saturating_mul(r as Weight)) + (41_994_000 as Weight) + // Standard Error: 22_000 + .saturating_add((3_230_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_set(r: u32, ) -> Weight { - (45_952_000 as Weight) - .saturating_add((3_601_000 as Weight).saturating_mul(r as Weight)) + (41_994_000 as Weight) + // Standard Error: 20_000 + .saturating_add((3_558_000 as Weight).saturating_mul(r as Weight)) } fn instr_local_tee(r: u32, ) -> Weight { - (45_883_000 as Weight) - .saturating_add((5_203_000 as Weight).saturating_mul(r as Weight)) + (41_965_000 as Weight) + // Standard Error: 33_000 + .saturating_add((4_806_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_get(r: u32, ) -> Weight { - (29_895_000 as Weight) - .saturating_add((8_221_000 as Weight).saturating_mul(r as Weight)) + (27_997_000 as Weight) + // Standard Error: 26_000 + .saturating_add((7_859_000 as Weight).saturating_mul(r as Weight)) } fn instr_global_set(r: u32, ) -> Weight { - (29_916_000 as Weight) - .saturating_add((12_036_000 as Weight).saturating_mul(r as Weight)) + (28_118_000 as Weight) + // Standard Error: 33_000 + .saturating_add((11_825_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_current(r: u32, ) -> Weight { - (28_878_000 as Weight) - .saturating_add((3_794_000 as Weight).saturating_mul(r as Weight)) + (27_172_000 as Weight) + // Standard Error: 19_000 + .saturating_add((3_466_000 as Weight).saturating_mul(r as Weight)) } fn instr_memory_grow(r: u32, ) -> Weight { - (27_351_000 as Weight) - .saturating_add((2_302_301_000 as Weight).saturating_mul(r as Weight)) + (25_582_000 as Weight) + // Standard Error: 4_756_000 + .saturating_add((2_290_170_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64clz(r: u32, ) -> Weight { - (26_535_000 as Weight) - .saturating_add((5_450_000 as Weight).saturating_mul(r as Weight)) + (24_712_000 as Weight) + // Standard Error: 24_000 + .saturating_add((5_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ctz(r: u32, ) -> Weight { - (26_489_000 as Weight) - .saturating_add((5_410_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 23_000 + .saturating_add((5_282_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64popcnt(r: u32, ) -> Weight { - (26_576_000 as Weight) - .saturating_add((5_976_000 as Weight).saturating_mul(r as Weight)) + (24_640_000 as Weight) + // Standard Error: 17_000 + .saturating_add((5_964_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eqz(r: u32, ) -> Weight { - (26_521_000 as Weight) - .saturating_add((5_465_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 11_000 + .saturating_add((5_128_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendsi32(r: u32, ) -> Weight { - (26_534_000 as Weight) - .saturating_add((5_375_000 as Weight).saturating_mul(r as Weight)) + (24_540_000 as Weight) + // Standard Error: 11_000 + .saturating_add((5_224_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64extendui32(r: u32, ) -> Weight { - (26_560_000 as Weight) - .saturating_add((5_284_000 as Weight).saturating_mul(r as Weight)) + (24_623_000 as Weight) + // Standard Error: 16_000 + .saturating_add((5_138_000 as Weight).saturating_mul(r as Weight)) } fn instr_i32wrapi64(r: u32, ) -> Weight { - (26_554_000 as Weight) - .saturating_add((5_358_000 as Weight).saturating_mul(r as Weight)) + (24_623_000 as Weight) + // Standard Error: 15_000 + .saturating_add((5_242_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64eq(r: u32, ) -> Weight { - (26_549_000 as Weight) - .saturating_add((7_402_000 as Weight).saturating_mul(r as Weight)) + (24_575_000 as Weight) + // Standard Error: 9_000 + .saturating_add((7_328_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ne(r: u32, ) -> Weight { - (26_582_000 as Weight) - .saturating_add((7_266_000 as Weight).saturating_mul(r as Weight)) + (24_674_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_147_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64lts(r: u32, ) -> Weight { - (26_558_000 as Weight) - .saturating_add((7_293_000 as Weight).saturating_mul(r as Weight)) + (24_645_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_158_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ltu(r: u32, ) -> Weight { - (26_569_000 as Weight) - .saturating_add((7_278_000 as Weight).saturating_mul(r as Weight)) + (24_688_000 as Weight) + // Standard Error: 16_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gts(r: u32, ) -> Weight { - (26_516_000 as Weight) - .saturating_add((7_334_000 as Weight).saturating_mul(r as Weight)) + (24_579_000 as Weight) + // Standard Error: 13_000 + .saturating_add((7_187_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64gtu(r: u32, ) -> Weight { - (26_561_000 as Weight) - .saturating_add((7_283_000 as Weight).saturating_mul(r as Weight)) + (24_578_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_235_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64les(r: u32, ) -> Weight { - (26_589_000 as Weight) - .saturating_add((7_244_000 as Weight).saturating_mul(r as Weight)) + (24_625_000 as Weight) + // Standard Error: 17_000 + .saturating_add((7_089_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64leu(r: u32, ) -> Weight { - (26_593_000 as Weight) - .saturating_add((7_318_000 as Weight).saturating_mul(r as Weight)) + (24_589_000 as Weight) + // Standard Error: 9_000 + .saturating_add((7_078_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64ges(r: u32, ) -> Weight { - (26_626_000 as Weight) - .saturating_add((7_348_000 as Weight).saturating_mul(r as Weight)) + (24_572_000 as Weight) + // Standard Error: 13_000 + .saturating_add((7_286_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64geu(r: u32, ) -> Weight { - (26_595_000 as Weight) - .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) + (24_566_000 as Weight) + // Standard Error: 19_000 + .saturating_add((7_247_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64add(r: u32, ) -> Weight { - (26_568_000 as Weight) - .saturating_add((8_657_000 as Weight).saturating_mul(r as Weight)) + (24_581_000 as Weight) + // Standard Error: 18_000 + .saturating_add((7_190_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64sub(r: u32, ) -> Weight { - (27_393_000 as Weight) - .saturating_add((6_743_000 as Weight).saturating_mul(r as Weight)) + (24_565_000 as Weight) + // Standard Error: 10_000 + .saturating_add((7_242_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64mul(r: u32, ) -> Weight { - (26_571_000 as Weight) - .saturating_add((7_329_000 as Weight).saturating_mul(r as Weight)) + (24_542_000 as Weight) + // Standard Error: 11_000 + .saturating_add((7_216_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divs(r: u32, ) -> Weight { - (26_585_000 as Weight) - .saturating_add((12_977_000 as Weight).saturating_mul(r as Weight)) + (24_608_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_966_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64divu(r: u32, ) -> Weight { - (26_554_000 as Weight) - .saturating_add((11_955_000 as Weight).saturating_mul(r as Weight)) + (24_564_000 as Weight) + // Standard Error: 1_424_000 + .saturating_add((13_665_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rems(r: u32, ) -> Weight { - (26_570_000 as Weight) - .saturating_add((12_903_000 as Weight).saturating_mul(r as Weight)) + (24_611_000 as Weight) + // Standard Error: 16_000 + .saturating_add((12_932_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64remu(r: u32, ) -> Weight { - (26_561_000 as Weight) - .saturating_add((12_112_000 as Weight).saturating_mul(r as Weight)) + (24_590_000 as Weight) + // Standard Error: 10_000 + .saturating_add((12_207_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64and(r: u32, ) -> Weight { - (26_587_000 as Weight) - .saturating_add((7_411_000 as Weight).saturating_mul(r as Weight)) + (24_622_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_172_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64or(r: u32, ) -> Weight { - (26_588_000 as Weight) - .saturating_add((7_479_000 as Weight).saturating_mul(r as Weight)) + (24_585_000 as Weight) + // Standard Error: 18_000 + .saturating_add((7_202_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64xor(r: u32, ) -> Weight { - (26_541_000 as Weight) - .saturating_add((7_386_000 as Weight).saturating_mul(r as Weight)) + (24_600_000 as Weight) + // Standard Error: 20_000 + .saturating_add((7_182_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shl(r: u32, ) -> Weight { - (26_562_000 as Weight) - .saturating_add((7_263_000 as Weight).saturating_mul(r as Weight)) + (24_621_000 as Weight) + // Standard Error: 11_000 + .saturating_add((7_226_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shrs(r: u32, ) -> Weight { - (26_569_000 as Weight) - .saturating_add((7_353_000 as Weight).saturating_mul(r as Weight)) + (24_643_000 as Weight) + // Standard Error: 22_000 + .saturating_add((7_254_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64shru(r: u32, ) -> Weight { - (26_533_000 as Weight) - .saturating_add((7_342_000 as Weight).saturating_mul(r as Weight)) + (24_586_000 as Weight) + // Standard Error: 14_000 + .saturating_add((7_246_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotl(r: u32, ) -> Weight { - (26_545_000 as Weight) - .saturating_add((7_362_000 as Weight).saturating_mul(r as Weight)) + (24_631_000 as Weight) + // Standard Error: 22_000 + .saturating_add((7_306_000 as Weight).saturating_mul(r as Weight)) } fn instr_i64rotr(r: u32, ) -> Weight { - (26_535_000 as Weight) - .saturating_add((7_330_000 as Weight).saturating_mul(r as Weight)) + (24_643_000 as Weight) + // Standard Error: 15_000 + .saturating_add((7_183_000 as Weight).saturating_mul(r as Weight)) } } -- GitLab