diff --git a/Cargo.lock b/Cargo.lock index 2a091ce6817d..61e0d68fc11b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10262,6 +10262,7 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", + "sp-core", "sp-io", "sp-runtime", "sp-std 8.0.0", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_multisig.rs index d2e0f0ec7f0b..83f576721ab8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-kusama/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_multisig.rs index 0bb05511d7a8..215ede678422 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-polkadot/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_multisig.rs index cf9c523f6571..27f53923d4a7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_multisig.rs @@ -162,4 +162,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_multisig.rs index 27687e10751b..d1e177f4c65d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_multisig.rs index f4135e975fbe..1f6b9a922941 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_multisig.rs index 44f3da351f65..2a59ac4b1009 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_multisig.rs index 832380d3876b..9cdc9f06fcf6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_multisig.rs index 91840ae0c6d7..797f89346a24 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_multisig.rs @@ -162,4 +162,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_multisig.rs index a7827b720090..cf79b567b6e4 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-polkadot/src/weights/pallet_multisig.rs @@ -161,4 +161,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs index a4f33fe198ca..015c3765025e 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs @@ -159,4 +159,8 @@ impl pallet_multisig::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + + fn clear_expired_multi(_s: u32) -> Weight { + unimplemented!() + } } diff --git a/polkadot/runtime/westend/src/weights/pallet_multisig.rs b/polkadot/runtime/westend/src/weights/pallet_multisig.rs index 616aea9c8e73..997cb23dcb91 100644 --- a/polkadot/runtime/westend/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/westend/src/weights/pallet_multisig.rs @@ -17,27 +17,25 @@ //! Autogenerated weights for `pallet_multisig` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-10-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner--ss9ysm1-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-cxxwyzfj-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=westend-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_multisig // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/westend/src/weights/ +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_multisig +// --chain=westend-dev +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/westend/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -55,111 +53,140 @@ impl pallet_multisig::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_218_000 picoseconds. - Weight::from_parts(14_749_472, 0) + // Minimum execution time: 13_728_000 picoseconds. + Weight::from_parts(14_142_793, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 10 - .saturating_add(Weight::from_parts(507, 0).saturating_mul(z.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(566, 0).saturating_mul(z.into())) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `309 + s * (2 ±0)` + // Measured: `267 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 45_891_000 picoseconds. - Weight::from_parts(33_546_627, 0) + // Minimum execution time: 41_477_000 picoseconds. + Weight::from_parts(29_848_990, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 2_347 - .saturating_add(Weight::from_parts(136_466, 0).saturating_mul(s.into())) - // Standard Error: 23 - .saturating_add(Weight::from_parts(1_595, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 856 + .saturating_add(Weight::from_parts(130_375, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_586, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `286` // Estimated: `6811` - // Minimum execution time: 30_355_000 picoseconds. - Weight::from_parts(19_611_682, 0) + // Minimum execution time: 29_244_000 picoseconds. + Weight::from_parts(19_533_886, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_383 - .saturating_add(Weight::from_parts(123_652, 0).saturating_mul(s.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_488, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 658 + .saturating_add(Weight::from_parts(112_698, 0).saturating_mul(s.into())) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_496, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `392 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 50_453_000 picoseconds. - Weight::from_parts(35_628_285, 0) + // Minimum execution time: 48_402_000 picoseconds. + Weight::from_parts(34_962_279, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 3_693 - .saturating_add(Weight::from_parts(203_453, 0).saturating_mul(s.into())) - // Standard Error: 36 - .saturating_add(Weight::from_parts(1_726, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(2)) + // Standard Error: 1_477 + .saturating_add(Weight::from_parts(157_073, 0).saturating_mul(s.into())) + // Standard Error: 14 + .saturating_add(Weight::from_parts(1_590, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `314 + s * (2 ±0)` + // Measured: `267 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 32_500_000 picoseconds. - Weight::from_parts(33_231_806, 0) + // Minimum execution time: 30_631_000 picoseconds. + Weight::from_parts(31_761_004, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_511 - .saturating_add(Weight::from_parts(134_500, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + // Standard Error: 1_141 + .saturating_add(Weight::from_parts(128_754, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `286` // Estimated: `6811` - // Minimum execution time: 17_906_000 picoseconds. - Weight::from_parts(18_757_928, 0) + // Minimum execution time: 18_303_000 picoseconds. + Weight::from_parts(19_026_721, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_172 - .saturating_add(Weight::from_parts(113_535, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 965 + .saturating_add(Weight::from_parts(105_394, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `458 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 33_018_000 picoseconds. - Weight::from_parts(34_186_533, 0) + // Minimum execution time: 30_910_000 picoseconds. + Weight::from_parts(31_844_665, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_188 - .saturating_add(Weight::from_parts(128_449, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 968 + .saturating_add(Weight::from_parts(115_982, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// The range of component `s` is `[2, 100]`. + fn clear_expired_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `572 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 34_337_000 picoseconds. + Weight::from_parts(35_393_774, 0) + .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 1_006 + .saturating_add(Weight::from_parts(106_678, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } } diff --git a/substrate/frame/multisig/Cargo.toml b/substrate/frame/multisig/Cargo.toml index a2ee608c33cd..b246540e032c 100644 --- a/substrate/frame/multisig/Cargo.toml +++ b/substrate/frame/multisig/Cargo.toml @@ -18,6 +18,7 @@ scale-info = { version = "2.10.0", default-features = false, features = ["derive frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true} frame-support = { path = "../support", default-features = false} frame-system = { path = "../system", default-features = false} +sp-core = { path = "../../primitives/core", default-features = false} sp-io = { path = "../../primitives/io", default-features = false} sp-runtime = { path = "../../primitives/runtime", default-features = false} sp-std = { path = "../../primitives/std", default-features = false} @@ -27,6 +28,7 @@ log = { version = "0.4.17", default-features = false } [dev-dependencies] pallet-balances = { path = "../balances" } +sp-core = { path = "../../primitives/core", default-features = false} [features] default = [ "std" ] @@ -38,6 +40,7 @@ std = [ "log/std", "pallet-balances/std", "scale-info/std", + "sp-core/std", "sp-io/std", "sp-runtime/std", "sp-std/std", diff --git a/substrate/frame/multisig/src/benchmarking.rs b/substrate/frame/multisig/src/benchmarking.rs index ebe19df5dc43..521e90eafe5a 100644 --- a/substrate/frame/multisig/src/benchmarking.rs +++ b/substrate/frame/multisig/src/benchmarking.rs @@ -21,7 +21,7 @@ use super::*; use frame_benchmarking::v1::{account, benchmarks}; -use frame_system::RawOrigin; +use frame_system::{Pallet as System, RawOrigin}; use sp_runtime::traits::Bounded; use crate::Pallet as Multisig; @@ -147,14 +147,14 @@ benchmarks! { let (mut signatories, call) = setup_multi::(s, z)?; let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - let call_hash = call.using_encoded(blake2_256); + let call_hash = H256::from(call.using_encoded(blake2_256)); // 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()); // Create the multi - }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash, Weight::zero()) + }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash, Weight::zero(), Some(42u32.into())) verify { - assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + assert!(Multisigs::::contains_key(multi_account_id, call_hash.0)); } approve_as_multi_approve { @@ -166,7 +166,7 @@ benchmarks! { let mut signatories2 = signatories.clone(); let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - let call_hash = call.using_encoded(blake2_256); + let call_hash = H256::from(call.using_encoded(blake2_256)); // before the call, get the timepoint let timepoint = Multisig::::timepoint(); // Create the multi @@ -182,9 +182,9 @@ benchmarks! { // Whitelist caller account from further DB operations. let caller_key = frame_system::Account::::hashed_key_for(&caller2); frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); - }: approve_as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call_hash, Weight::zero()) + }: approve_as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call_hash, Weight::zero(), None) verify { - let multisig = Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; + let multisig = Multisigs::::get(multi_account_id, call_hash.0).ok_or("multisig not created")?; assert_eq!(multisig.approvals.len(), 2); } @@ -210,5 +210,32 @@ benchmarks! { assert!(!Multisigs::::contains_key(multi_account_id, call_hash)); } - impl_benchmark_test_suite!(Multisig, crate::tests::new_test_ext(), crate::tests::Test); + clear_expired_multi { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get(); + // Transaction Length, not a component + let z = 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = H256::from(call.using_encoded(blake2_256)); + let timepoint = Multisig::::timepoint(); + // Create the multi + let o = RawOrigin::Signed(caller.clone()).into(); + Multisig::::approve_as_multi(o, s as u16, signatories.clone(), None, call_hash, Weight::zero(), Some(3u32.into()))?; + assert!(Multisigs::::contains_key(&multi_account_id, call_hash.0)); + // Multisig expires after block 3 so we proceed to block 4. + System::::set_block_number(4u32.into()); + // 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()); + // For calling clear_expired_multi all the signatories must be specified. + signatories.push(caller.clone()); + }: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) + verify { + assert!(!Multisigs::::contains_key(multi_account_id.clone(), call_hash.0)); + assert!(!MultisigExpiries::::contains_key(multi_account_id, call_hash)); + } + + impl_benchmark_test_suite!(Multisig, crate::tests::ExtBuilder::default().build(), crate::tests::Test); } diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs index e4426c64b412..18e62ea8ac1b 100644 --- a/substrate/frame/multisig/src/lib.rs +++ b/substrate/frame/multisig/src/lib.rs @@ -37,8 +37,11 @@ //! //! * `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a //! number of signed origins. -//! * `approve_as_multi` - Approve a call from a composite origin. +//! * `approve_as_multi_deprecated` - Approve a call from a composite origin. Should use the +//! `approve_as_multi` extrinsic instead. //! * `cancel_as_multi` - Cancel a call from a composite origin. +//! * `approve_as_multi` - Approve a call from a composite origin. +//! * `clear_expired_multi` - Removes an expired multisig operation from storage. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -61,6 +64,7 @@ use frame_support::{ }; use frame_system::{self as system, pallet_prelude::BlockNumberFor, RawOrigin}; use scale_info::TypeInfo; +use sp_core::H256; use sp_io::hashing::blake2_256; use sp_runtime::{ traits::{Dispatchable, TrailingZeroInput, Zero}, @@ -186,6 +190,11 @@ pub mod pallet { Multisig, BalanceOf, T::AccountId, T::MaxSignatories>, >; + /// Tracks optional expiry block numbers for [`Multisig`] entries + #[pallet::storage] + pub type MultisigExpiries = + StorageDoubleMap<_, Twox64Concat, T::AccountId, Blake2_128Concat, H256, BlockNumberFor>; + #[pallet::error] pub enum Error { /// Threshold must be 2 or greater. @@ -216,13 +225,24 @@ pub mod pallet { MaxWeightTooLow, /// The data to be stored is already stored. AlreadyStored, + /// A [`MultisigExpiries`] entry cannot be created for a non-existent [`Multisig`]. + UnexpectedExpiry, + /// The multisig operation has expired. + MultisigExpired, + /// The multisig has not expired. + MultisigNotExpired, } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// A new multisig operation has begun. - NewMultisig { approving: T::AccountId, multisig: T::AccountId, call_hash: CallHash }, + NewMultisig { + approving: T::AccountId, + multisig: T::AccountId, + call_hash: CallHash, + expiry: Option>, + }, /// A multisig operation has been approved by someone. MultisigApproval { approving: T::AccountId, @@ -248,7 +268,12 @@ pub mod pallet { } #[pallet::hooks] - impl Hooks> for Pallet {} + impl Hooks> for Pallet { + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { + Self::do_try_state() + } + } #[pallet::call] impl Pallet { @@ -378,9 +403,16 @@ pub mod pallet { maybe_timepoint, CallOrHash::Call(*call), max_weight, + None, ) } + /// DEPRECATED: Use the `approve_as_multi` extrinsic instead. + /// It will be removed after March 2024. + /// + /// This extrinsic sets the expiry to `None`, while the `approve_as_multi` will allow you + /// to set it to a certain block number. + /// /// Register approval for a dispatch to be made from a deterministic composite account if /// approved by a total of `threshold - 1` of `other_signatories`. /// @@ -419,7 +451,7 @@ pub mod pallet { .max(T::WeightInfo::approve_as_multi_approve(s)) .saturating_add(*max_weight) })] - pub fn approve_as_multi( + pub fn approve_as_multi_deprecated( origin: OriginFor, threshold: u16, other_signatories: Vec, @@ -435,6 +467,7 @@ pub mod pallet { maybe_timepoint, CallOrHash::Hash(call_hash), max_weight, + None, ) } @@ -481,9 +514,15 @@ pub mod pallet { ensure!(m.when == timepoint, Error::::WrongTimepoint); ensure!(m.depositor == who, Error::::NotOwner); - let err_amount = T::Currency::unreserve(&m.depositor, m.deposit); - debug_assert!(err_amount.is_zero()); - >::remove(&id, &call_hash); + let maybe_expiry = >::get(&id, H256::from(call_hash)); + + Self::remove_multisig( + &id, + H256::from(call_hash), + &m.depositor, + m.deposit, + maybe_expiry, + ); Self::deposit_event(Event::MultisigCancelled { cancelling: who, @@ -493,6 +532,122 @@ pub mod pallet { }); Ok(()) } + + /// Register approval for a dispatch to be made from a deterministic composite account if + /// approved by a total of `threshold - 1` of `other_signatories`. + /// + /// Payment: [`DepositBase`] will be reserved if this is the first approval, plus + /// `threshold` times [`DepositFactor`]. It is returned once this dispatch happens or + /// is cancelled. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `threshold`: The total number of approvals for this dispatch before it is executed. + /// - `other_signatories`: The accounts (other than the sender) who can approve this + /// dispatch. May not be empty. + /// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is + /// not the first approval, then it must be `Some`, with the timepoint (block number and + /// transaction index) of the first approval transaction. + /// - `call_hash`: The hash of the call to be executed. + /// - `maybe_expiry`: An optional expiry of the multisig operation defined in block number. + /// + /// ## Complexity + /// - `O(S)`. + /// - Up to one balance-reserve or unreserve operation. + /// - At most two inserts, both `O(S)` where `S` is the number of signatories. `S` is capped + /// by `MaxSignatories`, with weight being proportional. + /// - One encode & hash, both of complexity `O(S)`. + /// - Up to one binary search and insert (`O(logS + S)`). + /// - I/O: 2 reads `O(S)`, up to 2 mutations `O(S)`. Up to two removes. + /// - One event. + /// - Storage: inserts up to two items. One of them is bounded by `MaxSignatories`, with a + /// deposit taken for its lifetime of `DepositBase + threshold * DepositFactor`. The other + /// value is a `BlockNumber`. + #[pallet::call_index(4)] + #[pallet::weight({ + let s = other_signatories.len() as u32; + + T::WeightInfo::approve_as_multi_create(s) + .max(T::WeightInfo::approve_as_multi_approve(s)) + .saturating_add(*max_weight) + })] + pub fn approve_as_multi( + origin: OriginFor, + threshold: u16, + other_signatories: Vec, + maybe_timepoint: Option>>, + call_hash: H256, + max_weight: Weight, + maybe_expiry: Option>, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::operate( + who, + threshold, + other_signatories, + maybe_timepoint, + CallOrHash::Hash(call_hash.into()), + max_weight, + maybe_expiry, + ) + } + + /// Clear up all the state of an expired multisig operation. Any deposit reserved previously + /// for this operation will be unreserved on success. + /// + /// Anyone can call this and free up the not needed state of the expired multisig. + /// The dispatch origin for this call must be _Signed_. + /// + /// - `threshold`: The total number of approvals for this dispatch before it is executed. + /// - `signatories`: The accounts who can approve this dispatch. + /// - `timepoint`: The timepoint (block number and transaction index) of the first approval + /// transaction for this dispatch. + /// - `call_hash`: The hash of the call to be executed. + /// + /// ## Complexity + /// - `O(S)`. + /// - Up to one balance-reserve or unreserve operation. + /// - At most two inserts, both `O(S)` where `S` is the number of signatories. `S` is capped + /// by `MaxSignatories`, with weight being proportional. + /// - One encode & hash, both of complexity `O(S)`. + /// - One event. + /// - I/O: 2 reads `O(S)`, up to two removes. + /// - Storage: removes up to two items. + #[pallet::call_index(5)] + #[pallet::weight(T::WeightInfo::clear_expired_multi(signatories.len() as u32))] + pub fn clear_expired_multi( + origin: OriginFor, + threshold: u16, + signatories: Vec, + timepoint: Timepoint>, + call_hash: H256, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + let id = Self::multi_account_id(&signatories, threshold); + + let m = >::get(&id, call_hash.0).ok_or(Error::::NotFound)?; + let expiry = + >::get(&id, call_hash).ok_or(Error::::MultisigNotExpired)?; + + ensure!(m.when == timepoint, Error::::WrongTimepoint); + ensure!( + expiry < >::block_number(), + Error::::MultisigNotExpired + ); + + // Clean up all the state that is not needed anymore since the multisig expired. + Self::remove_multisig(&id, call_hash, &m.depositor, m.deposit, Some(expiry)); + + Self::deposit_event(Event::MultisigCancelled { + cancelling: who, + timepoint, + multisig: id, + call_hash: call_hash.0, + }); + + Ok(()) + } } } @@ -514,6 +669,7 @@ impl Pallet { maybe_timepoint: Option>>, call_or_hash: CallOrHash, max_weight: Weight, + maybe_expiry: Option>, ) -> DispatchResultWithPostInfo { ensure!(threshold >= 2, Error::::MinimumThreshold); let max_sigs = T::MaxSignatories::get() as usize; @@ -539,6 +695,23 @@ impl Pallet { let timepoint = maybe_timepoint.ok_or(Error::::NoTimepoint)?; ensure!(m.when == timepoint, Error::::WrongTimepoint); + let maybe_expiry = >::get(&id, H256::from(call_hash)); + // Ensure that the mutlisig did not expire. + if let Some(expiry) = maybe_expiry { + if expiry < >::block_number() { + // If the multisig is expired we will take the chance to remove it now so that + // the multisig creator does not have to make a separate call to clean it up. + Self::remove_multisig( + &id, + H256::from(call_hash), + &m.depositor, + m.deposit, + maybe_expiry, + ); + return Err(Error::::MultisigExpired.into()) + } + }; + // Ensure that either we have not yet signed or that it is at threshold. let mut approvals = m.approvals.len() as u16; // We only bother with the approval if we're below threshold. @@ -558,8 +731,13 @@ impl Pallet { // Clean up storage before executing call to avoid an possibility of reentrancy // attack. - >::remove(&id, call_hash); - T::Currency::unreserve(&m.depositor, m.deposit); + Self::remove_multisig( + &id, + H256::from(call_hash), + &m.depositor, + m.deposit, + maybe_expiry, + ); let result = call.dispatch(RawOrigin::Signed(id.clone()).into()); Self::deposit_event(Event::MultisigExecuted { @@ -609,6 +787,13 @@ impl Pallet { // Not yet started; there should be no timepoint given. ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); + // Not yet started; the expiry for this [`Multisig`] cannot already be specified + // in [`MultisigExpiries`]. + ensure!( + >::get(&id, H256::from(call_hash)).is_none(), + Error::::UnexpectedExpiry + ); + // Just start the operation by recording it in storage. let deposit = T::DepositBase::get() + T::DepositFactor::get() * threshold.into(); @@ -627,7 +812,19 @@ impl Pallet { approvals: initial_approvals, }, ); - Self::deposit_event(Event::NewMultisig { approving: who, multisig: id, call_hash }); + + // If an expiry is specified insert it into [`MultisigExpiries`] for + // this specific [`Multisig`]. + if let Some(expiry) = maybe_expiry { + >::insert(&id, H256::from(call_hash), expiry); + } + + Self::deposit_event(Event::NewMultisig { + approving: who, + multisig: id, + call_hash, + expiry: maybe_expiry, + }); let final_weight = T::WeightInfo::as_multi_create(other_signatories_len as u32, call_len as u32); @@ -636,6 +833,26 @@ impl Pallet { } } + /// Removes a multisig operation from the state. + /// + /// If the multisig had an expiry date it will also be removed from the + /// [`MultisigExpiries`] storage map. + fn remove_multisig( + id: &T::AccountId, + call_hash: H256, + depositor: &T::AccountId, + deposit: BalanceOf, + expiry: Option>, + ) { + let err_amount = T::Currency::unreserve(&depositor, deposit); + debug_assert!(err_amount.is_zero()); + >::remove(id, call_hash.0); + + if expiry.is_some() { + >::remove(id, call_hash); + } + } + /// The current `Timepoint`. pub fn timepoint() -> Timepoint> { Timepoint { @@ -665,6 +882,23 @@ impl Pallet { signatories.insert(index, who); Ok(signatories) } + + /// Ensure the correctness of the state of this pallet. + /// + /// This should be valid before or after each state transition of this pallet. + /// + /// ## Invariants: + /// + /// * Each multisig in [`MultisigExpiries`] must have an entry inside the [`Multisigs`] storage + /// map. + #[cfg(any(feature = "try-runtime", test))] + fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> { + >::iter_keys().try_for_each(|(id, call_hash)| { + ensure!(>::get(id, call_hash.0).is_some(), Error::::NotFound); + + Ok(()) + }) + } } /// Return the weight of a dispatch call result as an `Option`. diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index 179827255291..88421fa3e2b8 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Tests for Multisig Pallet +//! Tests for Multisig Pallet #![cfg(test)] @@ -75,17 +75,33 @@ impl Config for Test { } use pallet_balances::Call as BalancesCall; +pub struct ExtBuilder {} -pub fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], +impl Default for ExtBuilder { + fn default() -> Self { + Self {} + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], + } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } + + pub fn build_and_execute(self, test: impl FnOnce() -> ()) { + self.build().execute_with(|| { + test(); + Multisig::do_try_state().unwrap(); + }) } - .assimilate_storage(&mut t) - .unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext } fn now() -> Timepoint { @@ -98,7 +114,7 @@ fn call_transfer(dest: u64, value: u64) -> Box { #[test] fn multisig_deposit_is_taken_and_returned() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -132,16 +148,17 @@ fn multisig_deposit_is_taken_and_returned() { #[test] fn cancel_multisig_returns_deposit() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = call_transfer(6, 15).encode(); - let hash = blake2_256(&call); + let hash = H256::from(blake2_256(&call)); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 3, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(2), @@ -149,11 +166,18 @@ fn cancel_multisig_returns_deposit() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_eq!(Balances::free_balance(1), 6); assert_eq!(Balances::reserved_balance(1), 4); - assert_ok!(Multisig::cancel_as_multi(RuntimeOrigin::signed(1), 3, vec![2, 3], now(), hash)); + assert_ok!(Multisig::cancel_as_multi( + RuntimeOrigin::signed(1), + 3, + vec![2, 3], + now(), + hash.0 + )); assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::reserved_balance(1), 0); }); @@ -161,14 +185,14 @@ fn cancel_multisig_returns_deposit() { #[test] fn timepoint_checking_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5)); let call = call_transfer(6, 15); - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_noop!( Multisig::approve_as_multi( @@ -177,7 +201,8 @@ fn timepoint_checking_works() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None ), Error::::UnexpectedTimepoint, ); @@ -188,7 +213,8 @@ fn timepoint_checking_works() { vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_noop!( @@ -217,9 +243,148 @@ fn timepoint_checking_works() { }); } +#[test] +fn multisig_with_expiry_works() { + ExtBuilder::default().build_and_execute(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5)); + + let call = call_transfer(6, 15); + let call_weight = call.get_dispatch_info().weight; + let hash = H256::from(blake2_256(&call.encode())); + assert_ok!(Multisig::approve_as_multi( + RuntimeOrigin::signed(1), + 2, + vec![2, 3], + None, + hash, + Weight::zero(), + Some(5), // expiry is set to block five. + )); + + assert_eq!(Balances::free_balance(1), 2); + assert_eq!(Balances::reserved_balance(1), 3); + assert_eq!(Balances::free_balance(6), 0); + + let timepoint = now(); + + assert_eq!(MultisigExpiries::::get(multi, hash), Some(5)); + + // The expiry is at block 5, so at block 3 the multisig won't be expired. + System::set_block_number(3); + + // Cannot clear the multisig operation since it has not expired yet. + assert_noop!( + Multisig::clear_expired_multi( + RuntimeOrigin::signed(42), + 2, + vec![1, 2, 3], + timepoint, + hash + ), + Error::::MultisigNotExpired + ); + + assert_ok!(Multisig::as_multi( + RuntimeOrigin::signed(2), + 2, + vec![1, 3], + Some(timepoint), + call, + call_weight + ),); + + assert!(MultisigExpiries::::get(multi, hash).is_none()); + assert!(Multisigs::::get(multi, hash.0).is_none()); + + // The deposit is unreserved after clearing the multisig. + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!(Balances::free_balance(6), 15); + }) +} + +#[test] +fn mutlisig_wont_execute_when_expired() { + ExtBuilder::default().build_and_execute(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); + assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5)); + + let call = call_transfer(6, 15); + let call_weight = call.get_dispatch_info().weight; + let hash = H256::from(blake2_256(&call.encode())); + assert_ok!(Multisig::approve_as_multi( + RuntimeOrigin::signed(1), + 2, + vec![2, 3], + None, + hash, + Weight::zero(), + Some(5), // expiry is set to block five. + )); + + assert_eq!(Balances::free_balance(1), 2); + assert_eq!(Balances::reserved_balance(1), 3); + assert_eq!(Balances::free_balance(6), 0); + + let timepoint = now(); + + assert_eq!(MultisigExpiries::::get(multi, hash), Some(5)); + + // The expiry is at block 5, so at block 6 the multisig will get expired. + System::set_block_number(6); + + assert_noop!( + Multisig::as_multi( + RuntimeOrigin::signed(2), + 2, + vec![1, 3], + Some(timepoint), + call, + call_weight + ), + Error::::MultisigExpired + ); + + assert_ok!(Multisig::clear_expired_multi( + RuntimeOrigin::signed(42), + 2, + vec![1, 2, 3], + timepoint, + hash + )); + + assert!(MultisigExpiries::::get(multi, hash).is_none()); + assert!(Multisigs::::get(multi, hash.0).is_none()); + + // The deposit is unreserved after clearing the multisig. + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_eq!(Balances::free_balance(6), 0); + + // Cannot clear the multisig operation since it does not longer exist. + assert_noop!( + Multisig::clear_expired_multi( + RuntimeOrigin::signed(42), + 2, + vec![1, 2, 3], + timepoint, + hash + ), + Error::::NotFound + ); + }) +} + #[test] fn multisig_2_of_3_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -227,14 +392,15 @@ fn multisig_2_of_3_works() { let call = call_transfer(6, 15); let call_weight = call.get_dispatch_info().weight; - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 2, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_eq!(Balances::free_balance(6), 0); @@ -252,7 +418,7 @@ fn multisig_2_of_3_works() { #[test] fn multisig_3_of_3_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -260,14 +426,15 @@ fn multisig_3_of_3_works() { let call = call_transfer(6, 15); let call_weight = call.get_dispatch_info().weight; - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 3, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(2), @@ -275,7 +442,8 @@ fn multisig_3_of_3_works() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_eq!(Balances::free_balance(6), 0); @@ -293,16 +461,17 @@ fn multisig_3_of_3_works() { #[test] fn cancel_multisig_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = call_transfer(6, 15).encode(); - let hash = blake2_256(&call); + let hash = H256::from(blake2_256(&call)); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 3, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(2), @@ -310,19 +479,26 @@ fn cancel_multisig_works() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_noop!( - Multisig::cancel_as_multi(RuntimeOrigin::signed(2), 3, vec![1, 3], now(), hash), + Multisig::cancel_as_multi(RuntimeOrigin::signed(2), 3, vec![1, 3], now(), hash.0), Error::::NotOwner, ); - assert_ok!(Multisig::cancel_as_multi(RuntimeOrigin::signed(1), 3, vec![2, 3], now(), hash),); + assert_ok!(Multisig::cancel_as_multi( + RuntimeOrigin::signed(1), + 3, + vec![2, 3], + now(), + hash.0 + ),); }); } #[test] fn multisig_2_of_3_as_multi_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -354,7 +530,7 @@ fn multisig_2_of_3_as_multi_works() { #[test] fn multisig_2_of_3_as_multi_with_many_calls_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -405,7 +581,7 @@ fn multisig_2_of_3_as_multi_with_many_calls_works() { #[test] fn multisig_2_of_3_cannot_reissue_same_call() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -413,7 +589,7 @@ fn multisig_2_of_3_cannot_reissue_same_call() { let call = call_transfer(6, 10); let call_weight = call.get_dispatch_info().weight; - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_ok!(Multisig::as_multi( RuntimeOrigin::signed(1), 2, @@ -454,7 +630,7 @@ fn multisig_2_of_3_cannot_reissue_same_call() { approving: 3, timepoint: now(), multisig: multi, - call_hash: hash, + call_hash: hash.0, result: Err(TokenError::FundsUnavailable.into()), } .into(), @@ -464,7 +640,7 @@ fn multisig_2_of_3_cannot_reissue_same_call() { #[test] fn minimum_threshold_check_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = call_transfer(6, 15); assert_noop!( Multisig::as_multi( @@ -493,7 +669,7 @@ fn minimum_threshold_check_works() { #[test] fn too_many_signatories_fails() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = call_transfer(6, 15); assert_noop!( Multisig::as_multi( @@ -511,16 +687,17 @@ fn too_many_signatories_fails() { #[test] fn duplicate_approvals_are_ignored() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = call_transfer(6, 15).encode(); - let hash = blake2_256(&call); + let hash = H256::from(blake2_256(&call)); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 2, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_noop!( Multisig::approve_as_multi( @@ -529,7 +706,8 @@ fn duplicate_approvals_are_ignored() { vec![2, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None ), Error::::AlreadyApproved, ); @@ -539,7 +717,8 @@ fn duplicate_approvals_are_ignored() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_noop!( Multisig::approve_as_multi( @@ -548,7 +727,8 @@ fn duplicate_approvals_are_ignored() { vec![1, 2], Some(now()), hash, - Weight::zero() + Weight::zero(), + None ), Error::::AlreadyApproved, ); @@ -557,14 +737,14 @@ fn duplicate_approvals_are_ignored() { #[test] fn multisig_1_of_3_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 1); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5)); let call = call_transfer(6, 15); - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_noop!( Multisig::approve_as_multi( RuntimeOrigin::signed(1), @@ -572,7 +752,8 @@ fn multisig_1_of_3_works() { vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None ), Error::::MinimumThreshold, ); @@ -599,7 +780,7 @@ fn multisig_1_of_3_works() { #[test] fn multisig_filters() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let call = Box::new(RuntimeCall::System(frame_system::Call::set_code { code: vec![] })); assert_noop!( Multisig::as_multi_threshold_1(RuntimeOrigin::signed(1), vec![2], call.clone()), @@ -610,7 +791,7 @@ fn multisig_filters() { #[test] fn weight_check_works() { - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -646,7 +827,7 @@ fn multisig_handles_no_preimage_after_all_approve() { // This test checks the situation where everyone approves a multi-sig, but no-one provides the // call data. In the end, any of the multisig callers can approve again with the call data and // the call will go through. - new_test_ext().execute_with(|| { + ExtBuilder::default().build_and_execute(|| { let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(1), multi, 5)); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(2), multi, 5)); @@ -654,14 +835,15 @@ fn multisig_handles_no_preimage_after_all_approve() { let call = call_transfer(6, 15); let call_weight = call.get_dispatch_info().weight; - let hash = blake2_256(&call.encode()); + let hash = H256::from(blake2_256(&call.encode())); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(1), 3, vec![2, 3], None, hash, - Weight::zero() + Weight::zero(), + None )); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(2), @@ -669,7 +851,8 @@ fn multisig_handles_no_preimage_after_all_approve() { vec![1, 3], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_ok!(Multisig::approve_as_multi( RuntimeOrigin::signed(3), @@ -677,7 +860,8 @@ fn multisig_handles_no_preimage_after_all_approve() { vec![1, 2], Some(now()), hash, - Weight::zero() + Weight::zero(), + None )); assert_eq!(Balances::free_balance(6), 0); diff --git a/substrate/frame/multisig/src/weights.rs b/substrate/frame/multisig/src/weights.rs index 7b87d258d383..850d76b6e877 100644 --- a/substrate/frame/multisig/src/weights.rs +++ b/substrate/frame/multisig/src/weights.rs @@ -15,32 +15,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_multisig +//! Autogenerated weights for `pallet_multisig` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-09-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-nbnwcyh-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_multisig -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/multisig/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_multisig +// --chain=dev +// --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/multisig/src/weights.rs +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +47,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_multisig. +/// Weight functions needed for `pallet_multisig`. pub trait WeightInfo { fn as_multi_threshold_1(z: u32, ) -> Weight; fn as_multi_create(s: u32, z: u32, ) -> Weight; @@ -59,223 +56,298 @@ pub trait WeightInfo { fn approve_as_multi_create(s: u32, ) -> Weight; fn approve_as_multi_approve(s: u32, ) -> Weight; fn cancel_as_multi(s: u32, ) -> Weight; + fn clear_expired_multi(s: u32, ) -> Weight; } -/// Weights for pallet_multisig using the Substrate node and recommended hardware. +/// Weights for `pallet_multisig` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 13_452_000 picoseconds. - Weight::from_parts(14_425_869, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 20_045_000 picoseconds. + Weight::from_parts(21_561_816, 3997) + // Standard Error: 6 + .saturating_add(Weight::from_parts(519, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 46_012_000 picoseconds. - Weight::from_parts(34_797_344, 6811) - // Standard Error: 833 - .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) - // Standard Error: 8 - .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 48_133_000 picoseconds. + Weight::from_parts(37_319_345, 6811) + // Standard Error: 928 + .saturating_add(Weight::from_parts(121_897, 0).saturating_mul(s.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_473, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 29_834_000 picoseconds. - Weight::from_parts(20_189_154, 6811) - // Standard Error: 637 - .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 31_365_000 picoseconds. + Weight::from_parts(22_035_508, 6811) + // Standard Error: 771 + .saturating_add(Weight::from_parts(111_037, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_464, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `426 + s * (33 ±0)` + // Measured: `571 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 51_464_000 picoseconds. - Weight::from_parts(39_246_644, 6811) - // Standard Error: 1_251 - .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 59_875_000 picoseconds. + Weight::from_parts(49_453_318, 6811) + // Standard Error: 1_872 + .saturating_add(Weight::from_parts(174_224, 0).saturating_mul(s.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_522, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 33_275_000 picoseconds. - Weight::from_parts(34_073_221, 6811) - // Standard Error: 1_163 - .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 36_799_000 picoseconds. + Weight::from_parts(38_586_216, 6811) + // Standard Error: 1_273 + .saturating_add(Weight::from_parts(115_531, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 18_411_000 picoseconds. - Weight::from_parts(19_431_787, 6811) - // Standard Error: 694 - .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 19_956_000 picoseconds. + Weight::from_parts(21_213_694, 6811) + // Standard Error: 980 + .saturating_add(Weight::from_parts(107_574, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 33_985_000 picoseconds. - Weight::from_parts(35_547_970, 6811) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 36_044_000 picoseconds. + Weight::from_parts(37_455_098, 6811) + // Standard Error: 1_101 + .saturating_add(Weight::from_parts(115_477, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// The range of component `s` is `[2, 100]`. + fn clear_expired_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `606 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 40_021_000 picoseconds. + Weight::from_parts(42_004_970, 6811) + // Standard Error: 1_495 + .saturating_add(Weight::from_parts(126_719, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 13_452_000 picoseconds. - Weight::from_parts(14_425_869, 0) - // Standard Error: 4 - .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 20_045_000 picoseconds. + Weight::from_parts(21_561_816, 3997) + // Standard Error: 6 + .saturating_add(Weight::from_parts(519, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 46_012_000 picoseconds. - Weight::from_parts(34_797_344, 6811) - // Standard Error: 833 - .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) - // Standard Error: 8 - .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 48_133_000 picoseconds. + Weight::from_parts(37_319_345, 6811) + // Standard Error: 928 + .saturating_add(Weight::from_parts(121_897, 0).saturating_mul(s.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_473, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 29_834_000 picoseconds. - Weight::from_parts(20_189_154, 6811) - // Standard Error: 637 - .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 31_365_000 picoseconds. + Weight::from_parts(22_035_508, 6811) + // Standard Error: 771 + .saturating_add(Weight::from_parts(111_037, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_464, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `426 + s * (33 ±0)` + // Measured: `571 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 51_464_000 picoseconds. - Weight::from_parts(39_246_644, 6811) - // Standard Error: 1_251 - .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 59_875_000 picoseconds. + Weight::from_parts(49_453_318, 6811) + // Standard Error: 1_872 + .saturating_add(Weight::from_parts(174_224, 0).saturating_mul(s.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_522, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 33_275_000 picoseconds. - Weight::from_parts(34_073_221, 6811) - // Standard Error: 1_163 - .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 36_799_000 picoseconds. + Weight::from_parts(38_586_216, 6811) + // Standard Error: 1_273 + .saturating_add(Weight::from_parts(115_531, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 18_411_000 picoseconds. - Weight::from_parts(19_431_787, 6811) - // Standard Error: 694 - .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 19_956_000 picoseconds. + Weight::from_parts(21_213_694, 6811) + // Standard Error: 980 + .saturating_add(Weight::from_parts(107_574, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:0) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 33_985_000 picoseconds. - Weight::from_parts(35_547_970, 6811) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 36_044_000 picoseconds. + Weight::from_parts(37_455_098, 6811) + // Standard Error: 1_101 + .saturating_add(Weight::from_parts(115_477, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `Multisig::MultisigExpiries` (r:1 w:1) + /// Proof: `Multisig::MultisigExpiries` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// The range of component `s` is `[2, 100]`. + fn clear_expired_multi(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `606 + s * (1 ±0)` + // Estimated: `6811` + // Minimum execution time: 40_021_000 picoseconds. + Weight::from_parts(42_004_970, 6811) + // Standard Error: 1_495 + .saturating_add(Weight::from_parts(126_719, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } }