diff --git a/.github/scripts/cmd/cmd.py b/.github/scripts/cmd/cmd.py index a027d1edf54b7..2b36e795b1571 100755 --- a/.github/scripts/cmd/cmd.py +++ b/.github/scripts/cmd/cmd.py @@ -6,6 +6,7 @@ import argparse import _help import importlib.util +import re _HelpAction = _help._HelpAction @@ -40,20 +41,20 @@ def setup_logging(): setup_logging() """ -BENCH +BENCH """ bench_example = '''**Examples**: - Runs all benchmarks + Runs all benchmarks %(prog)s Runs benchmarks for pallet_balances and pallet_multisig for all runtimes which have these pallets. **--quiet** makes it to output nothing to PR but reactions %(prog)s --pallet pallet_balances pallet_xcm_benchmarks::generic --quiet - + Runs bench for all pallets for westend runtime and fails fast on first failed benchmark %(prog)s --runtime westend --fail-fast - - Does not output anything and cleans up the previous bot's & author command triggering comments in PR + + Does not output anything and cleans up the previous bot's & author command triggering comments in PR %(prog)s --runtime westend rococo --pallet pallet_balances pallet_multisig --quiet --clean ''' @@ -96,14 +97,14 @@ def setup_logging(): """ -FMT +FMT """ parser_fmt = subparsers.add_parser('fmt', help='Formats code (cargo +nightly-VERSION fmt) and configs (taplo format)') for arg, config in common_args.items(): parser_fmt.add_argument(arg, **config) """ -Update UI +Update UI """ parser_ui = subparsers.add_parser('update-ui', help='Updates UI tests') for arg, config in common_args.items(): @@ -215,7 +216,15 @@ def main(): print(f'-- package_dir: {package_dir}') print(f'-- manifest_path: {manifest_path}') output_path = os.path.join(package_dir, "src", "weights.rs") + # TODO: we can remove once all pallets in dev runtime are migrated to polkadot-sdk-frame + try: + uses_polkadot_sdk_frame = "true" in os.popen(f"cargo metadata --locked --format-version 1 --no-deps | jq -r '.packages[] | select(.name == \"{pallet.replace('_', '-')}\") | .dependencies | any(.name == \"polkadot-sdk-frame\")'").read() + # Empty output from the previous os.popen command + except StopIteration: + uses_polkadot_sdk_frame = False template = config['template'] + if uses_polkadot_sdk_frame and re.match(r"frame-(:?umbrella-)?weight-template\.hbs", os.path.normpath(template).split(os.path.sep)[-1]): + template = "substrate/.maintain/frame-umbrella-weight-template.hbs" else: default_path = f"./{config['path']}/src/weights" xcm_path = f"./{config['path']}/src/weights/xcm" @@ -434,4 +443,4 @@ def main(): print('🚀 Done') if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/Cargo.lock b/Cargo.lock index dfa70250e30fe..127e30d666af8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12099,15 +12099,11 @@ dependencies = [ name = "pallet-multisig" version = "28.0.0" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", "log", "pallet-balances", "parity-scale-codec", + "polkadot-sdk-frame", "scale-info", - "sp-io 30.0.0", - "sp-runtime 31.0.1", ] [[package]] @@ -12418,16 +12414,11 @@ dependencies = [ name = "pallet-proxy" version = "28.0.0" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", "pallet-balances", "pallet-utility", "parity-scale-codec", + "polkadot-sdk-frame", "scale-info", - "sp-core 28.0.0", - "sp-io 30.0.0", - "sp-runtime 31.0.1", ] [[package]] diff --git a/prdoc/pr_5995.prdoc b/prdoc/pr_5995.prdoc new file mode 100644 index 0000000000000..fdd754057bd15 --- /dev/null +++ b/prdoc/pr_5995.prdoc @@ -0,0 +1,21 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Use frame umbrella crate in pallet-proxy and pallet-multisig + +doc: + - audience: Runtime Dev + description: | + Extends the FRAME umbrella crate and uses it in pallet-proxy and pallet-multisig. + Migrates benchmarking from v1 to v2 for pallet-proxy and pallet-multisig. + Allows CI to pick the umbrella crate weights template to run benchmarks. + +crates: + - name: pallet-multisig + bump: minor + - name: pallet-proxy + bump: minor + - name: polkadot-sdk-frame + bump: major + - name: pallet-migrations + bump: patch diff --git a/substrate/.maintain/frame-umbrella-weight-template.hbs b/substrate/.maintain/frame-umbrella-weight-template.hbs new file mode 100644 index 0000000000000..0f26fae1d8f10 --- /dev/null +++ b/substrate/.maintain/frame-umbrella-weight-template.hbs @@ -0,0 +1,120 @@ +{{header}} +//! 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}}` +//! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` +//! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}` +//! WASM-EXECUTION: `{{cmd.wasm_execution}}`, CHAIN: `{{cmd.chain}}`, DB CACHE: `{{cmd.db_cache}}` + +// Executed Command: +{{#each args as |arg|}} +// {{arg}} +{{/each}} + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame::weights_prelude::*; + +/// Weight functions needed for `{{pallet}}`. +pub trait WeightInfo { + {{#each benchmarks as |benchmark|}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{c.name}}: u32, {{/each~}} + ) -> Weight; + {{/each}} +} + +/// Weights for `{{pallet}}` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +{{#if (eq pallet "frame_system")}} +impl WeightInfo for SubstrateWeight { +{{else}} +impl WeightInfo for SubstrateWeight { +{{/if}} + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}}_u64)) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}}_u64)) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}}_u64)) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(RocksDbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}}_u64)) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(RocksDbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} diff --git a/substrate/frame/migrations/src/benchmarking.rs b/substrate/frame/migrations/src/benchmarking.rs index 8ad1fa50d1498..c076d40bb05cd 100644 --- a/substrate/frame/migrations/src/benchmarking.rs +++ b/substrate/frame/migrations/src/benchmarking.rs @@ -158,7 +158,7 @@ mod benches { fn on_init_loop() { T::Migrations::set_fail_after(0); // Should not be called anyway. System::::set_block_number(1u32.into()); - Pallet::::on_runtime_upgrade(); + as Hooks>>::on_runtime_upgrade(); #[block] { diff --git a/substrate/frame/multisig/Cargo.toml b/substrate/frame/multisig/Cargo.toml index b24df856bcd75..c96be908faef0 100644 --- a/substrate/frame/multisig/Cargo.toml +++ b/substrate/frame/multisig/Cargo.toml @@ -18,11 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { workspace = true } scale-info = { features = ["derive"], workspace = true } -frame-benchmarking = { optional = true, workspace = true } -frame-support = { workspace = true } -frame-system = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } +frame = { workspace = true, features = ["experimental", "runtime"] } # third party log = { workspace = true } @@ -34,25 +30,15 @@ pallet-balances = { workspace = true, default-features = true } default = ["std"] std = [ "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", + "frame/std", "log/std", - "pallet-balances/std", "scale-info/std", - "sp-io/std", - "sp-runtime/std", ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", + "frame/runtime-benchmarks", "pallet-balances/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", ] try-runtime = [ - "frame-support/try-runtime", - "frame-system/try-runtime", + "frame/try-runtime", "pallet-balances/try-runtime", - "sp-runtime/try-runtime", ] diff --git a/substrate/frame/multisig/src/benchmarking.rs b/substrate/frame/multisig/src/benchmarking.rs index ebe19df5dc436..ccaa1ceab66e5 100644 --- a/substrate/frame/multisig/src/benchmarking.rs +++ b/substrate/frame/multisig/src/benchmarking.rs @@ -20,9 +20,7 @@ #![cfg(feature = "runtime-benchmarks")] use super::*; -use frame_benchmarking::v1::{account, benchmarks}; -use frame_system::RawOrigin; -use sp_runtime::traits::Bounded; +use frame::benchmarking::prelude::*; use crate::Pallet as Multisig; @@ -47,48 +45,59 @@ fn setup_multi( Ok((signatories, Box::new(call))) } -benchmarks! { - as_multi_threshold_1 { - // Transaction Length - let z in 0 .. 10_000; +#[benchmarks] +mod benchmarks { + use super::*; + + /// `z`: Transaction Length + #[benchmark] + fn as_multi_threshold_1(z: Linear<0, 10_000>) -> Result<(), BenchmarkError> { let max_signatories = T::MaxSignatories::get().into(); let (mut signatories, _) = setup_multi::(max_signatories, z)?; - let call: ::RuntimeCall = frame_system::Call::::remark { - 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 call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![0; z as usize] }.into(); let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; // 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.clone()), signatories, Box::new(call)) - verify { + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), signatories, Box::new(call)); + // If the benchmark resolves, then the call was dispatched successfully. + Ok(()) } - as_multi_create { - // Signatories, need at least 2 total people - let s in 2 .. T::MaxSignatories::get(); - // Transaction Length - let z in 0 .. 10_000; + /// `z`: Transaction Length + /// `s`: Signatories, need at least 2 people + #[benchmark] + fn as_multi_create( + s: Linear<2, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { let (mut signatories, call) = setup_multi::(s, z)?; let call_hash = call.using_encoded(blake2_256); 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")?; // 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()); - }: as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call, Weight::zero()) - verify { + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call, Weight::zero()); + assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + + Ok(()) } - as_multi_approve { - // Signatories, need at least 3 people (so we don't complete the multisig) - let s in 3 .. T::MaxSignatories::get(); - // Transaction Length - let z in 0 .. 10_000; + /// `z`: Transaction Length + /// `s`: Signatories, need at least 3 people (so we don't complete the multisig) + #[benchmark] + fn as_multi_approve( + s: Linear<3, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { let (mut signatories, call) = setup_multi::(s, z)?; let call_hash = call.using_encoded(blake2_256); let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); @@ -97,22 +106,43 @@ benchmarks! { // before the call, get the timepoint let timepoint = Multisig::::timepoint(); // Create the multi - Multisig::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone(), Weight::zero())?; + Multisig::::as_multi( + RawOrigin::Signed(caller).into(), + s as u16, + signatories, + None, + call.clone(), + Weight::zero(), + )?; let caller2 = signatories2.remove(0); // 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()); - }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call, Weight::zero()) - verify { - let multisig = Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + as_multi( + RawOrigin::Signed(caller2), + s as u16, + signatories2, + Some(timepoint), + call, + Weight::zero(), + ); + + let multisig = + Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; assert_eq!(multisig.approvals.len(), 2); + + Ok(()) } - as_multi_complete { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get(); - // Transaction Length - let z in 0 .. 10_000; + /// `z`: Transaction Length + /// `s`: Signatories, need at least 2 people + #[benchmark] + fn as_multi_complete( + s: Linear<2, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { let (mut signatories, call) = setup_multi::(s, z)?; let call_hash = call.using_encoded(blake2_256); let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); @@ -121,47 +151,87 @@ benchmarks! { // before the call, get the timepoint let timepoint = Multisig::::timepoint(); // Create the multi - Multisig::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone(), Weight::zero())?; + Multisig::::as_multi( + RawOrigin::Signed(caller).into(), + s as u16, + signatories, + None, + call.clone(), + Weight::zero(), + )?; // Everyone except the first person approves - for i in 1 .. s - 1 { + for i in 1..s - 1 { let mut signatories_loop = signatories2.clone(); let caller_loop = signatories_loop.remove(i as usize); let o = RawOrigin::Signed(caller_loop).into(); - Multisig::::as_multi(o, s as u16, signatories_loop, Some(timepoint), call.clone(), Weight::zero())?; + Multisig::::as_multi( + o, + s as u16, + signatories_loop, + Some(timepoint), + call.clone(), + Weight::zero(), + )?; } let caller2 = signatories2.remove(0); assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); // 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()); - }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call, Weight::MAX) - verify { + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + as_multi( + RawOrigin::Signed(caller2), + s as u16, + signatories2, + Some(timepoint), + call, + Weight::MAX, + ); + assert!(!Multisigs::::contains_key(&multi_account_id, call_hash)); + + Ok(()) } - approve_as_multi_create { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get(); - // Transaction Length, not a component - let z = 10_000; + /// `z`: Transaction Length, not a component + /// `s`: Signatories, need at least 2 people + #[benchmark] + fn approve_as_multi_create( + s: Linear<2, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { 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); // 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()); + add_to_whitelist(caller_key.into()); + // Create the multi - }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash, Weight::zero()) - verify { + #[extrinsic_call] + approve_as_multi( + RawOrigin::Signed(caller), + s as u16, + signatories, + None, + call_hash, + Weight::zero(), + ); + assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + + Ok(()) } - approve_as_multi_approve { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get(); - // Transaction Length, not a component - let z = 10_000; + /// `z`: Transaction Length, not a component + /// `s`: Signatories, need at least 2 people + #[benchmark] + fn approve_as_multi_approve( + s: Linear<2, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { let (mut signatories, call) = setup_multi::(s, z)?; let mut signatories2 = signatories.clone(); let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); @@ -176,23 +246,37 @@ benchmarks! { signatories, None, call, - Weight::zero() + Weight::zero(), )?; let caller2 = signatories2.remove(0); // 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()) - verify { - let multisig = Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + approve_as_multi( + RawOrigin::Signed(caller2), + s as u16, + signatories2, + Some(timepoint), + call_hash, + Weight::zero(), + ); + + let multisig = + Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; assert_eq!(multisig.approvals.len(), 2); + + Ok(()) } - cancel_as_multi { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get(); - // Transaction Length, not a component - let z = 10_000; + /// `z`: Transaction Length, not a component + /// `s`: Signatories, need at least 2 people + #[benchmark] + fn cancel_as_multi( + s: Linear<2, { T::MaxSignatories::get() }>, + z: Linear<0, 10_000>, + ) -> Result<(), BenchmarkError> { 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")?; @@ -204,10 +288,14 @@ benchmarks! { assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); // 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), s as u16, signatories, timepoint, call_hash) - verify { + add_to_whitelist(caller_key.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash); + assert!(!Multisigs::::contains_key(multi_account_id, call_hash)); + + Ok(()) } impl_benchmark_test_suite!(Multisig, crate::tests::new_test_ext(), crate::tests::Test); diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs index 8faae73c7161e..4a30b5c119b91 100644 --- a/substrate/frame/multisig/src/lib.rs +++ b/substrate/frame/multisig/src/lib.rs @@ -49,28 +49,15 @@ mod tests; pub mod weights; extern crate alloc; - use alloc::{boxed::Box, vec, vec::Vec}; -use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{ - dispatch::{ - DispatchErrorWithPostInfo, DispatchResult, DispatchResultWithPostInfo, GetDispatchInfo, - PostDispatchInfo, - }, - ensure, - traits::{Currency, Get, ReservableCurrency}, - weights::Weight, - BoundedVec, -}; -use frame_system::{self as system, pallet_prelude::BlockNumberFor, RawOrigin}; -use scale_info::TypeInfo; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Dispatchable, TrailingZeroInput, Zero}, - DispatchError, RuntimeDebug, +use frame::{ + prelude::*, + traits::{Currency, ReservableCurrency}, }; +use frame_system::RawOrigin; pub use weights::WeightInfo; +/// Re-export all pallet items. pub use pallet::*; /// The log target of this pallet. @@ -127,11 +114,9 @@ enum CallOrHash { Hash([u8; 32]), } -#[frame_support::pallet] +#[frame::pallet] pub mod pallet { use super::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; #[pallet::config] pub trait Config: frame_system::Config { @@ -167,7 +152,7 @@ pub mod pallet { type MaxSignatories: Get; /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; + type WeightInfo: weights::WeightInfo; } /// The in-code storage version. @@ -641,8 +626,8 @@ impl Pallet { /// The current `Timepoint`. pub fn timepoint() -> Timepoint> { Timepoint { - height: >::block_number(), - index: >::extrinsic_index().unwrap_or_default(), + height: >::block_number(), + index: >::extrinsic_index().unwrap_or_default(), } } diff --git a/substrate/frame/multisig/src/migrations.rs b/substrate/frame/multisig/src/migrations.rs index e6402600d0d36..8d6e778136736 100644 --- a/substrate/frame/multisig/src/migrations.rs +++ b/substrate/frame/multisig/src/migrations.rs @@ -17,21 +17,15 @@ // Migrations for Multisig Pallet -use super::*; -use frame_support::{ - traits::{GetStorageVersion, OnRuntimeUpgrade, WrapperKeepOpaque}, - Identity, -}; - -#[cfg(feature = "try-runtime")] -use frame_support::ensure; +use crate::*; +use frame::prelude::*; pub mod v1 { use super::*; - type OpaqueCall = WrapperKeepOpaque<::RuntimeCall>; + type OpaqueCall = frame::traits::WrapperKeepOpaque<::RuntimeCall>; - #[frame_support::storage_alias] + #[frame::storage_alias] type Calls = StorageMap< Pallet, Identity, @@ -42,15 +36,14 @@ pub mod v1 { pub struct MigrateToV1(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + fn pre_upgrade() -> Result, frame::try_runtime::TryRuntimeError> { log!(info, "Number of calls to refund and delete: {}", Calls::::iter().count()); Ok(Vec::new()) } fn on_runtime_upgrade() -> Weight { - use sp_runtime::Saturating; - + use frame::traits::ReservableCurrency as _; let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); @@ -76,7 +69,7 @@ pub mod v1 { } #[cfg(feature = "try-runtime")] - fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + fn post_upgrade(_state: Vec) -> Result<(), frame::try_runtime::TryRuntimeError> { ensure!( Calls::::iter().count() == 0, "there are some dangling calls that need to be destroyed and refunded" diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index 4f8a7a44243cf..c5a98845270c6 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -20,18 +20,13 @@ #![cfg(test)] use super::*; - use crate as pallet_multisig; -use frame_support::{ - assert_noop, assert_ok, derive_impl, - traits::{ConstU32, ConstU64, Contains}, -}; -use sp_runtime::{BuildStorage, TokenError}; +use frame::{prelude::*, runtime::prelude::*, testing_prelude::*}; type Block = frame_system::mocking::MockBlockU32; -frame_support::construct_runtime!( - pub enum Test { +construct_runtime!( + pub struct Test { System: frame_system, Balances: pallet_balances, Multisig: pallet_multisig, @@ -75,14 +70,14 @@ impl Config for Test { use pallet_balances::Call as BalancesCall; -pub fn new_test_ext() -> sp_io::TestExternalities { +pub fn new_test_ext() -> TestState { 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); + let mut ext = TestState::new(t); ext.execute_with(|| System::set_block_number(1)); ext } diff --git a/substrate/frame/multisig/src/weights.rs b/substrate/frame/multisig/src/weights.rs index ac1c1b23b0302..fb263116ea62a 100644 --- a/substrate/frame/multisig/src/weights.rs +++ b/substrate/frame/multisig/src/weights.rs @@ -46,9 +46,8 @@ #![allow(unused_imports)] #![allow(missing_docs)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - +// TODO update this in frame-weight-template.hbs +use frame::weights_prelude::*; /// Weight functions needed for `pallet_multisig`. pub trait WeightInfo { fn as_multi_threshold_1(z: u32, ) -> Weight; diff --git a/substrate/frame/proxy/Cargo.toml b/substrate/frame/proxy/Cargo.toml index 40c1c97506145..8897c66419c7a 100644 --- a/substrate/frame/proxy/Cargo.toml +++ b/substrate/frame/proxy/Cargo.toml @@ -18,43 +18,26 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { features = ["max-encoded-len"], workspace = true } scale-info = { features = ["derive"], workspace = true } -frame-benchmarking = { optional = true, workspace = true } -frame-support = { workspace = true } -frame-system = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } +frame = { workspace = true, features = ["experimental", "runtime"] } [dev-dependencies] pallet-balances = { workspace = true, default-features = true } pallet-utility = { workspace = true, default-features = true } -sp-core = { workspace = true, default-features = true } [features] default = ["std"] std = [ "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "pallet-balances/std", - "pallet-utility/std", + "frame/std", "scale-info/std", - "sp-core/std", - "sp-io/std", - "sp-runtime/std", ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", + "frame/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-utility/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", ] try-runtime = [ - "frame-support/try-runtime", - "frame-system/try-runtime", + "frame/try-runtime", "pallet-balances/try-runtime", "pallet-utility/try-runtime", - "sp-runtime/try-runtime", ] diff --git a/substrate/frame/proxy/src/benchmarking.rs b/substrate/frame/proxy/src/benchmarking.rs index 4081af49c2435..eebb506bf374b 100644 --- a/substrate/frame/proxy/src/benchmarking.rs +++ b/substrate/frame/proxy/src/benchmarking.rs @@ -22,9 +22,7 @@ use super::*; use crate::Pallet as Proxy; use alloc::{boxed::Box, vec}; -use frame_benchmarking::v1::{account, benchmarks, whitelisted_caller}; -use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; -use sp_runtime::traits::Bounded; +use frame::benchmarking::prelude::*; const SEED: u32 = 0; @@ -80,24 +78,36 @@ fn add_announcements( Ok(()) } -benchmarks! { - proxy { - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn proxy(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; // In this case the caller is the "target" proxy let caller: T::AccountId = account("target", p - 1, SEED); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value() / 2u32.into()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); let real_lookup = T::Lookup::unlookup(real); - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); - }: _(RawOrigin::Signed(caller), real_lookup, Some(T::ProxyType::default()), Box::new(call)) - verify { - assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into()) + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), real_lookup, Some(T::ProxyType::default()), Box::new(call)); + + assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into()); + + Ok(()) } - proxy_announced { - let a in 0 .. T::MaxPending::get() - 1; - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn proxy_announced( + a: Linear<0, { T::MaxPending::get() - 1 }>, + p: Linear<1, { T::MaxProxies::get() - 1 }>, + ) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; // In this case the caller is the "target" proxy let caller: T::AccountId = account("pure", 0, SEED); let delegate: T::AccountId = account("target", p - 1, SEED); @@ -106,43 +116,65 @@ benchmarks! { // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); let real_lookup = T::Lookup::unlookup(real); - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); Proxy::::announce( RawOrigin::Signed(delegate.clone()).into(), real_lookup.clone(), T::CallHasher::hash_of(&call), )?; add_announcements::(a, Some(delegate.clone()), None)?; - }: _(RawOrigin::Signed(caller), delegate_lookup, real_lookup, Some(T::ProxyType::default()), Box::new(call)) - verify { - assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into()) + + #[extrinsic_call] + _( + RawOrigin::Signed(caller), + delegate_lookup, + real_lookup, + Some(T::ProxyType::default()), + Box::new(call), + ); + + assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into()); + + Ok(()) } - remove_announcement { - let a in 0 .. T::MaxPending::get() - 1; - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn remove_announcement( + a: Linear<0, { T::MaxPending::get() - 1 }>, + p: Linear<1, { T::MaxProxies::get() - 1 }>, + ) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; // In this case the caller is the "target" proxy let caller: T::AccountId = account("target", p - 1, SEED); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value() / 2u32.into()); // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); let real_lookup = T::Lookup::unlookup(real); - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); Proxy::::announce( RawOrigin::Signed(caller.clone()).into(), real_lookup.clone(), T::CallHasher::hash_of(&call), )?; add_announcements::(a, Some(caller.clone()), None)?; - }: _(RawOrigin::Signed(caller.clone()), real_lookup, T::CallHasher::hash_of(&call)) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), real_lookup, T::CallHasher::hash_of(&call)); + let (announcements, _) = Announcements::::get(&caller); assert_eq!(announcements.len() as u32, a); + + Ok(()) } - reject_announcement { - let a in 0 .. T::MaxPending::get() - 1; - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn reject_announcement( + a: Linear<0, { T::MaxPending::get() - 1 }>, + p: Linear<1, { T::MaxProxies::get() - 1 }>, + ) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; // In this case the caller is the "target" proxy let caller: T::AccountId = account("target", p - 1, SEED); let caller_lookup = T::Lookup::unlookup(caller.clone()); @@ -150,22 +182,30 @@ benchmarks! { // ... and "real" is the traditional caller. This is not a typo. let real: T::AccountId = whitelisted_caller(); let real_lookup = T::Lookup::unlookup(real.clone()); - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); Proxy::::announce( RawOrigin::Signed(caller.clone()).into(), real_lookup, T::CallHasher::hash_of(&call), )?; add_announcements::(a, Some(caller.clone()), None)?; - }: _(RawOrigin::Signed(real), caller_lookup, T::CallHasher::hash_of(&call)) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(real), caller_lookup, T::CallHasher::hash_of(&call)); + let (announcements, _) = Announcements::::get(&caller); assert_eq!(announcements.len() as u32, a); + + Ok(()) } - announce { - let a in 0 .. T::MaxPending::get() - 1; - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn announce( + a: Linear<0, { T::MaxPending::get() - 1 }>, + p: Linear<1, { T::MaxProxies::get() - 1 }>, + ) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; // In this case the caller is the "target" proxy let caller: T::AccountId = account("target", p - 1, SEED); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value() / 2u32.into()); @@ -173,74 +213,101 @@ benchmarks! { let real: T::AccountId = whitelisted_caller(); let real_lookup = T::Lookup::unlookup(real.clone()); add_announcements::(a, Some(caller.clone()), None)?; - let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into(); + let call: ::RuntimeCall = + frame_system::Call::::remark { remark: vec![] }.into(); let call_hash = T::CallHasher::hash_of(&call); - }: _(RawOrigin::Signed(caller.clone()), real_lookup, call_hash) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), real_lookup, call_hash); + assert_last_event::(Event::Announced { real, proxy: caller, call_hash }.into()); + + Ok(()) } - add_proxy { - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn add_proxy(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; let caller: T::AccountId = whitelisted_caller(); let real = T::Lookup::unlookup(account("target", T::MaxProxies::get(), SEED)); - }: _( - RawOrigin::Signed(caller.clone()), - real, - T::ProxyType::default(), - BlockNumberFor::::zero() - ) - verify { + + #[extrinsic_call] + _( + RawOrigin::Signed(caller.clone()), + real, + T::ProxyType::default(), + BlockNumberFor::::zero(), + ); + let (proxies, _) = Proxies::::get(caller); assert_eq!(proxies.len() as u32, p + 1); + + Ok(()) } - remove_proxy { - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn remove_proxy(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; let caller: T::AccountId = whitelisted_caller(); let delegate = T::Lookup::unlookup(account("target", 0, SEED)); - }: _( - RawOrigin::Signed(caller.clone()), - delegate, - T::ProxyType::default(), - BlockNumberFor::::zero() - ) - verify { + + #[extrinsic_call] + _( + RawOrigin::Signed(caller.clone()), + delegate, + T::ProxyType::default(), + BlockNumberFor::::zero(), + ); + let (proxies, _) = Proxies::::get(caller); assert_eq!(proxies.len() as u32, p - 1); + + Ok(()) } - remove_proxies { - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn remove_proxies(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; let caller: T::AccountId = whitelisted_caller(); - }: _(RawOrigin::Signed(caller.clone())) - verify { + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone())); + let (proxies, _) = Proxies::::get(caller); assert_eq!(proxies.len() as u32, 0); + + Ok(()) } - create_pure { - let p in 1 .. (T::MaxProxies::get() - 1) => add_proxies::(p, None)?; + #[benchmark] + fn create_pure(p: Linear<1, { T::MaxProxies::get() - 1 }>) -> Result<(), BenchmarkError> { + add_proxies::(p, None)?; let caller: T::AccountId = whitelisted_caller(); - }: _( - RawOrigin::Signed(caller.clone()), - T::ProxyType::default(), - BlockNumberFor::::zero(), - 0 - ) - verify { + + #[extrinsic_call] + _( + RawOrigin::Signed(caller.clone()), + T::ProxyType::default(), + BlockNumberFor::::zero(), + 0, + ); + let pure_account = Pallet::::pure_account(&caller, &T::ProxyType::default(), 0, None); - assert_last_event::(Event::PureCreated { - pure: pure_account, - who: caller, - proxy_type: T::ProxyType::default(), - disambiguation_index: 0, - }.into()); - } + assert_last_event::( + Event::PureCreated { + pure: pure_account, + who: caller, + proxy_type: T::ProxyType::default(), + disambiguation_index: 0, + } + .into(), + ); - kill_pure { - let p in 0 .. (T::MaxProxies::get() - 2); + Ok(()) + } + #[benchmark] + fn kill_pure(p: Linear<0, { T::MaxProxies::get() - 2 }>) -> Result<(), BenchmarkError> { let caller: T::AccountId = whitelisted_caller(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -248,17 +315,28 @@ benchmarks! { RawOrigin::Signed(whitelisted_caller()).into(), T::ProxyType::default(), BlockNumberFor::::zero(), - 0 + 0, )?; - let height = system::Pallet::::block_number(); - let ext_index = system::Pallet::::extrinsic_index().unwrap_or(0); + let height = frame_system::Pallet::::block_number(); + let ext_index = frame_system::Pallet::::extrinsic_index().unwrap_or(0); let pure_account = Pallet::::pure_account(&caller, &T::ProxyType::default(), 0, None); add_proxies::(p, Some(pure_account.clone()))?; ensure!(Proxies::::contains_key(&pure_account), "pure proxy not created"); - }: _(RawOrigin::Signed(pure_account.clone()), caller_lookup, T::ProxyType::default(), 0, height, ext_index) - verify { + + #[extrinsic_call] + _( + RawOrigin::Signed(pure_account.clone()), + caller_lookup, + T::ProxyType::default(), + 0, + height, + ext_index, + ); + assert!(!Proxies::::contains_key(&pure_account)); + + Ok(()) } impl_benchmark_test_suite!(Proxy, crate::tests::new_test_ext(), crate::tests::Test); diff --git a/substrate/frame/proxy/src/lib.rs b/substrate/frame/proxy/src/lib.rs index c041880a59df2..cc8aeedcc5f94 100644 --- a/substrate/frame/proxy/src/lib.rs +++ b/substrate/frame/proxy/src/lib.rs @@ -34,23 +34,12 @@ mod tests; pub mod weights; extern crate alloc; - use alloc::{boxed::Box, vec}; -use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{ - dispatch::GetDispatchInfo, - ensure, - traits::{Currency, Get, InstanceFilter, IsSubType, IsType, OriginTrait, ReservableCurrency}, - BoundedVec, +use frame::{ + prelude::*, + traits::{Currency, ReservableCurrency}, }; -use frame_system::{self as system, ensure_signed, pallet_prelude::BlockNumberFor}; pub use pallet::*; -use scale_info::TypeInfo; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Dispatchable, Hash, Saturating, StaticLookup, TrailingZeroInput, Zero}, - DispatchError, DispatchResult, RuntimeDebug, -}; pub use weights::WeightInfo; type CallHashOf = <::CallHasher as Hash>::Output; @@ -96,11 +85,9 @@ pub struct Announcement { height: BlockNumber, } -#[frame_support::pallet] +#[frame::pallet] pub mod pallet { - use super::{DispatchResult, *}; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; + use super::*; #[pallet::pallet] pub struct Pallet(_); @@ -130,7 +117,7 @@ pub mod pallet { + Member + Ord + PartialOrd - + InstanceFilter<::RuntimeCall> + + frame::traits::InstanceFilter<::RuntimeCall> + Default + MaxEncodedLen; @@ -392,7 +379,7 @@ pub mod pallet { let announcement = Announcement { real: real.clone(), call_hash, - height: system::Pallet::::block_number(), + height: frame_system::Pallet::::block_number(), }; Announcements::::try_mutate(&who, |(ref mut pending, ref mut deposit)| { @@ -503,7 +490,7 @@ pub mod pallet { let def = Self::find_proxy(&real, &delegate, force_proxy_type)?; let call_hash = T::CallHasher::hash_of(&call); - let now = system::Pallet::::block_number(); + let now = frame_system::Pallet::::block_number(); Self::edit_announcements(&delegate, |ann| { ann.real != real || ann.call_hash != call_hash || @@ -639,8 +626,8 @@ impl Pallet { ) -> T::AccountId { let (height, ext_index) = maybe_when.unwrap_or_else(|| { ( - system::Pallet::::block_number(), - system::Pallet::::extrinsic_index().unwrap_or_default(), + frame_system::Pallet::::block_number(), + frame_system::Pallet::::extrinsic_index().unwrap_or_default(), ) }); let entropy = (b"modlpy/proxy____", who, height, ext_index, proxy_type, index) @@ -796,6 +783,7 @@ impl Pallet { real: T::AccountId, call: ::RuntimeCall, ) { + use frame::traits::{InstanceFilter as _, OriginTrait as _}; // This is a freshly authenticated new account, the origin restrictions doesn't apply. let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real).into(); origin.add_filter(move |c: &::RuntimeCall| { diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 3edb96026a82b..5baf9bb9e838e 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -20,22 +20,14 @@ #![cfg(test)] use super::*; - use crate as proxy; use alloc::{vec, vec::Vec}; -use codec::{Decode, Encode}; -use frame_support::{ - assert_noop, assert_ok, derive_impl, - traits::{ConstU32, ConstU64, Contains}, -}; -use sp_core::H256; -use sp_runtime::{traits::BlakeTwo256, BuildStorage, DispatchError, RuntimeDebug}; +use frame::testing_prelude::*; type Block = frame_system::mocking::MockBlock; -frame_support::construct_runtime!( - pub enum Test - { +construct_runtime!( + pub struct Test { System: frame_system, Balances: pallet_balances, Proxy: proxy, @@ -86,7 +78,7 @@ impl Default for ProxyType { Self::Any } } -impl InstanceFilter for ProxyType { +impl frame::traits::InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, @@ -136,20 +128,20 @@ use pallet_utility::{Call as UtilityCall, Event as UtilityEvent}; type SystemError = frame_system::Error; -pub fn new_test_ext() -> sp_io::TestExternalities { +pub fn new_test_ext() -> TestState { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 3)], } .assimilate_storage(&mut t) .unwrap(); - let mut ext = sp_io::TestExternalities::new(t); + let mut ext = TestState::new(t); ext.execute_with(|| System::set_block_number(1)); ext } fn last_events(n: usize) -> Vec { - system::Pallet::::events() + frame_system::Pallet::::events() .into_iter() .rev() .take(n) @@ -286,7 +278,7 @@ fn delayed_requires_pre_announcement() { assert_noop!(Proxy::proxy_announced(RuntimeOrigin::signed(0), 2, 1, None, call.clone()), e); let call_hash = BlakeTwo256::hash_of(&call); assert_ok!(Proxy::announce(RuntimeOrigin::signed(2), 1, call_hash)); - system::Pallet::::set_block_number(2); + frame_system::Pallet::::set_block_number(2); assert_ok!(Proxy::proxy_announced(RuntimeOrigin::signed(0), 2, 1, None, call.clone())); }); } @@ -304,7 +296,7 @@ fn proxy_announced_removes_announcement_and_returns_deposit() { let e = Error::::Unannounced; assert_noop!(Proxy::proxy_announced(RuntimeOrigin::signed(0), 3, 1, None, call.clone()), e); - system::Pallet::::set_block_number(2); + frame_system::Pallet::::set_block_number(2); assert_ok!(Proxy::proxy_announced(RuntimeOrigin::signed(0), 3, 1, None, call.clone())); let announcements = Announcements::::get(3); assert_eq!(announcements.0, vec![Announcement { real: 2, call_hash, height: 1 }]); diff --git a/substrate/frame/proxy/src/weights.rs b/substrate/frame/proxy/src/weights.rs index 3093298e3e54e..eab2cb4b26837 100644 --- a/substrate/frame/proxy/src/weights.rs +++ b/substrate/frame/proxy/src/weights.rs @@ -46,8 +46,7 @@ #![allow(unused_imports)] #![allow(missing_docs)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; +use frame::weights_prelude::*; /// Weight functions needed for `pallet_proxy`. pub trait WeightInfo { diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index ade1095cc504c..a8d2c0b3fc56f 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -32,10 +32,17 @@ //! //! ## Usage //! -//! The main intended use of this crate is for it to be imported with its preludes: +//! This crate is organized into 3 stages: +//! +//! 1. preludes: `prelude`, `testing_prelude` and `runtime::prelude`, `benchmarking`, +//! `weights_prelude`, `try_runtime`. +//! 2. domain-specific modules: `traits`, `hashing`, `arithmetic` and `derive`. +//! 3. Accessing frame/substrate dependencies directly: `deps`. +//! +//! The main intended use of this crate is for it to be used with the former, preludes: //! //! ``` -//! # use polkadot_sdk_frame as frame; +//! use polkadot_sdk_frame as frame; //! #[frame::pallet] //! pub mod pallet { //! # use polkadot_sdk_frame as frame; @@ -49,36 +56,98 @@ //! pub struct Pallet(_); //! } //! +//! #[cfg(test)] //! pub mod tests { //! # use polkadot_sdk_frame as frame; //! use frame::testing_prelude::*; //! } //! +//! #[cfg(feature = "runtime-benchmarks")] +//! pub mod benchmarking { +//! # use polkadot_sdk_frame as frame; +//! use frame::benchmarking::prelude::*; +//! } +//! //! pub mod runtime { //! # use polkadot_sdk_frame as frame; //! use frame::runtime::prelude::*; //! } //! ``` //! -//! See: [`prelude`], [`testing_prelude`] and [`runtime::prelude`]. +//! If not in preludes, one can look into the domain-specific modules. Finally, if an import is +//! still not feasible, one can look into `deps`. //! -//! Please note that this crate can only be imported as `polkadot-sdk-frame` or `frame`. +//! This crate also uses a `runtime` feature to include all of the types and tools needed to build +//! FRAME-based runtimes. So, if you want to build a runtime with this, import it as //! -//! ## Documentation +//! ```text +//! polkadot-sdk-frame = { version = "foo", features = ["runtime"] } +//! ``` //! -//! See [`polkadot_sdk::frame`](../polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html). +//! If you just want to build a pallet instead, import it as //! -//! ## Underlying dependencies +//! ```text +//! polkadot-sdk-frame = { version = "foo" } +//! ``` //! -//! This crate is an amalgamation of multiple other crates that are often used together to compose a -//! pallet. It is not necessary to use it, and it may fall short for certain purposes. +//! Notice that the preludes overlap since they have imports in common. More in detail: +//! - `testing_prelude` brings in frame `prelude` and `runtime::prelude`; +//! - `runtime::prelude` brings in frame `prelude`; +//! - `benchmarking` brings in frame `prelude`. //! -//! In short, this crate only re-exports types and traits from multiple sources. All of these -//! sources are listed (and re-exported again) in [`deps`]. +//! ## Naming +//! +//! Please note that this crate can only be imported as `polkadot-sdk-frame` or `frame`. This is due +//! to compatibility matters with `frame-support`. +//! +//! A typical pallet's `Cargo.toml` using this crate looks like: +//! +//! ```ignore +//! [dependencies] +//! codec = { features = ["max-encoded-len"], workspace = true } +//! scale-info = { features = ["derive"], workspace = true } +//! frame = { workspace = true, features = ["experimental", "runtime"] } +//! +//! [features] +//! default = ["std"] +//! std = [ +//! "codec/std", +//! "scale-info/std", +//! "frame/std", +//! ] +//! runtime-benchmarks = [ +//! "frame/runtime-benchmarks", +//! ] +//! try-runtime = [ +//! "frame/try-runtime", +//! ] +//! ``` +//! +//! ## Documentation +//! +//! See [`polkadot_sdk::frame`](../polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html). //! //! ## WARNING: Experimental //! //! **This crate and all of its content is experimental, and should not yet be used in production.** +//! +//! ## Maintenance Note +//! +//! > Notes for the maintainers of this crate, describing how the re-exports and preludes should +//! > work. +//! +//! * Preludes should be extensive. The goal of this pallet is to be ONLY used with the preludes. +//! The domain-specific modules are just a backup, aiming to keep things organized. Don't hesitate +//! in adding more items to the main prelude. +//! * The only non-module, non-prelude items exported from the top level crate is the `pallet` +//! macro, such that we can have the `#[frame::pallet] mod pallet { .. }` syntax working. +//! * In most cases, you might want to create a domain-specific module, but also add it to the +//! preludes, such as `hashing`. +//! * The only items that should NOT be in preludes are those that have been placed in +//! `frame-support`/`sp-runtime`, but in truth are related to just one pallet. +//! * The currency related traits are kept out of the preludes to encourage a deliberate choice of +//! one over the other. +//! * `runtime::apis` should expose all common runtime APIs that all FRAME-based runtimes need. #![cfg_attr(not(feature = "std"), no_std)] #![cfg(feature = "experimental")] @@ -92,6 +161,9 @@ pub use frame_support::pallet_macros::{import_section, pallet_section}; /// The logging library of the runtime. Can normally be the classic `log` crate. pub use log; +#[doc(inline)] +pub use frame_support::storage_alias; + /// Macros used within the main [`pallet`] macro. /// /// Note: All of these macros are "stubs" and not really usable outside `#[pallet] mod pallet { .. @@ -128,6 +200,11 @@ pub mod prelude { #[doc(no_inline)] pub use frame_support::pallet_prelude::*; + /// Dispatch types from `frame-support`, other fundamental traits + #[doc(no_inline)] + pub use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; + pub use frame_support::traits::{Contains, IsSubType, OnRuntimeUpgrade}; + /// Pallet prelude of `frame-system`. #[doc(no_inline)] pub use frame_system::pallet_prelude::*; @@ -135,6 +212,78 @@ pub mod prelude { /// All FRAME-relevant derive macros. #[doc(no_inline)] pub use super::derive::*; + + /// All hashing related things + pub use super::hashing::*; + + /// Runtime traits + #[doc(no_inline)] + pub use sp_runtime::traits::{ + Bounded, DispatchInfoOf, Dispatchable, SaturatedConversion, Saturating, StaticLookup, + TrailingZeroInput, + }; + + /// Other error/result types for runtime + #[doc(no_inline)] + pub use sp_runtime::{DispatchErrorWithPostInfo, DispatchResultWithInfo, TokenError}; +} + +#[cfg(any(feature = "try-runtime", test))] +pub mod try_runtime { + pub use sp_runtime::TryRuntimeError; +} + +/// Prelude to be included in the `benchmarking.rs` of a pallet. +/// +/// It supports both the `benchmarking::v1::benchmarks` and `benchmarking::v2::benchmark` syntax. +/// +/// ``` +/// use polkadot_sdk_frame::benchmarking::prelude::*; +/// // rest of your code. +/// ``` +/// +/// It already includes `polkadot_sdk_frame::prelude::*` and `polkadot_sdk_frame::testing_prelude`. +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking { + mod shared { + pub use frame_benchmarking::{add_benchmark, v1::account, whitelist, whitelisted_caller}; + // all benchmarking functions. + pub use frame_benchmarking::benchmarking::*; + // The system origin, which is very often needed in benchmarking code. Might be tricky only + // if the pallet defines its own `#[pallet::origin]` and call it `RawOrigin`. + pub use frame_system::RawOrigin; + } + + #[deprecated( + note = "'The V1 benchmarking syntax is deprecated. Please use the V2 syntax. This warning may become a hard error any time after April 2025. For more info, see: https://github.com/paritytech/polkadot-sdk/pull/5995" + )] + pub mod v1 { + pub use super::shared::*; + pub use frame_benchmarking::benchmarks; + } + + pub mod prelude { + pub use super::shared::*; + pub use crate::prelude::*; + pub use frame_benchmarking::v2::*; + } +} + +/// Prelude to be included in the `weight.rs` of each pallet. +/// +/// ``` +/// pub use polkadot_sdk_frame::weights_prelude::*; +/// ``` +pub mod weights_prelude { + pub use core::marker::PhantomData; + pub use frame_support::{ + traits::Get, + weights::{ + constants::{ParityDbWeight, RocksDbWeight}, + Weight, + }, + }; + pub use frame_system; } /// The main testing prelude of FRAME. @@ -145,9 +294,13 @@ pub mod prelude { /// use polkadot_sdk_frame::testing_prelude::*; /// // rest of your test setup. /// ``` +/// +/// This automatically brings in `polkadot_sdk_frame::prelude::*` and +/// `polkadot_sdk_frame::runtime::prelude::*`. #[cfg(feature = "std")] pub mod testing_prelude { - pub use super::prelude::*; + pub use crate::{prelude::*, runtime::prelude::*}; + /// Testing includes building a runtime, so we bring in all preludes related to runtimes as /// well. pub use super::runtime::testing_prelude::*; @@ -159,6 +312,10 @@ pub mod testing_prelude { }; pub use frame_system::{self, mocking::*}; + + #[deprecated(note = "Use `frame::testing_prelude::TestExternalities` instead.")] + pub use sp_io::TestExternalities; + pub use sp_io::TestExternalities as TestState; } @@ -170,9 +327,13 @@ pub mod runtime { /// A runtime typically starts with: /// /// ``` - /// use polkadot_sdk_frame::{prelude::*, runtime::prelude::*}; + /// use polkadot_sdk_frame::runtime::prelude::*; /// ``` + /// + /// This automatically brings in `polkadot_sdk_frame::prelude::*`. pub mod prelude { + pub use crate::prelude::*; + /// All of the types related to the FRAME runtime executive. pub use frame_executive::*; @@ -328,7 +489,6 @@ pub mod runtime { /// counter part of `runtime::prelude`. #[cfg(feature = "std")] pub mod testing_prelude { - pub use super::prelude::*; pub use sp_core::storage::Storage; pub use sp_runtime::BuildStorage; } @@ -350,12 +510,6 @@ pub mod arithmetic { pub use sp_arithmetic::{traits::*, *}; } -/// Low level primitive types used in FRAME pallets. -pub mod primitives { - pub use sp_core::{H160, H256, H512, U256, U512}; - pub use sp_runtime::traits::{BlakeTwo256, Hash, Keccak256}; -} - /// All derive macros used in frame. /// /// This is already part of the [`prelude`]. @@ -370,12 +524,17 @@ pub mod derive { pub use sp_runtime::RuntimeDebug; } -/// Access to all of the dependencies of this crate. In case the re-exports are not enough, this -/// module can be used. +pub mod hashing { + pub use sp_core::{hashing::*, H160, H256, H512, U256, U512}; + pub use sp_runtime::traits::{BlakeTwo256, Hash, Keccak256}; +} + +/// Access to all of the dependencies of this crate. In case the prelude re-exports are not enough, +/// this module can be used. /// -/// Any time one uses this module to access a dependency, you can have a moment to think about -/// whether this item could have been placed in any of the other modules and preludes in this crate. -/// In most cases, hopefully the answer is yes. +/// Note for maintainers: Any time one uses this module to access a dependency, you can have a +/// moment to think about whether this item could have been placed in any of the other modules and +/// preludes in this crate. In most cases, hopefully the answer is yes. pub mod deps { // TODO: It would be great to somehow instruct RA to prefer *not* suggesting auto-imports from // these. For example, we prefer `polkadot_sdk_frame::derive::CloneNoBound` rather than diff --git a/substrate/scripts/run_all_benchmarks.sh b/substrate/scripts/run_all_benchmarks.sh index fe5f89a5b56ea..053c230fedb45 100755 --- a/substrate/scripts/run_all_benchmarks.sh +++ b/substrate/scripts/run_all_benchmarks.sh @@ -108,6 +108,13 @@ for PALLET in "${PALLETS[@]}"; do FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')"; WEIGHT_FILE="./frame/${FOLDER}/src/weights.rs" + TEMPLATE_FILE_NAME="frame-weight-template.hbs" + if [ $(cargo metadata --locked --format-version 1 --no-deps | jq --arg pallet "${PALLET//_/-}" -r '.packages[] | select(.name == $pallet) | .dependencies | any(.name == "polkadot-sdk-frame")') = true ] + then + TEMPLATE_FILE_NAME="frame-umbrella-weight-template.hbs" + fi + TEMPLATE_FILE="./.maintain/${TEMPLATE_FILE_NAME}" + # Special handling of custom weight paths. if [ "$PALLET" == "frame_system_extensions" ] || [ "$PALLET" == "frame-system-extensions" ] then @@ -118,6 +125,9 @@ for PALLET in "${PALLETS[@]}"; do elif [ "$PALLET" == "pallet_asset_tx_payment" ] || [ "$PALLET" == "pallet-asset-tx-payment" ] then WEIGHT_FILE="./frame/transaction-payment/asset-tx-payment/src/weights.rs" + elif [ "$PALLET" == "pallet_asset_conversion_ops" ] || [ "$PALLET" == "pallet-asset-conversion-ops" ] + then + WEIGHT_FILE="./frame/asset-conversion/ops/src/weights.rs" fi echo "[+] Benchmarking $PALLET with weight file $WEIGHT_FILE"; @@ -133,7 +143,7 @@ for PALLET in "${PALLETS[@]}"; do --heap-pages=4096 \ --output="$WEIGHT_FILE" \ --header="./HEADER-APACHE2" \ - --template=./.maintain/frame-weight-template.hbs 2>&1 + --template="$TEMPLATE_FILE" 2>&1 ) if [ $? -ne 0 ]; then echo "$OUTPUT" >> "$ERR_FILE" @@ -173,4 +183,4 @@ if [ -f "$ERR_FILE" ]; then else echo "[+] All benchmarks passed." exit 0 -fi +fi \ No newline at end of file diff --git a/templates/minimal/pallets/template/src/lib.rs b/templates/minimal/pallets/template/src/lib.rs index b8a8614932a63..722b606079f9b 100644 --- a/templates/minimal/pallets/template/src/lib.rs +++ b/templates/minimal/pallets/template/src/lib.rs @@ -5,6 +5,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use frame::prelude::*; use polkadot_sdk::polkadot_sdk_frame as frame; // Re-export all pallet parts, this is needed to properly import the pallet into the runtime. @@ -19,4 +20,7 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(_); + + #[pallet::storage] + pub type Value = StorageValue; } diff --git a/templates/minimal/runtime/Cargo.toml b/templates/minimal/runtime/Cargo.toml index 74a09b9396e50..b803c74539ef7 100644 --- a/templates/minimal/runtime/Cargo.toml +++ b/templates/minimal/runtime/Cargo.toml @@ -13,7 +13,6 @@ publish = false codec = { workspace = true } scale-info = { workspace = true } polkadot-sdk = { workspace = true, features = [ - "experimental", "pallet-balances", "pallet-sudo", "pallet-timestamp", diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs index 4f914a823bf6d..304e50af25088 100644 --- a/templates/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -30,7 +30,7 @@ use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use polkadot_sdk::{ polkadot_sdk_frame::{ self as frame, - prelude::*, + deps::sp_genesis_builder, runtime::{apis, prelude::*}, }, *, @@ -38,15 +38,14 @@ use polkadot_sdk::{ /// Provides getters for genesis configuration presets. pub mod genesis_config_presets { + use super::*; use crate::{ interface::{Balance, MinimumBalance}, - sp_genesis_builder::PresetId, sp_keyring::AccountKeyring, BalancesConfig, RuntimeGenesisConfig, SudoConfig, }; use alloc::{vec, vec::Vec}; - use polkadot_sdk::{sp_core::Get, sp_genesis_builder}; use serde_json::Value; /// Returns a development genesis config preset. @@ -314,17 +313,17 @@ impl_runtime_apis! { } } - impl sp_genesis_builder::GenesisBuilder for Runtime { + impl apis::GenesisBuilder for Runtime { fn build_state(config: Vec) -> sp_genesis_builder::Result { build_state::(config) } - fn get_preset(id: &Option) -> Option> { + fn get_preset(id: &Option) -> Option> { get_preset::(id, self::genesis_config_presets::get_preset) } - fn preset_names() -> Vec { - crate::genesis_config_presets::preset_names() + fn preset_names() -> Vec { + self::genesis_config_presets::preset_names() } } }